#pragma rtGlobals=1 // Use modern global access method. // This was originally written 2001-2003 ish. This works very differently than SANSview, and I havne'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) // -- 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?) // -- 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. // -- 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, soo this would only be for epsilon // -- Many of the items on the Macros menu are just junk. // // -- Comprehensive instructions (after features are finalized) // // -- savePath seems to be obsolete. Report saving is sent to the procedure defined in Wrapper.ipf, and uses the home path // Menu "Macros" SubMenu "Auto-Fit" "InitializeAutoFitPanel" "-" "Generate_Data_Checklist" // "Make_HoldConstraintEps_Waves" //this is currently disabled "-" "CompileAndLoadReports" "LoadCompiledReports" "Compile_GlobalFit_Reports" "-" "PrintOpenNotebooks" "Close Open Notebooks" "-" "Generate_PICTS_list" "Layout_PICTS" 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 // // 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=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_PICTS_list() fGenerate_PICTS_list() End //spits up a list of PICTS Function fGenerate_PICTS_list() String List=IndexedFile(savePath, -1, "PICT") List2TextWave(List,";","PICT_files") WAVE/T picts=$"PICT_files" Edit/K=1 picts End Proc Layout_PICTS(pStr) String pStr="" Prompt pStr,"wave of PICTs to use",popup,WaveList("PICT_f*", ";", "") String List=TextWave2List($pStr,";") String item = "" //kill old picts KillPicts/A/Z //make a new layout Layout/C=1 as "PICT_Layout" DoWindow/C PICTLayout do item=StringFromList(0,List,";") //load each PICT, and append it to the layout Print "load item = ",item LoadPICT /O/Q/P=savePath item DoWindow/F PICTLayout //be sure layout is on top AppendLayoutObject /F=1/W=PICTLayout picture $item //AppendToLayout $item //Print item List = RemoveFromList(item, List, ";") while(ItemsInList(List, ";")>0) //tile the PICTs 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 // 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) Variable Number_of_Parameters=7 fCompile_Reports(Number_of_Parameters) 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 //// Function fCompile_GlobalFit_Reports(nPar,Files,Param,Param_err) Variable nPar String Files,Param,Param_Err String list=SortList(WinList("*", ";", "WIN:16")) String item = "",textStr="",fileStr,funcStr,dumStr Variable sstop,dum,chi,nFiles,val1,val2 Variable ii,jj nFiles = ItemsInList(list) Make/O/D/N=(nFiles) $Param,$Param_err Make/O/T/N=(nFiles) $Files WAVE pw = $Param WAVE pw_err = $Param_err WAVE/T fw = $Files for(jj=0;jj