source: sans/Release/trunk/NCNR_User_Procedures/SANS_Analysis_v4.0/SANS_Models_v4.00/Packages/Wrapper_v40.ipf @ 290

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

adding in the changes to the 2D conditional compile

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