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

Last change on this file since 515 was 515, checked in by srkline, 13 years ago

A bunch of random changes:
-SASCALC - added the 2.5 cm aperture NG3/7g/polarizer back in, but made the 5 cm the default
-Some fiddling with 2D functionality to enable 2D resolution smearing. Still a work in progress
-Added two new model functions, and added them to the list.
-Changes to the wrapper for the new release to generate kw=val strings as needed for each function
and its coefficients and parameters. This behavior has been changed in the new release, so this
fix should keep old analysis experiments compatible with the new version.

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