#pragma rtGlobals=1 // Use modern global access method. // This was originally written 2001-2003 ish. This works very differently than SANSview, and I haven't // mentioned that this exists, so that their ideas will be new. Still, some of this may be // serviceable for use within the Igor package, with some cleanup of the interface and functionality. // // // // to do - July 2010 // // X- smeared models don't work at all (now they work) // x- the report is good, but the parsing is not great - the format // could be more convenient to read back in to a table (text col, num cols (matrix that can be plotted?) // x- Maybe the report could be compiled as waves. Then they would be numeric. Nothing to plot them against // other than file names, but with a table of values and names, one could manually enter a meaningful // column of values to plot against. // x- Make_HoldConstraintEps_Waves() is currently disabled, both on the macros menu and the checkbox on the panel // Constraints and holds are part of the matrix already, so this would only be for epsilon // x- Many of the items on the Macros menu are just junk. Remove them. // // x- savePath is obsolete. Remove the button. Report saving is sent to the procedure defined in Wrapper.ipf, and uses the home path // x- add a checkbox for "all" to select all data files (function is already set -- CheckAllFiles()) // // x- make it easy for the user to save the results in a whole table. // x- remind to rename the results (or move to a folder?) before another batch is run // x- what to plot against? // // x- add a little text box of explanation on each of the tabs at the bottom - to give simple // instructions of what to do on each tab. This will need to change with each tab. // // x- need a help button to link to the help file // -- Comprehensive instructions (after features are finalized) // // -- add a way to save the setup and guesses. May be tough if the file list changes... Menu "Macros" SubMenu "Auto Fit" "Initialize AutoFit Panel" "-" // "Generate_Data_Checklist" // "Make_HoldConstraintEps_Waves" //this is currently disabled // "-" // "CompileAndLoadReports" "Compile_Reports" "Load Compiled Reports" // "Compile_GlobalFit_Reports" "-" "Close Open Notebooks" "Print Open Notebooks" "-" "Generate_PNG_list" "Layout_PNGs" End End //*********** //Automatic fitting routines for SANS or NSE data //requires model functions and their associated files // //************** //path to the data // ? have this automatically do the listing? Function PDPButton(ctrlName) : ButtonControl String ctrlName //set the global string to the selected pathname NewPath/O/M="pick the data folder" dataPath PathInfo/S dataPath Return(0) End Function SavePathButtonProc(ctrlName) : ButtonControl String ctrlName //set the global string to the selected pathname NewPath/O/M="pick the save folder" savePath PathInfo/S savePath Return(0) End // // this re-sizes AND re-initializes the guessMatrix // and is only done when the files are re-listed, using the list button - since the // new list will screw up the correspondence with the guess matrix // Function FileListButtonProc(ctrlName) : ButtonControl String ctrlName DoAlert 1,"This will re-initialize the file list and ALL of the entries in the guess matrix. Do you want to proceed?" if(V_flag!=1) //if the answer is not yes, get out return(0) endif String fileList="" fileList = IndexedFile(dataPath,-1,"????") fileList = RemoveFromList(".DS_Store", fileList, ";",0) List2TextWave(Filelist,";","root:AutoFit:fileListWave") Wave/T lw = $"root:AutoFit:fileListWave" Redimension/N=(-1,2) lw lw[][1] = "" Variable num = DimSize(lw,0) Wave sw = $"root:AutoFit:fileSelWave" Redimension/B/N=(num,2) sw sw[][1] = (sw[p][1] == 0) ? 2^5 : sw[p][1] //if the element is zero, make it 32, otherwise leave it alone // force a re-size (and re-initialization) of the guess-hold-constr-range matrices ToMatrixButtonProc("") return(0) End //currently set up to toggle state, based on the first row // Function CheckAllFiles(ctrlName,checked) : CheckBoxControl String ctrlName Variable checked WAVE sel = root:AutoFit:fileSelWave if( (sel[0][1] & 0x10) == 16 ) //first box is checked sel[][1] = 2^5 // uncheck them all else sel[][1] = 2^5 + 2^4 //bit 5== checkbox, bit 4== checked endif return(0) End // // this re-sizes AND re-initializes the guessMatrix // and is only done when the files are re-listed, using the list button - since the // new list will screw up the correspondence with the guess matrix // Function ToMatrixButtonProc(ctrlName) : ButtonControl String ctrlName SetDataFolder root:AutoFit WAVE sel = fileSelWave NVAR numPar=numPar Variable jj,numSelFiles=0 //update the number of steps for the progress bar // commented out - SRK - 28MAR05 // NVAR cur=curProgress // NVAR totSteps=endProgress // cur=0 // totSteps=numSelFiles*3 //3 fits per file // ValDisplay progressValdisp,limits={0,totSteps,0} // ControlUpdate/W=AutoFitPanel progressValdisp //redimension the matrices and lists Redimension/N=(numPar,DimSize(sel,0)) guessMatrix,HoldMatrix,constrMatrix,rangeMatrix Redimension/N=(numPar) guessList,holdList,constrList,rangeList,guessSel,holdSel,constrSel,rangeSel //Set the matrices to zero WAVE/T aa = guessMatrix WAVE/T bb = holdMatrix WAVE/T cc = constrMatrix WAVE/T rr = rangeMatrix aa="1" bb="0" cc="" //set to no constraints rr="0" // zero in points 0 and 1 force a fit of all of the data (default) //set the Lists to "0" WAVE/T dd=guessList WAVE/T ee=holdList WAVE/T ff=constrList WAVE/T rrl=rangeList dd="0" ee="0" ff="0" rrl="0" //Set the sel waves to 2 (editable) WAVE gg=guessSel WAVE hh=holdSel WAVE ii=constrSel WAVE rrs=rangeSel gg=2 hh=2 ii=2 rrs=2 SetDataFolder root: DisplayGuess() tabProc("",0) //force the Guess tab to top TabControl tabC,value=0 return(0) End //updates the lists (text waves) to display, depending on the current highlighted file Function DisplayGuess() //find the selected data file -[][0] is the file, not the checkbox Variable row row = FindSelectedRowInLB(0) // send 0 to look at the column with filenames //update the text waves based on the values in the matrix WAVE/T gm = root:AutoFit:guessMatrix WAVE/T gl = root:AutoFit:guessList // the hold matrix WAVE/T hm=root:AutoFit:holdMatrix WAVE/T hl=root:AutoFit:holdList // the constraint matrix WAVE/T cm=root:AutoFit:constrMatrix WAVE/T cl=root:AutoFit:constrList // the range matrix WAVE/T rm=root:AutoFit:rangeMatrix WAVE/T rl=root:AutoFit:rangeList WAVE sel = root:AutoFit:fileSelWave if( (sel[row][1] & 0x10) == 16 ) //box is checked gl = gm[p][row] hl = hm[p][row] cl = cm[p][row] rl = rm[p][row] else //file is not checked, don't display guess gl = "Not checked" hl = "Not checked" cl = "Not checked" rl = "Not checked" endif return(0) End //column 0 is the filenames, 1 is the checkboxes //returns the row that is selected, -1 if not found Function FindSelectedRowInLB(col) Variable col WAVE sel = root:AutoFit:fileSelWave Variable jj=0,row=-1 if(col==0) do if( (sel[jj][0] & 0x01) == 1 ) //returns 1 (bit 0) if selected, 0 otherwise row=jj //print "Row = ",jj break endif jj+=1 while(jj 0) Wave eps=$epsilonStr //in the root folder useEps = 1 endif //fit it //these two global variables must be created for IGOR to set them, so that //any errors in the fitting can be diagnosed Variable/G V_FitError=0 //0=no err, 1=error,(2^1+2^0)=3=singular matrix Variable/G V_FitQuitReason=0 //0=ok,1=maxiter,2=user stop,3=no chisq decrease NVAR tol=root:AutoFit:fitTol Variable/G V_FitTol=tol //default is 0.0001 Variable/G V_fitOptions=4 //suppress the dialog during fitting (we're not waiting for OK, anyways) Wave yw = $(DF+dataName+"_i") Wave xw = $(DF+dataName+"_q") Wave sw = $(DF+dataName+"_s") if(stringmatch(funcStr, "Smear*")) // if it's a smeared function, need a struct useRes=1 endif Struct ResSmearAAOStruct fs WAVE/Z resW = $(DF+dataName+"_res") //these may not exist, if 3-column data is used WAVE/Z fs.resW = resW WAVE yw=$(DF+dataName+"_i") WAVE xw=$(DF+dataName+"_q") WAVE sw=$(DF+dataName+"_s") Wave fs.coefW = cw Wave fs.yW = yw Wave fs.xW = xw Duplicate/O yw $(DF+"FitYw") WAVE fitYw = $(DF+"FitYw") fitYw = NaN NVAR useGenCurveFit = root:Packages:NIST:gUseGenCurveFit ///// SEE FitWrapper() for more details. Variable nPass = 1 do // outer do is the loop over passes do // this inner loop is abig switch to select the correct FutFunc to dispatch if(useGenCurveFit) #if !(exists("GenCurveFit")) // XOP not available useGenCurveFit = 0 Abort "Genetic Optimiztion XOP not available. Reverting to normal optimization." #endif //send everything to a function, to reduce the clutter // useEps and useConstr are not needed // pass the structure to get the current waves, including the trimmed USANS matrix Variable chi,pt chi = DoGenCurveFit(useRes,useCursors,sw,fitYw,fs,funcStr,ParseHoldString(ii,numpar,holdMatrix),val,lolim,hilim,pt1,pt2) pt = val break endif if(useRes && useEps && useCursors && useConstr) //do it all FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs break endif if(useRes && useEps && useCursors) //no constr FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs break endif if(useRes && useEps && useConstr) //no crsr FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs break endif if(useRes && useCursors && useConstr) //no eps FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /D=fitYw /C=constr /STRC=fs break endif if(useRes && useCursors) //no eps, no constr FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /D=fitYw /STRC=fs break endif if(useRes && useEps) //no crsr, no constr FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs break endif if(useRes && useConstr) //no crsr, no eps FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr /STRC=fs break endif if(useRes) //just res FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /STRC=fs break endif ///// same as above, but all without useRes (no /STRC flag) if(useEps && useCursors && useConstr) //do it all FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr break endif if(useEps && useCursors) //no constr FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /E=eps /D=fitYw break endif if(useEps && useConstr) //no crsr FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr break endif if(useCursors && useConstr) //no eps FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /D=fitYw /C=constr break endif if(useCursors) //no eps, no constr FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw[pt1,pt2] /X=xw /W=sw /I=1 /D=fitYw break endif if(useEps) //no crsr, no constr FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw break endif if(useConstr) //no crsr, no eps FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr break endif //just a plain vanilla fit FuncFit/H=ParseHoldString(ii,numpar,holdMatrix) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw while(0) //always exit the inner do to select the FutFunc syntax. The break will exit this loop if(nPass == 1) UpdateStatusString(dataname +" Fit #1") Variable/G gChiSq1 = V_chisq endif if(nPass == 2) UpdateStatusString(dataname +" Fit #2") Variable/G gChiSq2 = V_chisq endif if(nPass == 3) UpdateStatusString(dataname +" Fit #3") endif nPass += 1 while(nPass < 4) // append the fit // need to manage duplicate copies // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...) String traces=TraceNameList("", ";", 1 ) //"" as first parameter == look on the target graph if(strsearch(traces,"FitYw",0) == -1) if(useGenCurveFit && useCursors) WAVE trimX = trimX AppendtoGraph fitYw vs trimX else AppendToGraph FitYw vs xw endif else RemoveFromGraph FitYw if(useGenCurveFit && useCursors) WAVE trimX = trimX AppendtoGraph fitYw vs trimX else AppendToGraph FitYw vs xw endif endif ModifyGraph lsize(FitYw)=2,rgb(FitYw)=(52428,1,1) //do the report calling the function, not the proc String topGraph= WinName(0,1) //this is the topmost graph SVAR suffix = root:AutoFit:gExt //don't try to read as getModelSuffix(funcStr), since the smeared() may not be plotted String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+"_"+suffix, "", "TEXT:1," ) // this is *hopefully* one wave if(isNSE) GenerateReport_NSE(funcStr,dataname,"par","myCoef",1) else W_GenerateReport(funcStr,dataname,$parStr,$"myCoef",1,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph) // AutoFit_GenerateReport(funcStr,dataname,"par","myCoef",1) endif // if checked, also write out the fitted waves and coefficients as a text file, maybe an Igor Text format, or just plain text. if(1) AF_SaveFitWaves(dataName,$"myCoef",W_sigma,fitYw,xw) endif return(0) End // if checked, also write out the fitted waves and coefficients as a text file, maybe an Igor Text format, or just plain text. // Function AF_SaveFitWaves(dataName,cw,cw_err,yw,xw) String dataName Wave cw,cw_err,yw,xw String saveName,formatStr Variable refNum PathInfo dataPath saveName = S_path+dataName+"_fit.txt" formatStr="%15.4g\t%15.4g" formatStr += "\r" // Print saveName Open refNum as saveName fprintf refnum,"Model data created %s\r\n",(date()+" "+time()) wfprintf refnum,formatStr,xw,yw close refnum // then the coefficients saveName = S_path+dataName+"_coef.txt" Open refNum as saveName fprintf refnum,"Model coefficients and One Std. Deviation %s\r\n",(date()+" "+time()) wfprintf refnum,formatStr,cw,cw_err close refnum return(0) End //// to be able to simply fill in the pt range of the yw[lo,hi] //Function LowRange() // NVAR val = root:AutoFit:ptLow // return(val) //End // //Function HighRange() // NVAR val = root:AutoFit:ptHigh // return(val) //End //updates the status string, forcing a redraw twice, to overcome what seems to be a bug in Igor4 //also updates the progress bar and the countdown Function UpdateStatusString(newStr) String newStr SVAR gStatus=root:AutoFit:gStatus SVAR gStatFormat=root:AutoFit:gStatFormat gStatus="" ControlUpdate/W=AutoFitPanel tb1 //clears the line gStatus=gStatFormat+newStr ControlUpdate/W=AutoFitPanel tb1 //update the progress bar and timer NVAR cur=root:AutoFit:curProgress NVAR endProgress=root:AutoFit:endProgress NVAR startTicks=root:AutoFit:startTicks cur+=1 // Print "****" // Print "cur = ",cur Variable t2=ticks,projTot,projRemain String titleStr="" projTot = (t2-startTicks)/(cur-1)*endProgress projRemain = projTot - (t2-startTicks) projRemain /= 60.15 //to seconds DoWindow/F AutoFitPanel ValDisplay progressValdisp,title=Secs2time(projRemain,5) ControlUpdate/W=AutoFitPanel progressValdisp // Print "End Progress = ",endProgress // Print "ProjTot = ",projTot/60.15 // Print "ProjRemain = ",projRemain return(0) End // returns a string with the name of the epsilon wave, or null if it doesn't exist Function/S GetEpsilonWave() String retStr="",testStr SVAR extStr = root:AutoFit:gExt //do you want to use epsilon wave? ControlInfo/W=AutoFitPanel epsilonCheck if(V_Value == 0) //not checked return(retStr) endif testStr = "Epsilon_"+extStr if(waveexists($testStr) != 0) // return(" /E="+testStr) return(testStr) endif return(retStr) End //returns the y data to fit - "_i" suffix, and range if selected // enter the range as the first element[0] as low point, second element[1] as high point // leave the other elements blank // // if either point value is not entered, the whole data set is used // // -- if both of the elements are between 0 and 1, assume they are q-values (check for fractional part) // and find the appropriate points... // Function ParseRangeString(set,dataStr,rMat,lo,hi) Variable set String dataStr WAVE/T rMat Variable &lo,&hi Variable useCursors lo = str2num(rMat[0][set]) hi = str2num(rMat[1][set]) if(lo == 0 && hi == 0) return(0) endif if(numtype(lo) != 0 || numtype(hi) != 0) //not a normal number return(0) //don't use cursor values, use all of the dataset endif if(lo>=hi) //error in specification, or all data desired (both zero or undefined) return(0) //use all of the dataset endif if(trunc(lo) != lo || trunc(hi) != hi) //values have fractional parts WAVE xW = $("root:"+dataStr+":"+dataStr + "_q") FindLevel/P/Q xW, lo lo = trunc(V_levelX) //find the corresponding point values FindLevel/P/Q xW, hi hi = trunc(V_levelX) endif Variable/G root:AutoFit:ptLow = lo Variable/G root:AutoFit:ptHigh = hi return(1) End //returns the holdStr, i.e. "1010101" Function/S ParseHoldString(set,npar,hMat) Variable set,npar WAVE/T hMat Variable ii String retStr="" for(ii=0;ii"+loStr jj+=1 endif if(cmpstr(hiStr,"")!=0) //something there... InsertPoints jj,1,cw //insert before element jj cw[jj] = "K"+num2Str(ii)+"<"+hiStr jj+=1 endif endfor if(numpnts(cw) > 0 ) retStr = "/C=" + outWStr Endif // print "strlen, conStr= ",strlen(retStr),retstr return(retStr) //null string will be returned if no constraints End //************************* Proc DoGraph(dataname) String dataname SetDataFolder $dataname PauseUpdate; Silent 1 // building window... Display /W=(5,42,301,313)/K=1 $(dataname+"_i") vs $(dataname+"_q") DoWindow/C AutoGraph ModifyGraph mode($(dataname+"_i"))=3 ModifyGraph marker($(dataname+"_i"))=19 ModifyGraph rgb($(dataname+"_i"))=(1,4,52428) ModifyGraph msize($(dataname+"_i"))=2 ModifyGraph grid=1 ModifyGraph log=1 ModifyGraph tickUnit=1 // ModifyGraph mirror=2 // ErrorBars $(dataname+"_i") Y,wave=($(dataname+"_s"),$(dataname+"_s")) // Legend/A=LB // Legend/A=LB/X=0.00/Y=-32 //defaults to the top right Legend/A=MT/E // /X=-16.16/Y=5.17/E SetDataFolder root: EndMacro Proc DoGraph_NSE(dataname) String dataname SetDataFolder $dataname PauseUpdate; Silent 1 // building window... Display /W=(5,42,301,313)/K=1 $(dataname+"_i") vs $(dataname+"_q") DoWindow/C AutoGraph_NSE ModifyGraph mode($(dataname+"_i"))=3 ModifyGraph marker($(dataname+"_i"))=19 ModifyGraph rgb($(dataname+"_i"))=(1,4,52428) ModifyGraph msize($(dataname+"_i"))=3 ModifyGraph zColor($(dataname+"_i"))={$(dataname+"__Q"),$(dataname+"__Q")[0]*0.99,*,Rainbow} ModifyGraph grid=1 ModifyGraph mirror=2 ModifyGraph log(left)=1 ErrorBars $(dataname+"_i") Y,wave=($(dataname+"_s"),$(dataname+"_s")) Legend/A=MB SetAxis/A/E=1 bottom ModifyGraph standoff=0 SetAxis left 0.1,1 //ModifyGraph tickUnit(left)=1 EndMacro //************************* //************************** // Generate the report //************************** ////must have AutoGraph as the name of the graph window (any size) //// func is the name of the function (for print only) ////par and coef are the exact names of the waves ////yesSave==1 will save the file(name=func+time) //// //// //// general report function from the wrapper is used instead //// W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph) //// //Function AutoFit_GenerateReport(func,dataname,par,myCoef,yesSave) // String func,dataname,par,myCoef // Variable yesSave // // String str,pictStr="P_" // Wave sigWave=$"W_sigma" // Wave ans=$myCoef //// Wave/T param=$par // SVAR ext=root:AutoFit:gExt // Wave/T param=$"parameters_"+ext // // NVAR V_chisq = V_chisq // NVAR V_npnts = V_npnts // NVAR V_FitError = V_FitError // NVAR V_FitQuitReason = V_FitQuitReason // NVAR chi1=gChiSq1 // NVAR chi2=gChiSq2 // NVAR V_startRow = V_startRow // NVAR V_endRow = V_endRow // // // bring report up // DoWindow/F Report // if (V_flag == 0) // Report notebook doesn't exist ? // NewNotebook/W=(10,45,550,620)/F=1/N=Report as "Report" // endif // // // delete old stuff // Notebook Report selection={startOfFile, endOfFile}, text="\r", selection={startOfFile, startOfFile} // // // insert title // Notebook Report newRuler=Title, justification=1, rulerDefaults={"Times", 16, 1, (0, 0, 0)} // sprintf str, "Fit to %s, %s, %s\r\r", func,Secs2Date(datetime, 0), time() // Notebook Report ruler=Title, text=str // // // insert fit results // Variable num=numpnts(ans),ii=0 // Notebook Report ruler=Normal; Notebook Report margins={18,18,504}, tabs={63 + 3*8192} // str = "Data file: " + dataname + "\r\r" // Notebook Report text=str // do // sprintf str, "%s = %g±%g\r", param[ii],ans[ii],sigwave[ii] // Notebook Report text=str // ii+=1 // while(ii0) End //********************* //******************* //Notebook Utils //******************* Proc PrintOpenNotebooks() String list=WinList("*", ";", "WIN:16") String item = "" do item=StringFromList(0,list,";") Print item PrintNotebook $item list = RemoveFromList(item, list, ";") while(ItemsInList(list, ";")>0) End Proc CloseOpenNotebooks() String list=WinList("*", ";", "WIN:16") String item = "" do item=StringFromList(0,list,";") DoWindow/K $item list = RemoveFromList(item, list, ";") while(ItemsInList(list, ";")>0) End Proc Generate_PNG_list() fGenerate_PNG_list() End //spits up a list of PNGS Function fGenerate_PNG_list() // String List=IndexedFile(savePath, -1, ".png") String List=IndexedFile(home, -1, ".png") List2TextWave(List,";","PNG_files") WAVE/T PNGs=$"PNG_files" Edit/K=1 PNGs End Proc Layout_PNGS(pStr) String pStr="" Prompt pStr,"wave of PNGs to use",popup,WaveList("PNG*", ";", "") String List=TextWave2List($pStr,";") String item = "" //kill old picts from memory KillPicts/A/Z //make a new layout Layout/C=1 as "PNG_Layout" DoWindow/C PNGLayout do item=StringFromList(0,List,";") //load each PNG, and append it to the layout Print "load item = ",item // LoadPICT /O/Q/P=savePath item LoadPICT /O/Q/P=home item DoWindow/F PNGLayout //be sure layout is on top AppendLayoutObject /F=1/W=PNGLayout picture $CleanupName(item,0) //AppendToLayout $item //Print item List = RemoveFromList(item, List, ";") while(ItemsInList(List, ";")>0) //tile the PNGs in the layout Tile/O=8 End //spit up a list of everything in the folder that is a text file Proc Generate_Data_Checklist() fGenerate_Data_list() End Function fGenerate_Data_list() String List=IndexedFile(dataPath, -1, "TEXT") List2TextWave(List,";","data_files") WAVE/T files=$"data_files" Duplicate/O/T files ModelToUse,Done ModelToUse = "" Done = "" Edit/K=1 files,ModelToUse,Done End //*************** // with all of the notebooks open for a given model (with N parameters) // this will comile the reports, save the text notebook, then load it back in // and put it in a table for easy printing // Proc CompileAndLoadReports() Compile_Reports() // SaveNotebook /O/P=savePath/S=2 Compilation SaveNotebook /O/P=home/S=2 Compilation // Print "Saved as: ",S_Path DoWindow/K Compilation LoadCompiledReports(S_Path) End Proc LoadCompiledReports(str) String str LoadWave/J/D/W/E=1/K=0/V={"\t"," $",0,0} str End Proc Compile_Reports(Number_of_Parameters,tagStr) Variable Number_of_Parameters=(root:AutoFit:numPar) String tagStr="v1" fCompile_ReportsTable(Number_of_Parameters,tagStr) fCompile_Reports(Number_of_Parameters) DoWindow/F AutoFitResults End Proc Compile_GlobalFit_Reports(WhichParameter,FileStr,ParamStr,ParamErrStr) Variable WhichParameter=7 String FileStr="FileName_",ParamStr="par_",ParamErrStr="parErr_" fCompile_GlobalFit_Reports(WhichParameter,FileStr,ParamStr,ParamErrStr) End //// Function fCompile_Reports(nPar) Variable nPar String list=WinList("*", ";", "WIN:16") String item = "",textStr="",newStr="" Variable sstop,dum,chi Variable ii NewNotebook/F=0 /N=Compilation as "Compilation" Notebook Compilation text="Variable Name \tValues\tErrors\r" do item=StringFromList(0,list,";") DoWindow/F $item Notebook $item selection={(2,0), (3,0)} //paragraph 3 (starts from 0) = filename GetSelection notebook,$item,2 textStr=S_Selection textStr=textStr[0,strlen(textStr)-2] //remove CR textStr=textStr[10,strlen(textStr)-1] //remove "DATA FILE: Notebook Compilation text="File:\t"+textStr+"\t" Notebook Compilation text=textStr+"_err\r" // printf "%s %s\r",textStr,textStr+"_err" // // results are written as: "%s = \t%g\t±\t%g\r" // for(ii=0;ii0) DoWindow/F Compilation Notebook Compilation selection={startOfFile,startOfFile} End //// // compiles the results into a table. // add tagStr to the end to (try) to make sure that the compilations are unique Function fCompile_ReportsTable(nPar,tagStr) Variable nPar String tagStr String list=WinList("*", ";", "WIN:16") String item = "",textStr="",newStr="",str Variable sstop,dum,chi Variable ii,numRep,jj,val1,val2,pt numRep=ItemsInList(list,";") Make/O/T/N=(numRep) $("fittedFiles"+"_"+tagStr) Make/O/D/N=(numRep) $("chiSQ"+"_"+tagStr) Wave/T fittedFiles = $("fittedFiles"+"_"+tagStr) Wave chiSq = $("chiSQ"+"_"+tagStr) Edit/N=AutoFitResults fittedFiles,chiSQ for(ii=0;ii