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

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

Changes to the polarization reduction, tickets#355, #356, #362,

--saving of the panel states is now something that can be done from a menu item. (there is too much clutter on the panels to add more buttons, unless there is a great outcry).
--"?" has ben added to table columns that require input - coloring of individual columns can't be done with the matrices in the table.
-- the background is now polarization-independent
--the flow of the protocol execution now forces are-load and re--polarization correction every time for SAM, EMP, BGD (trivial) so that the correct files are in the correct locations, every time.

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