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

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

Switched the Decay panel plot to use atomic polariztion as the y-axis, rather than mu*P.

Added atomic polarization to the disaplayed matrix on the panel. It was already part of the calculation behind the scenes.

Switched the decay fit to use exp_XOffset (with an offset of 0). this fits naturally as gamma, not 1/gamma.

File size: 45.0 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.