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 + ')')
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 + ')')