source: sans/Dev/trunk/NCNR_User_Procedures/Analysis/Packages/Wrapper_v40.ipf @ 516

Last change on this file since 516 was 516, checked in by srkline, 14 years ago

Fixed bugs introduced in r515 concerning the back-compatibility of the kw=val strings for the
model functions. Now should work correctly when no models are loaded.

Changed integration limits on paracrystal models

File size: 42.0 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        //Set this variable to 1 to force use of trapezoidal integration routine for USANS smearing
24        Variable/G root:Packages:NIST:USANSUseTrap = 0
25        Variable/G root:Packages:NIST:USANS_dQv = 0.117
26        Variable/G root:Packages:NIST:gUseGenCurveFit = 0                       //set to 1 to use genetic optimization
27                       
28        //Ugly. Put this here to make sure things don't break
29        String/G root:Packages:NIST:gXMLLoader_Title
30       
31        DoWindow/F WrapperPanel
32        if(V_flag==0)
33                if(exists("root:Packages:NIST:coefKWStr")==0)
34                        String/G root:Packages:NIST:coefKWStr=""
35                endif
36                if(exists("root:Packages:NIST:suffixKWStr")==0)
37                        String/G root:Packages:NIST:suffixKWStr=""
38                endif
39                if(exists("root:Packages:NIST:paramKWStr")==0)
40                        String/G root:Packages:NIST:paramKWStr=""
41                endif
42                Execute "WrapperPanel()"
43        endif
44End
45
46////////
47//
48// if model is Smeared, search the DF for coefficients
49// if new DF chosen, need to reset
50// if new model function, need to reset table
51//
52// create hold_mod (0/1), constr_low_mod, constr_hi_mod
53// in either DF (smeared) or in root: (normal)
54// and put these in the table as needed
55//
56Window WrapperPanel()
57        PauseUpdate; Silent 1           // building window...
58        NewPanel /W=(459,44,1113,499)/N=wrapperPanel/K=1 as "Curve Fit Setup"
59        ModifyPanel fixedSize=1
60       
61        GroupBox grpBox_0,pos={18,11},size={390,113}
62        GroupBox grpBox_1,pos={426,10},size={207,113}
63        GroupBox grpBox_2 title="No Fit",pos={10,130},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
64        GroupBox grpBox_3 title="",pos={10,150},size={0,0},frame=1,fSize=10,fstyle=1,fColor=(39321,1,1)
65
66        Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
67        Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
68        Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
69        PopupMenu popup_0,pos={30,21},size={218,20},title="Data Set",proc=DataSet_PopMenuProc
70        PopupMenu popup_0,mode=1,value= #"W_DataSetPopupList()"
71        PopupMenu popup_1,pos={30,57},size={136,20},title="Function"
72        PopupMenu popup_1,mode=1,value= #"W_FunctionPopupList()",proc=Function_PopMenuProc
73        PopupMenu popup_2,pos={30,93},size={123,20},title="Coefficients"
74        PopupMenu popup_2,mode=1,value= #"W_CoefPopupList()",proc=Coef_PopMenuProc
75        CheckBox check_0,pos={440,19},size={79,14},title="Use Cursors?",value= 0
76        CheckBox check_0,proc=UseCursorsWrapperProc
77        CheckBox check_1,pos={440,42},size={74,14},title="Use Epsilon?",value= 0
78        CheckBox check_2,pos={440,65},size={95,14},title="Use Constraints?",value= 0
79        CheckBox check_3,pos={530,18},size={72,14},title="2D Functions?",value= 0
80        CheckBox check_3 proc=Toggle2DControlsCheckProc
81        CheckBox check_4,pos={440,85},size={72,14},title="Report?",value= 0
82        CheckBox check_5,pos={454,103},size={72,14},title="Save it?",value= 0
83        //change draw order to put button over text of checkbox
84        Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
85        Button button_4,pos={520,126},size={100,20},proc=FeedbackButtonProc,title="Feedback"
86        Button button_5,pos={520,150},size={100,20},proc=FitHelpButtonProc,title="Help"
87
88        Edit/W=(20,174,634,435)/HOST=# 
89        ModifyTable width(Point)=0
90        RenameWindow #,T0
91        SetActiveSubwindow ##
92EndMacro
93
94//open the Help file for the Fit Manager
95Function FitHelpButtonProc(ba) : ButtonControl
96        STRUCT WMButtonAction &ba
97
98        switch( ba.eventCode )
99                case 2: // mouse up
100                        // click code here
101                        DisplayHelpTopic/Z/K=1 "Fit Manager"
102                        if(V_flag !=0)
103                                DoAlert 0,"The Fit Manager Help file could not be found"
104                        endif
105                        break
106        endswitch
107
108        return 0
109End
110
111
112//open the trac page for feedback
113Function FeedbackButtonProc(ba) : ButtonControl
114        STRUCT WMButtonAction &ba
115
116        switch( ba.eventCode )
117                case 2: // mouse up
118                        // click code here
119                        OpenTracTicketPage()
120                        break
121        endswitch
122
123        return 0
124End
125
126
127//obvious use, now finds the most recent data loaded, finds the folder, and pops the menu with that selection...
128//
129Function W_LoadDataButtonProc(ba) : ButtonControl
130        STRUCT WMButtonAction &ba
131
132        switch( ba.eventCode )
133                case 2: // mouse up
134                        // click code here
135                        String  topGraph= WinName(0,1)
136                        if(strlen(topGraph) != 0)
137                                DoWindow/F $topGraph                    //so that the panel is not on top
138                        endif
139                        Execute "A_LoadOneDData()"
140                       
141                        ControlUpdate/W=WrapperPanel popup_0
142                        //instead of a simple controlUpdate, better to pop the menu to make sure that the other menus follow
143                        // convoluted method to find the right item and pop the menu.
144
145                        // data is plotted, so get the "new" top graph
146                        topGraph= WinName(0,1)  //this is the topmost graph, and should exist, but...
147                        if(cmpstr(topGraph,"")==0)
148                                return(0)
149                        endif
150                        String list,folderStr
151                        Variable num
152                        list = TraceNameList(topGraph,";",1)            //want the last item in the list
153                        num= ItemsInList(list)
154                        FolderStr = StringFromList(num-1,list,";")
155                        folderStr = folderStr[0,strlen(folderStr)-3]            //remove the "_i" that the loader enforced
156                        list = W_DataSetPopupList()
157                        num=WhichListItem(folderStr,list,";",0,0)
158                        if(num != -1)
159                                PopupMenu popup_0,mode=num+1,win=WrapperPanel
160                                ControlUpdate/W=WrapperPanel popup_0
161                               
162                                // fake mouse up to pop the menu
163                                Struct WMPopupAction ps
164                                ps.eventCode = 2                //fake mouse up
165                                DataSet_PopMenuProc(ps)
166                        endif
167                        break
168        endswitch
169       
170        return 0
171End
172
173
174// is there a simpler way to do this? I don't think so.
175Function/S W_DataSetPopupList()
176
177        String str=GetAList(4)
178
179        if(strlen(str)==0)
180                str = "No data loaded"
181        endif
182        str = SortList(str)
183       
184        return(str)
185End
186
187
188// show the available models
189// not the f*(cw,xw) point calculations
190// not the *X(cw,xw) XOPS
191//
192// KIND:10 should show only user-defined curve fitting functions
193// - not XOPs
194// - not other user-defined functions
195Function/S W_FunctionPopupList()
196        String list,tmp
197        list = FunctionList("*",";","KIND:10")          //get every user defined curve fit function
198
199        //now start to remove everything the user doesn't need to see...
200
201        tmp = FunctionList("*_proto",";","KIND:10")             //prototypes
202        list = RemoveFromList(tmp, list  ,";")
203       
204        //prototypes that show up if GF is loaded
205        list = RemoveFromList("GFFitFuncTemplate", list)
206        list = RemoveFromList("GFFitAllAtOnceTemplate", list)
207        list = RemoveFromList("NewGlblFitFunc", list)
208        list = RemoveFromList("NewGlblFitFuncAllAtOnce", list)
209        list = RemoveFromList("GlobalFitFunc", list)
210        list = RemoveFromList("GlobalFitAllAtOnce", list)
211        list = RemoveFromList("GFFitAAOStructTemplate", list)
212        list = RemoveFromList("NewGF_SetXWaveInList", list)
213        list = RemoveFromList("NewGlblFitFuncAAOStruct", list)
214       
215        // more to remove as a result of 2D/Gizmo
216        list = RemoveFromList("A_WMRunLessThanDelta", list)
217        list = RemoveFromList("WMFindNaNValue", list)
218        list = RemoveFromList("WM_Make3DBarChartParametricWave", list)
219        list = RemoveFromList("UpdateQxQy2Mat", list)
220        list = RemoveFromList("MakeBSMask", list)
221       
222        // MOTOFIT/GenFit bits
223        tmp = "GEN_allatoncefitfunc;GEN_fitfunc;GetCheckBoxesState;MOTO_GFFitAllAtOnceTemplate;MOTO_GFFitFuncTemplate;MOTO_NewGF_SetXWaveInList;MOTO_NewGlblFitFunc;MOTO_NewGlblFitFuncAllAtOnce;GeneticFit_UnSmearedModel;GeneticFit_SmearedModel;"
224        list = RemoveFromList(tmp, list  ,";")
225
226        // SANS Reduction bits
227        tmp = "ASStandardFunction;Ann_1D_Graph;Avg_1D_Graph;BStandardFunction;CStandardFunction;Draw_Plot1D;MyMat2XYZ;NewDirection;SANSModelAAO_MCproto;Monte_SANS_Threaded;Monte_SANS_NotThreaded;Monte_SANS_W1;Monte_SANS_W2;Monte_SANS;FractionReachingDetector;"
228        list = RemoveFromList(tmp, list  ,";")
229
230        // USANS Reduction bits
231        tmp = "DSM_Guinier_Fit;RemoveMaskedPoints;"
232        list = RemoveFromList(tmp, list  ,";")
233
234        //more functions from analysis models (2008)
235        tmp = "Barbell_Inner;Barbell_Outer;Barbell_integrand;BCC_Integrand;Integrand_BCC_Inner;Integrand_BCC_Outer;"
236        list = RemoveFromList(tmp, list  ,";")
237        tmp = "CapCyl;CapCyl_Inner;CapCyl_Outer;ConvLens;ConvLens_Inner;ConvLens_Outer;"
238        list = RemoveFromList(tmp, list  ,";")
239        tmp = "Dumb;Dumb_Inner;Dumb_Outer;FCC_Integrand;Integrand_FCC_Inner;Integrand_FCC_Outer;"
240        list = RemoveFromList(tmp, list  ,";")
241        tmp = "Integrand_SC_Inner;Integrand_SC_Outer;SC_Integrand;SphCyl;SphCyl_Inner;SphCyl_Outer;"
242        list = RemoveFromList(tmp, list  ,";")
243
244
245        tmp = FunctionList("f*",";","NPARAMS:2")                //point calculations
246        list = RemoveFromList(tmp, list  ,";")
247       
248        tmp = FunctionList("fSmear*",";","NPARAMS:3")           //smeared dependency calculations
249        list = RemoveFromList(tmp, list  ,";")
250       
251//      tmp = FunctionList("*X",";","KIND:4")           //XOPs, but these shouldn't show up if KIND:10 is used initially
252//      Print "X* = ",tmp
253//      print " "
254//      list = RemoveFromList(tmp, list  ,";")
255       
256        //non-fit functions that I can't seem to filter out
257        list = RemoveFromList("BinaryHS_PSF11;BinaryHS_PSF12;BinaryHS_PSF22;EllipCyl_Integrand;PP_Inner;PP_Outer;Phi_EC;TaE_Inner;TaE_Outer;",list,";")
258
259        if(strlen(list)==0)
260                list = "No functions plotted"
261        endif
262       
263        list = SortList(list)
264        return(list)
265End
266
267
268// show all the appropriate coefficient waves
269//
270// also need to search the folder listed in "data set" popup
271// for smeared coefs
272//
273// - or - restrict the coefficient list based on the model function
274// - new way, filter the possible values based on the data folder and function
275Function/S W_CoefPopupList()
276
277        String notPlotted="Please plot the function"
278        ControlInfo/W=wrapperpanel popup_1
279        String funcStr=S_Value
280        String coefStr=getFunctionCoef(funcStr)
281       
282        if(cmpstr(coefStr,"")==0)               //no correspondence in the KW string
283                return(notPlotted)
284        endif
285       
286       
287        //found a coefficient wave - only two places to look
288        // is it in the root folder?
289        if(exists("root:"+coefStr) != 0)
290                return(coefStr)
291        endif
292       
293        // is it in the data folder?
294        ControlInfo/W=wrapperpanel popup_0
295        String folderStr=S_Value
296        if(exists("root:"+folderStr+":"+coefStr) != 0)
297                return(coefStr)
298        endif
299
300        return(notPlotted)
301End
302
303// show all the appropriate coefficient waves
304//
305// also need to search the folder listed in "data set" popup
306// for smeared coefs
307//
308// - or - restrict the coefficient list based on the model function
309//
310// --old way
311//Function/S W_CoefPopupList()
312//      String list
313//      setDataFolder root:
314//      list = WaveList("coef*",";","")
315//     
316//      ControlInfo/W=wrapperpanel popup_0
317//      if(V_Value != 0)                //0== no items in menu
318//              if(DataFolderExists("root:"+S_Value))
319//                      SetDataFolder $("root:"+S_Value)
320//                      list += WaveList("*coef*",";","")
321//              endif
322//      endif
323//     
324//      // tmp coefficients that aren't being cleaned up from somewhere...
325//      list = RemoveFromList("temp_coef_1;temp_coef_2;", list  ,";")
326//
327//      if(strlen(list)==0)
328//              list = "No functions plotted"
329//      endif
330//      list = SortList(list)
331//     
332////    Print itemsinlist(list,";")
333//     
334//      setDataFolder root:
335//      return(list)
336//End
337
338// if the coefficients are changed, then update the table
339//
340//update the table
341// may be easier to just kill the subwindow (table) and create a new one
342// need to set/reset all of the waves in the table
343//
344// !! only respond to mouse up
345//
346Function Coef_PopMenuProc(pa) : PopupMenuControl
347        STRUCT WMPopupAction &pa
348
349        switch( pa.eventCode )
350                case 2: // mouse up
351                        Variable popNum = pa.popNum
352                        String popStr = pa.popStr
353                        ControlInfo/W=WrapperPanel popup_1
354                        String funcStr=S_Value
355                        String suffix = getModelSuffix(funcStr)
356                        ControlInfo/W=WrapperPanel popup_0
357                        String folderStr=S_Value
358                       
359                        if(cmpstr(popStr,"Please plot the function")==0)
360//                              Print "function not plotted"
361                                return(0)
362                        endif
363
364// this if/else/endif should not ever return an error alert     
365// it should simply set the data folder properly       
366                        if(DataFolderExists("root:"+folderStr))
367                                SetDataFolder $("root:"+folderStr)
368                                if(!exists(popStr))
369                                        // must be unsmeared model, work in the root folder
370                                        SetDataFolder root:                             
371                                        if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
372                                                DoAlert 0,"the coefficient and data sets do not match (1)"
373                                                return 0
374                                        endif
375                                endif
376                        else
377                                // must be unsmeared model, work in the root folder
378                                SetDataFolder root:     
379                                if(!exists(popStr))             //this should be fine if the coef filter is working, but check anyhow
380                                        DoAlert 0,"the coefficient and data sets do not match (2)"
381                                        return 0
382                                endif
383                        endif
384                       
385                        // farm the work out to another function?
386                        Variable num=numpnts($popStr)
387                        // make the necessary waves if they don't exist already
388                        if(exists("Hold_"+suffix) == 0)
389                                Make/O/D/N=(num) $("epsilon_"+suffix),$("Hold_"+suffix)
390                                Make/O/T/N=(num) $("LoLim_"+suffix),$("HiLim_"+suffix)
391                                Wave eps = $("epsilon_"+suffix)
392                                Wave coef=$popStr
393                                if(eps[0] == 0)         //if eps already if filled, don't change it
394                                        eps = abs(coef*1e-4) + 1e-10                    //default eps is proportional to the coefficients
395                                endif
396                        endif
397                        // default epsilon values, sometimes needed for the fit
398                       
399                        WAVE/T LoLim = $("LoLim_"+suffix)
400                        WAVE/T HiLim = $("HiLim_"+suffix)
401                       
402                        // clear the table (a subwindow)
403                        DoWindow/F WrapperPanel                         // ?? had to add this in during all of the cursor meddling...
404                        KillWindow wrapperPanel#T0
405                        Edit/W=(20,174,634,435)/HOST=wrapperPanel
406                        RenameWindow #,T0
407                        // get them onto the table
408                        // how do I get the parameter name?
409                        String param = getFunctionParams(funcStr)
410                        AppendtoTable/W=wrapperPanel#T0 $param,$(popStr)
411                        AppendToTable/W=wrapperPanel#T0 $("Hold_"+suffix),$("LoLim_"+suffix),$("HiLim_"+suffix),$("epsilon_"+suffix)
412                        ModifyTable/W=wrapperPanel#T0 width(Point)=0
413                       
414                        SetDataFolder root:
415                        break
416        endswitch
417
418        return 0
419End
420
421// if the Function is changed, then update the coef popup (if possible) and then the table (if possible)
422//
423// !! only respond to mouse up
424//
425Function Function_PopMenuProc(pa) : PopupMenuControl
426        STRUCT WMPopupAction &pa
427
428        switch( pa.eventCode )
429                case 2: // mouse up
430                        Variable popNum = pa.popNum
431                        String funcStr = pa.popStr
432                        String coefStr = W_CoefPopupList()
433                       
434//                      Print "coefStr = ",coefStr
435                       
436                        ControlInfo/W=WrapperPanel popup_0
437                        String folderStr=S_Value
438                       
439                        String listStr = W_CoefPopupList()
440                        Variable num=WhichListItem(coefStr, listStr, ";")
441                        String str=StringFromList(num, listStr  ,";")
442//                      print "str = ",str
443                        //set the item in the coef popup, and pop it
444                        PopupMenu popup_2 win=WrapperPanel,mode=(num+1)
445                       
446                        Struct WMPopupAction ps
447                        ps.eventCode = 2                //fake mouse up
448                        ps.popStr = str
449                        Coef_PopMenuProc(ps)
450                       
451                        SetDataFolder root:
452                        break
453        endswitch
454
455        return 0
456End
457
458// if the Data Set is changed, then update the function (if possible)
459// and the coef popup (if possible) and then the table (if possible)
460//
461// !! only respond to mouse up here, and simply send a fake mouse up
462// to the function pop, which will do what it can do
463//
464Function DataSet_PopMenuProc(pa) : PopupMenuControl
465        STRUCT WMPopupAction &pa
466       
467        switch( pa.eventCode )
468                case 2: // mouse up
469                        // make sure that the cursors are on/off appropriately
470                        // let the cursors checkbox decide what to do, sending the current state
471                        ControlInfo/W=WrapperPanel check_0
472                        STRUCT WMCheckboxAction cba
473                        cba.eventCode = 2
474                        cba.checked = V_Value
475                        UseCursorsWrapperProc(cba)
476                                       
477                        // then cascade the function/coefficient popups
478                        Struct WMPopupAction ps
479                        ps.eventCode = 2                //fake mouse up
480                        Function_PopMenuProc(ps)
481                       
482                        SetDataFolder root:
483                        break
484        endswitch
485
486        return 0
487End
488
489
490// always pass this the function string
491//
492// this is new in the 2009 release, so make sure that it generates itself as needed.
493// Two options: (1) search and construct as needed, ask for intervention if I need it.
494// (2) since I'm passed the function, try to replot it to re-run the function
495// to fill in the strings. (Being sure to save the coefficients)
496//
497// using method (1) to fill in what I need with no intervention
498//
499Function/S getFunctionParams(funcStr)
500        String funcStr
501
502        String paramStr=""
503        SVAR/Z listStr=root:Packages:NIST:paramKWStr
504
505        if(SVAR_Exists(listStr))
506                paramStr = StringByKey(funcStr, listStr  ,"=",";",0)
507                if(strlen(paramStr)!=0)                 //will drop out of loop if string can't be found
508                        return(paramStr)
509                endif
510        else    //global string does not exist, create it and fill it in
511                Variable/G root:Pacakges:NIST:gReconstructStrings = 1                   //coefficients old style and must be rebuilt too
512                String/G root:Packages:NIST:paramKWStr=""
513                SVAR/Z listStr=root:Packages:NIST:paramKWStr
514        endif   
515       
516        // find everything to rebuild only if the model has been plotted (if so, coefficients will exist)
517        String coef = getFunctionCoef(funcStr)
518        if(strlen(coef)==0)
519                //model not plotted, don't reconstruct, return null string
520                return(paramStr)
521        endif
522       
523        ///// NEED TO BE IN PROPER DATA FOLDER FOR SMEARED FUNCTIONS
524        // FUNCTION POP MENU WILL LOOK IN ROOT OTHERWISE
525        ControlInfo/W=WrapperPanel popup_0
526        String folderStr=S_Value
527        // this if/else/endif should not ever return an error alert     
528        // it should simply set the data folder properly       
529        if(Stringmatch(funcStr,"Smear*"))               //simple test for smeared function
530                if(DataFolderExists("root:"+folderStr))
531                        SetDataFolder $("root:"+folderStr)
532                else
533                        SetDataFolder root:
534                endif
535        else
536                SetDataFolder root:
537        endif
538       
539        // model was plotted, find the suffix to fill in the parameter wave
540        SVAR suffListStr=root:Packages:NIST:suffixKWStr
541        String suffix = StringByKey(coef, suffListStr  ,"=",";",0)
542       
543        String paramWave = WaveList("*par*"+suffix,"","TEXT:1")         //should be one wave name, no trailing semicolon
544        listStr += funcStr+"="+paramWave+";"
545
546        //now look it up again
547        paramStr = StringByKey(funcStr, listStr  ,"=",";",0)
548
549        return(paramStr)
550End
551
552// always pass this the function string
553//
554Function/S getFunctionCoef(funcStr)
555        String funcStr
556
557        SVAR listStr=root:Packages:NIST:coefKWStr
558        String coefStr = StringByKey(funcStr, listStr  ,"=",";",0)
559
560        return(coefStr)
561End
562
563// always pass this the Function string
564//
565// does NOT return the leading "_" as part of the suffix
566// may need to set the string correctly - so lost of messing around for back-compatibility
567Function/S getModelSuffix(funcStr)
568        String funcStr
569
570        SVAR listStr=root:Packages:NIST:suffixKWStr
571        String suffixStr = StringByKey(funcStr, listStr  ,"=",";",0)
572
573        if(strlen(suffixStr) !=0)               //found it, get out
574                return(suffixStr)
575        endif
576       
577        // was the model plotted?
578        String coef = getFunctionCoef(funcStr)
579        if(strlen(coef)==0)             
580                //nothing plotted
581                return("")
582        else
583                //plotted, find the coeff
584                String suffix = StringByKey(coef, ListStr  ,"=",";",0)
585       
586                // add to the suffix list in the new style, if it was found
587                if(strlen(suffix) !=0)
588                        listStr += funcStr+"="+suffix+";"
589                endif
590                return(suffix)
591        endif
592       
593        return("")
594End
595
596
597
598// - this is based on stringent "PlotNNN" naming requirements
599//
600//  ???
601// - how to kill the generated table and graph, that are not needed now
602//
603Function PlotModelFunction(ba) : ButtonControl
604        STRUCT WMButtonAction &ba
605
606        String folderStr,funcStr,coefStr,cmdStr=""
607        Variable useCursors,useEps,useConstr
608       
609        Variable killWhat=0             //kill nothing as default
610       
611        switch( ba.eventCode )
612                case 2: // mouse up
613                        ControlInfo/W=WrapperPanel popup_0
614                        folderStr=S_Value
615                       
616                        ControlInfo/W=WrapperPanel popup_1
617                        funcStr=S_Value
618                       
619                        // maybe nothing has been loaded yet...
620                        if(cmpstr(funcStr,"No functions plotted") == 0)
621                                break
622                        endif
623                       
624                        // check for smeared or smeared function
625                        if(stringmatch(funcStr, "Smear*" )==1)
626                                //it's a smeared model
627                                // check for the special case of RPA that has an extra parameter
628                                if(strsearch(funcStr, "RPAForm", 0 ,0) == -1)
629                                        sprintf cmdStr, "Plot%s(\"%s\")",funcStr,folderStr              //not RPA
630                                else
631                                        sprintf cmdStr, "Plot%s(\"%s\",)",funcStr,folderStr             //yes RPA, leave a comma for input
632                                endif
633                                killWhat = 1
634                        else
635                                // it's not,    don't kill the graph, just the table           
636                                sprintf cmdStr, "Plot%s()",funcStr
637                                killWhat = 2
638                        endif
639                       
640                        //Print cmdStr
641                        Execute cmdStr
642                       
643                        //pop the function menu to set the proper coefficients
644                        DoWindow/F WrapperPanel
645                        STRUCT WMPopupAction pa
646                        pa.popStr = funcStr
647                        pa.eventcode = 2
648                        Function_PopMenuProc(pa)
649       
650                        KillTopGraphAndTable(killWhat)          // crude
651       
652                        break
653        endswitch
654       
655        return 0
656End
657
658// passing 0 kills nothing
659// passing 1 kills the top graph and table
660// passing 2 kills the top table only
661//
662Function KillTopGraphAndTable(killwhat)
663        Variable killWhat
664       
665        String topGraph= WinName(0,1)   //this is the topmost graph     
666        String topTable= WinName(0,2)   //this is the topmost table
667
668        if(killWhat == 0)
669                return(0)
670        endif
671       
672        if(killWhat == 1)
673                KillWindow $topGraph
674                KillWindow $topTable
675        endif
676       
677        if(killWhat == 2)
678                KillWindow $topTable
679        endif
680       
681        return(0)
682End
683
684// How to bypass the step of plot and append?
685//
686// do it in two separate events
687//
688Function AppendModelToTarget(ba) : ButtonControl
689        STRUCT WMButtonAction &ba
690
691        String coefStr,suffix,yWStr,xWStr,folderStr,funcStr
692       
693        switch( ba.eventCode )
694                case 2: // mouse up                     
695                        ControlInfo/W=WrapperPanel popup_2
696                        coefStr=S_Value
697                       
698                        ControlInfo/W=WrapperPanel popup_1
699                        funcStr=S_Value
700                        suffix = getModelSuffix(funcStr)
701                       
702                        // check for smeared or smeared function
703                        if(stringmatch(coefStr, "smear*" )==1)
704                                //it's a smeared model
705                                ControlInfo/W=WrapperPanel popup_0
706                                folderStr=S_Value
707                                xWStr = "root:"+folderStr+":smeared_qvals"
708                                ywStr = "root:"+folderStr+":smeared_"+suffix
709                        else
710                                // it's not, so it's in the root folder
711                                xWStr = "xwave_"+suffix
712                                yWStr = "ywave_"+suffix
713                        endif
714                       
715                        Wave/Z yw = $yWStr
716                        Wave/Z xw = $xWStr
717                        if(WaveExists(yw) && WaveExists(xw))
718                                AppendtoGraph yw vs xw
719                        else
720                                DoAlert 0,"The selected model has not been plotted for the selected data set."
721                        endif
722                        break
723        endswitch
724       
725        return 0
726End
727
728
729// this should parse the panel and call the FitWrapper() function
730Function DoTheFitButton(ba) : ButtonControl
731        STRUCT WMButtonAction &ba
732
733        String folderStr,funcStr,coefStr
734        Variable useCursors,useEps,useConstr
735       
736        switch( ba.eventCode )
737                case 2: // mouse up
738                        ControlInfo/W=WrapperPanel popup_0
739                        folderStr=S_Value
740                       
741                        ControlInfo/W=WrapperPanel popup_1
742                        funcStr=S_Value
743                       
744                        ControlInfo/W=WrapperPanel popup_2
745                        coefStr=S_Value
746                       
747                        ControlInfo/W=WrapperPanel check_0
748                        useCursors=V_Value
749                        ControlInfo/W=WrapperPanel check_1
750                        useEps=V_Value
751                        ControlInfo/W=WrapperPanel check_2
752                        useConstr=V_Value
753                       
754                        if(!CheckFunctionAndCoef(funcStr,coefStr))
755                                DoAlert 0,"The coefficients and function type do not match. Please correct the selections in the popup menus."
756                                break
757                        endif
758                       
759                        FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
760                       
761                        //      DoUpdate (does not work!)
762                        //?? why do I need to force an update ??
763                        if(!exists("root:"+folderStr+":"+coefStr))
764                                Wave w=$coefStr
765                        else
766                                Wave w=$("root:"+folderStr+":"+coefStr) //smeared coefs in data folder
767                        endif
768                        w[0] += 1e-6
769                        w[0] -= 1e-6
770       
771                        break
772        endswitch
773       
774        return 0
775End
776
777Function CheckFunctionAndCoef(funcStr,coefStr)
778        String funcStr,coefStr
779       
780        SVAR listStr=root:Packages:NIST:coefKWStr
781        String properCoefStr = StringByKey(funcStr, listStr  ,"=",";",0)
782        if(cmpstr("",properCoefStr)==0)
783                return(0)               //false, no match found, so properCoefStr is returned null
784        endif
785        if(cmpstr(coefStr,properCoefStr)==0)
786                return(1)               //true, the coef is the correct match
787        endif
788        return(0)                       //false, wrong coef
789End
790
791/////////////////////////////////
792
793// wrapper to do the desired fit
794//
795// folderStr is the data folder for the desired data set
796//
797//
798Function FitWrapper(folderStr,funcStr,coefStr,useCursors,useEps,useConstr)
799        String folderStr,funcStr,coefStr
800        Variable useCursors,useEps,useConstr
801
802        String suffix=getModelSuffix(funcStr)
803       
804        SetDataFolder $("root:"+folderStr)
805        if(!exists(coefStr))
806                // must be unsmeared model, work in the root folder
807                SetDataFolder root:                             
808                if(!exists(coefStr))            //this should be fine if the coef filter is working, but check anyhow
809                        DoAlert 0,"the coefficient and data sets do not match"
810                        return 0
811                endif
812        endif
813               
814        WAVE cw=$(coefStr)     
815        Wave hold=$("Hold_"+suffix)
816        Wave/T lolim=$("LoLim_"+suffix)
817        Wave/T hilim=$("HiLim_"+suffix)
818        Wave eps=$("epsilon_"+suffix)
819       
820// fill a struct instance whether I need one or not
821        String DF="root:"+folderStr+":"
822       
823        Struct ResSmearAAOStruct fs
824        WAVE/Z resW = $(DF+folderStr+"_res")                    //these may not exist, if 3-column data is used
825        WAVE/Z fs.resW =  resW
826        WAVE yw=$(DF+folderStr+"_i")
827        WAVE xw=$(DF+folderStr+"_q")
828        WAVE sw=$(DF+folderStr+"_s")
829        Wave fs.coefW = cw
830        Wave fs.yW = yw
831        Wave fs.xW = xw
832       
833        Duplicate/O yw $(DF+"FitYw")
834        WAVE fitYw = $(DF+"FitYw")
835        fitYw = NaN
836       
837        Variable useRes=0,isUSANS=0,val
838        if(stringmatch(funcStr, "Smear*"))              // if it's a smeared function, need a struct
839                useRes=1
840        endif
841        if(dimsize(resW,1) > 4)
842                isUSANS=1
843        endif
844        // do not construct constraints for any of the coefficients that are being held
845        // -- this will generate an "unknown error" from the curve fitting
846        Make/O/T/N=0 constr
847        if(useConstr)
848                String constraintExpression
849                Variable i, nPnts=DimSize(lolim, 0),nextRow=0
850                for (i=0; i < nPnts; i += 1)
851                        if (strlen(lolim[i]) > 0 && hold[i] == 0)
852                                InsertPoints nextRow, 1, constr
853                                sprintf constraintExpression, "K%d > %s", i, lolim[i]
854                                constr[nextRow] = constraintExpression
855                                nextRow += 1
856                        endif
857                        if (strlen(hilim[i]) > 0 && hold[i] == 0)
858                                InsertPoints nextRow, 1, constr
859                                sprintf constraintExpression, "K%d < %s", i, hilim[i]
860                                constr[nextRow] = constraintExpression
861                                nextRow += 1
862                        endif
863                endfor
864        endif
865
866        // 20JUN if useCursors is true, and there are no cursors on the specified data set, uncheck and set to false
867        // this is a last line of defense, and should never actually do anything...
868        if(useCursors)
869                useCursors = AreCursorsCorrect(folderStr)
870        endif
871        //if useCursors, and the data is USANS, need to recalculate the matrix if the range is new
872        Variable pt1,pt2,newN,mPt1,mPt2
873        String noteStr
874        if(useCursors && isUSANS )
875                //where are the cursors, and what is the status of the current matrix?
876                if(pcsr(A) > pcsr(B))
877                        pt1 = pcsr(B)
878                        pt2 = pcsr(A)
879                else
880                        pt1 = pcsr(A)
881                        pt2 = pcsr(B)
882                endif
883               
884                noteStr = note(resW)
885                mPt1 = NumberByKey("P1",noteStr,"=",";")
886                mPt2 = NumberByKey("P2",noteStr,"=",";")
887                if((mPt1 != pt1) || (mPt2 != pt2) )
888                        // need to recalculate
889                        USANS_RE_CalcWeights(folderStr,pt1,pt2)
890                        Print "Done recalculating the matrix"
891                endif
892               
893                Wave trimResW=$(DF+folderStr+"_res"+"t")        //put the trimmed resW in the struct for the fit!
894                Wave fs.resW=trimResW
895        endif
896        if(useCursors)
897                //find the points so that genetic optimization can use them
898                if(pcsr(A) > pcsr(B))
899                        pt1 = pcsr(B)
900                        pt2 = pcsr(A)
901                else
902                        pt1 = pcsr(A)
903                        pt2 = pcsr(B)
904                endif
905        endif
906               
907// create these variables so that FuncFit will set them on exit
908        Variable/G V_FitError=0                         //0=no err, 1=error,(2^1+2^0)=3=singular matrix
909        Variable/G V_FitQuitReason=0            //0=ok,1=maxiter,2=user stop,3=no chisq decrease
910
911        NVAR useGenCurveFit = root:Packages:NIST:gUseGenCurveFit
912// don't use the auto-destination with no flag, it doesn't appear to work correctly
913// dispatch the fit
914
915// currently, none of the fit functions are defined as threadsafe, so I don't think that the /NTHR flag really
916// does anything. The functions themselves can be threaded since they are AAO, and that is probably enough,
917// since it doesn't make much sense to thread threads. In addition, there is a little-publicized warning
918// in the WM help file that /C=texWave cannot be used to specify constraints for threadsafe functions!
919// The textwave would have to be parsed into a constraint matrix first, then passed as /C={cMat,cVec}.
920// -- just something to watch out for.
921
922        do
923//              Variable t0 = stopMStimer(-2)           // corresponding print is at the end of the do-while loop (outside)
924
925
926                if(useGenCurveFit)
927               
928#if !(exists("GenCurveFit"))
929                        // XOP not available
930                        useGenCurveFit = 0
931                        Abort "Genetic Optimiztion XOP not available. Reverting to normal optimization."       
932#endif
933                        //send everything to a function, to reduce the clutter
934                        // useEps and useConstr are not needed
935                        // pass the structure to get the current waves, including the trimmed USANS matrix
936                        Variable chi,pt
937
938                        chi = DoGenCurveFit(useRes,useCursors,sw,fitYw,fs,funcStr,getHStr(hold),val,lolim,hilim,pt1,pt2)
939                        pt = val
940
941                        break
942                       
943                endif
944               
945               
946                if(useRes && useEps && useCursors && useConstr)         //do it all
947                        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
948                        break
949                endif
950               
951                if(useRes && useEps && useCursors)              //no constr
952                        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
953                        break
954                endif
955               
956                if(useRes && useEps && useConstr)               //no crsr
957                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr /STRC=fs
958                        break
959                endif
960               
961                if(useRes && useCursors && useConstr)           //no eps
962                        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
963                        break
964                endif
965               
966                if(useRes && useCursors)                //no eps, no constr
967                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
968                        break
969                endif
970               
971                if(useRes && useEps)            //no crsr, no constr
972//                      Print "timing test for Cylinder_PolyRadius --- the supposedly threaded version ---"
973//                      Variable t0 = stopMStimer(-2)
974                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
975//                      t0 = (stopMSTimer(-2) - t0)*1e-6
976//                      Printf  "CylPolyRad fit time using res and eps and /NTHR=0 time = %g seconds\r\r",t0
977                       
978//                      cw[0] = .01
979//                      cw[1] = 20
980//                      cw[2] = 400
981//                      cw[3] = 0.2
982//                      cw[4] = 3e-6
983//                      cw[5] = 0.0
984//                     
985//                      t0 = stopMSTimer(-2)
986//                      FuncFit/H=getHStr(hold) $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /STRC=fs
987//                      t0 = (stopMSTimer(-2) - t0)*1e-6
988//                      Printf  "CylPolyRad fit time using res and eps and NO THREADING time = %g seconds\r\r",t0
989                        break
990                endif
991       
992                if(useRes && useConstr)         //no crsr, no eps
993                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr /STRC=fs
994                        break
995                endif
996               
997                if(useRes)              //just res
998                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /STRC=fs
999                        break
1000                endif
1001               
1002/////   same as above, but all without useRes (no /STRC flag)
1003                if(useEps && useCursors && useConstr)           //do it all
1004                        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
1005                        break
1006                endif
1007               
1008                if(useEps && useCursors)                //no constr
1009                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /E=eps /D=fitYw
1010                        break
1011                endif
1012               
1013                if(useEps && useConstr)         //no crsr
1014                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw /C=constr
1015                        break
1016                endif
1017               
1018                if(useCursors && useConstr)             //no eps
1019                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw /C=constr
1020                        break
1021                endif
1022               
1023                if(useCursors)          //no eps, no constr
1024                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw[pcsr(A),pcsr(B)] /X=xw /W=sw /I=1 /D=fitYw
1025                        break
1026                endif
1027               
1028                if(useEps)              //no crsr, no constr
1029                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /E=eps /D=fitYw
1030                        break
1031                endif
1032       
1033                if(useConstr)           //no crsr, no eps
1034                        FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw /C=constr
1035                        break
1036                endif
1037               
1038                //just a plain vanilla fit
1039                FuncFit/H=getHStr(hold) /NTHR=0 $funcStr cw, yw /X=xw /W=sw /I=1 /D=fitYw
1040       
1041        while(0)
1042       
1043//      t0 = (stopMSTimer(-2) - t0)*1e-6
1044//      Printf  "fit time = %g seconds\r\r",t0
1045       
1046        // append the fit
1047        // need to manage duplicate copies
1048        // Don't plot the full curve if cursors were used (set fitYw to NaN on entry...)
1049        String traces=TraceNameList("", ";", 1 )                //"" as first parameter == look on the target graph
1050        if(strsearch(traces,"FitYw",0) == -1)
1051                if(useGenCurveFit && useCursors)
1052                        WAVE trimX = trimX
1053                        AppendtoGraph fitYw vs trimX
1054                else
1055                        AppendToGraph FitYw vs xw
1056                endif
1057        else
1058                RemoveFromGraph FitYw
1059                if(useGenCurveFit && useCursors)
1060                        WAVE trimX = trimX
1061                        AppendtoGraph fitYw vs trimX
1062                else
1063                        AppendToGraph FitYw vs xw
1064                endif
1065        endif
1066        ModifyGraph lsize(FitYw)=2,rgb(FitYw)=(0,0,0)
1067       
1068        DoUpdate                //force update of table and graph with fitted values (why doesn't this work? - the table still does not update)
1069       
1070        // report the results (to the panel?)
1071        if(useGenCurveFit)
1072                V_chisq = chi
1073                V_npnts = pt
1074        endif
1075        print "V_chisq = ",V_chisq
1076        print cw
1077        WAVE/Z w_sigma
1078        print w_sigma
1079        String resultStr=""
1080               
1081        //now re-write the results
1082        sprintf resultStr,"Chi^2 = %g  Sqrt(X^2/N) = %g",V_chisq,sqrt(V_chisq/V_Npnts)
1083        resultStr = PadString(resultStr,63,0x20)
1084        GroupBox grpBox_2 title=resultStr
1085        ControlUpdate/W=WrapperPanel grpBox_2
1086        sprintf resultStr,"FitErr = %s : FitQuit = %s",W_ErrorMessage(V_FitError),W_QuitMessage(V_FitQuitReason)
1087        resultStr = PadString(resultStr,63,0x20)
1088        GroupBox grpBox_3 title=resultStr
1089        ControlUpdate/W=WrapperPanel grpBox_3
1090       
1091        Variable yesSave=0,yesReport=0
1092        ControlInfo/W=WrapperPanel check_4
1093        yesReport = V_Value
1094        ControlInfo/W=WrapperPanel check_5
1095        yesSave = V_Value
1096       
1097       
1098        if(yesReport)
1099                String parStr=GetWavesDataFolder(cw,1)+ WaveList("*param*"+suffix, "", "TEXT:1," )              //this is *hopefully* one wave
1100                String topGraph= WinName(0,1)   //this is the topmost graph
1101       
1102                DoUpdate                //force an update of the graph before making a copy of it for the report
1103
1104                W_GenerateReport(funcStr,folderStr,$parStr,cw,yesSave,V_chisq,W_sigma,V_npnts,V_FitError,V_FitQuitReason,V_startRow,V_endRow,topGraph)
1105        endif
1106       
1107        SetDataFolder root:
1108        return(0)
1109End
1110
1111// parse something off of a table, or ?
1112Function/S getHStr(hold)
1113        Wave hold
1114       
1115        String str=""
1116        Variable ii
1117        for(ii=0;ii<numpnts(hold);ii+=1)
1118                str += num2str(hold[ii])
1119        endfor
1120
1121//      print str
1122        if(strsearch(str, "1", 0) == -1)
1123                return ("")
1124        else
1125                return(str)
1126        endif
1127End
1128
1129//taken from SRK Auto_Fit, and modified to work better with FitWrapper
1130//must have AutoGraph as the name of the graph window (any size)
1131// func is the name of the function (for print only)
1132//par and coef are the exact names of the waves
1133//yesSave==1 will save the file(name=func+time)
1134//
1135Function W_GenerateReport(func,dataname,param,ans,yesSave,chiSq,sigWave,npts,fitErr,fitQuit,fitStart,fitEnd,topGraph)
1136        String func,dataname
1137        Wave/T param
1138        Wave ans
1139        Variable yesSave,chiSq
1140        Wave sigWave
1141        Variable npts,fitErr,fitQuit,fitStart,fitEnd
1142        String topGraph
1143       
1144        String str,pictStr="P_"
1145        String nb="Report"
1146               
1147        // bring report up
1148        DoWindow/F Report
1149        if (V_flag == 0)                // Report notebook doesn't exist ?
1150                NewNotebook/W=(10,45,550,620)/F=1/N=Report as "Report"
1151        endif
1152        // delete old stuff
1153        Notebook $nb selection={startOfFile, endOfFile}, text="\r", selection={startOfFile, startOfFile}
1154       
1155        //setup
1156        Notebook $nb defaultTab=36, statusWidth=252, pageMargins={72,72,72,72}
1157        Notebook $nb showRuler=1, rulerUnits=1, updating={1, 60}
1158        Notebook $nb newRuler=Normal, justification=0, margins={0,0,468}, spacing={0,0,0}, tabs={}, rulerDefaults={"Geneva",10,0,(0,0,0)}
1159//     
1160        // insert title
1161        Notebook $nb newRuler=Title, justification=1, rulerDefaults={"Times", 16, 1, (0, 0, 0)}
1162        sprintf str, "Fit to %s, %s, %s\r\r", func,Secs2Date(datetime, 0), time()
1163        Notebook $nb ruler=Title, text=str
1164       
1165        // insert fit results
1166        Variable num=numpnts(ans),ii=0
1167        Notebook $nb ruler=Normal
1168        Notebook $nb  margins={18,18,504}, tabs={63 + 3*8192}
1169        str = "Data file: " + dataname + "\r\r"
1170        Notebook $nb text=str
1171        Notebook $nb ruler=Normal
1172        Notebook $nb margins={18,18,504}, tabs={144,234,252}
1173        do
1174                sprintf str, "%s = \t%g\t±\t%g\r", param[ii],ans[ii],sigwave[ii]
1175                Notebook $nb text=str
1176                ii+=1
1177        while(ii<num)
1178       
1179        //
1180        // no "fitted range" for 2D data, so make sure that this exists before using it
1181        Wave/Z dataXw = $("root:"+dataname+":"+dataname+"_q")   
1182        //
1183        Notebook $nb ruler=Normal
1184        Notebook $nb  margins={18,18,504}, tabs={63+3*8192}, fStyle=1, textRGB=(65000,0,0)
1185       
1186        sprintf str,"chisq = %g\r",chisq
1187        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
1188        sprintf str,"Npnts = %g \t\t Sqrt(X^2/N) = %g\r",npts,sqrt(chiSq/npts)
1189        Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
1190        if(WaveExists(dataXw))
1191                sprintf str "Fitted range = [%d,%d] = %g < Q < %g\r",fitStart,fitEnd,dataXw(fitStart),dataXw(fitEnd)
1192                Notebook $nb textRGB=(0,0,0),fstyle=0, text=str
1193        endif
1194        sprintf str,"FitError = %s\t\tFitQuitReason = %s\r",W_ErrorMessage(FitErr),W_QuitMessage(FitQuit)
1195        Notebook $nb textRGB=(65000,0,0),fstyle=1,text=str
1196        Notebook $nb ruler=Normal
1197       
1198        // insert graphs
1199        if(WaveExists(dataXw))
1200                Notebook $nb picture={$topGraph(0, 0, 400, 300), -5, 1}, text="\r"
1201        //
1202        else            //must be 2D Gizmo
1203                Execute "ExportGizmo Clip"                      //this ALWAYS is a PICT or BMP. Gizmo windows are different...
1204                LoadPict/Q/O "Clipboard",tmp_Gizmo
1205                Notebook $nb picture={tmp_Gizmo(0, 0, 400, 300), 0, 1}, text="\r"
1206        endif
1207        //Notebook Report picture={Table1, 0, 0}, text="\r"
1208       
1209        // show the top of the report
1210        Notebook $nb  selection= {startOfFile, startOfFile},  findText={"", 1}
1211       
1212        //save the notebook and the graphic file
1213        if(yesSave)
1214                String nameStr=CleanupName(func,0)
1215                nameStr = nameStr[0,8]  //shorten the name
1216                nameStr += "_"+dataname
1217                //make sure the name is no more than 31 characters
1218                namestr = namestr[0,30]         //if shorter than 31, this will NOT pad to 31 characters
1219                Print "file saved as ",nameStr
1220                SaveNotebook /O/P=home/S=2 $nb as nameStr
1221                //save the graph separately as a PICT file, 2x screen
1222                pictStr += nameStr
1223                pictStr = pictStr[0,28]         //need a shorter name - why?
1224//              DoWindow/F $topGraph
1225                // E=-5 is png @screen resolution
1226                // E=2 is PICT @2x screen resolution
1227///             SavePICT /E=-5/O/P=home /I/W=(0,0,3,3) as pictStr
1228                if(WaveExists(dataXw))
1229                        SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1230                else
1231                        Execute "ExportGizmo /P=home as \""+pictStr+"\""
1232                        //SavePICT /E=-5/O/P=home/WIN=$topGraph /W=(0,0,400,300) as pictStr
1233                endif
1234        Endif
1235       
1236        // ???maybe print the notebook too?
1237End
1238
1239Function/S W_ErrorMessage(code)
1240        Variable code
1241       
1242        switch (code)
1243                case 0:
1244                        return "No Error"
1245                        break
1246                case 3: //2^0 + 2^1
1247                        return "Singular Matrix"
1248                        break
1249                case 5:         //(2^0 + 2^2)
1250                        return "Out of Memory"
1251                        break
1252                case 9:         //(2^0 + 2^3)
1253                        return "Func= NaN or Inf"
1254                        break
1255                default:
1256                        return "Unknown error code "+num2str(code)
1257        endswitch
1258end
1259
1260Function/S W_QuitMessage(code)
1261        Variable code
1262       
1263        switch (code)
1264                case 0:
1265                        return "No Error"
1266                        break
1267                case 1:
1268                        return "Max iterations - re-run fit"
1269                        break
1270                case 2:
1271                        return "User terminated fit"
1272                        break
1273                case 3:
1274                        return "No decrease in chi-squared"
1275                        break
1276                default:
1277                        return "Unknown Quit code "+num2str(code)
1278        endswitch
1279end
1280
1281Function Toggle2DControlsCheckProc(cba) : CheckBoxControl
1282        STRUCT WMCheckboxAction &cba
1283
1284        switch( cba.eventCode )
1285                case 2: // mouse up
1286                        Variable checked = cba.checked
1287                        if(checked)
1288                                //print "change the buttons to 2D"
1289                                Button button_0,proc=Do2DFitButtonProc,title="Do 2D Fit"
1290                                Button button_1,size={120,20},proc=Plot2DFunctionButtonProc,title="Plot 2D Function"
1291                                Button button_2,size={100,20},proc=Append2DModelButtonProc,title="Append 2D"
1292                                Button button_3,size={100,20},proc=Load2DDataButtonProc,title="Load 2D Data"
1293                               
1294                                Button button_2D_0,pos={550,60},size={70,20},proc=LogToggle2DButtonProc,title="Log/Lin"
1295                                Button button_2D_1,pos={520,37},size={100,20},proc=Plot2DButtonProc,title="Plot 2D Data"
1296                               
1297                                Button button_2D_0,disable=0            //visible again, and enabled
1298                                Button button_2D_1,disable=0
1299                        else
1300                                //print "unchecked, change them back to 1D"
1301                                Button button_0,pos={520,93},size={100,20},proc=DoTheFitButton,title="Do 1D Fit"
1302                                Button button_1,pos={280,57},size={120,20},proc=PlotModelFunction,title="Plot 1D Function"
1303                                Button button_2,pos={300,93},size={100,20},proc=AppendModelToTarget,title="Append 1D"
1304                                Button button_3,pos={300,20},size={100,20},proc=W_LoadDataButtonProc,title="Load 1D Data"
1305                               
1306                                Button button_2D_0,disable=3    //hide the extra 2D buttons, and disable
1307                                Button button_2D_1,disable=3
1308                        endif
1309                        break
1310        endswitch
1311
1312        return 0
1313End
1314
1315// function to either add or remove the cursors from the topmost graph, as needed
1316
1317Function UseCursorsWrapperProc(cba) : CheckBoxControl
1318        STRUCT WMCheckboxAction &cba
1319
1320
1321        switch( cba.eventCode )
1322                case 2: // mouse up
1323               
1324                        // check to make sure there really is a "topmost" graph         
1325                        String topGraph= WinName(0,1)   //this is the topmost graph
1326                        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1327                                CheckBox check_0,value=0
1328                                return(0)
1329                        endif
1330                               
1331                        String ciStr = CsrInfo(A , topGraph)
1332                       
1333                        ControlInfo/W=wrapperpanel popup_0
1334                        String folderStr=S_Value
1335                        String traceList = TraceNameList(topGraph, ";", 1 )             
1336               
1337                        Variable checked = cba.checked
1338                       
1339                        if(checked)
1340                                //print "add the cursors to the topmost graph, if the data set is there, or move them"
1341                                if(strlen(ciStr)==0 && strsearch(traceList, folderStr, 0) != -1 )               //no cursors && data is there
1342                                        ShowInfo
1343                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1344                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0
1345                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1                     //deactivate the one at the high Q end
1346                                        DoUpdate
1347                                elseif (strlen(ciStr)!=0 && strsearch(traceList, folderStr, 0) != -1 ) //cursors present, but on wrong data
1348                                        Wave yw=$("root:"+folderStr+":"+folderStr+"_i")
1349                                        Cursor/P/W=$topGraph A, $(folderStr+"_i"),0                                                             //move the cursors
1350                                        Cursor/P/W=$topGraph/A=0 B, $(folderStr+"_i"),numpnts(yw)-1
1351                                        DoUpdate
1352                                endif
1353                               
1354                                AreCursorsCorrect(folderStr)
1355                        else
1356                                //print "unchecked, remove the cursors"
1357                                // go back to the full matrix for the resolution calculation (not if SANS data...)
1358                                if(waveExists($("root:"+folderStr+":weights_save")))
1359                                        Duplicate/O $("root:"+folderStr+":weights_save"), $("root:"+folderStr+":"+folderStr+"_res"),$("root:"+folderStr+":"+folderStr+"_rest")
1360                                endif
1361
1362                                HideInfo
1363                                Cursor/K A
1364                                Cursor/K B
1365                        endif
1366                        break
1367        endswitch
1368
1369        return 0
1370End
1371
1372// returns 1 if the specified data is on the top graph && has cursors on it
1373// returns 0 and unchecks the box if anything is wrong
1374//
1375// only call this function if the cursor box is checked, to uncheck it as needed
1376// if the box is unchecked, leave it be.
1377//
1378Function AreCursorsCorrect(folderStr)
1379        String folderStr
1380       
1381        String topGraph= WinName(0,1)   //this is the topmost graph
1382        if(cmpstr(topGraph,"")==0)      //no graphs, uncheck and exit
1383                CheckBox check_0,win=wrapperpanel,value=0
1384                return(0)
1385        endif
1386               
1387        String traceAisOn = CsrWave(A , "", 0)
1388        if(     strsearch(traceAisOn, folderStr, 0) == -1)              //data and cursors don't match
1389                CheckBox check_0,win=wrapperpanel,value=0
1390                HideInfo
1391                Cursor/K A
1392                Cursor/K B
1393                return(0)
1394        endif
1395       
1396        return(1)
1397End
Note: See TracBrowser for help on using the repository browser.