source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/Polarization/Pol_PolarizationPanels.ipf @ 835

Last change on this file since 835 was 835, checked in by srkline, 11 years ago

moving the Polarization routines to a temporary "beta" menu location on the macros menu, numbering the panels.

Created a loader for the polarization routines that will load the SANS reduction if needed.

File size: 40.6 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2
3
4// TODO:
5// x- on the decay panel. need to be able to manually enter a date that is to or an offset
6//              number of hours. currently it takes the first file as t=0, which is often not correct
7//
8
9
10// Polarized Beam Reduction Procedures
11//
12//
13// input panels to set and calculate polarization parameters necessary for the
14// matrix corrections to the cross sections
15//
16// -1- Fundamental Cell Parameters -- these are constants, generally not editable. (this file)
17// -2- Decay Parameters -- these are fitted values based on transmission mearurements (this file)
18// -3- Flipper Panel is in its own procedure (Pol_FlipperPanel.ipf)
19// -4- PolCor_Panel is in Pol_PolarizationCorrection.ipf
20//
21//
22// Driven by 4 panels to get the necessary information from the users
23// -1- Fundamental cell parameters: root:Packages:NIST:Polarization:Cells
24//              - default cell parameters are loaded. More cell definitions can be added as more cells are used
25//              - changes are saved per experiment
26//              - important parameters are held in global key=value strings gCell_<name>
27//              - cell names and parameters are used by the 2nd panel for calculation of the Decay constant
28//
29// -2- Decay Constant Panel
30//              - decay constant determined for each cell.
31//              - popping the cell name makes 2 waves, Decay_<cellname> and DecayCalc_<cellname>
32//              - Decay_ is the wave presented in the table. Specified transmission run numbers are entered
33//                      and "Calc Sel Row" does the calculation of mu and Pcell (for all rows, actually)
34//              - DimLabels are used for the arrays to make the column identity more readable than simply an index
35//              - time=0 is taken from the first file
36//              - Calculations are based on the count rate of the file, corrected for monitor and attenuation
37//              - alerts are posted for files in any row that are not at the same attenuation or SDD
38//              - if "include" column is == 1, that row will be included in the fit of the decay data
39//              - excluded points are plotted in red
40//              - results of the fit are printed on the panel, and written to the wave note of the Decay_ wave
41//                      (not DecayCalc_) for use in the next panel
42//              - manual entry of all of the parameters in the wave note is allowed.
43//
44//
45// -3- Flipper Panel (not in this procedure - in Pol_FlipperPanel.ipf)
46//              - calculates the flipper and supermirror efficiencies for a given "condition"
47//              - this "condition" may have contributions from multiple cells
48//              - start by entering a condition name
49//              - Waves Cond_<condition> and CondCalc_<condition>, and CondCell are created
50//              - DimLabels are used for the arrays to make the column identity more readable than simply an index
51//              - Enter the name of the cell in the first column (the cell must be defined and decay calculated)
52//              - enter transmission run numbers as specified in the table
53//              - Do Average will calculate the Psm and PsmPfl values (and errors) and average if more than
54//                      one row of data is present (and included)
55//              - results are printed on the panel, and written to the wave note of Cond_<condition>
56//              - results are used in the calculation of the polarization matrix
57//              - (the cell name is not entered using a contextual menu, since this is difficult for a subwindow)
58//              - (the wave note no longer needs the cell name)
59//
60// -4- PolCor_Panel (not in this procedure - in Pol_PolarizationCorrection.ipf)
61//              - gets all of the parameters from the user to do the polariztion correction, then the "normal" SANS reduction
62//              - up to 10 files can be added together for each of the different spin states (more than this??)
63//              - one polarization condition is set for everything with the popup @ the top
64//              - two-column list boxes for each state hold the run number and the cell name
65//              - the same list boxes are duplicated (hidden) for the SAM/EMP/BGD tabs as needed
66//              - on loading of the data, the 2-letter spin state is tagged onto the loaded waves (all of them)
67//              - displayed data is simply re-pointed to the desired data
68//              - on loading, the raw files are added together as ususal, normalized to monitor counts. Then each contribution
69//                      of the file to the polarization matrix is added (scaling each by mon/1e8)
70//              - loaded data and PolMatrix are stored in the ususal SAM, EMP, BGD folders.
71//              - Polarization correction is done with one click (one per tab). "_pc" tags are added to the resulting names,
72//                      and copies of all of the associated waves are again copied (wasteful), but makes switching display very easy
73//              - Once all of the polarization correction is done, then the UU_pc (etc.) data can be reduced as usual (xx_pc = 4 passes)
74//              - protocol is built as ususal, from this panel only (since the SAM, EMP, and BGD need to be switched, rather than loaded
75//              - protocols can be saved/recalled.
76//              - reduction will always ask for a protocol rather than using what's on the panel.
77//              - closing the panel will save the state (except the protocol). NOT initializing when re-opening will restore the
78//                      state of the entered runs and the popups of conditions.
79//
80//
81//
82//
83
84
85
86// for the menu
87Menu "Macros"
88        "1 Fundamental Cell Parameters",ShowCellParamPanel()
89        "2 Cell Decay",ShowCellDecayPanel()
90        "3 Flipper States",ShowFlipperPanel()
91        "4 Polarization Correction",ShowPolCorSetup()
92End
93
94
95//
96// Panel -1-
97//
98// Fundamental He cell parameters. Most of these are pre-defined, so that they are supplied as a
99// static table, only edited as parameters are refined.
100//
101// work with this as kwString
102// cell=nameStr
103// lambda=num
104// Te=num
105// err_Te=num
106// mu=num
107// err_mu=num
108//
109//
110// for this panel, the cell parameters are stored as kw strings
111// all of the strings start w/ "gCell_"
112//
113Proc ShowCellParamPanel()
114       
115        // init folders
116        // ASK before initializing cell constants
117        // open the panel
118        DoWindow/F CellParamPanel
119        if(V_flag == 0)
120                InitPolarizationFolders()
121                DoAlert 1,"Do you want to use default parameters?"
122                if(V_flag == 1)
123                        InitPolarizationGlobals()
124                endif
125                Make_HeCell_ParamWaves()
126                DrawCellParamPanel()
127        endif
128
129end
130
131// setup the data folder, etc
132//
133//
134Function InitPolarizationFolders()
135
136        NewDataFolder/O root:Packages:NIST:Polarization
137        NewDataFolder/O root:Packages:NIST:Polarization:Cells                   //holds the cell constants and waves
138       
139        SetDataFolder root:
140        return(0)
141End
142
143//
144// add more cells here as they are defined
145//
146Function InitPolarizationGlobals()
147
148        SetDataFolder root:Packages:NIST:Polarization:Cells
149       
150        // cell constants
151        String/G gCell_Maverick = "cell=Maverick,lambda=5.0,Te=0.87,err_Te=0.01,mu=3.184,err_mu=0.2,"
152        String/G gCell_Burgundy = "cell=Burgundy,lambda=5.0,Te=0.86,err_Te=0.01,mu=3.138,err_mu=0.15,"
153        String/G gCell_Olaf = "cell=Olaf,lambda=7.5,Te=0.86,err_Te=0.005,mu=2.97,err_mu=0.18,"
154       
155       
156        SetDataFolder root:
157        return(0)
158End
159
160
161// parse strings to fill in waves
162//
163//
164Function Make_HeCell_ParamWaves()
165
166        SetDataFolder root:Packages:NIST:Polarization:Cells
167       
168        String listStr,item
169        Variable num,ii
170       
171        // get a list of the strings
172        listStr=StringList("gCell_*",";")
173        num=ItemsInList(listStr,";")
174        print listStr
175       
176        Make/O/T/N=0 CellName
177        Make/O/N=0 lambda,Te,err_Te,mu,err_mu
178       
179        // parse the strings to fill the table
180        for(ii=0;ii<num;ii+=1)
181                item = StringFromList(ii, listStr,";")
182                SVAR gStr = $item
183                InsertPoints  ii, 1, CellName,lambda,Te,err_Te,mu,err_mu
184                CellName[ii] = StringByKey("cell", gStr, "=", ",", 0)
185                lambda[ii] = NumberByKey("lambda", gStr, "=", ",", 0)
186                Te[ii] = NumberByKey("Te", gStr, "=", ",", 0)
187                err_Te[ii] = NumberByKey("err_Te", gStr, "=", ",", 0)
188                mu[ii] = NumberByKey("mu", gStr, "=", ",", 0)
189                err_mu[ii] = NumberByKey("err_mu", gStr, "=", ",", 0)
190               
191        endfor
192
193       
194        SetDataFolder root:
195        return(0)
196End
197
198// take the waves from the table and write these back to the string, only for the current experiment
199//
200Function Save_HeCell_ParamWaves()
201
202        SetDataFolder root:Packages:NIST:Polarization:Cells
203       
204        String listStr,item,dummyStr
205        Variable num,ii
206       
207        // get a list of the strings
208        listStr=StringList("gCell_*",";")
209        num=ItemsInList(listStr,";")
210        KillStrings/Z listStr
211       
212        Wave/T CellName
213        Wave lambda,Te,err_Te,mu,err_mu
214       
215        dummyStr = "cell=Maverick,lambda=5.0,Te=0.87,err_Te=0.01,mu=3.184,err_mu=0.2,"
216       
217        num=numpnts(CellName)
218       
219        // parse the table to fill the Strings
220        for(ii=0;ii<num;ii+=1)
221                item = "gCell_"+CellName[ii]
222                String/G $item = dummyStr
223                SVAR kwListStr = $item
224               
225                kwListStr = ReplaceStringByKey("cell", kwListStr, CellName[ii], "=", ",", 0)
226                kwListStr = ReplaceNumberByKey("lambda", kwListStr, lambda[ii], "=", ",", 0)
227                kwListStr = ReplaceNumberByKey("Te", kwListStr, Te[ii], "=", ",", 0)
228                kwListStr = ReplaceNumberByKey("err_Te", kwListStr, err_Te[ii], "=", ",", 0)
229                kwListStr = ReplaceNumberByKey("mu", kwListStr, mu[ii], "=", ",", 0)
230                kwListStr = ReplaceNumberByKey("err_mu", kwListStr, err_mu[ii], "=", ",", 0)
231               
232        endfor
233
234        SetDataFolder root:
235        return(0)
236End
237
238
239// makes the panel after the waves are generated
240//
241// allow edits of the cells to update the string values
242// add a button to "revert" (with warning)
243// add a button to add new cells (insert a new row in the table, then update)
244//
245Function DrawCellParamPanel()
246
247        SetDataFolder root:Packages:NIST:Polarization:Cells
248       
249        PauseUpdate; Silent 1           // building window...
250        NewPanel /W=(775,44,1375,377)/N=CellParamPanel/K=1 as "Fundamental Cell Parameters"
251        ModifyPanel cbRGB=(65535,49151,55704)
252        ModifyPanel fixedSize=1
253
254//      ShowTools/A
255        Button button_0,pos={10,10},size={90,20},proc=AddCellButtonProc,title="Add Cell"
256        Button button_1,pos={118,10},size={130,20},proc=SaveCellParButtonProc,title="Save Parameters"
257        Button button_2,pos={265,10},size={130,20},proc=RevertCellParButtonProc,title="Revert Parameters"
258        Button button_3,pos={420,10},size={35,20},proc=CellHelpParButtonProc,title="?"
259
260       
261        Edit/W=(14,55,582,318)/HOST=#
262        ModifyTable width(Point)=0
263        RenameWindow #,T0
264
265        WAVE/T CellName
266        WAVE lambda,Te,err_Te,mu,err_mu
267
268        AppendtoTable/W=# CellName,lambda,Te,err_Te,mu,err_mu
269        SetActiveSubwindow ##
270
271        SetDataFolder root:
272        return(0)
273End
274
275Function CellHelpParButtonProc(ba) : ButtonControl
276        STRUCT WMButtonAction &ba
277
278        switch( ba.eventCode )
279                case 2: // mouse up
280                        // click code here
281                        DoAlert 0,"Help for Cell Param Panel not written yet"
282                        break
283                case -1: // control being killed
284                        break
285        endswitch
286
287        return 0
288End
289
290
291Function AddCellButtonProc(ba) : ButtonControl
292        STRUCT WMButtonAction &ba
293
294        switch( ba.eventCode )
295                case 2: // mouse up
296                        // click code here
297                        SetDataFolder root:Packages:NIST:Polarization:Cells
298
299                        WAVE/T CellName
300                        WAVE lambda,Te,err_Te,mu,err_mu
301                        Variable ii= numpnts(CellName)
302                       
303                        InsertPoints  ii, 1, CellName,lambda,Te,err_Te,mu,err_mu
304                       
305                        SetDataFolder root:
306                        break
307                case -1: // control being killed
308                        break
309        endswitch
310
311        return 0
312End
313
314Function SaveCellParButtonProc(ba) : ButtonControl
315        STRUCT WMButtonAction &ba
316
317        switch( ba.eventCode )
318                case 2: // mouse up
319                        // click code here
320                        Save_HeCell_ParamWaves()
321                        break
322                case -1: // control being killed
323                        break
324        endswitch
325
326        return 0
327End
328
329Function RevertCellParButtonProc(ba) : ButtonControl
330        STRUCT WMButtonAction &ba
331
332        switch( ba.eventCode )
333                case 2: // mouse up
334                        // click code here
335                        InitPolarizationGlobals()
336                        Make_HeCell_ParamWaves()
337                        break
338                case -1: // control being killed
339                        break
340        endswitch
341
342        return 0
343End
344
345// END PROCEDURES for He cell parameters
346/////////////////////////////////
347
348
349
350
351
352
353// Decay parameters for each cell. Results are stored in a wave note for each cell
354//
355//      muP=
356//      err_muP=
357// P0=
358//      err_P0=         ? is this needed?
359//      T0=
360// gamma=
361//      err_gamma=
362//
363// str = "muP=2,err_muP=0,P0=0.6,err_P0=0,T0=asdf,gamma=200,err_gamma=0,"
364//
365//
366// for this panel, the cell parameters are stored as kw strings
367// all of the strings start w/ "gDecay_"
368//
369Proc ShowCellDecayPanel()
370       
371        // init folders
372        // ASK before initializing cell constants
373        // open the panel
374        DoWindow/F DecayPanel
375        if(V_flag == 0)
376                InitPolarizationFolders()
377                InitDecayGlobals()
378                DecayParamPanel()
379        endif
380end
381
382Function InitDecayGlobals()
383
384        SetDataFolder root:Packages:NIST:Polarization:Cells
385       
386        String/G gMuPo = "muPo"
387        String/G gPo = "Po"
388        String/G gGamma = "gamma"
389        String/G gT0 = "today's the day"
390       
391       
392        SetDataFolder root:
393        return(0)
394End
395
396
397
398
399// makes the panel for the decay parameter and gamma fitting
400//
401Function DecayParamPanel()
402
403        SetDataFolder root:Packages:NIST:Polarization:Cells
404       
405        PauseUpdate; Silent 1           // building window...
406        NewPanel /W=(759,44,1572,713)/N=DecayPanel/K=1 as "Cell Decay Parameters"
407        ModifyPanel cbRGB=(32768,54615,65535)
408//      Button button_3,pos={505,16},size={35,20},proc=DecayHelpParButtonProc,title="?"
409        PopupMenu popup_0,pos={32,18},size={49,20},title="Cell",proc=DecayPanelPopMenuProc
410        PopupMenu popup_0,mode=1,value= #"D_CellNameList()"
411       
412        Button button_0,pos={584,365},size={70,20},proc=DecayFitButtonProc,title="Do Fit"
413       
414        GroupBox group_0,pos={550,399},size={230,149},title="FIT RESULTS",fSize=10
415        GroupBox group_0,fStyle=1
416        SetVariable setvar_0,pos={560,428},size={200,13},title="muPo of 3He"
417        SetVariable setvar_0,fStyle=1,limits={0,0,0},barmisc={0,1000}
418        SetVariable setvar_0,value= root:Packages:NIST:Polarization:Cells:gMuPo
419        SetVariable setvar_1,pos={560,460},size={200,13},title="Po of 3He"
420        SetVariable setvar_1,fStyle=1,limits={0,0,0},barmisc={0,1000}
421        SetVariable setvar_1,value= root:Packages:NIST:Polarization:Cells:gPo
422        SetVariable setvar_2,pos={560,518},size={200,13},title="Gamma (h)",fStyle=1
423        SetVariable setvar_2,limits={0,0,0},barmisc={0,1000}
424        SetVariable setvar_2,value= root:Packages:NIST:Polarization:Cells:gGamma
425        SetVariable setvar_3,pos={560,488},size={200,15},title="T0",fStyle=1
426        SetVariable setvar_3,limits={0,0,0},value= root:Packages:NIST:Polarization:Cells:gT0
427       
428
429        Button button_1,pos={579,294},size={120,20},proc=CalcRowParamButton,title="Calc Sel Row"
430        Button button_2,pos={307,18},size={110,20},proc=ClearDecayWavesButton,title="Clear Table"
431        Button button_3,pos={579,333},size={120,20},proc=ShowCalcRowButton,title="Show Calc"
432        Button button_4,pos={440,18},size={110,20},proc=ClearDecayWavesRowButton,title="Clear Row"
433        Button button_5,pos={620,18},size={40,20},proc=DecayHelpParButtonProc,title="?"
434        Button button_6,pos={620,620},size={100,20},proc=WindowSnapshotButton,title="Snapshot"
435        Button button_7,pos={620,580},size={130,20},proc=ManualEnterDecayButton,title="Manual Entry"
436        CheckBox check0,mode=0,pos={600,550},title="Overrride T0?",value=0
437
438
439        // table
440        Edit/W=(14,55,794,275)/HOST=#
441        ModifyTable format=1,width=0
442        RenameWindow #,T0
443        SetActiveSubwindow ##
444       
445        // graph
446        Display/W=(15,291,540,652)/HOST=#  //root:yy vs root:xx
447        ModifyGraph frameStyle=2
448        ModifyGraph mode=4
449        ModifyGraph marker=19
450        ModifyGraph rgb=(0,0,0)
451        ModifyGraph msize=2
452
453        Legend
454//      ModifyGraph log(left)=1
455//      ErrorBars yy OFF
456        RenameWindow #,G0
457        SetActiveSubwindow ##
458
459        SetDataFolder root:
460        return(0)
461End
462
463// allows manual entry of Decay values
464//
465// see DecayFitButtonProc
466//
467Function ManualEnterDecayButton(ba) : ButtonControl
468        STRUCT WMButtonAction &ba
469
470        Variable selRow,err=0
471        String fname, t0str, condStr,noteStr,t1Str,cellStr
472
473        switch( ba.eventCode )
474                case 2: // mouse up
475                        // click code here
476                        Variable gamma_val,err_gamma,muPo, err_muPo, Po, err_Po, runNum
477
478                        ControlInfo/W=DecayPanel popup_0
479                        cellStr = S_Value
480                               
481//                      SetDataFolder root:Packages:NIST:Polarization:Cells:
482                       
483                        WAVE decay=$("root:Packages:NIST:Polarization:Cells:Decay_"+cellStr)            //the one that is displayed
484//                      WAVE calc=$("root:Packages:NIST:Polarization:Cells:DecayCalc_"+cellStr)         //with the results
485
486
487                        Prompt Po, "Enter Po: "         
488                        Prompt err_Po, "Enter err_Po: "         
489                        Prompt muPo, "Enter muPo: "             
490                        Prompt err_muPo, "Enter err_muPo: "             
491                        Prompt gamma_val, "Enter gamma: "               
492                        Prompt err_gamma, "Enter err_gamma: "
493                        Prompt runNum,"Run number for time=0 of decay" 
494                        DoPrompt "Enter Cell Decay Parameters", Po, err_Po, muPo, err_muPo, gamma_val, err_gamma, runNum
495                        if (V_Flag)
496                                return -1                                                               // User canceled
497                        endif
498                       
499                        fname = FindFileFromRunNumber(runNum)
500                        t0str = getFileCreationDate(fname)
501                                       
502//              for the wave note
503                        noteStr = note(decay)
504                        noteStr = ReplaceNumberByKey("muP", noteStr, MuPo ,"=", ",", 0)
505                        noteStr = ReplaceNumberByKey("P0", noteStr, Po ,"=", ",", 0)
506                        noteStr = ReplaceNumberByKey("err_muP", noteStr, err_muPo ,"=", ",", 0)
507                        noteStr = ReplaceNumberByKey("err_P0", noteStr, err_Po ,"=", ",", 0)
508                        noteStr = ReplaceNumberByKey("gamma", noteStr, gamma_val ,"=", ",", 0)
509                        noteStr = ReplaceNumberByKey("err_gamma", noteStr, err_gamma ,"=", ",", 0)
510                        noteStr = ReplaceStringByKey("T0", noteStr, t0Str  ,"=", ",", 0)
511                        // replace the string
512                        Note/K decay
513                        Note decay, noteStr
514
515                        // for the panel display
516                        SVAR gGamma  = root:Packages:NIST:Polarization:Cells:gGamma
517                        SVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo
518                        SVAR gPo  = root:Packages:NIST:Polarization:Cells:gPo           
519                        SVAR gT0 = root:Packages:NIST:Polarization:Cells:gT0
520                       
521                        gT0 = t0Str             //for display
522                        sprintf gMuPo, "%g +/- %g",muPo, err_muPo
523                        sprintf gPo, "%g +/- %g",Po,err_Po
524                        sprintf gGamma, "%g +/- %g",gamma_val,err_gamma
525
526                       
527                        break
528                case -1: // control being killed
529                        break
530        endswitch
531
532        return 0
533End
534
535
536Function DecayPanelPopMenuProc(pa) : PopupMenuControl
537        STRUCT WMPopupAction &pa
538
539        switch( pa.eventCode )
540                case 2: // mouse up
541                        Variable popNum = pa.popNum
542                        String popStr = pa.popStr
543                       
544                        SetDataFolder root:Packages:NIST:Polarization:Cells
545
546                        // based on the selected string, display the right set of inputs
547//                      Print "now I need to display the right set of waves (2D text?) for ",popStr
548
549                        // for the given cell name, if the wave(s) exist, declare them
550                        if(exists("Decay_"+popStr) == 1)
551                                WAVE decay = $("Decay_"+popStr)
552                        else
553                                // if not, make it, and the space for the results of the calculation
554                                MakeDecayResultWaves(popStr)
555                                WAVE decay = $("root:Packages:NIST:Polarization:Cells:Decay_"+popStr)
556                        endif                   
557                        // append matrix, clearing the old one first
558                        SetDataFolder root:Packages:NIST:Polarization:Cells
559
560                        KillWindow DecayPanel#T0
561                        Edit/W=(14,55,794,275)/HOST=DecayPanel
562                        RenameWindow #,T0
563                        AppendtoTable/W=DecayPanel#T0 decay.ld                  //show the labels
564                        ModifyTable width(Point)=0
565                        ModifyTable width(decay.l)=20
566                       
567                        SetActiveSubwindow ##
568       
569                        SetDataFolder root:
570                       
571                        //
572                        // now show the fit results, if any, from the wave note
573                        //
574                        SVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo
575                        SVAR gPo  = root:Packages:NIST:Polarization:Cells:gPo
576                        SVAR gGamma  = root:Packages:NIST:Polarization:Cells:gGamma
577                        SVAR gT0  = root:Packages:NIST:Polarization:Cells:gT0
578                        String nStr=note(decay)
579                       
580
581                        // for the panel display
582                        sprintf gMuPo, "%g +/- %g",NumberByKey("muP", nStr, "=",","),NumberByKey("err_muP", nStr, "=",",")
583                        sprintf gPo, "%g +/- %g",NumberByKey("P0", nStr, "=",","),NumberByKey("err_P0", nStr, "=",",")
584                        sprintf gGamma, "%g +/- %g",NumberByKey("gamma", nStr, "=",","),NumberByKey("err_gamma", nStr, "=",",")
585                        gT0 = StringByKey("T0", nStr, "=",",")
586               
587                       
588                        // clear the graph - force the user to update it manually
589                        // clear old data, and plot the new
590                        //
591                        SetDataFolder root:Packages:NIST:Polarization:Cells:
592
593                        CheckDisplayed/W=DecayPanel#G0 tmp_muP,tmp_muP2,fit_tmp_muP
594                        // if both present, bit 0 + bit 1 = 3
595                        if(V_flag & 2^0)                        //check bit 0
596                                RemoveFromGraph/W=DecayPanel#G0 tmp_muP
597                        endif
598                        if(V_flag & 2^1)
599                                RemoveFromGraph/W=DecayPanel#G0 tmp_muP2
600                        endif
601                        if(V_flag & 2^2)
602                                RemoveFromGraph/W=DecayPanel#G0 fit_tmp_muP
603                        endif
604                       
605                        // kill the text box (name is hard-wired)
606                        TextBox/W=DecayPanel#G0/K/N=CF_tmp_muP
607                       
608                        setDataFolder root:
609                       
610                        break
611                case -1: // control being killed
612                        break
613        endswitch
614
615        return 0
616End
617
618Function MakeDecayResultWaves(popStr)
619        String popStr
620
621        SetDataFolder root:Packages:NIST:Polarization:Cells
622
623        Make/O/D/N=(1,8) $("Decay_"+popStr)
624        WAVE decay = $("Decay_"+popStr)
625        // set the column labels
626        SetDimLabel 1,0,Trans_He_In,decay
627        SetDimLabel 1,1,Trans_He_Out,decay
628        SetDimLabel 1,2,Blocked,decay
629        SetDimLabel 1,3,mu_star,decay
630        SetDimLabel 1,4,Pol_Cell,decay
631        SetDimLabel 1,5,T_Major,decay
632        SetDimLabel 1,6,Include,decay                   //for a mask wave, non-zero is used in the fit
633        SetDimLabel 1,7,elapsed_hr,decay
634        decay[0][6] = 1                 //default to include the point
635       
636        // generate the dummy wave note now, change as needed
637        Note decay, "muP=0,err_muP=0,P0=0,err_P0=0,T0=undefined,gamma=0,err_gamma=0,"
638       
639        // to hold the results of the calculation
640        Make/O/D/N=(1,14) $("DecayCalc_"+popStr)
641        WAVE decayCalc = $("DecayCalc_"+popStr)
642        SetDimLabel 1,0,CR_Trans_He_In,decayCalc
643        SetDimLabel 1,1,err_CR_Trans_He_In,decayCalc
644        SetDimLabel 1,2,CR_Trans_He_Out,decayCalc
645        SetDimLabel 1,3,err_CR_Trans_He_Out,decayCalc
646        SetDimLabel 1,4,CR_Blocked,decayCalc
647        SetDimLabel 1,5,err_CR_Blocked,decayCalc
648        SetDimLabel 1,6,muPo,decayCalc
649        SetDimLabel 1,7,err_muPo,decayCalc
650        SetDimLabel 1,8,Po,decayCalc
651        SetDimLabel 1,9,err_Po,decayCalc
652        SetDimLabel 1,10,Tmaj,decayCalc
653        SetDimLabel 1,11,err_Tmaj,decayCalc
654        SetDimLabel 1,12,gamm,decayCalc
655        SetDimLabel 1,13,err_gamm,decayCalc     
656
657        SetDataFolder root:
658
659        return(0)
660End
661
662
663// since the "Decay_" table can be edited directly to increase the number of rows, it is tough
664// to increase the number of rows in the "DecayCalc_" wave and keep them in sync.
665//
666// --so make sure that the sizes match, and do them all
667//
668Function CalcRowParamButton(ba) : ButtonControl
669        STRUCT WMButtonAction &ba
670
671        Variable selRow,err=0
672        String fname, t0str, cellStr,noteStr,t1Str
673
674        switch( ba.eventCode )
675                case 2: // mouse up
676                        // click code here
677                        Variable cr1,cr2,cr3,err_cr1,err_cr2,err_cr3
678                        Variable muPo,err_muPo,Po,err_Po,Pcell,err_Pcell,Tmaj,err_Tmaj
679                        //Variable Te,err_Te,mu,err_mu
680                               
681                        ControlInfo/W=DecayPanel popup_0
682                        cellStr = S_Value
683                        WAVE w=$("root:Packages:NIST:Polarization:Cells:Decay_"+cellStr)                //the one that is displayed
684                        WAVE calc=$("root:Packages:NIST:Polarization:Cells:DecayCalc_"+cellStr)         // behind the scenes
685                       
686                        Variable numRows,ncalc,diff
687                        numRows = DimSize(w,0)          //rows in the displayed table
688                        ncalc = DimSize(calc,0)
689                       
690                        // add rows to the DecayCalc_ matrix as needed
691                        if(numRows != ncalc)
692                                if(ncalc > numRows)
693                                        DoAlert 0,"The DecayCalc_ is larger than displayed. Seek help."
694                                        err = 1
695                                        return(err)
696                                else
697                                        diff = numRows - ncalc
698                                        InsertPoints/M=0 ncalc, diff, calc
699                                endif
700                        endif
701                       
702                       
703//                      GetSelection table, DecayPanel#T0, 1
704//                      selRow = V_startRow
705
706                        Variable sum_muP, err_avg_muP, sum_Po, err_avg_Po, avg_muP, avg_Po, overrideT0
707                        sum_muP = 0
708                        sum_Po = 0
709                        err_avg_muP = 0
710                        err_avg_Po = 0
711                       
712                        ControlInfo/W=DecayPanel check0
713                        overrideT0 = V_Value
714                       
715                        for(selRow=0;selRow<numRows;selRow+=1)
716                                Print "calculate the row ",selRow
717
718                                if(selRow == 0 && !overrideT0)
719                                        //find T0
720                                        fname = FindFileFromRunNumber(w[0][%Trans_He_In])
721                                        t0str = getFileCreationDate(fname)
722                                        SVAR gT0 = root:Packages:NIST:Polarization:Cells:gT0
723                                        gT0 = t0Str             //for display
724                                        noteStr = note(w)
725                                        noteStr = ReplaceStringByKey("T0", noteStr, gT0  ,"=", ",", 0)
726                                        Note/K w
727                                        Note w, noteStr
728                                        Print t0str
729                                else
730                                        // manually entered on the panel to override the
731                                        SVAR gT0 = root:Packages:NIST:Polarization:Cells:gT0
732                                        t0Str = gT0
733                                        noteStr = note(w)
734                                        noteStr = ReplaceStringByKey("T0", noteStr, gT0  ,"=", ",", 0)
735                                        Note/K w
736                                        Note w, noteStr
737                                        Print t0str
738                                endif
739                               
740                                // parse the rows, report errors (there, not here), exit if any found
741                                err = ParseDecayRow(w,selRow)
742                                if(err)
743                                        return 0
744                                endif
745                               
746                                // do the calculations:
747                                // 1 for each file, return the count rate and err_CR (normalize to atten or not)
748       
749                                Print "************The Blocked CR *is* rescaled to zero attenuators -- "
750                                cr1 = TotalCR_FromRun(w[selRow][%Trans_He_In],err_cr1,0)
751                                cr2 = TotalCR_FromRun(w[selRow][%Trans_He_Out],err_cr2,0)
752//                              cr3 = TotalCR_FromRun(w[selRow][%Blocked],err_cr3,1)                    //blocked beam is NOT normalized to zero attenuators
753                                cr3 = TotalCR_FromRun(w[selRow][%Blocked],err_cr3,0)                    //blocked beam is NOT normalized to zero attenuators
754                               
755                                calc[selRow][%CR_Trans_He_In] = cr1
756                                calc[selRow][%CR_Trans_He_Out] = cr2
757                                calc[selRow][%CR_Blocked] = cr3
758                                calc[selRow][%err_cr_Trans_He_In] = err_cr1
759                                calc[selRow][%err_cr_Trans_He_Out] = err_cr2
760                                calc[selRow][%err_cr_Blocked] = err_cr3
761       
762       
763                                // 2 find the mu and Te values for cellStr
764                                SVAR gCellKW = $("root:Packages:NIST:Polarization:Cells:gCell_"+cellStr)
765                                //(moved to a separate function, just pass the string)
766        //                      Te = NumberByKey("Te", gCellKW, "=", ",", 0)
767        //                      err_Te = NumberByKey("err_Te", gCellKW, "=", ",", 0)
768        //                      mu = NumberByKey("mu", gCellKW, "=", ",", 0)
769        //                      err_mu = NumberByKey("err_mu", gCellKW, "=", ",", 0)
770        //                     
771                                // 3 Calc muPo and error
772                                muPo = Calc_muPo(calc,gCellKW,selRow,err_muPo)
773                                calc[selRow][%muPo] = muPo
774                                calc[selRow][%err_muPo] = err_muPo
775                                w[selRow][%mu_star] = muPo
776                               
777                                // 3.5 calc Polarization of cell (no value or error stored in calc wave?)
778                                PCell = Calc_PCell(muPo,err_muPo,err_PCell)
779        //                      PCell = Calc_PCell(2,err_muPo,err_PCell)
780                                w[selRow][%Pol_Cell] = PCell
781       
782                                // 4 calc Po and error
783                                Po = Calc_Po(gCellKW,muPo,err_muPo,err_Po)
784        //                      Po = Calc_Po(gCellKW,2,err_muPo,err_Po)
785                                calc[selRow][%Po] = Po
786                                calc[selRow][%err_Po] = err_Po
787                               
788                                // 5 calc Tmaj and error
789                                Tmaj = Calc_Tmaj(gCellKW,Po,err_Po,err_Tmaj)
790                                calc[selRow][%Tmaj] = Tmaj
791                                calc[selRow][%err_Tmaj] = err_Tmaj
792                                w[selRow][%T_major] = Tmaj
793                               
794                                // elapsed hours
795                                fname = FindFileFromRunNumber(w[selRow][%Trans_He_In])
796                                t1str = getFileCreationDate(fname)
797                                w[selRow][%elapsed_hr] = ElapsedHours(t0Str,t1Str)
798                               
799                                // running average of muP and Po
800                                sum_muP += muPo
801                                sum_Po += Po
802                                err_avg_muP += err_muPo^2
803                                err_avg_Po += err_Po^2
804                               
805                        endfor          //loop over rows
806                       
807                        // now get a running average of muP, Po, and the errors
808                        avg_muP = sum_muP/numRows
809                        avg_Po = sum_Po/numRows
810                        err_avg_muP = sqrt(err_avg_muP) / numRows
811                        err_avg_Po = sqrt(err_avg_Po) / numRows
812                       
813//                      str = "muP=2,err_muP=0,P0=0.6,err_P0=0,T0=asdf,gamma=200,err_gamma=0,"
814
815                        // Don't put the average values into the wave note, but rather the results of the fit
816//                      noteStr = note(w)
817//                      noteStr = ReplaceNumberByKey("muP", noteStr, avg_muP ,"=", ",", 0)
818//                      noteStr = ReplaceNumberByKey("P0", noteStr, avg_Po ,"=", ",", 0)
819//                      noteStr = ReplaceNumberByKey("err_muP", noteStr, err_avg_muP ,"=", ",", 0)
820//                      noteStr = ReplaceNumberByKey("err_P0", noteStr, err_avg_Po ,"=", ",", 0)
821//                     
822//                      // replace the string
823//                      Note/K w
824//                      Note w, noteStr
825                                       
826                        Printf "Average muP = %g +/- %g (%g%)\r",avg_muP,err_avg_muP,err_avg_muP/avg_muP*100
827                        Printf "Average Po = %g +/- %g (%g%)\r",avg_Po,err_avg_Po,err_avg_Po/avg_Po*100
828                       
829                        //update the global values for display (not these, but after the fit)
830//                      Print " -- need to add the error to the display on the panel    "
831//                      NVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo
832//                      NVAR gPo  = root:Packages:NIST:Polarization:Cells:gPo
833//                      gMuPo = avg_muP
834//                      gPo = avg_Po
835                       
836                        break
837                case -1: // control being killed
838                        break
839        endswitch
840
841        return 0
842End
843
844
845// calculate Tmaj and its error
846Function Calc_Tmaj(cellStr,Po,err_Po,err_Tmaj)
847        String cellStr
848        Variable Po,err_Po,&err_Tmaj
849       
850        Variable Tmaj,arg
851        Variable Te,err_Te,mu,err_mu
852// cell constants       
853        Te = NumberByKey("Te", cellStr, "=", ",", 0)
854        err_Te = NumberByKey("err_Te", cellStr, "=", ",", 0)
855        mu = NumberByKey("mu", cellStr, "=", ",", 0)
856        err_mu = NumberByKey("err_mu", cellStr, "=", ",", 0)
857       
858        Tmaj = Te*exp(-mu*(1-Po))
859       
860        //the error
861        err_Tmaj = (Tmaj/Te)^2*err_Te^2 + (Tmaj*(1-Po))^2*err_mu^2 + (Tmaj*mu)^2*err_Po^2
862        err_Tmaj = sqrt(err_Tmaj)
863       
864        Printf "Tmaj = %g +/- %g (%g%)\r",Tmaj,err_Tmaj,err_Tmaj/Tmaj*100
865
866       
867        return(Tmaj)
868End
869
870
871// calculate PCell and its error
872//
873//
874Function Calc_PCell(muPo,err_muPo,err_PCell)
875        Variable muPo,err_muPo,&err_PCell
876       
877        Variable PCell,arg
878
879        PCell = tanh(muPo)
880       
881        // error (single term, sqrt already done)
882        err_Pcell = (1 - (tanh(muPo))^2) * err_muPo
883       
884        Printf "Pcell = %g +/- %g (%g%)\r",Pcell,err_Pcell,err_Pcell/PCell*100
885
886        return(PCell)
887End
888
889// calculate Po and its error
890Function Calc_Po(cellStr,muPo,err_muPo,err_Po)
891        String cellStr
892        Variable muPo,err_muPo,&err_Po
893       
894        Variable Po,tmp
895        Variable mu,err_mu
896// cell constants       
897        mu = NumberByKey("mu", cellStr, "=", ",", 0)
898        err_mu = NumberByKey("err_mu", cellStr, "=", ",", 0)
899       
900        Po = muPo/mu
901       
902        tmp = (err_muPo/muPo)^2 + (err_mu/mu)^2
903        err_Po = Po * sqrt(tmp)
904       
905        Printf "Po = %g +/- %g (%g%)\r",Po,err_Po,err_Po/Po*100
906        return(Po)
907End
908
909// calculate muPo and its error
910Function Calc_muPo(calc,cellStr,selRow,err_muPo)
911        Wave calc
912        String cellStr
913        Variable selRow,&err_muPo
914       
915        Variable muPo,arg
916        Variable Te,err_Te,mu,err_mu
917// cell constants       
918        Te = NumberByKey("Te", cellStr, "=", ",", 0)
919        err_Te = NumberByKey("err_Te", cellStr, "=", ",", 0)
920        mu = NumberByKey("mu", cellStr, "=", ",", 0)
921        err_mu = NumberByKey("err_mu", cellStr, "=", ",", 0)
922       
923        Variable cr1,cr2,cr3,err_cr1,err_cr2,err_cr3
924        // cr1 is He in, 2 is He out, 3 is blocked
925        cr1      =      calc[selRow][%CR_Trans_He_In]
926        cr2 =   calc[selRow][%CR_Trans_He_Out]
927        cr3 =   calc[selRow][%CR_Blocked]
928        err_cr1 =       calc[selRow][%err_cr_Trans_He_In]
929        err_cr2 =       calc[selRow][%err_cr_Trans_He_Out]
930        err_cr3 =       calc[selRow][%err_cr_Blocked]
931       
932        muPo = acosh( (cr1 - cr3)/(cr2 - cr3) * (1/(Te*exp(-mu))) )
933       
934        Variable arg_err, tmp1, tmp2
935        // the error is a big mess to calculate, since it's messy argument inside acosh
936        arg = (cr1 - cr3)/(cr2 - cr3) * (1/(Te*exp(-mu)))
937        tmp2 =  (1/sqrt(arg+1)/sqrt(arg-1))^2                                   // derivative of acosh(arg) (squared)
938       
939        // calculate the error of the argument first, then the error of acosh(arg)
940        // there are 5 partial derivatives
941        arg_err = tmp2 * ( arg/(cr1 - cr3) * err_cr1 )^2                //CR in
942        arg_err += tmp2 * ( arg/(cr2 - cr3) * err_cr2 )^2       //CR out
943        arg_err += tmp2 * ((-arg/(cr1 - cr3) +  arg/(cr2 - cr3) )* err_cr3 )^2//CR bkg
944        arg_err += tmp2 * ( -arg/Te * err_Te )^2                                        //Te
945        arg_err += tmp2 * ( arg * err_mu )^2                                            //mu  (probably the dominant relative error)
946       
947        err_muPo = sqrt(arg_err)
948       
949       
950        return(muPo)
951End
952
953
954//Function testCR(num)
955//      Variable num
956//      Variable err_cr
957//     
958//      Variable noNorm=0
959//      Variable cr = TotalCR_FromRun(num,err_cr,noNorm)
960//      printf "CR = %g +/- %g (%g%)\r",cr,err_cr,err_cr/cr*100
961//      return(0)
962//End
963
964// calculate the total detector CR ane its error.
965//
966// the result is automatically normalized to 10^8 monitor counts, and to zero attenuators
967//
968// if noNorm = 1, then the normalization to attenuators is not done
969//
970Function TotalCR_FromRun(num,err_cr,noNorm)
971        Variable num,&err_cr,noNorm
972
973        String fname="",instr="",tmpStr=""
974        Variable cr,cts,err_cts,ctTime,monCts,attenNo,lambda,attenTrans,atten_err
975       
976        fname = FindFileFromRunNumber(num)
977        cts = getDetCount(fname)
978        err_cts = sqrt(cts)
979       
980        ctTime = getCountTime(fname)
981        monCts = getMonitorCount(fname)
982        attenNo = getAttenNumber(fname)
983        instr = getAcctName(fname)              //this is 11 characters
984        lambda = getWavelength(fname)
985        attenTrans = AttenuationFactor(instr,lambda,AttenNo,atten_err)
986       
987        if(noNorm==1)                   //don't normalize to attenuation
988                attenTrans=1
989                atten_err=0
990        endif
991        cr = cts/ctTime*1e8/monCts/attenTrans
992        err_cr = cr * sqrt(err_cts^2/cts^2 + atten_err^2/attenTrans^2)
993       
994        printf "CR = %g +/- %g (%g%)\r",cr,err_cr,err_cr/cr*100
995
996               
997        return(cr)
998end
999
1000
1001// input is VAX date and time string, t1 later than t0
1002//
1003Function ElapsedHours(t0Str,t1Str)
1004        String t0Str,t1Str
1005       
1006        Variable t0,t1,elapsed
1007       
1008        t0 = ConvertVAXDateTime2Secs(t0Str)             //seconds
1009        t1 = ConvertVAXDateTime2Secs(t1Str)
1010       
1011        elapsed = t1-t0
1012        elapsed /= 3600                 //convert to hours
1013       
1014        return(elapsed)
1015End
1016
1017// bring up a table with the calculation results
1018Function ShowCalcRowButton(ba) : ButtonControl
1019        STRUCT WMButtonAction &ba
1020
1021        switch( ba.eventCode )
1022                case 2: // mouse up
1023                        // click code here
1024                        ControlInfo/W=DecayPanel popup_0
1025                        String cellStr = S_Value
1026                        WAVE calc=$("root:Packages:NIST:Polarization:Cells:DecayCalc_"+cellStr)         //the one that is displayed
1027                        edit calc.ld
1028                                               
1029                        break
1030                case -1: // control being killed
1031                        break
1032        endswitch
1033
1034        return 0
1035End
1036
1037
1038Function DecayFitButtonProc(ba) : ButtonControl
1039        STRUCT WMButtonAction &ba
1040
1041        String cellStr=""
1042        Variable num
1043
1044        switch( ba.eventCode )
1045                case 2: // mouse up
1046                        // click code here
1047
1048                        ControlInfo/W=DecayPanel popup_0
1049                        cellStr = S_Value
1050                       
1051                        SetDataFolder root:Packages:NIST:Polarization:Cells:
1052                       
1053                        WAVE decay=$("Decay_"+cellStr)          //the one that is displayed
1054                        WAVE calc=$("DecayCalc_"+cellStr)               //the one that is displayed
1055                       
1056//                      make temp copies for the fit and plot, extra for mask
1057                        num = DimSize(calc,0)
1058                        Make/O/D/N=(num)                tmp_Mask,tmp_hr,tmp_muP,tmp_err_muP,tmp_muP2
1059                       
1060                        tmp_Mask = decay[p][%Include]
1061                        tmp_hr = decay[p][%elapsed_hr]
1062                        tmp_muP = calc[p][%muPo]
1063                        tmp_muP2 = tmp_muP
1064                        tmp_err_muP = calc[p][%err_muPo]
1065                       
1066                        tmp_muP2 = (tmp_Mask == 1) ? NaN : tmp_muP2                     //only excluded points will plot
1067                       
1068                        // clear old data, and plot the new
1069                        //
1070                        CheckDisplayed/W=DecayPanel#G0 tmp_muP,tmp_muP2,fit_tmp_muP
1071                        // if both present, bit 0 + bit 1 = 3
1072                        if(V_flag & 2^0)                        //check bit 0
1073                                RemoveFromGraph/W=DecayPanel#G0 tmp_muP
1074                        endif
1075                        if(V_flag & 2^1)
1076                                RemoveFromGraph/W=DecayPanel#G0 tmp_muP2
1077                        endif
1078                        if(V_flag & 2^2)
1079                                RemoveFromGraph/W=DecayPanel#G0 fit_tmp_muP
1080                        endif
1081                       
1082                        AppendToGraph/W=DecayPanel#G0 tmp_muP vs tmp_hr
1083                        AppendToGraph/W=DecayPanel#G0 tmp_muP2 vs tmp_hr
1084
1085                        ModifyGraph/W=DecayPanel#G0 log(left)=1
1086                        ModifyGraph/W=DecayPanel#G0 frameStyle=2
1087                        ModifyGraph/W=DecayPanel#G0 mode=3
1088                        ModifyGraph/W=DecayPanel#G0 marker=19
1089                        ModifyGraph/W=DecayPanel#G0 rgb(tmp_muP)=(1,16019,65535),rgb(tmp_muP2)=(65535,0,0)
1090                        ModifyGraph/W=DecayPanel#G0 msize=3
1091                        ErrorBars/W=DecayPanel#G0 tmp_muP,Y wave=(tmp_err_muP,tmp_err_muP)
1092                       
1093                        Label/W=DecayPanel#G0 left "mu*P"
1094                        Label/W=DecayPanel#G0 bottom "time (h)"
1095                       
1096// do the fit
1097//       as long as the constant X0 doesn't stray from zero, exp_XOffset is OK, otherwise I'll need to switch to the exp function
1098
1099                        SetActiveSubwindow DecayPanel#G0                        //to get the automatic fit to show up on the graph
1100
1101//                      Make/O/D/N=3 fitCoef={0,5,0.05}
1102//                      CurveFit/H="100"/M=2/W=0/TBOX=(0x310) exp_XOffset, kwCWave=fitCoef, tmp_muP /X=tmp_hr /D /I=1 /W=tmp_err_muP /M=tmp_Mask
1103
1104
1105                        Make/O/D/N=3 fitCoef={0,5,0.05}
1106                        CurveFit/H="100"/M=2/W=0/TBOX=(0x310) exp, kwCWave=fitCoef, tmp_muP /X=tmp_hr /D /I=1 /W=tmp_err_muP /M=tmp_Mask
1107                       
1108
1109                        SetActiveSubwindow ##
1110                       
1111                       
1112// then report and save the results
1113//                      the exp function => y = y0 + A*exp(-Bx)
1114//                      W_coef[0] = y0 should be close to zero (or fixed at zero)
1115//                      W_coef[1] = A should be close to the initial muP value
1116//                      W_coef[2] = B is 1/Gamma
1117//                      WAVE W_coef=W_coef
1118                        WAVE W_sigma=W_sigma
1119                        Variable gamma_val,err_gamma,muPo, err_muPo, Po, err_Po
1120                        String noteStr=""
1121       
1122                        SVAR gCellKW = $("root:Packages:NIST:Polarization:Cells:gCell_"+cellStr)       
1123                        SVAR gGamma  = root:Packages:NIST:Polarization:Cells:gGamma
1124                        SVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo
1125                        SVAR gPo  = root:Packages:NIST:Polarization:Cells:gPo
1126                       
1127                        muPo = fitCoef[1]
1128                        err_muPo = W_sigma[1]
1129                       
1130                        Po = Calc_Po(gCellKW,muPo,err_muPo,err_Po)
1131
1132                        // if exp_XOffset used
1133//                      gGamma = fitCoef[2]
1134//                      err_Gamma = W_sigma[2]
1135
1136                        // calculating the error using exp is the inverse of coef[2]:
1137                        gamma_val  = 1/fitCoef[2]
1138                        err_gamma = W_sigma[2]/(fitCoef[2])^2
1139               
1140                       
1141//              for the wave note
1142                        noteStr = note(decay)
1143                        noteStr = ReplaceNumberByKey("muP", noteStr, MuPo ,"=", ",", 0)
1144                        noteStr = ReplaceNumberByKey("P0", noteStr, Po ,"=", ",", 0)
1145                        noteStr = ReplaceNumberByKey("err_muP", noteStr, err_muPo ,"=", ",", 0)
1146                        noteStr = ReplaceNumberByKey("err_P0", noteStr, err_Po ,"=", ",", 0)
1147                        noteStr = ReplaceNumberByKey("gamma", noteStr, gamma_val ,"=", ",", 0)
1148                        noteStr = ReplaceNumberByKey("err_gamma", noteStr, err_gamma ,"=", ",", 0)
1149
1150                        // replace the string
1151                        Note/K decay
1152                        Note decay, noteStr
1153                       
1154                       
1155                        // for the panel display
1156                        sprintf gMuPo, "%g +/- %g",fitCoef[1],W_sigma[1]
1157                        sprintf gPo, "%g +/- %g",Po,err_Po
1158                        sprintf gGamma, "%g +/- %g",gamma_val,err_gamma
1159
1160                       
1161                       
1162                        SetDataFolder root:
1163                       
1164                        break
1165                case -1: // control being killed
1166                        break
1167        endswitch
1168
1169        return 0
1170End
1171
1172
1173// clear just the row
1174//
1175Function ClearDecayWavesRowButton(ba) : ButtonControl
1176        STRUCT WMButtonAction &ba
1177
1178        String popStr=""
1179        Variable selRow
1180       
1181        switch( ba.eventCode )
1182                case 2: // mouse up
1183                        // click code here
1184                        DoAlert 1,"Clear the selected row?"
1185                        if(V_flag !=1)
1186                                return(0)
1187                        endif
1188                       
1189                        SetDataFolder root:Packages:NIST:Polarization:Cells
1190
1191                        ControlInfo/W=DecayPanel popup_0
1192                        popStr = S_Value
1193                       
1194                        Wave decay = $("Decay_"+popStr)
1195                        Wave calc = $("DecayCalc_"+popStr)
1196
1197                        // Delete just those points
1198                                               
1199                        GetSelection table, DecayPanel#T0, 1
1200                        selRow = V_startRow
1201                        DeletePoints selRow,1,decay,calc                       
1202                       
1203                        // clear the graph and the results                     
1204                        SVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo
1205                        SVAR gPo  = root:Packages:NIST:Polarization:Cells:gPo
1206                        SVAR gGamma  = root:Packages:NIST:Polarization:Cells:gGamma
1207                        SVAR gT0  = root:Packages:NIST:Polarization:Cells:gT0
1208                        gMuPo = "0"
1209                        gPo = "0"
1210                        gGamma = "0"
1211                        gT0 = "recalculate"
1212                       
1213                        SetDataFolder root:
1214                        break
1215                case -1: // control being killed
1216                        break
1217        endswitch
1218
1219        return 0
1220End
1221
1222
1223
1224// for this, do I want to clear everything, or just a selected row??
1225//
1226//
1227Function ClearDecayWavesButton(ba) : ButtonControl
1228        STRUCT WMButtonAction &ba
1229
1230        String popStr=""
1231       
1232        switch( ba.eventCode )
1233                case 2: // mouse up
1234                        // click code here
1235                        DoAlert 1,"Clear all of the decay waves for the selected cell?"
1236                        if(V_flag !=1)
1237                                return(0)
1238                        endif
1239                       
1240                        SetDataFolder root:Packages:NIST:Polarization:Cells
1241
1242                        ControlInfo/W=DecayPanel popup_0
1243                        popStr = S_Value
1244                       
1245                        Wave decay = $("Decay_"+popStr)
1246                        Wave calc = $("DecayCalc_"+popStr)
1247                       
1248//                      re-initialize the decay waves, so it appears as a blank, initialized table
1249
1250                        MakeDecayResultWaves(popStr)
1251                        decay = 0
1252                        calc = 0
1253       
1254                        // clear the graph and the results?     
1255                       
1256                       
1257                                       
1258                        SVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo
1259                        SVAR gPo  = root:Packages:NIST:Polarization:Cells:gPo
1260                        SVAR gGamma  = root:Packages:NIST:Polarization:Cells:gGamma
1261                        SVAR gT0  = root:Packages:NIST:Polarization:Cells:gT0
1262                        gMuPo = "0"
1263                        gPo = "0"
1264                        gGamma = "0"
1265                        gT0 = "recalculate"
1266                       
1267                       
1268                        SetDataFolder root:
1269                        break
1270                case -1: // control being killed
1271                        break
1272        endswitch
1273
1274        return 0
1275End
1276
1277
1278Function DecayHelpParButtonProc(ba) : ButtonControl
1279        STRUCT WMButtonAction &ba
1280
1281        switch( ba.eventCode )
1282                case 2: // mouse up
1283                        // click code here
1284                        DoAlert 0,"Help for Cell Decay Panel not written yet"
1285                        break
1286                case -1: // control being killed
1287                        break
1288        endswitch
1289
1290        return 0
1291End
1292
1293// E=-5 is a PNG, =8 is PDF
1294// there are other options to do EPS, embed fonts, etc.
1295//
1296Function WindowSnapshotButton(ba) : ButtonControl
1297        STRUCT WMButtonAction &ba
1298
1299        switch( ba.eventCode )
1300                case 2: // mouse up
1301                        // click code here
1302                        SavePICT /E=-5/SNAP=1
1303                        break
1304                case -1: // control being killed
1305                        break
1306        endswitch
1307
1308        return 0
1309End
1310
1311// null condition is not right. if the loop fails, then the
1312// retStr will be ";;;;", not zero length. What's the proper test?
1313// Does it matter? the list of default gCell_sss should already be there.
1314//
1315Function/S D_CellNameList()
1316
1317        String retStr="",listStr,item
1318        Variable num,ii
1319       
1320        SetDataFolder root:Packages:NIST:Polarization:Cells
1321
1322        // get a list of the cell strings
1323        listStr=StringList("gCell_*",";")
1324        num=ItemsInList(listStr,";")
1325//      print listStr
1326       
1327        // parse the strings to fill the table
1328        for(ii=0;ii<num;ii+=1)
1329                item = StringFromList(ii, listStr,";")
1330                SVAR gStr = $item
1331                retStr += StringByKey("cell", gStr, "=", ",", 0) + ";"
1332        endfor
1333       
1334        if(strlen(retStr) == 0)
1335                retStr = "no cells defined;"
1336        endif
1337       
1338        SetDataFolder root:             
1339        return(retStr)
1340End
1341
1342
1343// parse the row to be sure that:
1344//
1345// - files are valid numbers
1346// - files are all at same SDD
1347// - files are all with same attenuation (just print a warning to cmd)
1348// - due to ICE FP values, I need to do a fuzzy comparison
1349//
1350//
1351Function ParseDecayRow(w,selRow)
1352        Wave w
1353        Variable selRow
1354       
1355        Variable err=0, atten1,atten2,atten3,sdd1,sdd2,sdd3,tol
1356        String fname=""
1357        tol = 0.01              //SDDs within 1%
1358       
1359        // are all file numbers valid?
1360        fname = FindFileFromRunNumber(w[selRow][%Trans_He_In])
1361        if(cmpstr(fname,"")==0)
1362                DoAlert 0,"Trans_He_In run "+num2str(w[selRow][%Trans_He_In])+" is not a valid run number"
1363                err = 1
1364        else
1365                atten1 = getAttenNumber(fname)
1366                sdd1 = getSDD(fname)
1367        endif
1368       
1369        fname = FindFileFromRunNumber(w[selRow][%Trans_He_Out])
1370        if(cmpstr(fname,"")==0)
1371                DoAlert 0,"Trans_He_Out run "+num2str(w[selRow][%Trans_He_Out])+" is not a valid run number"
1372                err = 1
1373        else
1374                atten2 = getAttenNumber(fname)
1375                sdd2 = getSDD(fname)
1376        endif
1377       
1378        fname = FindFileFromRunNumber(w[selRow][%Blocked])
1379        if(cmpstr(fname,"")==0)
1380                DoAlert 0,"Blocked run "+num2str(w[selRow][%Blocked])+" is not a valid run number"
1381                err = 1
1382        else
1383                atten3 = getAttenNumber(fname)
1384                sdd3 = getSDD(fname)
1385        endif
1386       
1387       
1388        if( (abs(sdd1 - sdd2) > tol) || (abs(sdd2 - sdd3) > tol) || (abs(sdd1 - sdd3) > tol) )
1389                DoAlert 0,"Files in row "+num2str(selRow)+" are not all at the same detector distance"
1390                err = 1
1391        endif
1392       
1393        if( (atten1 != atten2) || (atten2 != atten3) || (atten1 != atten3) )
1394                DoAlert 0,"Files in row "+num2str(selRow)+" are not all collected with the same attenuation. Just so you know."
1395                err = 0
1396        endif
1397       
1398        return(err)
1399end
1400
1401
1402////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.