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

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

changes to FFT routines to clean things up for a beta release at the next startup. No functionality changes, just cleaning up the operation, interface, and menu items.

Some important changes to the polarization routines. New equations for calculating the coefficient matrix. Now appears to be correct. Also, proper proportions are used when adding multiple files together to the matrix.

Change to the Model Docs is an updated reference.

WorkFileUtils? was broken when I changed to use linear_data exclusively. This has now been fixed and it operates as expected.

PackageLoader? now has menu items (under Macros) for the Polarization routines. These may later be moved to the SANS menu.

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