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

Last change on this file since 863 was 863, checked in by srkline, 10 years ago

Tweaking the labels on the polarization panels to add "?" to columns that require user input.

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