Finding maximum value in multiple waves

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

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).

Function get_maxvalues(inputfilter)
    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.

function get_stats(inputFilter)
    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

Here is another option for inspiration. It will introduce you to wave reference waves, wave indexing, multithreading, free waves and other interesting bits
 

Function MyFunction()

    //  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

 

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.