source: sans/Analysis/branches/ajj_23APR07/IGOR_Package_Files/Put in User Procedures/SANS_Models_v4.00/Packages/Wrapper_v40.ipf @ 301

Last change on this file since 301 was 301, checked in by srkline, 15 years ago

Fixed errors in the Fractal documentation that Mathieu found.

File size: 33.4 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=4.00
3#pragma IgorVersion=6.0
4
5//
6// need a way of importing more functions into the experiment
7// ? call the picker panel from the panel?
8//
9//
10
11//Macro OpenWrapperPanel()
12//      Init_WrapperPanel()
13//End
14
15Function Init_WrapperPanel()
16        //make sure that folders exist - this is the first initialization to be called
17        NewDataFolder/O root:Packages
18        NewDataFolder/O root:Packages:NIST
19
20        //Create useful globals
21        Variable/G root:Packages:NIST:SANS_ANA_VERSION=4.00
22        String/G root:Packages:NIST:SANS_ANA_EXTENSION="_v40"
23       
24        DoWindow/F WrapperPanel
25        if(V_flag==0)
26                if(exists("root:Packages:NIST:coefKWStr")==0)
27                        String/G root:Packages:NIST:coefKWStr=""
28                endif
29                if(exists("root:Packages:NIST:suffixKWStr")==0)
30                        String/G root:Packages:NIST:suffixKWStr=""
31                endif
32                Execute "WrapperPanel()"
33        endif
34End
35
36////////
37//
38// if model is Smeared, search the DF for coefficients
39// if new DF chosen, need to reset
40// if new model function, need to reset table
41//
42// create hold_mod (0/1), constr_low_mod, constr_hi_mod
43// in either DF (smeared) or in root: (normal)
44// and put these in the table as needed
45//
46Window WrapperPanel()
47        PauseUpdate; Silent 1           // building window...
48        NewPanel /W=(459,44,1113,499)/N=wrapperPanel/K=1 as "Curve Fit Setup"
49        ModifyPanel fixedSize=1
50       
51        GroupBox grpBox_0,pos={18,11},size={390,113}
52        GroupBox grpBox_1,pos={426,10},size={207,113}
53        GroupBox grpBox_2 title="No Fit",pos={10,130},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
54        GroupBox grpBox_3 title="",pos={10,150},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
55
56        Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
57        Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
58        Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
59        PopupMenu popup_0,pos={30,21},size={218,20},title="Data Set",proc=DataSet_PopMenuProc
60        PopupMenu popup_0,mode=1,value= #"W_DataSetPopupList()"
61        PopupMenu popup_1,pos={30,57},size={136,20},title="Function"
62        PopupMenu popup_1,mode=1,value= #"W_FunctionPopupList()",proc=Function_PopMenuProc
63        PopupMenu popup_2,pos={30,93},size={123,20},title="Coefficients"
64        PopupMenu popup_2,mode=1,value= #"W_CoefPopupList()",proc=Coef_PopMenuProc
65        CheckBox check_0,pos={440,19},size={79,14},title="Use Cursors?",value= 0
66        CheckBox check_0,proc=UseCursorsWrapperProc
67        CheckBox check_1,pos={440,42},size={74,14},title="Use Epsilon?",value= 0
68        CheckBox check_2,pos={440,65},size={95,14},title="Use Constraints?",value= 0
69        CheckBox check_3,pos={530,18},size={72,14},title="2D Functions?",value= 0
70        CheckBox check_3 proc=Toggle2DControlsCheckProc
71        CheckBox check_4,pos={440,85},size={72,14},title="Report?",value= 0
72        CheckBox check_5,pos={454,103},size={72,14},title="Save it?",value= 0
73        //change draw order to put button over text of checkbox
74        Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
75        Button button_4,pos={520,126},size={100,20},proc=FeedbackButtonProc,title="Feedback"
76        Button button_5,pos={520,150},size={100,20},proc=FitHelpButtonProc,title="Help"
77
78        Edit/W=(20,174,634,435)/HOST=# 
79        ModifyTable width(Point)=0
80        RenameWindow #,T0
81        SetActiveSubwindow ##
82EndMacro
83
84//open the Help file for the Fit Manager
85Function FitHelpButtonProc(ba) : ButtonControl
86        STRUCT WMButtonAction &ba
87
88        switch( ba.eventCode )
89                case 2: // mouse up
90                        // click code here
91                        DisplayHelpTopic "Fit Manager"
92                        break
93        endswitch
94
95        return 0
96End
97
98
99//open the trac page for feedback
100Function FeedbackButtonProc(ba) : ButtonControl
101        STRUCT WMButtonAction &ba
102
103        switch( ba.eventCode )
104                case 2: // mouse up
105                        // click code here
106                        OpenTracTicketPage()
107                        break
108        endswitch
109
110        return 0
111End
112
113
114//obvious use
115Function W_LoadDataButtonProc(ba) : ButtonControl
116        STRUCT WMButtonAction &ba
117
118        switch( ba.eventCode )
119                case 2: // mouse up
120                        // click code here
121                        String  topGraph= WinName(0,1)
122                        if(strlen(topGraph) != 0)
123                                DoWindow/F $topGraph                    //so that the panel is not on top
124                        endif
125                        Execute "A_LoadOneDData()"
126                        break
127        endswitch
128
129        ControlUpdate/W=WrapperPanel popup_0
130        return 0
131End
132
133
134// is there a simpler way to do this?
135Function/S W_DataSetPopupList()
136
137        String str=GetAList(4),tmp="",onTargetStr=""
138        Variable ii
139//      ControlInfo/W=WrapperPanel check_3
140//      if(V_Value==1)          //if "from target" checked
141//              //ther must be a better way to do this
142//              onTargetStr = TraceNameList("",";",1)
143//              onTargetStr = ReplaceString("_i",onTargetStr,"")                //get rid of the "_i"
144//              for(ii=0;ii<ItemsInList(onTargetStr);ii+=1)
145//                      if(WhichListItem(StringFromList(ii,onTargetStr,";"), str  , ";") != -1)
146//                              tmp = Addlistitem(StringFromList(ii,onTargetStr,";"),tmp)               //only keep the matches w/data folder listing
147//                      endif
148//              endfor
149//              return(tmp)
150//      endif
151
152        if(strlen(str)==0)
153                str = "No data loaded"
154        endif
155        str = SortList(str)
156       
157        return(str)
158End
159
160
161// show the available models
162// not the f*(cw,xw) point calculations
163// not the *X(cw,xw) XOPS
164//
165// KIND:10 should show only user-defined curve fitting functions
166// - not XOPs
167// - not other user-defined functions
168Function/S W_FunctionPopupList()
169        String list,tmp
170        list = FunctionList("*",";","KIND:10")          //get every user defined curve fit function
171
172        //now start to remove everything the user doesn't need to see...
173               
174        tmp = FunctionList("*_proto",";","KIND:10")             //prototypes
175        list = RemoveFromList(tmp, list  ,";")
176        //prototypes that show up if GF is loaded
177        list = RemoveFromList("GFFitFuncTemplate", list)
178        list = RemoveFromList("GFFitAllAtOnceTemplate", list)
179        list = RemoveFromList("NewGlblFitFunc", list)
180        list = RemoveFromList("NewGlblFitFuncAllAtOnce", list)
181        list = RemoveFromList("GlobalFitFunc", list)
182        list = RemoveFromList("GlobalFitAllAtOnce", list)
183        list = RemoveFromList("GFFitAAOStructTemplate", list)
184        list = RemoveFromList("NewGF_SetXWaveInList", list)
185        list = RemoveFromList("NewGlblFitFuncAAOStruct", list)
186       
187        // more to remove as a result of 2D/Gizmo
188        list = RemoveFromList("A_WMRunLessThanDelta", list)
189        list = RemoveFromList("WMFindNaNValue", list)
190        list = RemoveFromList("WM_Make3DBarChartParametricWave", list)
191        list = RemoveFromList("UpdateQxQy2Mat", list)
192        list = RemoveFromList("MakeBSMask", list)
193       
194
195        tmp = FunctionList("f*",";","NPARAMS:2")                //point calculations
196        list = RemoveFromList(tmp, list  ,";")
197       
198        tmp = FunctionList("fSmear*",";","NPARAMS:3")           //smeared dependency calculations
199        list = RemoveFromList(tmp, list  ,";")
200       
201//      tmp = FunctionList("*X",";","KIND:4")           //XOPs, but these shouldn't show up if KIND:10 is used initially
202//      Print "X* = ",tmp
203//      print " "
204//      list = RemoveFromList(tmp, list  ,";")
205       
206        //non-fit functions that I can't seem to filter out
207        list = RemoveFromList("BinaryHS_PSF11;BinaryHS_PSF12;BinaryHS_PSF22;EllipCyl_Integrand;PP_Inner;PP_Outer;Phi_EC;TaE_Inner;TaE_Outer;",list,";")
208
209        if(strlen(list)==0)
210                list = "No functions plotted"
211        endif
212       
213        list = SortList(list)
214        return(list)
215End
216
217
218// show all the appropriate coefficient waves
219//
220// also need to search the folder listed in "data set" popup
221// for smeared coefs
222//
223// - or - restrict the coefficient list based on the model function
224// - new way, filter the possible values based on the data folder and function
225Function/S W_CoefPopupList()
226
227        String notPlotted="Please plot the function"
228        ControlInfo/W=wrapperpanel popup_1
229        String funcStr=S_Value
230        String coefStr=getFunctionCoef(funcStr)
231       
232        if(cmpstr(coefStr,"")==0)               //no correspondence in the KW string
233                return(notPlotted)
234        endif
235       
236       
237        //found a coefficient wave - only two places to look
238        // is it in the root folder?
239        if(exists("root:"+coefStr) != 0)
240                return(coefStr)
241        endif
242       
243        // is it in the data folder?
244        ControlInfo/W=wrapperpanel popup_0
245        String folderStr=S_Value
246        if(exists("root:"+folderStr+":"+coefStr) != 0)
247                return(coefStr)
248        endif
249
250        return(notPlotted)
251End
252
253// show all the appropriate coefficient waves
254//
255// also need to search the folder listed in "data set" popup
256// for smeared coefs
257//
258// - or - restrict the coefficient list based on the model function
259//
260// --old way
261//Function/S W_CoefPopupList()
262//      String list
263//      setDataFolder root:
264//      list = WaveList("coef*",";","")
265//     
266//      ControlInfo/W=wrapperpanel popup_0
267//      if(V_Value != 0)                //0== no items in menu
268//              if(DataFolderExists("root:"+S_Value))
269//                      SetDataFolder $("root:"+S_Value)
270//                      list += WaveList("*coef*",";","")
271//              endif
272//      endif
273//     
274//      // tmp coefficients that aren't being cleaned up from somewhere...
275//      list = RemoveFromList("temp_coef_1;temp_coef_2;", list  ,";")
276//
277//      if(strlen(list)==0)
278//              list = "No functions plotted"
279//      endif
280//      list = SortList(list)
281//     
282////    Print itemsinlist(list,";")
283//     
284//      setDataFolder root:
285//      return(list)
286//End
287
288// if the coefficients are changed, then update the table
289//
290//update the table
291// may be easier to just kill the subwindow (table) and create a new one
292// need to set/reset all of the waves in the table
293//
294// !! only respond to mouse up
295//
296Function Coef_PopMenuProc(pa) : PopupMenuControl
297        STRUCT WMPopupAction &pa
298
299        switch( pa.eventCode )
300                case 2: // mouse up
301                        Variable popNum = pa.popNum
302                        String popStr = pa.popStr
303                        String suffix = getModelSuffix(popStr)
304                        ControlInfo/W=WrapperPanel popup_0
305                        String folderStr=S_Value
306                       
307                        if(cmpstr(popStr,"Please plot the function")==0)
308//                              Print "function not plotted"
309                                return(0)
310                        endif
311
312// this if/else/endif should not ever return an error alert     
313// it should simply set the data folder properly       
314                        if(DataFolderExists("root:"+folderStr))
315                                SetDataFolder $("root:"+folderStr)
316                                if(!exists(popStr))
317                                        // must be unsmeared model, work in the root folder
318                                        SetDataFolder root:                             
319                                        if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
320                                                DoAlert 0,"the coefficient and data sets do not match (1)"
321                                                return 0
322                                        endif
323                                endif
324                        else
325                                // must be unsmeared model, work in the root folder
326                                SetDataFolder root:     
327                                if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
328                                        DoAlert 0,"the coefficient and data sets do not match (2)"
329                                        return 0
330                                endif
331                        endif
332                       
333                        // farm the work out to another function?
334                        Variable num=numpnts($popStr)
335                        // make the necessary waves if they don't exist already
336                        if(exists("Hold_"+suffix) == 0)
337                                Make/O/D/N=(num) $("epsilon_"+suffix),$("Hold_"+suffix)
338                                Make/O/T/N=(num) $("LoLim_"+suffix),$("HiLim_"+suffix)
339                        endif
340                        // default epsilon values, sometimes needed for the fit
341                        Wave eps = $("epsilon_"+suffix)
342                        Wave coef=$popStr
343                        eps = abs(coef*1e-4) + 1e-10                    //default eps is proportional to the coefficients
344                        WAVE/T LoLim = $("LoLim_"+suffix)
345                        WAVE/T HiLim = $("HiLim_"+suffix)
346                       
347                        // clear the table (a subwindow)
348                        KillWindow wrapperPanel#T0
349                        Edit/W=(20,174,634,435)/HOST=#
350                        RenameWindow #,T0
351                        // get them onto the table
352                        // how do I get the parameter name?
353                        String param = WaveList("*param*_"+suffix, "", "TEXT:1," )              //this is *hopefully* one wave
354                        AppendtoTable/W=wrapperPanel#T0 $param,$(popStr)
355                        AppendToTable/W=wrapperPanel#T0 $("Hold_"+suffix),$("LoLim_"+suffix),$("HiLim_"+suffix),$("epsilon_"+suffix)
356                        ModifyTable width(Point)=0
357                       
358                        SetDataFolder root:
359                        break
360        endswitch
361
362        return 0
363End
364
365// if the Function is changed, then update the coef popup (if possible) and then the table (if possible)
366//
367// !! only respond to mouse up
368//
369Function Function_PopMenuProc(pa) : PopupMenuControl
370        STRUCT WMPopupAction &pa
371
372        switch( pa.eventCode )
373                case 2: // mouse up
374                        Variable popNum = pa.popNum
375                        String funcStr = pa.popStr
376                        String coefStr = W_CoefPopupList()
377                       
378//                      Print "coefStr = ",coefStr
379                       
380                        ControlInfo/W=WrapperPanel popup_0
381                        String folderStr=S_Value
382                       
383                        String listStr = W_CoefPopupList()
384                        Variable num=WhichListItem(coefStr, listStr, ";")
385                        String str=StringFromList(num, listStr  ,";")
386//                      print "str = ",str
387                        //set the item in the coef popup, and pop it
388                        PopupMenu popup_2 mode=(num+1)
389                       
390                        Struct WMPopupAction ps
391                        ps.eventCode = 2                //fake mouse up
392                        ps.popStr = str
393                        Coef_PopMenuProc(ps)
394                       
395                        SetDataFolder root:
396                        break
397        endswitch
398
399        return 0
400End
401
402// if the Data Set is changed, then update the function (if possible)
403// and the coef popup (if possible) and then the table (if possible)
404//
405// !! only respond to mouse up here, and simply send a fake mouse up
406// to the function pop, which will do what it can do
407//
408Function DataSet_PopMenuProc(pa) : PopupMenuControl
409        STRUCT WMPopupAction &pa
410
411        switch( pa.eventCode )
412                case 2: // mouse up
413//                      Variable popNum = pa.popNum
414//                      String funcStr = pa.popStr
415//                      String coefStr = W_CoefPopupList()
416//                     
417////                    Print "coefStr = ",coefStr
418//                     
419//                      ControlInfo/W=WrapperPanel popup_0
420//                      String folderStr=S_Value
421//                     
422//                      String listStr = W_CoefPopupList()
423//                      Variable num=WhichListItem(coefStr, listStr, ";")
424//                      String str=StringFromList(num, listStr  ,";")
425////                    print "str = ",str
426//                      //set the item in the coef popup, and pop it
427//                      PopupMenu popup_2 mode=(num+1)
428                       
429                        Struct WMPopupAction ps
430                        ps.eventCode = 2                //fake mouse up
431                        Function_PopMenuProc(ps)
432                       
433                        SetDataFolder root:
434                        break
435        endswitch
436
437        return 0
438End
439
440
441
442// always pass this the coefficient string
443//
444// either "coef_"
445// or "smear_coef_"
446//
447Function/S getFunctionCoef(funcStr)
448        String funcStr
449
450        SVAR listStr=root:Packages:NIST:coefKWStr
451        String coefStr = StringByKey(funcStr, listStr  ,"=",";",0)
452
453        return(coefStr)
454End
455
456// always pass this the coefficient string
457//
458// either "coef_"
459// or "smear_coef_"
460//
461// does NOT return the leading "_" as part of the suffix
462Function/S getModelSuffix(coefStr)
463        String coefStr
464
465        SVAR listStr=root:Packages:NIST:suffixKWStr
466        String suffixStr = StringByKey(coefStr, listStr  ,"=",";",0)
467
468        return(suffixStr)
469//      Variable pos,start=0
470
471//      if(stringmatch(coefStr,"smear_*") == 1)
472//              start=7 //look forwards to find "_", skipping "smear_coe" if necessary
473//      endif
474//      pos=Strsearch(coefStr,"_",start,0)
475        //Print start, pos
476//      return(coefStr[pos,strlen(coefStr)-1])
477End
478
479
480
481// - this is based on stringent "PlotNNN" naming requirements
482//
483//  ???
484// - how to kill the generated table and graph, that are not needed now
485//
486Function PlotModelFunction(ba) : ButtonControl
487        STRUCT WMButtonAction &ba
488
489        String folderStr,funcStr,coefStr,cmdStr=""
490        Variable useCursors,useEps,useConstr
491       
492        Variable killWhat=0             //kill nothing as default
493       
494        switch( ba.eventCode )
495                case 2: // mouse up
496                        ControlInfo/W=WrapperPanel popup_0
497                        folderStr=S_Value
498                       
499                        ControlInfo/W=WrapperPanel popup_1
500                        funcStr=S_Value
501                       
502                        // maybe nothing has been loaded yet...
503                        if(cmpstr(funcStr,"No functions plotted") == 0)
504                                break
505                        endif
506                       
507                        // check for smeared or smeared function
508                        if(stringmatch(funcStr, "Smear*" )==1)
509                                //it's a smeared model
510                                // check for the special case of RPA that has an extra parameter
511                                if(strsearch(funcStr, "RPAForm", 0 ,0) == -1)
512                                        sprintf cmdStr, "Plot%s(\"%s\")",funcStr,folderStr              //not RPA
513                                else
514                                        sprintf cmdStr, "Plot%s(\"%s\",)",funcStr,folderStr             //yes RPA, leave a comma for input
515                                endif
516                                killWhat = 1
517                        else
518                                // it's not,    don't kill the graph, just the table           
519                                sprintf cmdStr, "Plot%s()",funcStr
520                                killWhat = 2
521                        endif
522                       
523                        //Print cmdStr
524                        Execute cmdStr
525                       
526                        //pop the function menu to set the proper coefficients
527                        DoWindow/F WrapperPanel
528                        STRUCT WMPopupAction pa
529                        pa.popStr = funcStr
530                        pa.eventcode = 2
531                        Function_PopMenuProc(pa)
532       
533                        KillTopGraphAndTable(killWhat)          // crude
534       
535                        break
536        endswitch
537       
538        return 0
539End
540
541// passing 0 kills nothing
542// passing 1 kills the top graph and table
543// passing 2 kills the top table only
544//
545Function KillTopGraphAndTable(killwhat)
546        Variable killWhat
547       
548        String topGraph= WinName(0,1)   //this is the topmost graph     
549        String topTable= WinName(0,2)   //this is the topmost table
550
551        if(killWhat == 0)
552                return(0)
553        endif
554       
555        if(killWhat == 1)
556                KillWindow $topGraph
557                KillWindow $topTable
558        endif
559       
560        if(killWhat == 2)
561                KillWindow $topTable
562        endif
563       
564        return(0)
565End
566
567// How to bypass the step of plot and append?
568//
569// do it in two separate events
570//
571Function AppendModelToTarget(ba) : ButtonControl
572        STRUCT WMButtonAction &ba
573
574        String coefStr,suffix,yWStr,xWStr,folderStr
575       
576        switch( ba.eventCode )
577                case 2: // mouse up                     
578                        ControlInfo/W=WrapperPanel popup_2
579                        coefStr=S_Value
580                        suffix = getModelSuffix(coefStr)
581                       
582                        // check for smeared or smeared function
583                        if(stringmatch(coefStr, "smear*" )==1)
584                                //it's a smeared model
585                                ControlInfo/W=WrapperPanel popup_0
586                                folderStr=S_Value
587                                xWStr = "root:"+folderStr+":smeared_qvals"
588                                ywStr = "root:"+folderStr+":smeared_"+suffix
589                        else
590                                // it's not, so it's in the root folder
591                                xWStr = "xwave_"+suffix
592                                yWStr = "ywave_"+suffix
593                        endif
594                       
595                        Wave/Z yw = $yWStr
596                        Wave/Z xw = $xWStr
597                        if(WaveExists(yw) && WaveExists(xw))
598                                AppendtoGraph yw vs xw
599                        else
600                                DoAlert 0,"The selected model has not been plotted for the selected data set."
601                        endif
602                        break
603        endswitch
604       
605        return 0
606End
607
608
609// this should parse the panel and call the FitWrapper() function
610Function DoTheFitButton(ba) : ButtonControl
611        STRUCT WMButtonAction &ba
612
613        String folderStr,funcStr,coefStr
614        Variable useCursors,useEps,useConstr
615       
616        switch( ba.eventCode )
617                case 2: // mouse up
618                        ControlInfo/W=WrapperPanel popup_0
619                        folderStr=S_Value
620                       
621                        ControlInfo/W=WrapperPanel popup_1
622                        funcStr=S_Value
623                       
624                        ControlInfo/W=WrapperPanel popup_2
625                        coefStr=S_Value
626                       
627                        ControlInfo/W=WrapperPanel check_0
628                        useCursors=V_Value
629                        ControlInfo/W=WrapperPanel check_1
630                        useEps=V_Value
631                        ControlInfo/W=WrapperPanel check_2
632                        useConstr=V_Value
633                       
634                        if(!CheckFunctionAndCoef(funcStr,coefStr))
635                                DoAlert 0,"The coefficients and function type do not match. Please correct the selections in the popup menus."
636                                break
637                        endif
638                       
639                        FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
640                       
641                        //      DoUpdate (does not work!)
642                        //?? why do I need to force an update ??
643                        if(!exists("root:"+folderStr+":"+coefStr))
644                                Wave w=$coefStr
645                        else
646                                Wave w=$("root:"+folderStr+":"+coefStr) //smeared coefs in data folder
647                        endif
648                        w[0] += 1e-6
649                        w[0] -= 1e-6
650       
651                        break
652        endswitch
653       
654        return 0
655End
656
657Function CheckFunctionAndCoef(funcStr,coefStr)
658        String funcStr,coefStr
659       
660        SVAR listStr=root:Packages:NIST:coefKWStr
661        String properCoefStr = StringByKey(funcStr, listStr  ,"=",";",0)
662        if(cmpstr(coefStr,properCoefStr)==0)
663                return(1)               //true, the coef is the correct match
664        endif
665        return(0)                       //false, wrong coef
666End
667
668/////////////////////////////////
669
670// wrapper to do the desired fit
671//
672// folderStr is the data folder for the desired data set
673//
674//
675Function FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
676        String folderStr,funcStr,coefStr
677        Variable useCursors,useEps,useConstr
678
679        String suffix=getModelSuffix(coefStr)
680       
681        SetDataFolder $("root:"+folderStr)
682        if(!exists(coefStr))
683                // must be unsmeared model, work in the root folder
684                SetDataFolder root:                             
685                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
686                        DoAlert 0,"the coefficient and data sets do not match"
687                        return 0
688                endif
689        endif
690               
691        WAVE cw=$(coefStr)     
692        Wave hold=$("Hold_"+suffix)
693        Wave/T lolim=$("LoLim_"+suffix)
694        Wave/T hilim=$("HiLim_"+suffix)
695        Wave eps=$("epsilon_"+suffix)
696       
697// fill a struct instance whether I need one or not
698        String DF="root:"+folderStr+":"
699       
700        Struct ResSmearAAOStruct fs
701        WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
702        WAVE/Z fs.resW =  resW
703        WAVE yw=$(DF+folderStr+"_i")
704        WAVE xw=$(DF+folderStr+"_q")
705        WAVE sw=$(DF+folderStr+"_s")
706        Wave fs.coefW = cw
707        Wave fs.yW = yw
708        Wave fs.xW = xw
709       
710        Duplicate/O yw $(DF+"FitYw")
711        WAVE fitYw = $(DF+"FitYw")
712        fitYw = NaN
713       
714        Variable useRes=0
715        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
716                useRes=1
717        endif
718       
719        // do not construct constraints for any of the coefficients that are being held
720        // -- this will generate an "unknown error" from the curve fitting
721        Make/O/T/N=0 constr
722        if(useConstr)
723                String constraintExpression
724                Variable i, nPnts=DimSize(lolim, 0),nextRow=0
725                for (i=0; i < nPnts; i += 1)
726                        if (strlen(lolim[i]) > 0 && hold[i] == 0)
727                                InsertPoints nextRow, 1, constr
728                                sprintf constraintExpression, "K%d > %s", i, lolim[i]
729                                constr[nextRow] = constraintExpression
730                                nextRow += 1
731                        endif
732                        if (strlen(hilim[i]) > 0 && hold[i] == 0)
733                                InsertPoints nextRow, 1, constr
734                                sprintf constraintExpression, "K%d < %s", i, hilim[i]
735                                constr[nextRow] = constraintExpression
736                                nextRow += 1
737                        endif
738                endfor
739        endif
740
741        //if useCursors, and the data is USANS, need to feed a (reassigned) trimmed matrix to the fit
742        Variable pt1,pt2,newN
743        if(useCursors && (dimsize(resW,1) > 4) )
744                if(pcsr(A) > pcsr(B))
745                        pt1 = pcsr(B)
746                        pt2 = pcsr(A)
747                else
748                        pt1 = pcsr(A)
749                        pt2 = pcsr(B)
750                endif
751                newN = pt2 - pt1 + 1            // +1 includes both cursors in the fit
752                Make/O/D/N=(newN,newN) $(DF+"crsrResW")
753                WAVE crsrResW = $(DF+"crsrResW")
754                crsrResW = resW[p+pt1][q+pt1]
755                //assign to the struct
756                WAVE fs.resW =  crsrResW               
757        endif
758
759// create these variables so that FuncFit will set them on exit
760        Variable/G V_FitError=0                         //0=no err, 1=error,(2^1+2^0)=3=singular matrix
761        Variable/G V_FitQuitReason=0            //0=ok,1=maxiter,2=user stop,3=no chisq decrease
762       
763// don't use the auto-destination with no flag, it doesn't appear to work correctly
764// dispatch the fit
765        do
766                if(useRes && useEps && useCursors && useConstr)         //do it all
767                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs
768                        break
769                endif
770               
771                if(useRes && useEps && useCursors)              //no constr
772                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
773                        break
774                endif
775               
776                if(useRes && useEps && useConstr)               //no crsr
777                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs
778                        break
779                endif
780               
781                if(useRes && useCursors && useConstr)           //no eps
782                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /C=constr /STRC=fs
783                        break
784                endif
785               
786                if(useRes && useCursors)                //no eps, no constr
787                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
788                        break
789                endif
790               
791                if(useRes && useEps)            //no crsr, no constr
792//                      Print "timing test for Cylinder_PolyRadius --- the supposedly threaded version ---"
793//                      Variable t0 = stopMStimer(-2)
794                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
795//                      t0 = (stopMSTimer(-2) - t0)*1e-6
796//                      Printf  "CylPolyRad fit time using res and eps and /NTHR=0 time = %g seconds\r\r",t0
797                       
798//                      cw[0] = .01
799//                      cw[1] = 20
800//                      cw[2] = 400
801//                      cw[3] = 0.2
802//                      cw[4] = 3e-6
803//                      cw[5] = 0.0
804//                     
805//                      t0 = stopMSTimer(-2)
806//                      FuncFit/H=getHStr(hold) $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
807//                      t0 = (stopMSTimer(-2) - t0)*1e-6
808//                      Printf  "CylPolyRad fit time using res and eps and NO THREADING time = %g seconds\r\r",t0
809                        break
810                endif
811       
812                if(useRes && useConstr)         //no crsr, no eps
813                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr /STRC=fs
814                        break
815                endif
816               
817                if(useRes)              //just res
818                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
819                        break
820                endif
821               
822/////   same as above, but all without useRes (no /STRC flag)
823                if(useEps && useCursors && useConstr)           //do it all
824                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr
825                        break
826                endif
827               
828                if(useEps && useCursors)                //no constr
829                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /E=eps /D=fitYw
830                        break
831                endif
832               
833                if(useEps && useConstr)         //no crsr
834                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr
835                        break
836                endif
837               
838                if(useCursors && useConstr)             //no eps
839                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /C=constr
840                        break
841                endif
842               
843                if(useCursors)          //no eps, no constr
844                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw
845                        break
846                endif
847               
848                if(useEps)              //no crsr, no constr
849                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw
850                        break
851                endif
852       
853                if(useConstr)           //no crsr, no eps
854                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr
855                        break
856                endif
857               
858                //just a plain vanilla fit
859                FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw
860       
861        while(0)
862       
863        // append the fit
864        // need to manage duplicate copies
865        // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...)
866        String traces=TraceNameList("", ";", 1 )                //"" as first parameter == look on the target graph
867        if(strsearch(traces,"FitYw",0) == -1)
868                AppendToGraph FitYw vs xw
869        else
870                RemoveFromGraph FitYw
871                AppendToGraph FitYw vs xw
872        endif
873        ModifyGraph lsize(FitYw)=2,rgb(FitYw)=(0,0,0)
874       
875        DoUpdate                //force update of table and graph with fitted values (why doesn't this work? - the table still does not update)
876       
877        // report the results (to the panel?)
878        print "V_chisq = ",V_chisq
879        print cw
880        WAVE w_sigma
881        print w_sigma
882        String resultStr=""
883               
884        //now re-write the results
885        sprintf resultStr,"Chi^2 = %g  Sqrt(X^2/N) = %g",V_chisq,sqrt(V_chisq/V_Npnts)
886        resultStr = PadString(resultStr,63,0x20)
887        GroupBox grpBox_2 title=resultStr
888        ControlUpdate/W=WrapperPanel grpBox_2
889        sprintf resultStr,"FitErr = %s : FitQuit = %s",W_ErrorMessage(V_FitError),W_QuitMessage(V_FitQuitReason)
890        resultStr = PadString(resultStr,63,0x20)
891        GroupBox grpBox_3 title=resultStr
892        ControlUpdate/W=WrapperPanel grpBox_3
893       
894        Variable yesSave=0,yesReport=0
895        ControlInfo/W=WrapperPanel check_4
896        yesReport = V_Value
897        ControlInfo/W=WrapperPanel check_5
898        yesSave = V_Value
899       
900       
901        if(yesReport)
902                String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+suffix, "", "TEXT:1," )              //this is *hopefully* one wave
903                String topGraph= WinName(0,1)   //this is the topmost graph
904       
905                DoUpdate                //force an update of the graph before making a copy of it for the report
906
907                W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph)
908        endif
909       
910        SetDataFolder root:
911        return(0)
912End
913
914// parse something off of a table, or ?
915Function/S getHStr(hold)
916        Wave hold
917       
918        String str=""
919        Variable ii
920        for(ii=0;ii<numpnts(hold);ii+=1)
921                str += num2str(hold[ii])
922        endfor
923
924//      print str
925        if(strsearch(str, "1", 0) == -1)
926                return ("")
927        else
928                return(str)
929        endif
930End
931
932//taken from SRK Auto_Fit, and modified to work better with FitWrapper
933//must have AutoGraph as the name of the graph window (any size)
934// func is the name of the function (for print only)
935//par and coef are the exact names of the waves
936//yesSave==1 will save the file(name=func+time)
937//
938Function W_GenerateReport(func,dataname,param,ans,yesSave,chiSq,sigWave,npts,fitErr,fitQuit,fitStart,fitEnd,topGraph)
939        String func,dataname
940        Wave/T param
941        Wave ans
942        Variable yesSave,chiSq
943        Wave sigWave
944        Variable npts,fitErr,fitQuit,fitStart,fitEnd
945        String topGraph
946       
947        String str,pictStr="P_"
948        String nb="Report"
949               
950        // bring report up
951        DoWindow/F Report
952        if (V_flag == 0)                // Report notebook doesn't exist ?
953                NewNotebook/W=(10,45,550,620)/F=1/N=Report as "Report"
954        endif
955        // delete old stuff
956        Notebook $nb selection={startOfFile, endOfFile}, text="\r", selection={startOfFile, startOfFile}
957       
958        //setup
959        Notebook $nb defaultTab=36, statusWidth=252, pageMargins={72,72,72,72}
960        Notebook $nb showRuler=1, rulerUnits=1, updating={1, 60}
961        Notebook $nb newRuler=Normal, justification=0, margins={0,0,468}, spacing={0,0,0}, tabs={}, rulerDefaults={"Geneva",10,0,(0,0,0)}
962//     
963        // insert title
964        Notebook $nb newRuler=Title, justification=1, rulerDefaults={"Times", 16, 1, (0, 0, 0)}
965        sprintf str, "Fit to %s, %s, %s\r\r", func,Secs2Date(datetime, 0), time()
966        Notebook $nb ruler=Title, text=str
967       
968        // insert fit results
969        Variable num=numpnts(ans),ii=0
970        Notebook $nb ruler=Normal
971        Notebook $nb  margins={18,18,504}, tabs={63 + 3*8192}
972        str = "Data file: " + dataname + "\r\r"
973        Notebook $nb text=str
974        Notebook $nb ruler=Normal
975        Notebook $nb margins={18,18,504}, tabs={144,234,252}
976        do
977                sprintf str, "%s = \t%g\t±\t%g\r", param[ii],ans[ii],sigwave[ii]
978                Notebook $nb text=str
979                ii+=1
980        while(ii<num)
981       
982        //
983        // no "fitted range" for 2D data, so make sure that this exists before using it
984        Wave/Z dataXw = $("root:"+dataname+":"+dataname+"_q")   
985        //
986        Notebook $nb ruler=Normal
987        Notebook $nb  margins={18,18,504}, tabs={63+3*8192}, fStyle=1, textRGB=(65000,0,0)
988       
989        sprintf str,"chisq = %g\r",chisq
990        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
991        sprintf str,"Npnts = %g \t\t Sqrt(X^2/N) = %g\r",npts,sqrt(chiSq/npts)
992        Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
993        if(WaveExists(dataXw))
994                sprintf str "Fitted range = [%d,%d] = %g < Q < %g\r",fitStart,fitEnd,dataXw(fitStart),dataXw(fitEnd)
995                Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
996        endif
997        sprintf str,"FitError = %s\t\tFitQuitReason = %s\r",W_ErrorMessage(FitErr),W_QuitMessage(FitQuit)
998        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
999        Notebook $nb ruler=Normal
1000       
1001        // insert graphs
1002        if(WaveExists(dataXw))
1003                Notebook $nb picture={$topGraph(0, 0, 400, 300), 0, 1}, text="\r"
1004        //
1005        else            //must be 2D Gizmo
1006                Execute "ExportGizmo Clip"
1007                LoadPict/Q/O "Clipboard",tmp_Gizmo
1008                Notebook $nb picture={tmp_Gizmo(0, 0, 400, 300), 0, 1}, text="\r"
1009        endif
1010        //Notebook Report picture={Table1, 0, 0}, text="\r"
1011       
1012        // show the top of the report
1013        Notebook $nb  selection= {startOfFile, startOfFile},  findText={"", 1}
1014       
1015        //save the notebook and the graphic file
1016        if(yesSave)
1017                String nameStr=CleanupName(func,0)
1018                nameStr = nameStr[0,8]  //shorten the name
1019                nameStr += "_"+dataname
1020                //make sure the name is no more than 31 characters
1021                namestr = namestr[0,30]         //if shorter than 31, this will NOT pad to 31 characters
1022                Print "file saved as ",nameStr
1023                SaveNotebook /O/P=home/S=2 $nb as nameStr
1024                //save the graph separately as a PICT file, 2x screen
1025                pictStr += nameStr
1026                pictStr = pictStr[0,28]         //need a shorter name - why?
1027//              DoWindow/F $topGraph
1028                // E=-5 is png @screen resolution
1029                // E=2 is PICT @2x screen resolution
1030///             SavePICT /E=-5/O/P=home /I/W=(0,0,3,3) as pictStr
1031                if(WaveExists(dataXw))
1032                        SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1033                else
1034                        Execute "ExportGizmo /P=home as \""+pictStr+"\""
1035                        //SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1036                endif
1037        Endif
1038       
1039        // ???maybe print the notebook too?
1040End
1041
1042Function/S W_ErrorMessage(code)
1043        Variable code
1044       
1045        switch (code)
1046                case 0:
1047                        return "No Error"
1048                        break
1049                case 3: //2^0 + 2^1
1050                        return "Singular Matrix"
1051                        break
1052                case 5:         //(2^0 + 2^2)
1053                        return "Out of Memory"
1054                        break
1055                case 9:         //(2^0 + 2^3)
1056                        return "Func= NaN or Inf"
1057                        break
1058                default:
1059                        return "Unknown error code "+num2str(code)
1060        endswitch
1061end
1062
1063Function/S W_QuitMessage(code)
1064        Variable code
1065       
1066        switch (code)
1067                case 0:
1068                        return "No Error"
1069                        break
1070                case 1:
1071                        return "Max iterations - re-run fit"
1072                        break
1073                case 2:
1074                        return "User terminated fit"
1075                        break
1076                case 3:
1077                        return "No decrease in chi-squared"
1078                        break
1079                default:
1080                        return "Unknown Quit code "+num2str(code)
1081        endswitch
1082end
1083
1084Function Toggle2DControlsCheckProc(cba) : CheckBoxControl
1085        STRUCT WMCheckboxAction &cba
1086
1087        switch( cba.eventCode )
1088                case 2: // mouse up
1089                        Variable checked = cba.checked
1090                        if(checked)
1091                                //print "change the buttons to 2D"
1092                                Button button_0,proc=Do2DFitButtonProc,title="Do 2D Fit"
1093                                Button button_1,size={120,20},proc=Plot2DFunctionButtonProc,title="Plot 2D Function"
1094                                Button button_2,size={100,20},proc=Append2DModelButtonProc,title="Append 2D"
1095                                Button button_3,size={100,20},proc=Load2DDataButtonProc,title="Load 2D Data"
1096                               
1097                                Button button_2D_0,pos={550,60},size={70,20},proc=LogToggle2DButtonProc,title="Log/Lin"
1098                                Button button_2D_1,pos={520,37},size={100,20},proc=Plot2DButtonProc,title="Plot 2D Data"
1099                               
1100                                Button button_2D_0,disable=0            //visible again, and enabled
1101                                Button button_2D_1,disable=0
1102                        else
1103                                //print "unchecked, change them back to 1D"
1104                                Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
1105                                Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
1106                                Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
1107                                Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
1108                               
1109                                Button button_2D_0,disable=3    //hide the extra 2D buttons, and disable
1110                                Button button_2D_1,disable=3
1111                        endif
1112                        break
1113        endswitch
1114
1115        return 0
1116End
1117
1118// function to either add or remove the cursors from the topmost graph, as needed
1119
1120Function UseCursorsWrapperProc(cba) : CheckBoxControl
1121        STRUCT WMCheckboxAction &cba
1122
1123        String topGraph= WinName(0,1)   //this is the topmost graph     
1124        String ciStr = CsrInfo(A , topGraph)
1125       
1126        ControlInfo/W=wrapperpanel popup_0
1127        String folderStr=S_Value
1128        String traceList = TraceNameList(topGraph, ";", 1 )
1129       
1130        switch( cba.eventCode )
1131                case 2: // mouse up
1132                        Variable checked = cba.checked
1133                        if(checked)
1134                                //print "add the cursors to the topmost graph, if the data set is there, or move them"
1135                                if(strlen(ciStr)==0 && strsearch(traceList, folderStr, 0) != -1 )               //no cursors && data is there
1136                                        ShowInfo
1137                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1138                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0
1139                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1                     //deactivate the one at the high Q end
1140                                        DoUpdate
1141//                              else            //if (strlen(ciStr)!=0 && strsearch(traceList, folderStr, 0) != -1 ) //cursors present, but on wrong data
1142//                                      Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1143//                                      Cursor/P/W=$topGraph A, $(folderStr+"_i"),0                                                             //move the cursors
1144//                                      Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1
1145//                                      DoUpdate
1146                                endif
1147                       
1148                        else
1149                                //print "unchecked, remove the cursors"
1150                                HideInfo
1151                                Cursor/K A
1152                                Cursor/K B
1153                        endif
1154                        break
1155        endswitch
1156
1157        return 0
1158End
Note: See TracBrowser for help on using the repository browser.