#pragma rtGlobals=3 // Use modern global access method and strict wave access. //Usage: //Before opening/compiling this, first open Analysis - Packages - Multipeak Fitting - Multipeak Fitting 2 //Waves need to be appropriately scaled: this does not recognize "X" waves //Fit peaks on a single graph first using multi peak fitting //Be sure to hold appropriate parameters and add constraints if desired //Save a checkpoint. This makes a folder within the Packages folder for the fitting set with "CP" appended //Then create a graph with all the spectra on the same graph //Run this function with that graph as the top graph //Example usage: MultiBatchFitting("root:packages:MultiPeakFit2:MPF_SetFolder_1CP") Function MultiBatchFitting(datafoldername) String datafolderName String ywavelist = TraceNameList("", ";", 1) string ywave String remove1,remove2,rmv Variable nfits = ItemsInList(ywavelist) // The structure required by MPF2_DoMPFit() STRUCT MPFitInfoStruct MPStruct Variable i, err String saveDF = GetDataFolder(1) //Delete all previous "batchpeakfit" folders SetDataFolder saveDF string folderlist=DataFolderDir(1) variable lastspot=strsearch(folderlist,"BatchPeakFit",Inf,1) variable lastwave=0 string foldertokill="" variable killfolder=0 if(lastspot>-1) lastspot+=13 lastwave=str2num(folderlist[lastspot,lastspot+3]) // add 0 for up to 9 folders, add 1 for up to 99 folders, add 2 for up to 999 folders do foldertokill="BatchPeakFit_"+num2str(killfolder) KillDataFolder $foldertokill killfolder+=1 while (killfolder <= lastwave) Print "Killed old fit data folders." endif // Switch to the Multi-peak fit folder and look up some stuff //String saveDF = GetDataFolder(1) SetDataFolder datafolderName // Look up the function type list saved by Multi-peak Fit SVAR SavedFunctionTypes MPStruct.ListOfFunctions = SavedFunctionTypes // Create the list of coefficient waves and hold strings MPStruct.ListOfCWaveNames = "" MPStruct.ListOfHoldStrings = "" Wave/Z cw = 'Baseline Coefs' if (WaveExists(cw)) MPStruct.ListOfCWaveNames = NameOfWave(cw) endif MPStruct.ListOfCWaveNames += ";" Variable npeaks = 0 do Wave/Z cw = $("Peak "+num2istr(npeaks)+" Coefs") if (!WaveExists(cw)) break endif MPStruct.ListOfCWaveNames += NameOfWave(cw)+";" npeaks += 1 while (1) variable howmanypeaks = npeaks //Add hold strings Wave/T/Z hsw = 'HoldStrings' string holdinfo="" string holdstrings="" variable myi=0 do holdinfo=hsw[myi] holdstrings += holdinfo +";" myi += 1 while (myi <= howmanypeaks) MPStruct.ListOfHoldStrings = holdstrings //Get constraints wave/T ctw=$"constraintsTextWave" string constring="", cons="",newcons="" variable imax=0, pk=0,ia=0,totalcount=0,maxval=nan,minval=nan for(pk=0;pk"+num2str(minval)+";" endif endif totalcount+=0.5 endfor endfor if(strlen(newcons)!=0) Print "Applying constraints." endif SetDataFolder saveDF // fill in more members of the structure MPStruct.NPeaks = npeaks MPStruct.XPointRangeBegin = 0 // this function always fits the entire data set MPStruct.FitCurvePoints = 1000 MPStruct.fitOptions = 4 // you might want to change this to 4 // loop through each of the data sets, calling MPF2_DoMPFit // on each one. After each call, the results are checked and acted // on appropriately. variable wasalert=0 for (i = 0; i < nfits; i += 1) // We make a copy of the Multi-peak fit folder for // each data set. That also duplicates all the coefficient waves // so that we preserve the results for each fit. The duplicated data folder // is created inside the current data folder. String BatchDFName = "BatchPeakFit_"+num2str(i) DuplicateDataFolder $datafolderName, $BatchDFName // Most of the contents of the structure don't need to change. // Naturally, we have to put in a wave reference to the // data set being fit this time through the loop ywave = StringFromList(i,ywavelist) //ywave = ywave[1,(strlen(ywave)-2)] //uncomment this line if single quotes needed //Wave MPStruct.yWave = $StringFromList(i, ywavelist) // works if no quotes around wave Wave MPStruct.yWave = $ywave //apply constraints if any were found if(strlen(newcons)!=0) //Print newcons Make/N=1/O/T fittingconstraints fittingconstraints=newcons Wave/T MPStruct.Constraints = fittingconstraints endif //print which point is which wave from the top graph string messag="Point " + num2str((i)) + " wave " + ywave rmv=ywave ywave="'"+ywave+"'" Print messag // just in case the new wave has a different number of points MPStruct.XPointRangeEnd = numpnts(MPStruct.yWave)-1 err = MPF2_DoMPFit(MPStruct, saveDF+BatchDFName+":") if (err) // error return from MPF2_DoMPFit generally indicates // a programmer error DoAlert 0, "Error calling MPF2_DoMPFit: "+num2str(err) return err endif if (MPStruct.fitQuitReason == 2) // if the user aborts a fit, we assume that the whole process // should be aborted DoAlert 0, "User aborted batch fit" return -1 endif if (MPStruct.fitError) // Something went wrong with the current fit, and it // failed to converge. We note this fact to the user via // an alert, then move on to the next one. You may wish // to do something more sophisticated than this. // Avoid a long line by concatenating the message // in small pieces String alertMsg = "Error doing fit to " alertMsg += StringFromList(i, ywavelist)+": " alertMsg += num2str(MPStruct.fitError)+ " | " alertMsg += MPStruct.fitErrorMsg alertMsg += "; continuing with next fit." Print alertMsg wasalert=1 //DoAlert 0, alertMsg endif remove1 = "fit_"+rmv remove2 = "Res_"+rmv RemoveFromGraph $remove1,$remove2 endfor if(wasalert==1) alertMsg="Error detected, check history window." DoAlert 0,alertMsg endif ///////////////////////////////////////////////// //Everything below this point is custom code to display whatever parameters you want to extract SetDataFolder saveDF Make/O/N=(nfits) spanov5bws Make/O/N=(nfits) spanov5gws Make/O/N=(nfits) spanov5amps variable peak0bw,peak0gw,peak0amp for (i = 0; i < nfits; i += 1) // Get desired peak data by looping through folders BatchDFName = saveDF+"BatchPeakFit_"+num2str(i) SetDataFolder BatchDFName wave peak0vars='Peak 0 Coefs' peak0bw=peak0vars[0] peak0gw=peak0vars[2] peak0amp=peak0vars[4] SetDataFolder saveDF spanov5bws[i]=peak0bw spanov5gws[i]=peak0gw spanov5amps[i]=peak0amp endfor Display spanov5bws Display spanov5gws Display spanov5amps end