#pragma rtGlobals=1 // Use modern global access method. // TODO: // x- on the decay panel. need to be able to manually enter a date that is to or an offset // number of hours. currently it takes the first file as t=0, which is often not correct // // Polarized Beam Reduction Procedures // // // input panels to set and calculate polarization parameters necessary for the // matrix corrections to the cross sections // // -1- Fundamental Cell Parameters -- these are constants, generally not editable. (this file) // -2- Decay Parameters -- these are fitted values based on transmission mearurements (this file) // -3- Flipper Panel is in its own procedure (Pol_FlipperPanel.ipf) // -4- PolCor_Panel is in Pol_PolarizationCorrection.ipf // // // Driven by 4 panels to get the necessary information from the users // -1- Fundamental cell parameters: root:Packages:NIST:Polarization:Cells // - default cell parameters are loaded. More cell definitions can be added as more cells are used // - changes are saved per experiment // - important parameters are held in global key=value strings gCell_ // - cell names and parameters are used by the 2nd panel for calculation of the Decay constant // // -2- Decay Constant Panel // - decay constant determined for each cell. // - popping the cell name makes 2 waves, Decay_ and DecayCalc_ // - Decay_ is the wave presented in the table. Specified transmission run numbers are entered // and "Calc Sel Row" does the calculation of mu and Pcell (for all rows, actually) // - DimLabels are used for the arrays to make the column identity more readable than simply an index // - time=0 is taken from the first file // - Calculations are based on the count rate of the file, corrected for monitor and attenuation // - alerts are posted for files in any row that are not at the same attenuation or SDD // - if "include" column is == 1, that row will be included in the fit of the decay data // - excluded points are plotted in red // - results of the fit are printed on the panel, and written to the wave note of the Decay_ wave // (not DecayCalc_) for use in the next panel // - manual entry of all of the parameters in the wave note is allowed. // // // -3- Flipper Panel (not in this procedure - in Pol_FlipperPanel.ipf) // - calculates the flipper and supermirror efficiencies for a given "condition" // - this "condition" may have contributions from multiple cells // - start by entering a condition name // - Waves Cond_ and CondCalc_, and CondCell are created // - DimLabels are used for the arrays to make the column identity more readable than simply an index // - Enter the name of the cell in the first column (the cell must be defined and decay calculated) // - enter transmission run numbers as specified in the table // - Do Average will calculate the Psm and PsmPfl values (and errors) and average if more than // one row of data is present (and included) // - results are printed on the panel, and written to the wave note of Cond_ // - results are used in the calculation of the polarization matrix // - (the cell name is not entered using a contextual menu, since this is difficult for a subwindow) // - (the wave note no longer needs the cell name) // // -4- PolCor_Panel (not in this procedure - in Pol_PolarizationCorrection.ipf) // - gets all of the parameters from the user to do the polariztion correction, then the "normal" SANS reduction // - up to 10 files can be added together for each of the different spin states (more than this??) // - one polarization condition is set for everything with the popup @ the top // - two-column list boxes for each state hold the run number and the cell name // - the same list boxes are duplicated (hidden) for the SAM/EMP/BGD tabs as needed // - on loading of the data, the 2-letter spin state is tagged onto the loaded waves (all of them) // - displayed data is simply re-pointed to the desired data // - on loading, the raw files are added together as ususal, normalized to monitor counts. Then each contribution // of the file to the polarization matrix is added (scaling each by mon/1e8) // - loaded data and PolMatrix are stored in the ususal SAM, EMP, BGD folders. // - Polarization correction is done with one click (one per tab). "_pc" tags are added to the resulting names, // and copies of all of the associated waves are again copied (wasteful), but makes switching display very easy // - Once all of the polarization correction is done, then the UU_pc (etc.) data can be reduced as usual (xx_pc = 4 passes) // - protocol is built as ususal, from this panel only (since the SAM, EMP, and BGD need to be switched, rather than loaded // - protocols can be saved/recalled. // - reduction will always ask for a protocol rather than using what's on the panel. // - closing the panel will save the state (except the protocol). NOT initializing when re-opening will restore the // state of the entered runs and the popups of conditions. // // // // // for the menu Menu "Macros" "1 Fundamental Cell Parameters",ShowCellParamPanel() "2 Cell Decay",ShowCellDecayPanel() "3 Flipper States",ShowFlipperPanel() "4 Polarization Correction",ShowPolCorSetup() End // // Panel -1- // // Fundamental He cell parameters. Most of these are pre-defined, so that they are supplied as a // static table, only edited as parameters are refined. // // work with this as kwString // cell=nameStr // lambda=num // Te=num // err_Te=num // mu=num // err_mu=num // // // for this panel, the cell parameters are stored as kw strings // all of the strings start w/ "gCell_" // Proc ShowCellParamPanel() // init folders // ASK before initializing cell constants // open the panel DoWindow/F CellParamPanel if(V_flag == 0) InitPolarizationFolders() DoAlert 1,"Do you want to use default parameters?" if(V_flag == 1) InitPolarizationGlobals() endif Make_HeCell_ParamWaves() DrawCellParamPanel() endif end // setup the data folder, etc // // Function InitPolarizationFolders() NewDataFolder/O root:Packages:NIST:Polarization NewDataFolder/O root:Packages:NIST:Polarization:Cells //holds the cell constants and waves SetDataFolder root: return(0) End // // add more cells here as they are defined // Function InitPolarizationGlobals() SetDataFolder root:Packages:NIST:Polarization:Cells // cell constants String/G gCell_Maverick = "cell=Maverick,lambda=5.0,Te=0.87,err_Te=0.01,mu=3.184,err_mu=0.2," String/G gCell_Burgundy = "cell=Burgundy,lambda=5.0,Te=0.86,err_Te=0.01,mu=3.138,err_mu=0.15," String/G gCell_Olaf = "cell=Olaf,lambda=7.5,Te=0.86,err_Te=0.005,mu=2.97,err_mu=0.18," SetDataFolder root: return(0) End // parse strings to fill in waves // // Function Make_HeCell_ParamWaves() SetDataFolder root:Packages:NIST:Polarization:Cells String listStr,item Variable num,ii // get a list of the strings listStr=StringList("gCell_*",";") num=ItemsInList(listStr,";") print listStr Make/O/T/N=0 CellName Make/O/N=0 lambda,Te,err_Te,mu,err_mu // parse the strings to fill the table for(ii=0;ii numRows) DoAlert 0,"The DecayCalc_ is larger than displayed. Seek help." err = 1 return(err) else diff = numRows - ncalc InsertPoints/M=0 ncalc, diff, calc endif endif // GetSelection table, DecayPanel#T0, 1 // selRow = V_startRow Variable sum_muP, err_avg_muP, sum_Po, err_avg_Po, avg_muP, avg_Po, overrideT0 sum_muP = 0 sum_Po = 0 err_avg_muP = 0 err_avg_Po = 0 ControlInfo/W=DecayPanel check0 overrideT0 = V_Value for(selRow=0;selRow y = y0 + A*exp(-Bx) // W_coef[0] = y0 should be close to zero (or fixed at zero) // W_coef[1] = A should be close to the initial muP value // W_coef[2] = B is 1/Gamma // WAVE W_coef=W_coef WAVE W_sigma=W_sigma Variable gamma_val,err_gamma,muPo, err_muPo, Po, err_Po String noteStr="" SVAR gCellKW = $("root:Packages:NIST:Polarization:Cells:gCell_"+cellStr) SVAR gGamma = root:Packages:NIST:Polarization:Cells:gGamma SVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo SVAR gPo = root:Packages:NIST:Polarization:Cells:gPo muPo = fitCoef[1] err_muPo = W_sigma[1] Po = Calc_Po(gCellKW,muPo,err_muPo,err_Po) // if exp_XOffset used // gGamma = fitCoef[2] // err_Gamma = W_sigma[2] // calculating the error using exp is the inverse of coef[2]: gamma_val = 1/fitCoef[2] err_gamma = W_sigma[2]/(fitCoef[2])^2 // for the wave note noteStr = note(decay) noteStr = ReplaceNumberByKey("muP", noteStr, MuPo ,"=", ",", 0) noteStr = ReplaceNumberByKey("P0", noteStr, Po ,"=", ",", 0) noteStr = ReplaceNumberByKey("err_muP", noteStr, err_muPo ,"=", ",", 0) noteStr = ReplaceNumberByKey("err_P0", noteStr, err_Po ,"=", ",", 0) noteStr = ReplaceNumberByKey("gamma", noteStr, gamma_val ,"=", ",", 0) noteStr = ReplaceNumberByKey("err_gamma", noteStr, err_gamma ,"=", ",", 0) // replace the string Note/K decay Note decay, noteStr // for the panel display sprintf gMuPo, "%g +/- %g",fitCoef[1],W_sigma[1] sprintf gPo, "%g +/- %g",Po,err_Po sprintf gGamma, "%g +/- %g",gamma_val,err_gamma SetDataFolder root: break case -1: // control being killed break endswitch return 0 End // clear just the row // Function ClearDecayWavesRowButton(ba) : ButtonControl STRUCT WMButtonAction &ba String popStr="" Variable selRow switch( ba.eventCode ) case 2: // mouse up // click code here DoAlert 1,"Clear the selected row?" if(V_flag !=1) return(0) endif SetDataFolder root:Packages:NIST:Polarization:Cells ControlInfo/W=DecayPanel popup_0 popStr = S_Value Wave decay = $("Decay_"+popStr) Wave calc = $("DecayCalc_"+popStr) // Delete just those points GetSelection table, DecayPanel#T0, 1 selRow = V_startRow DeletePoints selRow,1,decay,calc // clear the graph and the results SVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo SVAR gPo = root:Packages:NIST:Polarization:Cells:gPo SVAR gGamma = root:Packages:NIST:Polarization:Cells:gGamma SVAR gT0 = root:Packages:NIST:Polarization:Cells:gT0 gMuPo = "0" gPo = "0" gGamma = "0" gT0 = "recalculate" SetDataFolder root: break case -1: // control being killed break endswitch return 0 End // for this, do I want to clear everything, or just a selected row?? // // Function ClearDecayWavesButton(ba) : ButtonControl STRUCT WMButtonAction &ba String popStr="" switch( ba.eventCode ) case 2: // mouse up // click code here DoAlert 1,"Clear all of the decay waves for the selected cell?" if(V_flag !=1) return(0) endif SetDataFolder root:Packages:NIST:Polarization:Cells ControlInfo/W=DecayPanel popup_0 popStr = S_Value Wave decay = $("Decay_"+popStr) Wave calc = $("DecayCalc_"+popStr) // re-initialize the decay waves, so it appears as a blank, initialized table MakeDecayResultWaves(popStr) decay = 0 calc = 0 // clear the graph and the results? SVAR gMuPo = root:Packages:NIST:Polarization:Cells:gMuPo SVAR gPo = root:Packages:NIST:Polarization:Cells:gPo SVAR gGamma = root:Packages:NIST:Polarization:Cells:gGamma SVAR gT0 = root:Packages:NIST:Polarization:Cells:gT0 gMuPo = "0" gPo = "0" gGamma = "0" gT0 = "recalculate" SetDataFolder root: break case -1: // control being killed break endswitch return 0 End Function DecayHelpParButtonProc(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up // click code here DisplayHelpTopic/Z/K=1 "Cell Decay Constant Panel" if(V_flag !=0) DoAlert 0,"The Cell Decay Help file could not be found" endif break case -1: // control being killed break endswitch return 0 End // E=-5 is a PNG, =8 is PDF // there are other options to do EPS, embed fonts, etc. // Function WindowSnapshotButton(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up // click code here SavePICT /E=-5/SNAP=1 break case -1: // control being killed break endswitch return 0 End // null condition is not right. if the loop fails, then the // retStr will be ";;;;", not zero length. What's the proper test? // Does it matter? the list of default gCell_sss should already be there. // Function/S D_CellNameList() String retStr="",listStr,item Variable num,ii SetDataFolder root:Packages:NIST:Polarization:Cells // get a list of the cell strings listStr=StringList("gCell_*",";") num=ItemsInList(listStr,";") // print listStr // parse the strings to fill the table for(ii=0;ii tol) || (abs(sdd2 - sdd3) > tol) || (abs(sdd1 - sdd3) > tol) ) DoAlert 0,"Files in row "+num2str(selRow)+" are not all at the same detector distance" err = 1 endif if( (atten1 != atten2) || (atten2 != atten3) || (atten1 != atten3) ) DoAlert 0,"Files in row "+num2str(selRow)+" are not all collected with the same attenuation. Just so you know." err = 0 endif return(err) end ////////////////////////////////////////////