def UCNyield(x, p): scale = p[0] if x[0] >= 0 else p[5] T = UCN.HeTemperature(abs(x[0])) tau1 = 1. / (1. / p[1] + p[2] * (1. - p[3] * T) * T**7) tau2 = 1. / (1. + p[4] * T**7) # print(tau1, tau2) if tau1 <= 0 or tau2 <= 0: return 0. return scale * tau1 * tau2 * ( 1. - math.exp(-x[2] * p[6] / tau1)) * math.exp(-x[1] / tau1)
def TauVsTemp(experiments, parameter, variable, color=ROOT.kBlack, convert=False): exs = [ex for ex in experiments if ex[variable] > 0.] if not convert: x = numpy.array([ (max(ex['max' + parameter]) + min(ex['min' + parameter])) / 2 for ex in exs ]) xerr = numpy.array([ (max(ex['max' + parameter]) - min(ex['min' + parameter])) / 2 for ex in exs ]) else: x = numpy.array([(UCN.HeTemperature(max(ex['max' + parameter])) + UCN.HeTemperature(min(ex['min' + parameter]))) / 2 for ex in exs]) xerr = numpy.array([(UCN.HeTemperature(max(ex['max' + parameter])) - UCN.HeTemperature(min(ex['min' + parameter]))) / 2 for ex in exs]) gr = ROOT.TGraphErrors(len(exs), x, numpy.array([ex[variable] for ex in exs]), xerr, numpy.array([ex[variable + 'err'] for ex in exs])) gr.SetTitle('') if parameter == 'temperature': gr.GetXaxis().SetTitle('Temperature (K)') elif parameter == 'vaporpressure' and not convert: gr.GetXaxis().SetTitle('Vapor pressure (Torr)') elif parameter == 'vaporpressure' and convert: gr.GetXaxis().SetTitle('Temperature (K)') else: assert (True) gr.GetYaxis().SetTitle('Storage lifetime (s)') gr.SetLineColor(color) gr.SetMarkerColor(color) return gr
def StorageLifetime(ex): print('\nAnalyzing TCN' + ex['TCN']) if len(ex['start']) == 0: print('Found no cycles with run numbers {0}!'.format(ex['runs'])) return ex['li6backgroundrate'], ex['li6backgroundrateerr'] = UCN.BackgroundRate( ex['li6background'], ex['backgroundduration']) print('Li6 detector background rate: {0} +/- {1} 1/s'.format( ex['li6backgroundrate'], ex['li6backgroundrateerr'])) beam = [numpy.mean(cur) for cur in ex['beamcurrent'] ], [numpy.std(cur) for cur in ex['beamcurrent']] ex['li6irradiationrate'], ex[ 'li6irradiationrateerr'] = UCN.SubtractBackgroundAndNormalizeRate( ex['li6irradiation'], ex['irradiationduration'], 'li6', beam[0], beam[1]) # report average monitor counts, range of beam current, range of He-II temperature monitoravg = numpy.average(ex['monitorcounts'], None, [1. / m for m in ex['monitorcounts']], True) print 'Monitor counts: {0} +/- {1}'.format(monitoravg[0], 1. / math.sqrt(monitoravg[1])) print('Beam current from {0} to {1} uA'.format( min(min(c) for c in ex['beamcurrent']), max(max(c) for c in ex['beamcurrent']))) print 'Temperatures from {0} to {1} K'.format(min(ex['mintemperature']), max(ex['maxtemperature'])) x = ex['storageduration'] xerr = [0. for _ in ex['storageduration']] y, yerr = UCN.SubtractBackgroundAndNormalize( ex['li6counts'], ex['countduration'], 'li6', ex['monitorcounts'], [math.sqrt(m) for m in ex['monitorcounts']]) # plot normalized, background corrected counts vs storage time graph = ROOT.TGraphErrors(len(x), numpy.array(x), numpy.array(y), numpy.array(xerr), numpy.array(yerr)) graph.SetTitle( 'TCN{0} (single exponential fit, with background subtracted, normalized to monitor detector)' .format(ex['TCN'])) graph.GetXaxis().SetTitle('Storage time (s)') graph.GetYaxis().SetTitle('UCN-count-to-monitor ratio') # graph.SetMarkerStyle(20) # do single exponential fit f = graph.Fit(UCN.SingleExpo(), 'SQB', '', 0., 1000.) canvas = ROOT.TCanvas('c', 'c') canvas.SetLogy() graph.Draw('AP') pdf = 'TCN{0}.pdf'.format(ex['TCN']) canvas.Print(pdf + '(') ex['tau'] = f.GetParams()[1] ex['tauerr'] = f.GetErrors()[1] print( '{0} +/- {1} (single exponential fit, with background subtracted, normalized to monitor detector)' .format(ex['tau'], ex['tauerr'])) #do single exponential fit with data point at 0 excluded f = graph.Fit(UCN.SingleExpo(), 'SQB', '', 1., 1000.) graph.SetTitle( 'TCN{0} (single exponential fit, with background subtracted, normalized to monitor detector, 0s excluded)' .format(ex['TCN'])) graph.Draw('AP') canvas.Print(pdf) # do double exponential fit graph.SetTitle( 'TCN{0} (double exponential fit, with background subtracted, normalized to monitor detector)' .format(ex['TCN'])) f = graph.Fit(UCN.DoubleExpo(), 'SQB') graph.Draw('AP') canvas.Print(pdf) print( '{0} +/- {1}, {2} +/- {3} (double exponential fit, with background subtracted, normalized to monitor detector)' .format(f.GetParams()[1], f.GetErrors()[1], f.GetParams()[3], f.GetErrors()[3])) # plot uncorrected UCN counts y = [float(c) for c in ex['li6counts']] yerr = [math.sqrt(c) for c in ex['li6counts']] graph = ROOT.TGraphErrors(len(x), numpy.array(x), numpy.array(y), numpy.array(xerr), numpy.array(yerr)) graph.SetTitle( 'TCN{0} (single exponential fit + background, unnormalized)'.format( ex['TCN'])) graph.GetXaxis().SetTitle('Storage time (s)') graph.GetYaxis().SetTitle('UCN count') # do single exponential fit with background f = graph.Fit(UCN.SingleExpoWithBackground(), 'SQB') graph.Draw('AP') canvas.Print(pdf) print( '{0} +/- {1} (single exponential fit with {2} +/- {3} background, unnormalized)' .format(f.GetParams()[1], f.GetErrors()[1], f.GetParams()[2], f.GetErrors()[2])) mtau = [] mtauerr = [] for he3rate, m, s in zip(ex['he3rate'], ex['monitorduration'], ex['storageduration']): fitstart = m + 5 fitend = m + s if fitend > fitstart + 10 and he3rate.Integral( he3rate.FindBin(fitstart), he3rate.FindBin(fitend)) > 0: f = he3rate.Fit(UCN.SingleExpo(), 'SQB', '', fitstart, fitend) he3rate.Draw() canvas.Print(pdf) # print fitted He3 rate to pdf mtau.append(f.GetParams()[1]) mtauerr.append(f.GetErrors()[1]) # print average storage lifetime from He3 fits to pdf canvas = ROOT.TCanvas('c', 'c') if len(mtau) > 0: tauavg = numpy.average(mtau, None, [1. / dt**2 for dt in mtauerr], True) label = ROOT.TLatex(0.1, 0.6, 'Average lifetime from He3 data:') label.Draw() label2 = ROOT.TLatex( 0.1, 0.5, '#tau = {0} +/- {1} s'.format(tauavg[0], 1. / tauavg[1]**2)) label2.Draw() print( '{0} +/- {1} (single exponential fit to rate in monitor detector during storage period)' .format(tauavg[0], 1. / tauavg[1]**2)) canvas.Print(pdf + ')')
'TCN': '18-381 (UGD22+20, high pos, IV2-IV3)', 'runs': [1189, 1190] }, { 'TCN': '18-382 (UGD22+20, high pos, IV1-IV3)', 'runs': [1191] } ] ReadCycles(ROOT.TFile(sys.argv[1]), experiments) # loop over experiments for ex in experiments: StorageLifetime(ex) UCN.PrintBackground(experiments) canvas = ROOT.TCanvas('c', 'c') for tcn in ['18-066', '18-068', '18-268', '18-266']: SCMex = [ex for ex in experiments if ex['TCN'].startswith(tcn)] gr = ROOT.TGraphErrors() for ex in SCMex: SCMcurrent = numpy.concatenate(ex['SCMcurrent']) i = gr.GetN() gr.SetPoint(i, numpy.mean(SCMcurrent), ex['tau']) gr.SetPointError(i, numpy.std(SCMcurrent) / math.sqrt(len(SCMcurrent)), ex['tauerr']) gr.SetTitle('TCN' + tcn) gr.GetXaxis().SetTitle('SCM current (A)') gr.GetYaxis().SetTitle('Storage lifetime (s)')
def Transmission(ex): print('\nAnalyzing TCN{0}'.format(ex['TCN'])) if len(ex['start']) == 0: print('Found no cycles with run numbers {0}!'.format(ex['runs'])) return ex['li6backgroundrate'], ex['li6backgroundrateerr'] = UCN.BackgroundRate( ex['li6background'], ex['backgroundduration']) ex['li6irradiationrate'], ex['li6irradiationrateerr'] = UCN.SubtractBackgroundAndNormalizeRate(ex['li6irradiation'], ex['irradiationduration'], 'li6', \ [numpy.mean(cur) for cur in ex['beamcurrent']], [numpy.std(cur) for cur in ex['beamcurrent']]) print('Li6 background rate: {0} +/- {1} 1/s'.format( ex['li6backgroundrate'], ex['li6backgroundrateerr'])) # report average monitor counts monitoravg = numpy.average(ex['monitorcounts'], None, [1. / m for m in ex['monitorcounts']], True) print('Monitor counts: {0} +/- {1}'.format(monitoravg[0], 1. / math.sqrt(monitoravg[1]))) # report range of beam current print('Beam current from {0} to {1} uA'.format( min(min(c) for c in ex['beamcurrent']), max(max(c) for c in ex['beamcurrent']))) # report He-II temperature range print('Temperatures from {0} to {1} K'.format(min(ex['mintemperature']), max(ex['maxtemperature']))) canvas = ROOT.TCanvas('c', 'c') pdf = 'TCN{0}.pdf'.format(ex['TCN']) # plot ratio of background-corrected counts to monitor counts during counting y, yerr = UCN.SubtractBackgroundAndNormalize( ex['li6counts'], ex['countduration'], 'li6', ex['monitorcounts'], [math.sqrt(c) for c in ex['monitorcounts']]) graph = ROOT.TGraphErrors(len(y), numpy.array(ex['cyclenumber']), numpy.array(y), numpy.array([0. for _ in ex['cyclenumber']]), numpy.array(yerr)) graph.SetTitle('TCN{0}, normalized during counting'.format(ex['TCN'])) graph.GetXaxis().SetTitle('Cycle') graph.GetXaxis().SetLimits(0., max(ex['cyclenumber'])) graph.GetYaxis().SetTitle('UCN-count-to-monitor ratio') graph.SetMarkerStyle(20) transfit = ROOT.TF1('transfit', 'pol0', 0, 100) transfit.SetParName(0, '#bar{R}_{c}') f = graph.Fit(transfit, 'QS') graph.Draw('AP') canvas.Print(pdf + '(') ex['transmission'] = f.GetParams()[0] ex['transmissionerr'] = f.GetErrors()[0] * max(f.Chi2() / f.Ndf(), 1.) print('Li6-to-He3 ratio during counting: {0} +/- {1}'.format( ex['transmission'], ex['transmissionerr'])) if min(ex['monitorcounts2']) > 0: # plot ratio of background-corrected counts to monitor counts during irradiation y, yerr = UCN.SubtractBackgroundAndNormalize( ex['li6counts2'], ex['countduration2'], 'li6', ex['monitorcounts2'], [math.sqrt(c) for c in ex['monitorcounts2']]) graph = ROOT.TGraphErrors(len(y), numpy.array(ex['cyclenumber']), numpy.array(y), numpy.array([0. for _ in ex['cyclenumber']]), numpy.array(yerr)) graph.SetTitle('TCN{0}, normalized during irradiation'.format( ex['TCN'])) graph.GetXaxis().SetTitle('Cycle') graph.GetXaxis().SetLimits(0., max(ex['cyclenumber'])) graph.GetYaxis().SetTitle('UCN-count-to-monitor ratio') graph.SetMarkerStyle(20) transfit.SetParName(0, '#bar{R}_{i}') f = graph.Fit(transfit, 'QS') graph.Draw('AP') canvas.Print(pdf) ex['transmission2'] = f.GetParams()[0] ex['transmission2err'] = f.GetErrors()[0] * max(f.Chi2() / f.Ndf(), 1.) print('Li6-to-He3 ratio during irradiation: {0} +/- {1}\n'.format( ex['transmission2'], ex['transmission2err'])) UCN.PrintTemperatureVsCycle(ex, pdf) he3axis = ex['He3rate'][0].GetXaxis() he3rate = ROOT.TH1D('TCN{0}_He3'.format(ex['TCN']), ';Time (s); He3 rate (1/s)', he3axis.GetNbins(), he3axis.GetXmin(), he3axis.GetXmax()) he3rate.SetDirectory(0) for he3 in ex['He3rate']: he3rate.Add(he3) satfit = ROOT.TF1( 'satfit', '[0]*(erfc(sqrt([1]/x)-sqrt(x/[2]))-exp(4*sqrt([1]/[2]))*erfc(sqrt([1]/x)+sqrt(x/[2])))', 0, 60) for i, p in enumerate( zip([500., 12., 30.], [10000., 100., 100.], ['p_{0}', '#tau_{d}', '#tau'])): satfit.SetParameter(i, p[0]) satfit.SetParName(i, p[2]) fit = he3rate.Fit(satfit, 'MRSQ') he3rate.Draw() canvas.Print(pdf) li6fit = ROOT.TF1( 'li6fit', '(x<60 + [0]?0:[1])*(1 - exp(-(x - 60 - [0])/[2]))*(exp(-(x - 60 - [0])/[3]) + [4]*exp(-(x - 60 - [0])/[5]) +[6]*exp(-(x - 60 - [0])/[7])) + [8]', 60, 180) li6axis = ex['Li6rate'][0].GetXaxis() binwidth = li6axis.GetBinWidth(1) li6rate = ROOT.TH1D('TCN{0}_Li6'.format(ex['TCN']), ';Time (s); Li6 rate (1/{0}s)'.format(binwidth), li6axis.GetNbins(), li6axis.GetXmin(), li6axis.GetXmax()) li6rate.SetDirectory(0) for h in ex['Li6rate']: li6rate.Add(h) li6fit.SetNpx(li6rate.GetNbinsX()) li6fit.SetParameters(1.5, 1000., 0.2, 1.5, 1., 14., 0.1, 30.) for i, p in enumerate( zip([5, 1e5, 5., 10., 10, 30., 10., 100.], [ 't_{d}', 'p_{0}', '#tau_{rise}', '#tau_{1}', 'N_{2}', '#tau_{2}', 'N_{3}', '#tau_{3}' ])): li6fit.SetParLimits(i, 0., p[0]) li6fit.SetParName(i, p[1]) li6fit.FixParameter(8, UCN.DetectorBackground['li6'][0] * binwidth) li6fit.SetParError(8, UCN.DetectorBackground['li6'][1] * binwidth) li6rate.Fit(li6fit, 'MRSQL', '') # canvas.SetLogy() li6rate.Draw() canvas.Print(pdf) # canvas.SetLogy(0) li6background = ROOT.TH1D( 'Li6background', ';Time (s); Li6 background rate (1/{0}s)'.format(binwidth), li6axis.GetNbins(), li6axis.GetXmin(), li6axis.GetXmax()) li6background.SetDirectory(0) for b in range(li6background.GetNbinsX()): li6background.SetBinContent( b, UCN.DetectorBackground['li6'][0] * li6background.GetBinWidth(b)) li6background.SetBinError( b, UCN.DetectorBackground['li6'][1] * li6background.GetBinWidth(b)) li6background.Sumw2() li6norm = ROOT.TH1D( 'TCN{0}_Li6_norm'.format(ex['TCN']), ';Time (s);Li6 rate normalized during counting (1/{0}s)'.format( binwidth), int(li6axis.GetNbins() / 4.), li6axis.GetXmin(), li6axis.GetXmax()) li6norm.SetDirectory(0) for li6, m in zip(ex['Li6rate'], ex['monitorcounts']): li6copy = li6.Clone() li6copy.Add(li6background, -1.) li6copy.Rebin(4) normhist = ROOT.TH1D('normhist', ';Time (s);Normalization factor', int(li6axis.GetNbins() / 4.), li6axis.GetXmin(), li6axis.GetXmax()) for b in range(normhist.GetNbinsX()): normhist.SetBinContent(b, m) normhist.SetBinError(b, math.sqrt(m)) normhist.Sumw2() li6copy.Divide(normhist) li6copy.SetBit(ROOT.TH1.kIsAverage) li6norm.Add(li6copy) li6norm.SetBit(ROOT.TH1.kIsAverage) li6norm.Draw() canvas.Print(pdf) ex['Li6rate_normalized'] = li6norm li6norm2 = ROOT.TH1D( 'TCN{0}_Li6_norm'.format(ex['TCN']), ';Time (s);Li6 rate normalized during irradiation (1/{0}s)'.format( binwidth), int(li6axis.GetNbins() / 4.), li6axis.GetXmin(), li6axis.GetXmax()) li6norm2.SetDirectory(0) for li6, m in zip(ex['Li6rate'], ex['monitorcounts2']): li6copy = li6.Clone() li6copy.Add(li6background, -1.) li6copy.Rebin(4) normhist2 = ROOT.TH1D('normhist', ';Time (s);Normalization factor', int(li6axis.GetNbins() / 4.), li6axis.GetXmin(), li6axis.GetXmax()) for b in range(normhist2.GetNbinsX()): normhist2.SetBinContent(b, m) normhist2.SetBinError(b, math.sqrt(m)) normhist2.Sumw2() li6copy.Divide(normhist2) li6copy.SetBit(ROOT.TH1.kIsAverage) li6norm2.Add(li6copy) li6norm2.SetBit(ROOT.TH1.kIsAverage) li6norm2.Draw() canvas.Print(pdf) ex['Li6rate_normalized2'] = li6norm2 li6rate.SetStats(False) li6rate.GetYaxis().SetTitle('Ratio of cumulated rates') li6rate.Add(li6background, -len(ex['Li6rate'])) li6rate.Rebin(int(1. / binwidth)) li6rate.Divide(he3rate) li6rate.Draw('HIST') canvas.Print(pdf) rateratio = ROOT.TH1D('TCN{0}_ratio'.format(ex['TCN']), ';Time (s);Average rate ratio', int(he3axis.GetNbins() / 10.), he3axis.GetXmin(), he3axis.GetXmax()) rateratio.SetDirectory(0) for li6, he3 in zip(ex['Li6rate'], ex['He3rate']): li6.Add(li6background, -1) li6.Rebin(int(10. / binwidth)) he3.Rebin(10) li6.Divide(he3) # li6.Draw() # canvas.Print(pdf) li6.SetBit(ROOT.TH1.kIsAverage) rateratio.Add(li6) rateratio.SetBit(ROOT.TH1.kIsAverage) rateratio.Draw() canvas.Print(pdf) ex['channels'].Draw() canvas.Print(pdf) window = ROOT.TH1I('li6window', 'Li6 window;Time after valve opened (s);Frequency', 100, 0., 5.) for w in ex['li6window']: window.Fill(w[0]) window.Draw() canvas.Print(pdf + ')')
'runs': [1181] }, { 'TCN': '18-380 (high position: UGD22+20)', 'runs': [1188] }, { 'TCN': '18-310 (high position: UGD22+20, smooth elbow)', 'runs': [1192] }] ReadCycles(ROOT.TFile(sys.argv[1]), experiments) # loop over experiments and analyze transmission in runs for ex in experiments: Transmission(ex) UCN.PrintBackground(experiments, 'li6') UCN.PrintMonitorCounts(experiments) Normalize(experiments, '18-215', '18-380') # Ti foil in high position Normalize(experiments, '18-115', '18-480') # Ti foil in low position Normalize(experiments, '18-240', '18-302') # Al foil above detector Normalize(experiments, '18-310', '18-380') # smooth elbow Normalize(experiments, '18-035', '18-031') # UGD22+IV3 compared to UGD17 only Normalize(experiments, '18-045', '18-035') # UGD22+IV3 compared to UGD17 only Normalize(experiments, '18-057', '18-045') # spider + UGD2 compared to UGD22 Normalize(experiments, '18-053', '18-045') # burst disk + UGD2 compared to UGD22 Normalize(experiments, '18-053', '18-480') # burst disk compared to UGD22 Normalize(experiments, '18-057', '18-053') # spider compared to burst disk Normalize(experiments, '18-480', '18-045') # Stainless guide compared to no guide
def StorageLifetime(ex, FitResult=None): print('\nAnalyzing TCN{0} in runs {1}'.format(ex['TCN'], ex['runs'])) if len(ex['start']) == 0: print('Found no cycles with run numbers {0}!'.format(ex['runs'])) return # report start time print(datetime.datetime.fromtimestamp(min(ex['start']))) # report range of beam current print('Beam current from {0:.3} to {1:.3} uA'.format( min(min(c) for c in ex['beamcurrent']), max(max(c) for c in ex['beamcurrent']))) # report range of temperature and vapor pressure print('Temperatures from {0:.3} to {1:.3} K'.format( min(ex['mintemperature']), max(ex['maxtemperature']))) print('Vapor pressure from {0:.3} to {1:.3} torr'.format( min(ex['minvaporpressure']), max(ex['maxvaporpressure']))) beam = [numpy.mean(cur) for cur in ex['beamcurrent'] ], [numpy.std(cur) for cur in ex['beamcurrent']] canvas = ROOT.TCanvas('c1', 'c1') canvas.SetLogy() for det in ['li6', 'he3']: ex[det + 'backgroundrate'], ex[det + 'backgroundrateerr'] = UCN.BackgroundRate( ex[det + 'background'], ex['backgroundduration']) ex[det + 'irradiationrate'], ex[ det + 'irradiationrateerr'] = UCN.SubtractBackgroundAndNormalizeRate( ex[det + 'irradiation'], ex['irradiationduration'], det, beam[0], beam[1]) print(det + ' detector background rate: {0:.4} +/- {1:.2} 1/s'.format( ex[det + 'backgroundrate'], ex[det + 'backgroundrateerr'])) x = numpy.array(ex['storageduration']) xerr = numpy.array([0. for _ in x]) # subtract background from UCN counts ex[det + 'counts_normalized'], ex[ det + 'counts_normalized_err'] = UCN.SubtractBackgroundAndNormalize( ex[det + 'counts'], ex['countduration'], det, beam[0], beam[1]) y = numpy.array(ex[det + 'counts_normalized']) yerr = numpy.array(ex[det + 'counts_normalized_err']) # plot normalized Li6 counts vs storage time graph = ROOT.TGraphErrors(len(x), x, y, xerr, yerr) graph.SetTitle( 'TCN{0} ({1} detector, single exponential fit, background subtracted, normalized to beam current)' .format(ex['TCN'], det)) graph.GetXaxis().SetTitle('Storage time (s)') graph.GetYaxis().SetTitle('UCN count (#muA^{-1})') # graph.SetMarkerStyle(20) # do single exponential fit f = graph.Fit(UCN.SingleExpo(), 'SQB') if sum(y) > 0 and f.Error(1) < 5.: ex[det + 'tau'] = f.Parameter(1) ex[det + 'tauerr'] = f.Error(1) * max(f.Chi2() / f.Ndf(), 1.) else: print( 'SKIPPING lifetime measurement from {0} detector in run(s) {1} because there were no counts detected or the error is larger than 5 s.' .format(det, ex['runs'])) ex[det + 'tau'] = 0. ex[det + 'tauerr'] = 0. print( '{0:.4} +/- {1:.2} ({2} detector, single exponential fit, background subtracted, normalized to beam current)' .format(ex[det + 'tau'], ex[det + 'tauerr'], det)) graph.Draw('AP') pdf = 'TCN{0}_{1}.pdf'.format(ex['TCN'], ex['runs'][0]) if det == 'li6': canvas.Print(pdf + '(') else: canvas.Print(pdf) if FitResult: r = DoCombinedFit([ex], pdf, FitResult) print('{0:.4} +/- {1:.2} (wall-storage lifetime from combined fit)'. format(ex['tau_wall'], ex['tau_wallerr'])) canvas.SetLogy(0) UCN.PrintTemperatureVsCycle(ex, pdf) ex['channels'].Draw() canvas.Print(pdf + ')') # return result from primary detector if max(ex['li6counts']) > max(ex['he3counts']): ex['tau'] = ex['li6tau'] ex['tauerr'] = ex['li6tauerr'] else: ex['tau'] = ex['he3tau'] ex['tauerr'] = ex['he3tauerr']
] ReadCycles(ROOT.TFile(sys.argv[1]), experiments) tauvstemp = [ ex for ex in experiments if ex['TCN'] == '18-300' or 1167 in ex['runs'] ] for ex in tauvstemp: StorageLifetime(ex) r = DoCombinedFit(tauvstemp, 'combinedfit.pdf') for ex in experiments: if ex['TCN'] != '18-300': StorageLifetime(ex, r) UCN.PrintBackground(experiments, 'li6', 930, 1206) UCN.PrintBackground(experiments, 'he3') def TauVsTime(experiments, parameter, variable, timeformat, color): exs = [ex for ex in experiments if ex[variable] > 0.] x = numpy.array([float(min(ex[parameter])) for ex in exs]) y = numpy.array([ex[variable] for ex in exs]) yerr = numpy.array([ex[variable + 'err'] for ex in exs]) grtaus = ROOT.TGraphErrors(len(exs), x, y, numpy.array([0. for _ in exs]), yerr) if timeformat: grtaus.GetXaxis().SetTimeDisplay(1) grtaus.GetXaxis().SetTimeFormat('%m-%d%F2018-01-01 00:00:00') grtaus.GetXaxis().SetNdivisions(10, 10, 0) grtaus.GetXaxis().SetTitle('Date')
def StorageLifetime(ex): print('\nAnalyzing TCN' + ex['TCN']) if len(ex['start']) == 0: print('Found no cycles with run numbers {0}!'.format(ex['runs'])) return canvas = ROOT.TCanvas('c', 'c') pdf = 'TCN{0}.pdf'.format(ex['TCN']) # subtract background from Li6 counts and normalize to monitor counts y, yerr = UCN.SubtractBackgroundAndNormalize(ex['li6counts'], ex['countduration'], 'li6', ex['monitorcounts2'], [math.sqrt(m) for m in ex['monitorcounts2']]) x = ex['storageduration'] xerr = [0. for _ in ex['storageduration']] # plot normalized, background corrected counts vs storage time graph = ROOT.TGraphErrors(len(x), numpy.array(x), numpy.array(y), numpy.array(xerr), numpy.array(yerr)) graph.SetTitle('TCN{0} (single exponential fit, with background subtracted, normalized to monitor detector)'.format(ex['TCN'])) graph.GetXaxis().SetTitle('Storage time (s)') graph.GetYaxis().SetTitle('UCN-count-to-monitor ratio') graph.SetMarkerStyle(20) canvas.SetLogy() #do single exponential fit with data point at 0 excluded f = graph.Fit(UCN.SingleExpo(), 'SQB', '', 1., 1000.) graph.SetTitle('TCN{0} (single exponential fit, with background subtracted, normalized to monitor detector, 0s excluded)'.format(ex['TCN'])) graph.Draw('AP') canvas.Print(pdf + '(') ex['tau'] = f.GetParams()[1] ex['tauerr'] = f.GetErrors()[1]*max(math.sqrt(f.Chi2()/f.Ndf()), 1.0) # do double exponential fit graph.SetTitle('TCN{0} (double exponential fit, with background subtracted, normalized to monitor detector, 0s excluded)'.format(ex['TCN'])) f = graph.Fit(UCN.DoubleExpo(), 'SQB', '', 1., 1000.) graph.Draw('AP') canvas.Print(pdf) print('{0} +/- {1}, {2} +/- {3} (double exponential fit, with background subtracted, normalized to monitor detector, 0s excluded)'.format(f.GetParams()[1], f.GetErrors()[1], f.GetParams()[3], f.GetErrors()[3])) # plot uncorrected UCN counts # y = [float(c) for c in ex['li6counts']] # yerr = [math.sqrt(c) for c in ex['li6counts']] # graph = ROOT.TGraphErrors(len(x), numpy.array(x), numpy.array(y), numpy.array(xerr), numpy.array(yerr)) # graph.SetTitle('TCN{0} (single exponential fit + background, unnormalized)'.format(ex['TCN'])) # graph.GetXaxis().SetTitle('Storage time (s)') # graph.GetYaxis().SetTitle('UCN count') # do single exponential fit with background # f = graph.Fit(UCN.SingleExpoWithBackground(), 'SQB') # graph.Draw('AP') # canvas.Print(pdf) # print('{0} +/- {1} (single exponential fit with {2} +/- {3} background, unnormalized)'.format(f.GetParams()[1], f.GetErrors()[1], f.GetParams()[2], f.GetErrors()[2])) # draw plot of temperature during each cycle UCN.PrintTemperatureVsCycle(ex, pdf) mtau = [] mtauerr = [] # fit single exponential to He3 count-rate histogram during storage period (pinhole method) for he3rate, m, s, c in zip(ex['he3rate'], ex['monitorduration'], ex['storageduration'], ex['countduration']): fitstart = m + 5 fitend = m + s # if not ex['pinhole']: # fitend = fitend + c if fitend > fitstart + 10 and he3rate.Integral(he3rate.FindBin(fitstart), he3rate.FindBin(fitend)) > 0: f = he3rate.Fit(UCN.SingleExpo(), 'SQB', '', fitstart, fitend) he3rate.SetTitle('TCN{0} (He3 rate)'.format(ex['TCN'])) he3rate.Draw() canvas.Print(pdf) # print fitted He3 rate to pdf mtau.append(f.GetParams()[1]) mtauerr.append(f.GetErrors()[1]*max(math.sqrt(f.Chi2()/f.Ndf()), 1.0)) # print average storage lifetime from He3 fits to pdf canvas = ROOT.TCanvas('c','c') if len(mtau) > 0: he3tau = ROOT.TGraphErrors(len(mtau), numpy.array(ex['cyclenumber']), numpy.array(mtau), numpy.array([0. for _ in mtau]), numpy.array(mtauerr)) fit = he3tau.Fit('pol0', 'SQ') ex['pinholetau'] = fit.Parameter(0) ex['pinholetauerr'] = fit.ParError(0)*max(math.sqrt(f.Chi2()/f.Ndf()), 1.0) he3tau.SetMarkerStyle(20) he3tau.GetXaxis().SetTitle('Cycle') he3tau.GetYaxis().SetTitle('Pinhole storage lifetime (s)') he3tau.SetTitle('') he3tau.Draw('AP') print('{0} +/- {1} (single exponential fit to rate in monitor detector during storage period)'.format(fit.Parameter(0), fit.ParError(0))) else: ex['pinholetau'] = 0. ex['pinholetauerr'] = 0. canvas.Print(pdf) # draw plot of Li6 background rate during each cycle ex['li6backgroundrate'], ex['li6backgroundrateerr'] = UCN.PrintBackgroundVsCycle(ex, pdf, 'li6') print('Li6 detector background rate: {0} +/- {1} 1/s'.format(ex['li6backgroundrate'], ex['li6backgroundrateerr'])) beam = [numpy.mean(cur) for cur in ex['beamcurrent']], [numpy.std(cur) for cur in ex['beamcurrent']] # subtract background from Li6 counts during irradiation and normalize to beam current, draw plot for each cycle ex['li6irradiationrate'], ex['li6irradiationrateerr'] = UCN.SubtractBackgroundAndNormalizeRate(ex['li6irradiation'], ex['irradiationduration'], 'li6', beam[0], beam[1]) UCN.PrintIrradiationBackgroundVsCycle(ex, pdf, 'li6') # report average monitor counts, range of beam current, range of He-II temperature monitoravg = numpy.average(ex['monitorcounts2'], None, [1./m for m in ex['monitorcounts2']], True) print('Monitor counts: {0} +/- {1}'.format(monitoravg[0], 1./math.sqrt(monitoravg[1]))) print('Beam current from {0} to {1} uA'.format(min(min(c) for c in ex['beamcurrent']), max(max(c) for c in ex['beamcurrent']))) print('Temperatures from {0} to {1} K'.format(min(ex['mintemperature']), max(ex['maxtemperature']))) # draw Li6 channel histogram ex['channels'].Draw() canvas.Print(pdf + ')')