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

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

more tweaks to the polarization correction. Adjusting control positions on the panels, makeing sure that reverting the fundamental cell parameters really does just that, adding buttons to export/import protocols from the PolCor? panel.

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