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

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

Added a simple panel to calculate the flipping ratio. Accessed from the Macros menu, like the other panels.

Added a line of information to ask users to input the name of the cell in the flipper panel, which is cell dependent. Still may not be obvious for the users.

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