Finding a peak value and a y maximum corresponding to maximum x value in a 2d wave
greenriver
Hi all,
I have a 2d wave with 400 rows and 50 columns, a wave-x, and a wave-y. A wave-x and a wave-y correspond to the rwos and columns of the 2d wave. I am searching a way to solve the followings.
(i) finding a peak value in every row of the 2d wave, which follows lognormal distribution.
(ii) finding a y value where the peak value exists every row.
Finally, I would like to get two waves including results of (i) and (ii).
Thank you for any suggestion.
You can just use the point number (row location) to access the corresponding value in the x wave. Use square brackets to do so:
•WaveStats yWave
V_npnts= 100; V_numNaNs= 0; V_numINFs= 0; V_avg= 0.040611;
V_Sum= 4.0611; V_sdev= 1.01568; V_sem= 0.101568; V_rms= 1.01141;
V_adev= 0.809275; V_skew= 0.506827; V_kurt= -0.201675;
V_minloc= 16; V_maxloc= 86; V_min= -1.71073; V_max= 3.0736;
V_minRowLoc= 16; V_maxRowLoc= 86; V_startRow= 0; V_endRow= 99;
•Print xWave[V_minRowLoc]
32
September 23, 2020 at 11:04 pm - Permalink
In reply to You can just use the point… by sjr51
I have a big data set with many rows, where I need x values. Using just the point numbers takes too much time. I need a way efficiently find corresponding x value in each row and make a new wave.
October 1, 2020 at 05:04 am - Permalink
WaveStats has /RMD which allows to work only on one row.
October 1, 2020 at 07:42 am - Permalink
@greenriver I'm not clear on what you're asking- I take it you have a 2D wave. Do you have another wave with X values for the rows? Or have you set the X scaling? When you say, "Using just the point numbers takes too much time" can you tell us what Igor commands are involved?
October 1, 2020 at 09:18 am - Permalink
In reply to @greenriver I'm not clear on… by johnweeks
Dear all, I am very sorry for my mistake in the previous question. I've editied my question. Any suggestion would be very helpful.
October 4, 2020 at 10:22 pm - Permalink
I am not sure I still understand. And it is better not to edit the prior message (because of replies to it) but restate the problem.
Here is my best guess: I think you have 2D wave which represents 400 measurements of some value for which you have 50 points. That could be written in 2D wave with 400 rows and 50 columns. You are trying to find peak value in each row (= for each measurement). That is easy, you need to write function which works on 50 point wave and returns you index value of the peak value location as well as maximum value in this location (if not simply value of the data point there). Then run a loop over all rows, which extract a wave from each row, evaluates this function, saves the value returned. You have 400 values, one for each row.
What confuses me is what the x-wave and y-wave relate to.
I understand to have y-values for each column, that could mean you have specific measurement location for each point which may not be equidistant. In this case after you find maximum location in point number V_maxLoc, you simply get wavey[V_maxLoc] and you have value at that location. So your location is wavey[V_maxLoc] and value in this location is the row[V_maxLoc].
What I do not understand is what the x-wave contains and why do you need it. It seems to relate to the rows (400 rows) which you seem to treat as independent observations? Are these specific locations (e.g. time of observation) of measurements? You can, of course, plot wavey[V_maxLoc] vs wavex and, you would get plot of maximum value in wavey vs time of observation in wavex.
But all of this is speculation, because this all can be completely wrong.
Now you added something about lognormal distribution. My best guess is that the values in any row are measurements which you expect to follow differential lognormal distribution. If that is the case, the question is agains which axis. If against point numbers or against values from wavey. In either case, this changes only one small thing - when processing line, instead of doing wavestats on each row, you will ned to do more complicated analysis. How complicated depends on what you need to fit and how.
So, basically... You need to write function, which returns for a row of data whatever you are looking for (e.g., location of maximum when fitted by log-normal distribution - and possibly maximum value if you need it). Test that. Then write a loop over all rows which extracts these values. Now you have 400 points, which are locations for your point of interest. Then you need to convert that to proper value from wavey and plot against row number of wavex values.
I cannot imagine this taking excessive time, but if it does, this probably can be sped up by some tricks. Multithread processing can handle some of that as line analysis can be run in parallel. Some other steps might be faster with MatrixOp, may be. But fitting log-normal distribution will be slowest step likely anyway and there is not much you can do on that.
But as said, this is my best guess and this may be completely wrong.
October 5, 2020 at 10:22 am - Permalink
If what you need is a 1D wave with the maximum value from each row of your 2D wave, you can use MatrixOP:
MatrixOP maxFromRows = MaxRows(TwoDWave)
Naturally, substitute a better name for your situation than "maxFromRows" and use the actual name of your 2D wave instead of "TwoDWave".
October 5, 2020 at 11:30 am - Permalink
I should note that the maxRows keyword requires Igor 8 or later.
October 5, 2020 at 01:39 pm - Permalink
In reply to If what you need is a 1D… by johnweeks
@johnweeks, Good! I got peak values in every row using "MatrixOP". Thanks!!
October 5, 2020 at 07:11 pm - Permalink
In reply to I am not sure I still… by ilavsky
@ilavsky, Thank you for your effort to understand and solve out the issue that I face. It would be much better to approach it with a sample data. Please find the attachment. Basically, I have "TwoDWave" that is 2d-wave, "wave-x", and "wave-y". "wave-x" and "wave-y" are corresponding to "TwoDWave". The "wave-x" is datetime information for each measurement. The "wave-y" is y values for each column of the 2d-wave, as you guess.
I've tried "MatrixOP" function and found peak values in each measurement. So, my issue (i) is solved out.
For issue (ii), I would find a y value (not the location!) where a peak value found in each row. For example, in the file attached, the value "0.46258" in maxFromRows came from 25th column of TwoDWave. The value of 25th row in wave-y is "194.247", which is what I need to finid. It there a way to extract the y values? If you are not still clear, please let me know. Thank you in advance!
October 5, 2020 at 07:29 pm - Permalink
In reply to Thank you for your effort to… by greenriver
print wavey[V_maxColLoc]
October 6, 2020 at 03:34 am - Permalink
Well, tony answered the question correctly, but may be bit too terse for what you may need. This is kind of Igor 101, so reading manual here about what wave point numbers are would be helpful.
MatrixOp returns you point number, that is in which column the maximum is (maxLocation=25 in your case). As tony pointed out, you just get the value of wavey in that point : wavey[maxLocation] ( print wavey[maxLocation] will give you 194.247). Be careful to use proper [ ] and not ( ) which would use wave scaling. It might give the same value in this case, but it would be by accident.
Best guess - and this has no declarations of waves and no error checking, so this is really a code sketch at best....
//maxFromRowsLoc should be 1D wave with point number for maximum locations
Duplicate maxFromRowsLoc, maxFromRowsVals //make wave for values in the max
maxFromRowsVals = wavey[maxFromRowsLoc]
//maxFromRowsVals now has values of wavey in points maxFromRowsLoc
//Assuming you also have wavex with the times when each row was collected
Display maxFromRowsVals vs wavex
//should create graph of maximum values for each row against time when they were collected
This is very basic way Igor addresses the waves. Reading at least introduction chapter for Igor should make this clear and Guided tour of Igor will be even better. It is not long. It is kind of cool reading in the evening, next to fireplace...
Note that no data seem attached to your prior post, but I think by now it is clear.
October 6, 2020 at 07:20 am - Permalink
In reply to Well, tony answered the… by ilavsky
While you're online here at Igor Exchange, Igor video tutorials discus "wave scaling" starting at 2:10 in Guided Tour 1.
https://www.wavemetrics.com/products/igorpro/videotutorials
October 6, 2020 at 09:37 am - Permalink
Reading the Igor manual will teach you a lot, and if you read in bed it will solve insomnia :)
October 6, 2020 at 01:50 pm - Permalink
In reply to Well, tony answered the… by ilavsky
@ilavsky, thank you for your approach! But MaxRows function gives me the maximum value of each row, not the point number. I would start one by one as you suggested. :)
October 7, 2020 at 12:32 am - Permalink
In reply to Reading the Igor manual will… by johnweeks
Thank you all for your help. @johnweeks, I will restart read the manual, although that is a kind of nightmare.. ! :) Thank you.
October 7, 2020 at 12:35 am - Permalink
In reply to Thank you all for your help… by greenriver
To expand on my horribly terse response, a (very inefficient) way to do this with wavestats:
wavestats /Q /RMD=[row, row][] w
return v_max
end
function getMaxLoc(wave w, variable row)
wavestats /Q /RMD=[row, row][] w
return V_maxColLoc
end
make /n=(dimsize(w, 0)) wmax, wmaxloc
wmax=getMax(w, p)
wmaxloc=ywave[getMaxLoc(w, p)]
if the values in ywave are regularly spaced, you can set the y scale for your twoDwave:
setscale /I y, ywave[0], ywave[numpnts(ywave)-1], w
then V_maxColLoc will give you the location without having to look in ywave.
October 7, 2020 at 05:06 am - Permalink
I have to think that this is equivalent to asking for an image analysis method that will trace a path along a mountain range, with no doubling back.
October 7, 2020 at 04:39 pm - Permalink