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

Last change on this file since 708 was 708, checked in by srkline, 12 years ago

SA_Includes_v410 : now include Smear_2D

PeakGauss_2D, Sphere_2D : included threaded resolution smearing calculations for testing

DataSetHandling? : Included a quick and dirty batch converter for XML->6-col. See the top
of the file for the command to run

GaussUtils? : re-define the ResSemear_2D_AAOStruct. Relocated q-value and phi calculations from
RawWindowHook? to this file so they would be available for reduction and analysis

Smear_2D : now has a generic (non-threaded) smearing routine. Threading must be done in
individual functions since FUNCREF can't be passed to threads (plus a few other issues)

PlotUtils_2D : updated loader for new QxQy? columns. Fixes to Wrapper_2D to enable smeared fits

RawWindowHook? : removed Q-value calculation functions and moved these to GaussUtils?

WriteQIS : now writes out 8-columns for QxQy? data, defining the resolution
function in terms of directions parallel and perpendicular to Q. TEMPORARILY in the data
file an error in intensity is generated that is SQRT(I), being careful to
replace any NaN, inf, or zero with an average error value

MultiScatter_MonteCarlo_2D : 4-processor aware

NCNR_Utils : 2D resolution calculation is now in terms of parallel and perpendicular
rather than x and y. Gravity is included in the y-component

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