Finding maximum value in multiple waves
y.b.vogel
Hi,
I am new to Igor Pro, so apologizes if this problem is trivial.
I have a large amount of waves called wave_0, wave_1,wave_2,... The waves are 1D, a single column with numeric values. I would like to find the maximum value in each wave and save it as a new wave (maxval). I am able to do this with a single wave:
function FindMax()
wave wave_1
Make/O maxval = {WaveMax(wave_1)}
print maxval
end function
wave wave_1
Make/O maxval = {WaveMax(wave_1)}
print maxval
end function
However I do not know how could I find the maximum value for each wave and save these values in a single wave (maxval). I thought using a for loop, but not sure how.
Any help is appreciated.
Hi,
There are quite a few strategies to do this and each has advantages and limitations.
The first thing that needs to be done is to define the waves that need the max values extracted. This could be a defined list that you create (ok for a one off situation) or it could be a function that returns a list (better for repeated work flows or if you are like me and lazy which is a good thing).
string inputfilter
string theList, theRun
variable index,maxindex
// inputfilter is a string that captures the wave name filter and can include wildcards see manual for details
thelist=wavelist(inputfilter,";","")
//Now we have the whole list to work on and let's get the number of waves
maxindex=itemsInList(theList)
//Create a wave to store the results and I use the overwrite flag so if I rerun it does not give error
make/O /n=(maxindex) results
//run over the list
for(index=0;index<maxindex; index+=1)
//get the item as string
theRun=stringFromList(index,theList)
//use this to define the data wave you are interested. These two step could be combined, but I use the string in a bit
wave temp = $theRun
results[index] = wavemax(temp)
// Since I am big fan of dimension labels to keep track of data sources I label each point
setdimLabel 0,index,$theRun, Results
// I set the point label to the wave name of data wave that
endfor
End
You could run it like
get_maxvalues("test*") which will create a list of waves that start with test and process that list.
An alternative approach that works if the waves are the same length.
Use concatenate to create a new master wave that is a 2D wave with each column holding the data from each wave and I use /DL flag to set the column dimension label to the wave name
Then run wavestats /PCST which:
Computes the statistics on a per-column basis for a real valued wave of two or more dimensions. The results are saved in the wave M_WaveStats which has the same number of columns, layers and chunks as the input wave and where the rows, designated by dimension labels, contain the standard WaveStats statistics. All the V_ variables are set to NaN. Note that this flag is not compatible with the flags /C, /R, /RMD.
string inputFilter
string theList
thelist=wavelist(inputfilter,";","")
// Create a 2D wave with the data as free wave
concatenate/FREE /DL theList, ConCatWave
Wavestats /PCST ConcatWave
Wave results = M_WaveStats
//Copy the wave data labels as data provenance
CopydimLabels /COLS=1 ConCatWave, results
// I like to have the stats in columns instead of rows
matrixtranspose results
end
The advantage of this approach is that it gives you many more stats for "free" including mean, min, std dev,..
Andy
December 16, 2021 at 08:00 am - Permalink
Here is another option for inspiration. It will introduce you to wave reference waves, wave indexing, multithreading, free waves and other interesting bits
// Defines a datafolder to look for waves in
DFREF MyFolder=root:
// Counts the number of waves in the folder
Variable NumberOfWaves=CountObjectsDFR(MyFolder, 1)
// Creates a wave reference list of all waves in the folder
Make/FREE/O/WAVE/N=(NumberOfWaves) WaveRefWave
MultiThread WaveRefWave=WaveRefIndexedDFR(MyFolder, p)
// Extracts the number of numeric waves
Extract/FREE/INDX/O WaveRefWave, IndexWave, (WaveType(WaveRefWave[p], 1)==1)
Variable NumberOfNumericWaves=NumPnts(IndexWave)
// Finds the maximum value in each wave and saves them as a new wave
Make/O/N=(NumberOfNumericWaves) MyFolder:MaxValues/WAVE=MaxValues
MultiThread MaxValues=WaveMax(WaveRefWave[IndexWave[p]])
end
December 17, 2021 at 06:00 am - Permalink
Keep in mind that the MaxValues wave in created in root: so if you run the function twice it will also find the maximum value in the old MaxValue wave and include that.
December 17, 2021 at 06:03 am - Permalink