def WorkingPMTs(material): # Select which energy to use based on the material in the detector energy = 0.0 if material == "lightwater_sno": energy = WaterEnergy else: energy = ScintEnergy totalActiveChannels = 0 # Read in ROOT files reader = RAT.DU.DSReader(material + "_E=" + str(int(energy * 1000)) + "keV_sf=0.root") for ievent in range(0, reader.GetEntryCount()): if ievent != 0: continue ds = reader.GetEntry(ievent) # Get total number of channels pmt_info = rat.utility().GetPMTInfo() numChannels = pmt_info.GetCount() # Find active channels channelHardwareStatus = rat.utility().GetChanHWStatus() for lcn in range(0, numChannels): if pmt_info.GetType(lcn) != pmt_info.NORMAL: continue if channelHardwareStatus.IsEnabled(): if channelHardwareStatus.IsTubeOnline(lcn): totalActiveChannels = totalActiveChannels + 1 return totalActiveChannels
def plot_hit_time_residuals_mc_position(file_name): """ Plot the hit time residuals for the MC position. :param file_name: Path to the RAT DS file to plot. :return: The created histogram """ hit_time_residuals = ROOT.TH1D( "hHitTimeResidualsMC", "Hit time residuals using the MC position", 1000, -500.0, 500.0 ); hit_time_residuals.SetDirectory(0) light_path = rat.utility().GetLightPath() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() for ds, run in rat.dsreader(file_name): event_position = ds.GetMC().GetMCParticle(0).GetPosition() # At least 1 is somewhat guaranteed for iev in range(0, ds.GetEVCount()): calibrated_pmts = ds.GetEV(iev).GetCalPMTs() for ipmt in range(0, calibrated_pmts.GetCount()): pmt_cal = calibrated_pmts.GetPMT(ipmt) scint_distance = ROOT.Double() av_distance = ROOT.Double() water_distance = ROOT.Double() light_path.CalcByPosition(event_position, pmt_info.GetPosition(pmt_cal.GetID()), scint_distance, av_distance, water_distance) transit_time = group_velocity.CalcByDistance(scint_distance, av_distance, water_distance) # Assumes 400nm photon hit_time_residuals.Fill(pmt_cal.GetTime() - transit_time) hit_time_residuals.GetYaxis().SetTitle("Count per 1 ns bin") hit_time_residuals.GetXaxis().SetTitle("Hit time residuals [ns]") hit_time_residuals.Draw() return hit_time_residuals
def WorkingPMTs(material): if material == "lightwater_sno": energy = 5.0 else: energy = 2.5 totalActiveChannels = 0 infileName = material + "_P=" + str(int(0.0)) + "mm_E=" + str(int(energy * 1000)) + "keV_sf=0.root" print infileName reader = RAT.DU.DSReader(infileName) for ievent in range(0, reader.GetEntryCount()): if ievent != 0: continue ds = reader.GetEntry(ievent) # Get total number of channels pmt_info = rat.utility().GetPMTInfo() numChannels = pmt_info.GetCount() # Find active channels channelHardwareStatus = rat.utility().GetChanHWStatus() for lcn in range(0, numChannels): if pmt_info.GetType( lcn ) != pmt_info.NORMAL: continue if channelHardwareStatus.IsEnabled(): if channelHardwareStatus.IsTubeOnline( lcn ): totalActiveChannels = totalActiveChannels + 1 return totalActiveChannels
def plot_hit_time_residuals_fit_position(file_name): """ Plot the hit time residuals for the fit position. :param file_name: Path to the RAT DS file to plot. :return: The created histogram """ hit_time_residuals = ROOT.TH1D( "hHitTimeResidualsFit", "Hit time residuals using the fit position", 1000, -500.0, 500.0 ); hit_time_residuals.SetDirectory(0) light_path = rat.utility().GetLightPath() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() for ds, run in rat.dsreader(file_name): for iev in range(0, ds.GetEVCount()): ev = ds.GetEV(iev) if not ev.DefaultFitVertexExists() or not ev.GetDefaultFitVertex().ContainsPosition() or not ev.GetDefaultFitVertex().ValidPosition(): continue #Didn't fit correctly event_position = ev.GetDefaultFitVertex().GetPosition(); calibrated_pmts = ev.GetCalPMTs() for ipmt in range(0, calibrated_pmts.GetCount()): pmt_cal = calibrated_pmts.GetPMT(ipmt) scint_distance = ROOT.Double() av_distance = ROOT.Double() water_distance = ROOT.Double() light_path.CalcByPosition(event_position, pmt_info.GetPosition(pmt_cal.GetID()), scint_distance, av_distance, water_distance) transit_time = group_velocity.CalcByDistance(scint_distance, av_distance, water_distance) # Assumes 400nm photon hit_time_residuals.Fill(pmt_cal.GetTime() - transit_time) hit_time_residuals.GetYaxis().SetTitle("Count per 1 ns bin") hit_time_residuals.GetXaxis().SetTitle("Hit time residuals [ns]") hit_time_residuals.Draw() return hit_time_residuals
def getHitTimeResiduals_MC(filename): data = [] ratreader = rat.dsreader(filename) for ds, run in ratreader: light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() event_position = ds.GetMC().GetMCParticle(0).GetPosition() for iev in range(0, ds.GetEVCount()): calibrated_pmts = ds.GetEV(iev).GetCalPMTs() #print calibrated_pmts.GetCount() for ipmt in range(0, calibrated_pmts.GetCount()): pmt_cal = calibrated_pmts.GetPMT(ipmt) light_path.CalcByPosition( event_position, pmt_info.GetPosition(pmt_cal.GetID())) inner_av_distance = light_path.GetDistInInnerAV() av_distance = light_path.GetDistInAV() water_distance = light_path.GetDistInWater() transit_time = group_velocity.CalcByDistance( inner_av_distance, av_distance, water_distance) # Assumes 400nm photon data.append(pmt_cal.GetTime() - transit_time) data = np.array(data) ratreader.close() return data
def ProduceTimeResAndEnergyPDF(infileName): energyList = [] nbins = (TimeRes_upperBound - TimeRes_lowerBound) / TimeRes_stepSize Histogram = ROOT.TH1D(infileName, "", nbins, TimeRes_lowerBound, TimeRes_upperBound) effectiveVelocity = rat.utility().GetEffectiveVelocity() lightPath = rat.utility().GetLightPathCalculator() pmtInfo = rat.utility().GetPMTInfo() for ds, run in rat.dsreader(infileName): if ds.GetEVCount() > 0: mcParticle = ds.GetMC().GetMCParticle(0) mcPos = mcParticle.GetPosition() mcTime = mcParticle.GetTime() ev = ds.GetEV(0) if not ev.FitResultExists("scintFitter"): continue if not ev.GetFitResult("scintFitter").GetValid(): continue if not ev.GetFitResult("scintFitter").GetVertex( 0).ContainsPosition(): continue fitVertex = ev.GetFitResult("scintFitter").GetVertex(0) vertPos = fitVertex.GetPosition() vertTime = fitVertex.GetTime() if (fitVertex.ContainsEnergy()): energyList.append(fitVertex.GetEnergy()) calibratedPMTs = ev.GetCalPMTs() for iPMT in range(0, calibratedPMTs.GetCount()): pmtPos = pmtInfo.GetPosition( calibratedPMTs.GetPMT(iPMT).GetID()) pmtTime = calibratedPMTs.GetPMT(iPMT).GetTime() lightPath.CalcByPosition(vertPos, pmtPos) distInScint = lightPath.GetDistInInnerAV() distInAV = lightPath.GetDistInAV() distInWater = lightPath.GetDistInWater() flightTime = effectiveVelocity.CalcByDistance( distInScint, distInAV, distInWater) timeResidual = pmtTime - flightTime - vertTime Histogram.Fill(timeResidual) Histogram.Scale(1.0 / Histogram.Integral()) pdfVector = [] for i in range(1, Histogram.GetNbinsX()): pdfVector.append(Histogram.GetBinContent(i)) Histogram.Delete() return (pdfVector, energyList)
def PlotHitTimeResiduals(material): # Select which energy and fitter to use based on the material in the detector energy = 0.0 fitter = "" if material == "lightwater_sno": energy = 5.0 fitter = "waterResult" else: energy = 2.5 fitter = "scintFitter" energy = 5.0 infileName = material + "_P=" + str(int(0.0)) + "mm_E=" + str(int(energy * 1000)) + "keV_sf=0.root" print infileName hit_time_residuals = ROOT.TH1D( "hHitTimeResidualsMC", "Hit time residuals using the MC position", 120, -20.0, 100.0 ) hit_time_residuals.SetDirectory(0) for ds, run in rat.dsreader(infileName): # rat.utility().GetLightPath() must be called *after* the rat.dsreader constructor. light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() event_position = ds.GetMC().GetMCParticle(0).GetPosition() # At least 1 is somewhat guaranteed for iev in range(0, ds.GetEVCount()): ev = ds.GetEV(iev) # Check fit worked if not ev.FitResultExists(fitter) or not ev.GetFitResult(fitter).GetVertex(0).ContainsTime() or not ev.GetFitResult(fitter).GetVertex(0).ValidTime(): continue event_time = ev.GetFitResult(fitter).GetVertex(0).GetTime() calibrated_pmts = ds.GetEV(iev).GetCalPMTs() for ipmt in range(0, calibrated_pmts.GetCount()): pmt_cal = calibrated_pmts.GetPMT(ipmt) light_path.CalcByPosition(event_position, pmt_info.GetPosition(pmt_cal.GetID())) inner_av_distance = light_path.GetDistInInnerAV() av_distance = light_path.GetDistInAV() water_distance = light_path.GetDistInWater() transit_time = group_velocity.CalcByDistance(inner_av_distance, av_distance, water_distance) # Assumes 400nm photon hit_time_residuals.Fill(pmt_cal.GetTime() - transit_time - event_time) hit_time_residuals.GetYaxis().SetTitle("Count per 1 ns bin") hit_time_residuals.GetXaxis().SetTitle("Hit time residuals [ns]") hit_time_residuals.SetTitle("Hit Time Residuals") canvas = ROOT.TCanvas() canvas.SetLogy() hit_time_residuals.Draw() canvas.Update(); canvas.SaveAs("HitTimeResiduals.eps") raw_input("Press 'Enter' to exit")
def ProduceRatioHistogram(infileName, t1, t2): Histogram = ROOT.TH1D(infileName, infileName + ": Prompt PMTs/Total PMTs in Event", 100, 0.0, 1.0) effectiveVelocity = rat.utility().GetEffectiveVelocity() lightPath = rat.utility().GetLightPathCalculator() pmtInfo = rat.utility().GetPMTInfo() for ds, run in rat.dsreader(infileName): if ds.GetEVCount() == 0: continue ev = ds.GetEV(0) if not ev.FitResultExists("scintFitter"): continue if not ev.GetFitResult("scintFitter").GetValid(): continue if not ev.GetFitResult("scintFitter").GetVertex(0).ContainsPosition(): continue vertPos = ev.GetFitResult("scintFitter").GetVertex(0).GetPosition() if vertPos.Mag() > maxRadius: continue vertTime = ev.GetFitResult("scintFitter").GetVertex(0).GetTime() calibratedPMTs = ev.GetCalPMTs() peak = total = 0.0 for j in range(0, calibratedPMTs.GetCount()): pmtPos = pmtInfo.GetPosition(calibratedPMTs.GetPMT(j).GetID()) pmtTime = calibratedPMTs.GetPMT(j).GetTime() lightPath.CalcByPosition(vertPos, pmtPos) distInScint = lightPath.GetDistInScint() distInAV = lightPath.GetDistInAV() distInWater = lightPath.GetDistInWater() flightTime = effectiveVelocity.CalcByDistance( distInScint, distInAV, distInWater) timeResid = pmtTime - flightTime - vertTime if timeResid > t1 and timeResid < t2: peak += 1.0 if timeResid > t1 and timeResid < maxTimeResid: total += 1.0 ratio = peak / total Histogram.Fill(ratio) return Histogram
def get_PMT_hits_cone(fname, fibre_pos, max_angle, flag=5241): """Find how many times PMTs in a cone surrounding the light injection vector were hit during a run. :param fname: Name of a .root data file containing the run data. :param fibre_pos: Vector of fibre injection position, relative to the centre of the psup. :param max_angle: The angle of the cone to be projected. :return pmt_hits: Dictionary containing number of hits at PMTs activated during run. """ pmt_hits = {} pmtInfo = rat.utility().GetPMTInfo() for ds, run in rat.dsreader(fname): for iEV in range(ds.GetEVCount()): ev = ds.GetEV(iEV) if (ev.GetTrigType() != 32768): continue unCal_pmts = ev.GetUncalPMTs() for pmt in range(unCal_pmts.GetNormalCount()): uncal = unCal_pmts.GetPMT(pmt) pmtID = unCal_pmts.GetNormalPMT(pmt).GetID() pmt_pos = pmtInfo.GetPosition(pmtID) fibre_vec = ROOT.TVector3(fibre_pos.GetD("x"), fibre_pos.GetD("y"), fibre_pos.GetD("z")) fibre_to_pmt = -pmt_pos + fibre_vec angle = fibre_to_pmt.Angle(fibre_vec) * (180 / np.pi) lcn = uncal.GetID() if angle <= max_angle: if lcn != flag: if lcn not in pmt_hits: pmt_hits[lcn] = 1. else: pmt_hits[lcn] += 1. return pmt_hits
def get_crossing_points(self, wl): """ Function to obtain the crossing coordinates of the direct beam light with the detector geometry Args: wl (float) : wavelength Returns: AV1_cross (TVector3) : AV crossing coordinates of the direct beam light near side of the fibre AV2_cross (TVector3) : AV crossing coordinates of the direct beam light far side of the fibre PSUP_cross (TVector3) : Coordinates at which the direct beam light hits the PSUP n_scint (float) : refractive index of the material inside the AV n_water (float) : refractive index of the material outside the AV Calculates the crossing points of the direct beam light with the near side of the AV, the far side of the AV and the PSUP using the RAT LightPath class. Fills self.AV1_cross, self.AV2_cross, self.PSUP_cross and the refractive indices self.n_scint and self.n_water. """ #Define radius of AV and PSUP rav = 6000. rpsup = 8400. self.wl = wl #Get LightPath class and calculate refractive indices LightPath = rat.utility().GetLightPathCalculator() energy = LightPath.WavelengthToEnergy(self.wl * math.pow(10, -6)) self.n_scint = LightPath.GetScintRI(energy) self.n_water = LightPath.GetWaterRI(energy) #calculate first crossing point with AV self.AV1_cross = LightPath.VectorToSphereEdge(self.sourcepos, self.sourcedir, rav, True) #calculate refracted source direction AV1_norm = -self.AV1_cross.Unit() newsourcedir = LightPath.PathRefraction(self.sourcedir, AV1_norm, self.n_water, self.n_scint) #calculate second crossing point with AV self.AV2_cross = LightPath.VectorToSphereEdge(self.AV1_cross, newsourcedir, rav, False) #calculate refracted source direction AV2_norm = -self.AV2_cross.Unit() newnewsourcedir = LightPath.PathRefraction(newsourcedir, AV2_norm, self.n_scint, self.n_water) #calculate crossing point with PSUP self.PSUP_cross = LightPath.VectorToSphereEdge(self.AV2_cross, newnewsourcedir, rpsup, False) return self.AV1_cross, self.AV2_cross, self.PSUP_cross, self.n_scint, self.n_water
def GetHParameterAtCentre(material): '''Extract and store the h parameters as a function of energy at the centre of the detector. Fit each histogram with a gaussian before saving. ''' hFile = ROOT.TFile(CentralHistFilename, "recreate") hGraph = ROOT.TGraphErrors() # tgraph of hparameter vs energy for i, energy in enumerate(CentralEnergies): infilename = CentralFilename(material, energy) + ".root" hHist = ROOT.TH1F(CentralHistname(energy), ";H parameter", 10000, 0, 10000) for ds, run in rat.dsreader(infilename): if ds.GetEVCount() == 0: continue segmentor = rat.utility().GetSegmentor() segmentor.SetNumberOfDivisions(NumberOfSegments) rawPMTSegmentIDs = segmentor.GetSegmentIDs() rawPMTSegmentPopulations = segmentor.GetSegmentPopulations() hitPMTSegmentPopulations = [0] * len(rawPMTSegmentPopulations) calPMTs = ds.GetEV(0).GetCalPMTs() for j in range(0, calPMTs.GetCount()): hitPMTSegmentPopulations[rawPMTSegmentIDs[calPMTs.GetPMT(j).GetID()]] += 1 hValue = 0.0 for s in range(len(rawPMTSegmentPopulations)): if (hitPMTSegmentPopulations[s] >= rawPMTSegmentPopulations[s]): correctedHitPMTSegmentPopulation = rawPMTSegmentPopulations[s] - 1 else: correctedHitPMTSegmentPopulation = hitPMTSegmentPopulations[s] hValue += (rawPMTSegmentPopulations[s] * math.log(1.0 - (float(correctedHitPMTSegmentPopulation) / float(rawPMTSegmentPopulations[s])))) hValue *= -1.0 hHist.Fill(hValue) hFile.cd() hHist.Fit("gaus", "Q") hHist.Write() hGraph.SetPoint(i, energy, hHist.GetFunction("gaus").GetParameter(1)) hGraph.SetPointError(i, 0, hHist.GetFunction("gaus").GetParError(1)) hGraph.SetName("grHVsEnergy") hGraph.Write()
def UpdatePlot(infileName, fullPlot): groupVelocity = rat.utility().GetGroupVelocity() lightPath = rat.utility().GetLightPathCalculator() pmtInfo = rat.utility().GetPMTInfo() eventNumber = 0 for ds, run in rat.dsreader(infileName): if eventNumber % 100 == 0: print eventNumber eventNumber += 1 mc = ds.GetMC() startTime = mc.GetMCParticle(0).GetTime() startPosition = mc.GetMCParticle(0).GetPosition() for pmtIndex in range(0, mc.GetMCPMTCount()): mcPMT = mc.GetMCPMT(pmtIndex) pmtPosition = pmtInfo.GetPosition(mcPMT.GetPMTID()) # If the event was not near the AV centre, only look at PMTs within 10 degrees angle (forwards and backwards) if (startPosition.Mag() > 500.0 and startPosition.Dot(endPosition) < 0.985 and startPosition.Dot(endPosition) > -0.985): continue for peIndex in range(0, mcPMT.GetMCPECount()): mcPE = mcPMT.GetMCPE(peIndex) lightPath.CalcByPosition(startPosition, pmtPosition) distInScint = lightPath.GetDistInScint() distInAV = lightPath.GetDistInAV() distInWater = lightPath.GetDistInWater() transitTime = groupVelocity.CalcByDistance(0.0, distInAV, distInWater) fullPlot.Fill(distInScint, mcPE.GetCreationTime() - startTime - transitTime) return
def plot_slices(hists, slice_width, fibre_pos): """ Plot individual pmt time spectra within angular slices. :param hist: Dictionary containing time spectra histograms of all pmts within defined light cone. Keys are pmtID ints. :param slice_width: Angular with of slices of interest. """ pmt_info = rat.utility().GetPMTInfo() # Find max angle max_angle = 0 pmtIDs = hists.keys() for pmtID in pmtIDs: angle = taf.fibre_to_pmt_angle(fibre_pos, pmt_info.GetPosition(pmtID)) if angle > max_angle: max_angle = angle print max_angle # Step between 0 and max_angle in slices of slice_width # create a plot of all pmt time spectra within each slice ROOT.gStyle.SetPalette(1) cuts = np.arange(0., max_angle + slice_width, slice_width) for i, cut in enumerate(cuts): tmpHists = [] if i > 0: low_range = cuts[i - 1] hi_range = cuts[i] s = ROOT.THStack( "stack", "Slice: %1.1f - %1.1f deg" % (low_range, hi_range)) count = 0 for pmtID in pmtIDs: angle = taf.fibre_to_pmt_angle(fibre_pos, pmt_info.GetPosition(pmtID)) if angle > low_range and angle < hi_range: #print pmtID count = count + 1 hists[pmtID].SetLineColor(count) s.Add(hists[pmtID]) print "Drawing..." s.Draw("nostack") s.GetHistogram().GetXaxis().SetTitle("Time (ns)") #s.Write() #c1.BuildLegend(0.5, 0.2, 0.88, 0.88) c1.Update() c1.Modified() c1.Print("./results/slices/Slice_%1.1f.png" % low_range) s.Delete()
def dumpArray( indir, branch_name, outdir = None, show_info = False, ax_lim = [None, None], max_files = -1): isdata = False print indir if 'data' in indir: isdata = True print '\n\n***Using data!' file_list = [os.path.join(indir, x) for x in os.listdir(indir) if '.root' in x] file_list.sort() if max_files >0: file_list = file_list[:max_files] print 'Going over ', len(file_list), ' files' if branch_name == 'energy': print 'Using RSP energy correction AND CALIBRATION' rc = rat.utility().GetReconCorrector().Get() calib = rat.utility().GetReconCalibrator().Get() print 'Test RSP correction', rc.CorrectEnergyRSP(5.0) print 'Test Energy calibration', calib.CalibrateEnergyRSP(False, 4., 300., 40) # Test one file for content tfile = ROOT.TFile(file_list[0]) tree = tfile.Get('output') branch = tree.GetBranch(branch_name) tot_entries = branch.GetEntries() if tot_entries < 100: tot_entries = 100 print 'Entries in file ', tot_entries, ' - adding 20% contintengcy' print file_list[0] values = np.zeros(int(tot_entries*len(file_list)*1.2)) counter = 0 for ifile, one_file in enumerate(file_list): if ifile % 400 == 0: print ifile try: tfile = ROOT.TFile(one_file) tree = tfile.Get('output') branch = tree.GetBranch(branch_name) tot_entries = branch.GetEntries() except: print 'File cannot be opened ', one_file continue # Special loop for energy to avoid doing many ifs if branch_name == 'energy': posx_branch = tree.GetBranch('posx') posy_branch = tree.GetBranch('posy') posz_branch = tree.GetBranch('posz') None for i in range(tot_entries): branch.GetEntry(i) posx_branch.GetEntry(i) posy_branch.GetEntry(i) posz_branch.GetEntry(i) corrected = rc.CorrectEnergyRSP(branch.GetLeaf(branch_name).GetValue(0)) # Calibrated! rho = np.sqrt(posx_branch.GetLeaf('posx').GetValue(0)**2 + posy_branch.GetLeaf('posy').GetValue(0)**2) calibrated = calib.CalibrateEnergyRSP(isdata, corrected, rho, posz_branch.GetLeaf('posz').GetValue(0)) values[counter] = calibrated counter += 1 else: for i in range(tot_entries): branch.GetEntry(i) values[counter] = branch.GetLeaf(branch_name).GetValue(0) counter += 1 tfile.Close() values = values[:counter] if outdir != None: np.save(os.path.join(outdir, branch_name+'.npy'), values) print 'Saved!' if show_info: try: fig, ax=arrayDiagnostics(values,branch_name, ax_lim) fig.savefig(os.path.join(outdir, branch_name+'.png')) except: print 'Diagnostics failed' return values
def PositionDirectionScaleFactor(material): # Select which time residual window to use based on the material in the detector time_residual_window = [] subfiles = 0 energy = 0.0 fitter = "" if material == "lightwater_sno": time_residual_window = WaterTimeResidualWindow subfiles = WaterSubfiles energy = 5.0 fitter = "waterResult" else: time_residual_window = ScintTimeResidualWindow subfiles = ScintSubfiles energy = 2.5 fitter = "scintFitter" # Calculate edges of position bins lowBins = [Positions[0]-(Positions[1]-Positions[0])/2] for i in range(1,len(Positions)): lowBins.append( (Positions[i-1]+Positions[i])/2 ) lowBins.append( Positions[-1]+(Positions[-1]-Positions[-2])/2 ) lowBinsArray = array('d',lowBins) HistogramTotal = ROOT.TH2D("Total", "Total", len(Positions), lowBinsArray, uDotrBins, -1.0, 1.0) HistogramPrompt = ROOT.TH2D("Prompt", "Prompt", len(Positions), lowBinsArray, uDotrBins, -1.0, 1.0) # Read in ROOT files reader = RAT.DU.DSReader(material + "_P=" + str(int(Positions[0])) + "mm_E=" + str(int(energy * 1000)) + "keV_sf=0.root") for position in Positions: for sf in range(0, subfiles): if position == Positions[0] and sf == 0: continue infileName = material + "_P=" + str(int(position)) + "mm_E=" + str(int(energy * 1000)) + "keV_sf=" + str(int(sf)) + ".root" print infileName reader.Add(infileName) for ievent in range(0, reader.GetEntryCount()): if ievent % 100 == 0: print "PositionDirectionScaleFactor:: " + str(ievent) + " : " + str(reader.GetEntryCount()) ds = reader.GetEntry(ievent) light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() mc = ds.GetMC() # Get MC event info eventPosition = mc.GetMCParticle(0).GetPosition() eventDirection = mc.GetMCParticle(0).GetMomentum().Unit() # Loop through events for iev in range(0, ds.GetEVCount()): if iev != 0: continue ev = ds.GetEV( iev ) calibratedPMTs = ev.GetCalPMTs() # Check fit worked and positions close if False in (ev.FitResultExists(fitter), ev.GetFitResult(fitter).GetVertex(0).ContainsPosition(), ev.GetFitResult(fitter).GetVertex(0).ValidPosition(), ev.GetFitResult(fitter).GetVertex(0).ContainsTime(), ev.GetFitResult(fitter).GetVertex(0).ValidTime()): continue # Didn't fit successfully positionDiff = eventPosition - ev.GetFitResult(fitter).GetVertex(0).GetPosition() if positionDiff.Mag() > 1000.0: continue # Position fit outside tolerace # If at centre radial magnitude is zero so fill first bin if abs(eventPosition.Mag()-0.0)<0.01 or abs(eventPosition.Mag()-8000.0)<0.01: HistogramTotal.Fill( eventPosition.Mag(), -1.0 ) else: if material == "lightwater_sno": HistogramTotal.Fill( eventPosition.Mag(), eventPosition.Unit().Dot(eventDirection) ) else: HistogramTotal.Fill( eventPosition.Mag(), eventPosition.CosTheta() ) # Get fitted time eventTime = ev.GetFitResult(fitter).GetVertex(0).GetTime() # Loop through PMTs for ipmt in range(0, calibratedPMTs.GetCount()): pmtCal = calibratedPMTs.GetPMT( ipmt ) # Calculate time residual light_path.CalcByPosition( eventPosition, pmt_info.GetPosition( pmtCal.GetID() ) ) distInInnerAV = light_path.GetDistInInnerAV() distInAV = light_path.GetDistInAV() distInWater = light_path.GetDistInWater() transitTime = group_velocity.CalcByDistance( distInInnerAV, distInAV, distInWater ) timeResidual = pmtCal.GetTime() - transitTime - eventTime # Fill if time residual within range if timeResidual > time_residual_window[0] and timeResidual < time_residual_window[1]: if abs(eventPosition.Mag()-0.0) < 0.01 or abs(eventPosition.Mag()-8000.0) < 0.01: HistogramPrompt.Fill( eventPosition.Mag(), -1.0 ) else: if material == "lightwater_sno": HistogramPrompt.Fill( eventPosition.Mag(), eventPosition.Unit().Dot(eventDirection) ) else: HistogramPrompt.Fill( eventPosition.Mag(), eventPosition.CosTheta() ) # Calculate average prompt Nhits, if up to 8000mm set edge to same value (low statistics) and scale by value at centre HistogramPrompt.Divide(HistogramTotal) centre_value = HistogramPrompt.GetBinContent(1,1) edge_value = HistogramPrompt.GetBinContent(len(Positions),1) if Positions[-1] == 8000.0: for i in range(1, uDotrBins+1): HistogramPrompt.SetBinContent(len(Positions),i,edge_value) HistogramPrompt.Scale(1.0/centre_value) for i in range(1, uDotrBins+1): HistogramPrompt.SetBinContent(1,i,1.0) scaleFactor = [] for binc in range(0, uDotrBins): singleUDotrScaleFactor = [] for binr in range(0, len(Positions)): singleUDotrScaleFactor.append(HistogramPrompt.GetBinContent( binr+1, binc+1 )) scaleFactor.append(singleUDotrScaleFactor) del HistogramPrompt del HistogramTotal return scaleFactor
action="store_true") args = parser.parse_args() file_list = [] for root, dirs, files in os.walk(args.directory): for file in files: match = False if args.passnum: if (file.find(r"SNOP_[0-9]+_[0-9]+_p"+str(args.passnum)+".root") > 0): match = True else: match = re.search(r"SNOP_[0-9]+_[0-9]+_p[0-9]+.root", file) if match: file_list.append(os.path.join(root, file)) max_bits = 13 utility = rat.utility() dq_bits = utility.GetDataQualityBits() hist_title = "Performance of DQ checks" hist_dq_flags = TH1D("TH1D_dq_status", hist_title, max_bits, 0, max_bits) hist_dq_flags.GetXaxis().SetBinLabel(1, "run_type") hist_dq_flags.GetXaxis().SetBinLabel(2, "mc_flag") hist_dq_flags.GetXaxis().SetBinLabel(3, "trigger") hist_dq_flags.GetXaxis().SetBinLabel(4, "run_length") hist_dq_flags.GetXaxis().SetBinLabel(5, "general_coverage") hist_dq_flags.GetXaxis().SetBinLabel(6, "crate_coverage") hist_dq_flags.GetXaxis().SetBinLabel(7, "panel_coverage") hist_dq_flags.GetXaxis().SetBinLabel(8, "run_header") hist_dq_flags.GetXaxis().SetBinLabel(9, "delta_t_comparison") hist_dq_flags.GetXaxis().SetBinLabel(10, "clock_forward") hist_dq_flags.GetXaxis().SetBinLabel(11, "event_separation")
def getTimeResiduals(infile_list = [], outfile = '', bin_width = 0.5, # in ns time_window = 300., # in ns calibration = True, remove_bad_pmts = False, min_intimehits = 10., min_nhits = 15, radius_range = [7020, 10000], udotr_range = [-1., -0.8], emin = 3., dcmask = -1, start_time = -120., max_ev = -1): # in ns - trigger is at ~340 print 'Radius range', radius_range print 'UdotR range', udotr_range # Size of the array time_edges = np.arange(start_time, start_time+time_window+bin_width, bin_width) nbins = time_edges.size-1 all_toa = np.zeros([9800, nbins]) light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() ev_counter = 0 ev_earlyhit10 = 0 ev_earlyhit20 = 0 qpdt_flagged = 0 break_all = False # Loop over all the files in infile_list for iFile, one_file in enumerate(infile_list): if break_all: break print iFile,'/', len(infile_list), ' - reading ', one_file if True: #try: reader = rat.dsreader(one_file) this_file_ev = 0 this_file_qpdt = 0 for ds, run in reader: for iEv in range(ds.GetEVCount()): if break_all: break event = ds.GetEV(iEv) pmts = event.GetCalPMTs() # Select which events to run on if len(event.GetFitNames()) < 1: continue if event.GetNhitsCleaned() < min_nhits: continue if event.GetInTimeHits100() < min_intimehits: continue event_vtx = event.GetFitResult(event.GetFitNames()[0]).GetVertex(0) if not (event_vtx.ValidDirection()*event_vtx.ValidEnergy()): continue use_event = False # Selecting only FECD tagged if calibration: for iFECD in range(pmts.GetFECDCount()): fecd = pmts.GetFECDPMT(iFECD) if fecd.GetID() != 9188: continue use_event = True else: # For Non calibration runs I'm doing the following cuts # to get the PMT box only # E > 3. MeV # UdotR < -0.8 # posR > 7020. if event_vtx.GetEnergy() < emin: continue r = np.array(event_vtx.GetPosition()) radius = np.linalg.norm(r) if radius < radius_range[0] or radius > radius_range[1]: continue u = np.array(event_vtx.GetDirection()) udotr = np.dot(u,r)/radius if udotr < udotr_range[0] or udotr > udotr_range[1]: continue use_event = True if use_event: this_early10 = 0 this_early20 = 0 # Data cleaning if dcmask>0: dcapplied = event.GetDataCleaningFlags().GetApplied(0).GetULong64_t(0) dcflagged = event.GetDataCleaningFlags().GetFlags(0).GetULong64_t(0) dcpass = ((dcapplied & dcmask) & dcflagged) == (dcapplied & dcmask) if not dcpass: continue # Fill the PMT info event_pos = event_vtx.GetPosition() for iPMT in range(pmts.GetNormalCount()): one_pmt = pmts.GetNormalPMT(iPMT) pmtid = int(one_pmt.GetID()) if remove_bad_pmts: if one_pmt.GetCrate() == 8 and one_pmt.GetCard() == 9: continue light_path.CalcByPosition(event_pos, pmt_info.GetPosition(pmtid)) inner_av_distance = light_path.GetDistInInnerAV() av_distance = light_path.GetDistInAV() water_distance = light_path.GetDistInWater() transit_time = group_velocity.CalcByDistance(inner_av_distance, av_distance, water_distance) time_residual = one_pmt.GetTime() - event_vtx.GetTime() - transit_time tbin = np.digitize(time_residual, time_edges)-1 # Getting the rejection probability if time_residual < -10 and time_residual > -100: this_early10 = 1 if time_residual < -20 and time_residual > -75: this_early20 = 1 # Filling the histogram if tbin >= 0 and tbin < nbins: all_toa[pmtid, tbin] += 1 qpdt = event.GetClassifierResult('QPDT:waterFitter').GetClassification('NHits_early') if qpdt > 0: qpdt_flagged += 1 this_file_qpdt += 1 # Summing up the rejection probability ev_earlyhit10 += this_early10 ev_earlyhit20 += this_early20 ev_counter += 1 this_file_ev += 1 if ev_counter%1000 ==0: print 'Counter ', ev_counter if ev_counter == max_ev: break_all = True break if break_all: break if break_all: break if this_file_ev > 0: print '\n\n *** File: ', one_file.split('/')[-1] print 'QPDT this file rej', this_file_qpdt*1./this_file_ev print 'QPDT global rejection', qpdt_flagged*1./ev_counter, '\n' reader.close() # After I'm done with one file, save if len(outfile)>0: if os.path.isfile(outfile): in_data = pickle.load(open(outfile)) in_data['toa'] += all_toa in_data['events'] += ev_counter in_data['ev_early10'] += ev_earlyhit10 in_data['ev_early20'] += ev_earlyhit20 in_data['qpdt_flagged'] += qpdt_flagged pickle.dump(in_data, open(outfile, 'wb'), protocol=2) else: pickle.dump({'time_edges':time_edges, 'toa':all_toa, 'events':ev_counter, 'ev_early10':ev_earlyhit10, 'ev_early20':ev_earlyhit20, 'qpdt_flagged':qpdt_flagged}, open(outfile, 'wb'), protocol=2) else: #except: print 'Could not open file! skipping it for now...' try: reader.close() except: print 'No reader closed' return time_edges, all_toa, ev_counter print 'Done with all the files!'
class DataCorrections: """Class to set all correction variables to be applied to data To be used after the database is loaded but before loop over the root file The fibre position and direction have to be known (see FibreHandling class). Calculates the delay due to the trigger time and fills PMT ID histogram for multiple hits correction before analysis loop is started. Args: reader (RAT DSReader) : Iterator over the RAT::DS objects stored in a file passed to the reader Attributes: variables shared by all instances: pmt_prop (RAT PMT properties) : data base of the protperties of the SNO+ PMTs LightPath (RAT LightPath class) : calculates light path distances between points within the SNO+ detector groupVelTime (RAT GroupVelocity class) : calculates the total transit time of particles using group velocities variables unique to each instance: r (RAT DSReader) : data structure reader beam_time_mean (float) : time the direct beam light arrives in PMTs pmtid (TH1D) : histogram of hits vs the PMT ID the hit was registered in """ pmt_prop = rat.utility().GetPMTInfo() LightPath = rat.utility().GetLightPathCalculator() groupVelTime = rat.utility().GetGroupVelocity() def __init__(self, reader): self.r = reader self.beam_time_mean = 0.0 self.pmtid = ROOT.TH1D("pmtid", "pmtid", 10000, 0.0, 10000.0) def fit_beam_time(self, sourcepos, sourcedir): """ Function to calculate the time the direct light is detected Args: sourcepos (TVector3) : vector of the position of the fibre in the detector sourcedir (TVector3) : direction vector the fibre is pointed at Returns: beam_time_mean (float) : time the direct light arrives in PMT Loops over all PMT hits and gets the time the PMT was hit and calculates the angle of the PMT with respect to the fibre direction. For all PMT hits within a certain angle (considered as direct beam light) a time residual histogram is filled (time residual = PMT hit time - tansit time). The mean of this distribution is returned as self.beam_time_mean """ tres = ROOT.TH1D("tres", "", 500, 0, 500) #loop through file for ievent in range(0, self.r.GetEntryCount()): ds = self.r.GetEntry(ievent) for iev in range(ds.GetEVCount()): ev = ds.GetEV(iev) #get all PMTs in event pmts = ev.GetCalPMTs() for ipmt in range(0, pmts.GetCount()): pmt_cal = pmts.GetPMT(ipmt) pmt_id = pmt_cal.GetID() pmt_time = pmt_cal.GetTime() pmtpos = self.pmt_prop.GetPosition(pmt_id) #only consider PMTs with valid timing if pmt_time > 0: #calculate transit time of photon to PMT self.LightPath.CalcByPosition(sourcepos, pmtpos) PathTime = self.groupVelTime.CalcByDistance( self.LightPath.GetDistInScint(), self.LightPath.GetDistInAV(), self.LightPath.GetDistInWater()) #calculate angle of PMT with respect to fibre position pmtdir = (pmtpos - sourcepos) alpha_mc_rad = math.acos( (sourcedir * pmtdir) / (sourcedir.Mag() * pmtdir.Mag())) if alpha_mc_rad <= (13.5 / 180.) * math.pi: tres.Fill(pmt_time - PathTime) c1 = ROOT.TCanvas("c1", "c1", 1) c1.SetLogy(1) tres.Draw() max_bin = tres.GetBinCenter(tres.GetMaximumBin()) f1 = ROOT.TF1("f1", "gaus", max_bin - 20, max_bin + 20) tres.Fit(f1, "R") self.beam_time_mean = f1.GetParameter(1) c1.Close() return self.beam_time_mean def mh_corr(self): """ Function to fill PMT ID histogram to carry out multiple hits correction Returns: pmtid (TH1D) : histogram of hits vs the PMT ID the hit was registered in """ #loop through file for ievent in range(0, self.r.GetEntryCount()): ds = self.r.GetEntry(ievent) #loop through events for iev in range(ds.GetEVCount()): ev = ds.GetEV(iev) #run over pmts pmts = ev.GetCalPMTs() for ipmt in range(pmts.GetCount()): pmt_cal = pmts.GetPMT(ipmt) pmt_id = pmt_cal.GetID() self.pmtid.Fill(pmt_id) return self.pmtid
def PlotPMTAngularResponseInternals(material): # Select which energies to use based on the material in the detector energies = [] if material == "lightwater_sno": energies = WaterEnergies else: energies = ScintEnergies hResponseLP = ROOT.TH1D("hResponseLP", "PMT response as function of lp angle", len(angularValues), angularArray) hHitsLP = ROOT.TH1D("hHitsLP", "PMT hits as function of lp angle", len(angularValues), angularArray) hResponseMC = ROOT.TH1D("hResponseMC", "PMT response as function of mc angle", len(angularValues), angularArray) hHitsMC = ROOT.TH1D("hHitsMC", "PMT hits as function of mc angle", len(angularValues), angularArray) hResponseOptics = ROOT.TH1D("hResponseOptics", "PMT response from Optics", len(angularValues), angularArray) hResponseMCandOptics = ROOT.TH1D( "hResponseMCandOptics", "PMT response from Optics with MC for tail", len(angularValues), angularArray) energy = 5.0 # Read in ROOT files reader = RAT.DU.DSReader(material + "_E=" + str(int(energy * 1000)) + "keV_sf=0.root") for subfile in range(1, subfiles): infileName = material + "_E=" + str(int( energy * 1000)) + "keV_sf=" + str(int(subfile)) + ".root" print infileName reader.Add(infileName) # Loop through events for ievent in range(0, reader.GetEntryCount()): if ievent % 100 == 0: print "PMTAngularResponse:: " + str(ievent) + " : " + str( reader.GetEntryCount()) ds = reader.GetEntry(ievent) light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() mc = ds.GetMC() # Get MC event position and time initialPosition = mc.GetMCParticle(0).GetPosition() initialTime = mc.GetMCParticle(0).GetTime() # Ignore events beyond inner AV if initialPosition.Mag() > 6005.0: continue # Loop through PMTs for iPMT in range(0, mc.GetMCPMTCount()): mcPMT = mc.GetMCPMT(iPMT) # Only consider "normal" PMTs pmtID = mcPMT.GetID() if pmt_info.GetType(pmtID) != pmt_info.NORMAL: continue # Calculate transit time and angle with PMT as calculated by light_path light_path.CalcByPosition(initialPosition, pmt_info.GetPosition(mcPMT.GetID())) light_path.CalculateSolidAngle( pmt_info.GetDirection(mcPMT.GetID()), 0) inner_av_distance = light_path.GetDistInInnerAV() av_distance = light_path.GetDistInAV() water_distance = light_path.GetDistInWater() transit_time = group_velocity.CalcByDistance( inner_av_distance, av_distance, water_distance) lp_costheta = -1.0 * light_path.GetCosThetaAvg() lp_angle = ROOT.TMath.ACos(lp_costheta) * ROOT.TMath.RadToDeg() # PMT direction in PMT local coordinates pmtDirection = ROOT.TVector3(0.0, 0.0, -1.0) # Loop through photons for iPhoton in range(0, mcPMT.GetMCPhotonCount()): mcPhoton = mcPMT.GetMCPhoton(iPhoton) # Calculate time residual lastTime = mcPhoton.GetInTime() time_residual = lastTime - transit_time - initialTime # Check in position not beyond radius of PMT xyRadius = math.sqrt(mcPhoton.GetInPosition().X() * mcPhoton.GetInPosition().X() + mcPhoton.GetInPosition().Y() * mcPhoton.GetInPosition().Y()) if mcPhoton.GetInPosition().Z() < 132.0 or xyRadius > 137.0: continue # Get true photon incident angle with PMT mc_angle = ROOT.TMath.ACos(mcPhoton.GetInDirection().Dot( pmtDirection)) * ROOT.TMath.RadToDeg() # Fill if photon is prompt if time_residual > -10 and time_residual < 8: hHitsLP.Fill(lp_angle) hHitsMC.Fill(mc_angle) # Fill if photon results in a photoelectron if mcPhoton.GetFate() == mcPhoton.ePhotoelectron: hResponseLP.Fill(lp_angle) hResponseMC.Fill(mc_angle) hResponseMCandOptics.Fill(mc_angle) # Divide to find fraction of prompt photons resulting in a photoelectron hHitsLP.Sumw2() hResponseLP.Sumw2() hHitsMC.Sumw2() hResponseMC.Sumw2() hResponseMCandOptics.Sumw2() hResponseLP.Divide(hHitsLP) hResponseMC.Divide(hHitsMC) hResponseMCandOptics.Divide(hHitsMC) # The output of an optics fit for the PMT angular response - hard coded for now!!!!! optics_values = [ 1, 1.00116, 1.00281, 1.00426, 1.00861, 1.01179, 1.01551, 1.01972, 1.02457, 1.02928, 1.03309, 1.03827, 1.04423, 1.04904, 1.056, 1.06018, 1.06401, 1.06884, 1.07541, 1.08086, 1.08649, 1.09198, 1.09905, 1.10051, 1.10806, 1.111, 1.11984, 1.12772, 1.13161, 1.13924, 1.13904, 1.14615, 1.14351, 1.14567, 1.1315, 1.14798, 1.12914, 1.12197, 1.12262, 1.11159, 1.11434, 1.11812, 1.12082, 1.10308, 1.07932, 1.09548, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] optics_errors = [ 0, 0.000545447, 0.000508987, 0.000516206, 0.000522549, 0.000993215, 0.000962659, 0.000909435, 0.000880224, 0.00086217, 0.000823764, 0.000812432, 0.00080622, 0.000805476, 0.00080843, 0.000835871, 0.000862054, 0.000897842, 0.000939236, 0.000964726, 0.000969903, 0.00097783, 0.000985927, 0.00103344, 0.00107909, 0.00114315, 0.00124654, 0.00131553, 0.00133006, 0.00135414, 0.0013889, 0.00145807, 0.00151927, 0.00164041, 0.00173792, 0.00186205, 0.00186791, 0.0019548, 0.00203682, 0.00210602, 0.00223987, 0.00236149, 0.00245823, 0.00264676, 0.00323336, 0.00568283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] for index, value in enumerate(optics_values): hResponseOptics.SetBinContent(index + 1, value) for index, error in enumerate(optics_errors): hResponseOptics.SetBinError(index + 1, error) # Get values by which to scale # Use average of last five bins to scale the MC tail to optics fit hResponseLP_first_value = hResponseLP.GetBinContent(1) hResponseMC_first_value = hResponseMC.GetBinContent(1) hResponseMCandOptics_av_value = hResponseMCandOptics.GetBinContent(39) for i in range(40, 44): hResponseMCandOptics_av_value += hResponseMCandOptics.GetBinContent(i) hResponseMCandOptics_av_value /= 5.0 optics_av_value = optics_values[38] for i in range(39, 43): optics_av_value += optics_values[i] optics_av_value /= 5.0 # Scale responses to start at 1 and so the MC and optics fit overlap hResponseLP.Scale(1.0 / hResponseLP_first_value) hResponseMC.Scale(1.0 / hResponseMC_first_value) hResponseMCandOptics.Scale(optics_av_value / hResponseMCandOptics_av_value) # Replace MC values with optics fit for first 43 bins for bin in range(1, 44): hResponseMCandOptics.SetBinContent(bin, optics_values[bin - 1]) for bin in range(1, 44): hResponseMCandOptics.SetBinError(bin, optics_errors[bin - 1]) canvas = ROOT.TCanvas() hResponseLP.GetXaxis().SetTitle("angle [degrees]") hResponseLP.SetTitle("PMT angular response") hResponseLP.SetLineColor(ROOT.kRed + 1) hResponseLP.SetMinimum(0.0) hResponseLP.Draw() hResponseMC.SetLineColor(ROOT.kGreen + 1) hResponseMC.Draw("SAME") hResponseOptics.SetLineColor(ROOT.kBlue + 1) hResponseOptics.Draw("SAME") hResponseMCandOptics.SetLineColor(ROOT.kBlack) hResponseMCandOptics.Draw("SAME") t1 = ROOT.TLegend(0.7, 0.7, 0.88, 0.88) t1.AddEntry(hResponseLP, "mc: light path", "l") t1.AddEntry(hResponseMC, "mc: truth", "l") t1.AddEntry(hResponseOptics, "optics fit", "l") t1.AddEntry(hResponseMCandOptics, "optics fit w/ MC tail", "l") t1.SetLineColor(ROOT.kWhite) t1.SetFillColor(ROOT.kWhite) t1.Draw() canvas.Update() canvas.SaveAs("PMTAngularResponseInternals.eps") canvas.SaveAs("PMTAngularResponseInternals.root") raw_input("Press 'Enter' to exit")
# Open file and read fibre = "FT044A" dataPath = "./results/reflections/" fname = "%s%s_pmts.root" % (dataPath, fibre) # Create root file. #r = sf.create_root_file("./results/slices_%s.root" % (fibre)) # Load rat defualts for fibre pos stuff ROOT.RAT.DB.Get().LoadDefaults() ROOT.RAT.DB.Get().Load("pmt/airfill2.ratdb") ROOT.RAT.DB.Get().Load("geo/snoplus.geo") ROOT.RAT.DU.Utility.Get().BeginOfRun() fibre_pos = ROOT.RAT.DB.Get().GetLink("FIBRE", fibre) pmt_info = rat.utility().GetPMTInfo() f = ROOT.TFile(fname) hists, graphs = {}, {} for key in f.GetListOfKeys(): pmt_no = int(''.join(x for x in key.GetName() if x.isdigit())) if len(key.GetName().split("_")) == 2: hists[pmt_no] = f.Get(key.GetName()) graph_name = "%s_ordered" % key.GetName() print key.GetName(), graph_name graphs[pmt_no] = f.Get(graph_name) #plot_slices(hists, 1., fibre_pos) savePath = "./results/pmt_plots/%s/" % fibre r1 = sf.create_root_file("%s/pmts.root" % (savePath)) plot_interesting_pmts(hists, graphs, r1, savePath, c1)
def GetTimeResidsVector(infileName, numberOfBins): numberOfPMTs = 0.0 timeResidsHist = ROOT.TH1D("timeResidsHist", "timeResidsHist", numberOfBins, minTimeResid, maxTimeResid) effectiveVelocity = rat.utility().GetEffectiveVelocity() lightPath = rat.utility().GetLightPathCalculator() pmtInfo = rat.utility().GetPMTInfo() for ds, run in rat.dsreader(infileName): if ds.GetEVCount() == 0: continue for j in range(0, ds.GetEVCount()): ev = ds.GetEV(j) if not ev.FitResultExists("scintFitter"): continue if not ev.GetFitResult("scintFitter").GetValid(): continue if not ev.GetFitResult("scintFitter").GetVertex( 0).ContainsPosition(): continue vertPos = ev.GetFitResult("scintFitter").GetVertex(0).GetPosition() if (vertPos.Mag() < fidVolLow) or (vertPos.Mag() >= fidVolHigh): continue vertTime = ev.GetFitResult("scintFitter").GetVertex(0).GetTime() calibratedPMTs = ev.GetCalPMTs() if (calibratedPMTs.GetCount() < 10): continue timeResidsList = [] for k in range(0, calibratedPMTs.GetCount()): pmtPos = pmtInfo.GetPosition(calibratedPMTs.GetPMT(k).GetID()) pmtTime = calibratedPMTs.GetPMT(k).GetTime() lightPath.CalcByPosition(vertPos, pmtPos) distInInnerAV = lightPath.GetDistInInnerAV() distInAV = lightPath.GetDistInAV() distInWater = lightPath.GetDistInWater() flightTime = effectiveVelocity.CalcByDistance( distInInnerAV, distInAV, distInWater) timeResid = pmtTime - flightTime - vertTime timeResidsList.append(timeResid) numberOfPMTs += 1.0 timeResidsList.sort() for t in timeResidsList: timeResidsHist.Fill(t - timeResidsList[9]) timeResidsHist.Scale(1.0 / numberOfPMTs) timeResidsVector = [] for l in range(1, timeResidsHist.GetNbinsX() + 1): timeResidsVector.append(timeResidsHist.GetBinContent(l)) return timeResidsVector
def transcribe_hits(input, start_evt): evt_count = 0 current_clock = clock(0) n_qe_values = MAX_PRESSURE + 1 photocoverage_scale = list(np.linspace(0.1413, 0.1016, 9)) feature_map_collections = np.zeros( ((((len(photocoverage_scale), n_qe_values, 1, current_clock.clock_size(), ROWS, COLS))))) pmt_info = rat.utility().GetPMTInfo() for ds, run in tqdm(rat.dsreader(str(input))): if evt_count != start_evt: evt_count += 1 continue rmc = ds.GetMC() particleNum = rmc.GetMCParticleCount() nevC = ds.GetEVCount() #Remove Retriggers if nevC > 1: nevC = 1 # #Read PMT DAQ information # for iev in range(0, nevC): # calibrated_pmts = ds.GetMCEV(iev).GetMCHits() # for ipmt in range(0, calibrated_pmts.GetNormalCount()): # pmt_cal = calibrated_pmts.GetNormalPMT(ipmt) # pmt_pos = pmt_info.GetPosition(pmt_cal.GetID()) # if not (pmt_cal.GetCrossTalkFlag()): # pmt_hit.append([pmt_pos.x(), pmt_pos.y(), pmt_pos.z()]) # hit_time.append(pmt_cal.GetTime()) # pmt_hit = np.array(pmt_hit) # hit_time = np.array(hit_time) # current_clock = set_clock(hit_time) #Start Optical Photon Tracking for iev in range(0, nevC): trackIDs = rmc.GetMCTrackIDs() pmt_hit = [] hit_time = [] #Read MC PMT Info pmts = rmc.GetMCPMTCount() for ipmt in range(pmts): mcpmt = rmc.GetMCPMT(ipmt) mcpes = mcpmt.GetMCPECount() mcpmt_pos = pmt_info.GetPosition(mcpmt.GetID()) pos_vec = [mcpmt_pos.x(), mcpmt_pos.y(), mcpmt_pos.z()] for ipe in range(mcpes): mcpe = mcpmt.GetMCPE(ipe) pmt_hit.append(pos_vec) hit_time.append(mcpe.GetCreationTime()) pmt_hit = np.array(pmt_hit) hit_time = np.array(hit_time) current_clock = set_clock(hit_time) #Start Tracking Individual Photon for trackID in trackIDs: mctrack = rmc.GetMCTrack(trackID) detected_photon = False if (mctrack.GetParticleName() == "opticalphoton"): pos = mctrack.GetLastMCTrackStep().GetPosition() if pos.Mag() < MIN_PMT_RADIUS: continue input_time = mctrack.GetLastMCTrackStep().GetGlobalTime() pmt_index, detector_radius, pmt_angle = pmt_setup(pos) pmt_radius = (PMT_POSITION[pmt_index][0]**2 + PMT_POSITION[pmt_index][1]**2 + PMT_POSITION[pmt_index][2]**2)**0.5 if detector_radius < pmt_radius: continue else: # #Matching Photon Tracking information with detected PMT DAQ information based on Position and Time # try: # hit_index = np.where(pmt_hit == PMT_POSITION[pmt_index])[0] # current_pmt_index = hit_index # if not len(hit_index) == 0: # detected_photon = True # if len(hit_index) > 1: # abs_time_diff = np.array([abs(time - input_time) for time in hit_time[hit_index]]) # current_pmt_index = hit_index(np.argmin(abs_time_diff)) # input_time = hit_time(current_pmt_index) # except: # print "PMT Allocation Failed! Using Truth Position of photon hit to Allocate PMT" #Writing Photon Hit into Pressure Map with various pressures #print(detected_photon) for pressure_pc in photocoverage_scale: if (pmt_allocator(pmt_angle, detector_radius, pressure_pc)): row, col = xyz_to_row_col( PMT_POSITION[pmt_index][0], PMT_POSITION[pmt_index][1], PMT_POSITION[pmt_index][2]) for pressure_pe in range(0, n_qe_values): if (detected_photon) or random_decision( MAX_PRESSURE - pressure_pe): time_index = current_clock.tick( smearing_time(input_time)) feature_map_collections[ photocoverage_scale. index(pressure_pc)][pressure_pe][ 0][time_index][row][col] += 1.0 evt_count += 1 # dim1, dim2, dim3, dim4, dim5, dim6 = feature_map_collections.shape # lst = np.zeros((dim3,dim4,1)) # input_name = os.path.basename(input).split('.')[0] # data_path = os.path.join(outputdir, "data_%s" % (input_name)) # indices_path = os.path.join(outputdir, "indices_%s" % (input_name)) # indptr_path = os.path.join(outputdir, "indptr_%s" % (input_name)) # data = lst.tolist() # indices = lst.tolist() # indptr = lst.tolist() # for qcindex, qc in enumerate(feature_map_collections): # for qeindex, qe in enumerate(qc): # currentEntry = qe # if (qe.max() != 0): # currentEntry = np.divide(qe, (1.2 * qe.max())) # for evt_index, evt in enumerate(currentEntry): # for time_index, maps in enumerate(evt): # sparse_map = sparse.csr_matrix(maps) # data[evt_index][time_index] = map(float, sparse_map.data) # indices[evt_index][time_index] = map(int, sparse_map.indices) # indptr[evt_index][time_index] = map(int, sparse_map.indptr) # qcqename = str(qcindex) + '_' + str(qeindex) + '.json' # savefile(data, 'data', qcqename, data_path) # savefile(indices, 'indices', qcqename, indices_path) # savefile(indptr, 'indptr', qcqename, indptr_path) return feature_map_collections
def PromptNhits(material): # Select which energies and time residual window to use based on the material in the detector energy = 0.0 time_residual_window = [] subfiles = 0 if material == "lightwater_sno": energy = WaterEnergy time_residual_window = WaterTimeResidualWindow subfiles = WaterSubfiles else: energy = ScintEnergy time_residual_window = ScintTimeResidualWindow subfiles = ScintSubfiles # Create histogram bins = 0 bin_min = 0.0 bin_max = 0.0 if material == "lightwater_sno": bins = 100 bin_min = 0.0 bin_max = 20.0 else: bins = 200 bin_min = 0.0 bin_max = 600.0 histogram = ROOT.TH1D("PromptNhits_" + str(int(energy * 1000)), "Prompt Nhits", bins, bin_min, bin_max) # Read in ROOT files reader = RAT.DU.DSReader(material + "_E=" + str(int(energy * 1000)) + "keV_sf=0.root") for sf in xrange(1, subfiles): infileName = material + "_E=" + str(int( energy * 1000)) + "keV_sf=" + sf + ".root" print infileName reader.Add(infileName) # Fill appropriate histograms with prompt hits for ievent in range(0, reader.GetEntryCount()): if ievent % 100 == 0: print "PromptNhitsVs:: " + str(ievent) + " : " + str( reader.GetEntryCount()) ds = reader.GetEntry(ievent) light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() mc = ds.GetMC() # Get MC event info eventPosition = mc.GetMCParticle(0).GetPosition() kineticEnergy = mc.GetMCParticle(0).GetKineticEnergy() # Loop through events for iev in range(0, ds.GetEVCount()): if iev != 0: continue ev = ds.GetEV(iev) calibratedPMTs = ev.GetCalPMTs() # Check fit worked if False in (ev.DefaultFitVertexExists(), ev.GetDefaultFitVertex().ContainsPosition(), ev.GetDefaultFitVertex().ValidPosition(), ev.GetDefaultFitVertex().ContainsTime(), ev.GetDefaultFitVertex().ValidTime()): continue # Get fitted event time eventTime = ev.GetDefaultFitVertex().GetTime() promptNhits = 0 # Loop through calibrated PMTs for ipmt in range(0, calibratedPMTs.GetCount()): pmtCal = calibratedPMTs.GetPMT(ipmt) # Calculate time residual light_path.CalcByPosition(eventPosition, pmt_info.GetPosition(pmtCal.GetID())) distInInnerAV = light_path.GetDistInInnerAV() distInAV = light_path.GetDistInAV() distInWater = light_path.GetDistInWater() transitTime = group_velocity.CalcByDistance( distInInnerAV, distInAV, distInWater) timeResidual = pmtCal.GetTime() - transitTime - eventTime if timeResidual > time_residual_window[ 0] and timeResidual < time_residual_window[1]: promptNhits += 1 # Fill with number of prompt Nhits histogram.Fill(promptNhits / kineticEnergy) # Calculate histogram mean value tolerance = 10 lowBin = histogram.FindFirstBinAbove(0.0) lowBin = lowBin - tolerance highBin = histogram.FindLastBinAbove(0.0) highBin = highBin + tolerance if lowBin < 1: lowBin = 1 if highBin > histogram.GetNbinsX(): highBin = histogram.GetNbinsX() gaussFit = ROOT.TF1("gaus", "gaus", histogram.GetBinCenter(lowBin), histogram.GetBinCenter(highBin)) histogram.Fit(gaussFit, "RQN") return gaussFit.GetParameter(1), histogram
from core import stability_funcs as sf import time import sys if __name__ == "__main__": # Reset all roor stuff ROOT.gROOT.Reset() # Make canvas and TFile c1 = ROOT.TCanvas("c1","c1",600,400); run = "100Hz" r = sf.create_root_file("results/%s_triggers.root" % run) # File stuff file_name = "/home/el230/SNO+/rat_data_scripts/stability/%s/*.root" % (run) print file_name # Analysis begins utils = rat.utility() #print utils.GetTrigBits().DumpNames() sys.exit() trig_hist= sf.plot_trigger_int(file_name) trig_hist.Draw("") trig_hist.Write() c1.Update() print rat.dureader(fname).TrigBits
def PlotHitTimeResiduals(material): # Select which time residual window to use based on the material in the detector time_residual_window = [] subfiles = 0 energy = 0.0 time_window = [] bins = 0 if material == "lightwater_sno": time_residual_window = WaterTimeResidualWindow subfiles = WaterSubfiles energy = WaterEnergy time_window = [-20.0, 40.0] bins = 60 else: time_residual_window = ScintTimeResidualWindow subfiles = ScintSubfiles energy = ScintEnergy time_window = [-200.0, 400.0] bins = 600 hit_time_residuals = ROOT.TH1D("hHitTimeResidualsMC", "Hit time residuals using the MC position", bins, time_window[0], time_window[1]) hit_time_residuals.SetDirectory(0) # Read in ROOT files reader = RAT.DU.DSReader(material + "_P=" + str(int(0.0)) + "mm_E=" + str(int(energy * 1000)) + "keV_sf=0.root") for sf in range(1, subfiles): infileName = material + "_P=" + str(int(0.0)) + "mm_E=" + str( int(energy * 1000)) + "keV_sf=" + str(int(sf)) + ".root" print infileName reader.Add(infileName) for ievent in range(0, reader.GetEntryCount()): if ievent % 100 == 0: print "PlotHitTimeResiduals:: " + str(ievent) + " : " + str( reader.GetEntryCount()) ds = reader.GetEntry(ievent) light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() event_position = ds.GetMC().GetMCParticle( 0).GetPosition() # At least 1 is somewhat guaranteed for iev in range(0, ds.GetEVCount()): ev = ds.GetEV(iev) # Check fit worked if not ev.DefaultFitVertexExists() or not ev.GetDefaultFitVertex( ).ContainsTime() or not ev.GetDefaultFitVertex().ValidTime(): continue event_time = ev.GetDefaultFitVertex().GetTime() calibrated_pmts = ds.GetEV(iev).GetCalPMTs() for ipmt in range(0, calibrated_pmts.GetCount()): pmt_cal = calibrated_pmts.GetPMT(ipmt) light_path.CalcByPosition( event_position, pmt_info.GetPosition(pmt_cal.GetID())) inner_av_distance = light_path.GetDistInInnerAV() av_distance = light_path.GetDistInAV() water_distance = light_path.GetDistInWater() transit_time = group_velocity.CalcByDistance( inner_av_distance, av_distance, water_distance) # Assumes 400nm photon hit_time_residuals.Fill(pmt_cal.GetTime() - transit_time - event_time) hit_time_residuals.GetYaxis().SetTitle("Count per 1 ns bin") hit_time_residuals.GetXaxis().SetTitle("Hit time residual [ns]") hit_time_residuals.SetTitle("Hit Time Residuals") hit_time_residuals.SetLineColor(ROOT.kBlue + 2) canvas = ROOT.TCanvas() canvas.SetLogy() hit_time_residuals.Draw() canvas.Update() #top = canvas.GetFrame().GetY2() #bottom = canvas.GetFrame().GetY1() top = canvas.GetUymax() bottom = canvas.GetUymin() line1 = ROOT.TLine(time_residual_window[0], math.pow(10.0, bottom), time_residual_window[0], math.pow(10.0, top)) line2 = ROOT.TLine(time_residual_window[1], math.pow(10.0, bottom), time_residual_window[1], math.pow(10.0, top)) line1.SetLineColor(ROOT.kBlack) line2.SetLineColor(ROOT.kBlack) line1.SetLineWidth(2) line2.SetLineWidth(2) line1.Draw() line2.Draw() canvas.Update() canvas.SaveAs("HitTimeResiduals_" + material + ".eps") raw_input("Press 'Enter' to exit")
import ROOT, rat import os, sys, pickle indir = '/home/jp/projects/snoplus/laserball_calibration/all_runs' outdir = '/home/jp/projects/snoplus/laserball_calibration/all_runs_pckl' du = rat.utility() du.LoadDBAndBeginRun() def wavelengthToEnergy(wavelength): # wl in nm hc = 1.2398 #eV * um return 1E-3 * hc / wavelength # in MeV light_path = du.GetLightPathCalculator() shadow_path = du.GetShadowingCalculator() laserE = wavelengthToEnergy(420.) # This won't matter for direct paths def isPMTshadowed(source_position, pmt_position, tolerance=0.): shadow_path.SetAllGeometryTolerances(tolerance) light_path.CalcByPosition(ROOT.TVector3(source_position), ROOT.TVector3(pmt_position), laserE, 0.) return shadow_path.CheckForShadowing(light_path) def simplifySOCfiles(): file_list = os.listdir(indir) for file_index, file_name in enumerate(file_list):
def PromptNhitsVsEnergy(material): # Select which energies and time residual window to use based on the material in the detector energies = [] time_residual_window = [] fitter = "" if material == "lightwater_sno": energies = WaterEnergies time_residual_window = WaterTimeResidualWindow fitter = "waterResult" else: energies = ScintEnergies time_residual_window = ScintTimeResidualWindow fitter = "scintFitter" nhitsTable = [] histograms = [] # Read in ROOT files reader = RAT.DU.DSReader(material + "_P=" + str(int(0.0)) + "mm_E=" + str(int(energies[0] * 1000)) + "keV_sf=0.root") for energy in energies: if energy == energies[0]: continue infileName = material + "_P=" + str(int(0.0)) + "mm_E=" + str(int(energy * 1000)) + "keV_sf=0.root" print infileName reader.Add(infileName) # Create vector of histograms bins = 0 bin_min = 0.0 bin_max = 0.0 if material == "lightwater_sno": bins = 150 bin_min = 0.0 bin_max = 300.0 else: bins = 2500 bin_min = 0.0 bin_max = 5000.0 for energy in energies: histograms.append(ROOT.TH1D("PromptNhits_" + str(int(energy * 1000)), "Prompt Nhits", bins, bin_min, bin_max)) # Fill appropriate histograms with prompt hits for ievent in range(0, reader.GetEntryCount()): if ievent % 100 == 0: print "PromptNhitsVsEnergy:: " + str(ievent) + " : " + str(reader.GetEntryCount()) ds = reader.GetEntry(ievent) light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() mc = ds.GetMC() kineticEnergy = mc.GetMCParticle(0).GetKineticEnergy() # Get MC event info eventPosition = mc.GetMCParticle(0).GetPosition() # Loop through events for iev in range(0, ds.GetEVCount()): if iev != 0: continue ev = ds.GetEV(iev) calibratedPMTs = ev.GetCalPMTs(); # Check fit worked if False in (ev.FitResultExists(fitter), ev.GetFitResult(fitter).GetVertex(0).ContainsPosition(), ev.GetFitResult(fitter).GetVertex(0).ValidPosition(), ev.GetFitResult(fitter).GetVertex(0).ContainsTime(), ev.GetFitResult(fitter).GetVertex(0).ValidTime()): continue # Get fitted event time eventTime = ev.GetFitResult(fitter).GetVertex(0).GetTime() promptNhits = 0 # Loop through calibrated PMTs for ipmt in range(0, calibratedPMTs.GetCount()): pmtCal = calibratedPMTs.GetPMT( ipmt ) # Calculate time residual light_path.CalcByPosition( eventPosition, pmt_info.GetPosition( pmtCal.GetID() ) ) distInInnerAV = light_path.GetDistInInnerAV() distInAV = light_path.GetDistInAV() distInWater = light_path.GetDistInWater() transitTime = group_velocity.CalcByDistance( distInInnerAV, distInAV, distInWater ) timeResidual = pmtCal.GetTime() - transitTime - eventTime if timeResidual > time_residual_window[0] and timeResidual < time_residual_window[1]: promptNhits += 1; # Fill with number of prompt Nhits histograms[energies.index(round(kineticEnergy,1))].Fill( promptNhits ) # Fill list with histogram mean values for Histogram in histograms: tolerance = 10 lowBin = Histogram.FindFirstBinAbove(0.0) lowBin = lowBin - tolerance highBin = Histogram.FindLastBinAbove(0.0) highBin = highBin + tolerance if lowBin < 1: lowBin = 1 if highBin > Histogram.GetNbinsX(): highBin = Histogram.GetNbinsX() gaussFit = ROOT.TF1("gaus", "gaus", Histogram.GetBinCenter(lowBin), Histogram.GetBinCenter(highBin)) Histogram.Fit(gaussFit, "RQN") # Store mean prompt Nhits in table nhitsTable.append(gaussFit.GetParameter(1)) del gaussFit return nhitsTable, histograms
def RayleighAttenuationProb(material): # Select which energies to use based on the material in the detector energies = [] if material == "lightwater_sno": energies = WaterEnergies else: energies = ScintEnergies attenuationProb = [] mcphotonTrackIDs = [] mcphotonTimes = [] mcphotonPositions = [] hRayleighTotal = ROOT.TH2D("hRayleighTotal", "hRayleighTotal", len(radialValues), radialArray, len(uDotpValues), uDotpArray) hRayleighLate = ROOT.TH2D("hRayleighLate", "hRayleighLate", len(radialValues), radialArray, len(uDotpValues), uDotpArray) energy = 5.0 # Read in ROOT files reader = RAT.DU.DSReader(material + "_E=" + str(int(energy * 1000)) + "keV_sf=0.root") for subfile in range(1, subfiles): infileName = material + "_E=" + str(int( energy * 1000)) + "keV_sf=" + str(int(subfile)) + ".root" print infileName reader.Add(infileName) # Loop through events for ievent in range(0, reader.GetEntryCount()): if ievent % 100 == 0: print "RayleighAttenuationProb:: " + str(ievent) + " : " + str( reader.GetEntryCount()) ds = reader.GetEntry(ievent) light_path = rat.utility().GetLightPathCalculator() group_velocity = rat.utility().GetGroupVelocity() pmt_info = rat.utility().GetPMTInfo() mc = ds.GetMC() # Ignore events beyond inner AV zeroPosition = mc.GetMCParticle(0).GetPosition() if zeroPosition.Mag() > 6005.0: continue # Store photon information from PMT hits for ipmt in range(0, mc.GetMCPMTCount()): mcpmt = mc.GetMCPMT(ipmt) mcpmtid = mcpmt.GetID() for iphoton in range(0, mcpmt.GetMCPhotonCount()): if iphoton != 0: continue mcphoton = mcpmt.GetMCPhoton(iphoton) mcphotonTrackIDs.append(mcphoton.GetPhotonTrackID()) mcphotonTimes.append(mcphoton.GetInTime()) mcphotonPositions.append(pmt_info.GetPosition(mcpmtid)) # Loop through MC tracks for itrack in range(0, mc.GetMCTrackCount()): mctrack = mc.GetMCTrackFromIndex(itrack) # Check if track hit PMT mctrackID = mctrack.GetTrackID() if mctrackID in mcphotonTrackIDs: photonTime = mcphotonTimes[mcphotonTrackIDs.index(mctrackID)] photonPosition = mcphotonPositions[mcphotonTrackIDs.index( mctrackID)] # Only consider optical photons if mctrack.GetPDGCode() != 0: continue initialStep = mctrack.GetMCTrackStep(0) # Only consider Cerenkov photons if initialStep.GetProcess() != "Cerenkov": continue # Want tracks which Rayleigh scattered and then hit a PMT if mctrack.GetSummaryFlag( mctrack.OpRayleigh) and mctrack.GetSummaryFlag( mctrack.HitPMT): # Get initial position, direction and time initialPosition = initialStep.GetPosition() initialDirection = initialStep.GetMomentum().Unit() initialTime = initialStep.GetGlobalTime() # Fill for Rayleigh scattered photons hitting a PMT hRayleighTotal.Fill( math.pow(initialPosition.Mag() / 6005.0, 3.0), initialDirection.Dot(initialPosition.Unit())) # Calculate time residual light_path.CalcByPosition(initialPosition, photonPosition) inner_av_distance = light_path.GetDistInInnerAV() av_distance = light_path.GetDistInAV() water_distance = light_path.GetDistInWater() transit_time = group_velocity.CalcByDistance( inner_av_distance, av_distance, water_distance) time_residual = photonTime - transit_time - initialTime # Fill for Rayleigh scattered photons hitting PMT that are late if time_residual > 8 or time_residual < -10: hRayleighLate.Fill( math.pow(initialPosition.Mag() / 6005.0, 3.0), initialDirection.Dot(initialPosition.Unit())) del mcphotonTrackIDs[:] del mcphotonTimes[:] del mcphotonPositions[:] # Divide to find fraction of Rayleigh scattered photons that are late hRayleighLate.Divide(hRayleighTotal) Attenuation = [] for binj in range(0, len(uDotpValues)): singleuDotpAttenuation = [] for bini in range(0, len(radialValues)): singleuDotpAttenuation.append( hRayleighLate.GetBinContent(bini + 1, binj + 1)) Attenuation.append(singleuDotpAttenuation) del hRayleighLate del hRayleighTotal return Attenuation
def GetCDFVector(energyLow, energyHigh, numberOfBins): numberOfEvents = 0.0 cumuHist = ROOT.TH1D("cumuHist", "cumuHist", numberOfBins, minTimeResid, maxTimeResid) effectiveVelocity = rat.utility().GetEffectiveVelocity() lightPath = rat.utility().GetLightPathCalculator() pmtInfo = rat.utility().GetPMTInfo() for ds, run in rat.dsreader(infileName): if ds.GetEVCount() == 0: continue ev = ds.GetEV(0) if not ev.FitResultExists("scintFitter"): continue if not ev.GetFitResult("scintFitter").GetValid(): continue if not ev.GetFitResult("scintFitter").GetVertex(0).ContainsPosition(): continue vertPos = ev.GetFitResult("scintFitter").GetVertex(0).GetPosition() if (vertPos.Mag() < fidVolLow) or (vertPos.Mag() >= fidVolHigh): continue vertEnergy = ev.GetFitResult("scintFitter").GetVertex(0).GetEnergy() if (vertEnergy < energyLow) or (vertEnergy >= energyHigh): continue vertTime = ev.GetFitResult("scintFitter").GetVertex(0).GetTime() calibratedPMTs = ev.GetCalPMTs() timeResidsHist = ROOT.TH1D("timeResidsHist", "timeResidsHist", numberOfBins, minTimeResid, maxTimeResid) for j in range(0, calibratedPMTs.GetCount()): pmtPos = pmtInfo.GetPosition(calibratedPMTs.GetPMT(j).GetID()) pmtTime = calibratedPMTs.GetPMT(j).GetTime() lightPath.CalcByPosition(vertPos, pmtPos) distInInnerAV = lightPath.GetDistInInnerAV() distInAV = lightPath.GetDistInAV() distInWater = lightPath.GetDistInWater() flightTime = effectiveVelocity.CalcByDistance( distInInnerAV, distInAV, distInWater) timeResid = pmtTime - flightTime - vertTime timeResidsHist.Fill(timeResid) tempHist = ROOT.TH1D("tempHist", "tempHist", numberOfBins, minTimeResid, maxTimeResid) for k in range(1, timeResidsHist.GetNbinsX() + 1): numberOfPMTs = timeResidsHist.Integral(0, k) timeValue = timeResidsHist.GetBinLowEdge(k) tempHist.Fill(timeValue, (numberOfPMTs / calibratedPMTs.GetCount())) cumuHist.Add(cumuHist, tempHist, 1, 1) numberOfEvents += 1.0 del timeResidsHist del tempHist cumuHist.Scale(1.0 / numberOfEvents) cumuVector = [] for l in range(1, cumuHist.GetNbinsX() + 1): cumuVector.append(cumuHist.GetBinContent(l)) return cumuVector
class AngleMeasurement: """Class to define the bins for the histograms used for angular profile measurements. Creates the number of bins and upper bin edges for histograms used to measure the angular profiles of the fibres. The amount of PMTs covered by each bin is specified by the user. The bin width is dependent on the fibre which is measured. Attributes: variables shared by all instances: pmt_prop (RAT PMT properties) : data base of the protperties of the SNO+ PMTs variables unique to each instance: pmt (int) : number of PMTs nbins (int) : number of bins pmt_angle_map (list) : list of two element lists containing [angle, pmt], with angle being the angle of the PMT with respect to the fibre direction and pmt being the PMT number n (int) : variable to define how many PMTs should be covered by each angular bin bin_edges (array) : array to define the upper angular bin edges """ pmt_prop = rat.utility().GetPMTInfo() def __init__(self): self.pmt = 0 self.nbins = 0 self.pmt_angle_map = [] self.n = 0 self.bin_edges = array('d') def get_number_of_pmts(self, n): """Function to get number of PMTs and calculate the number of bins of the histogram. Args: n (int) : number of PMTs which should be covered by each bin Returns: pmt (int) : number of PMTs nbins (int) : number of bins """ self.n = n for ipmt in range(0, self.pmt_prop.GetCount()): pmt_type = self.pmt_prop.GetType(ipmt) if pmt_type == 1: self.pmt += 1 self.nbins = self.pmt / n return self.pmt, self.nbins def create_pmt_angle_map(self, sourcepos, sourcedir): """Function to calculate the angle of each PMT Args: sourcepos (TVector3) : vector of the position of the fibre in the detector sourcedir (TVector3) : direction vector the fibre is pointed at Returns: pmt_angle_map (list) : list assigning a PMT to each angle """ #loop through all pmts for ipmt in range(0, self.pmt + 1): pmtpos = self.pmt_prop.GetPosition(ipmt) pmtdir = pmtpos - sourcepos #get angle of PMT alpha_mc_rad = math.acos( (sourcedir * pmtdir) / (sourcedir.Mag() * pmtdir.Mag())) alpha_mc = math.degrees(alpha_mc_rad) #create a two object list of angle and pmt lcn_angle = [alpha_mc, ipmt] self.pmt_angle_map.append(lcn_angle) #sort list of two object lists by increasing angle self.pmt_angle_map = sorted(self.pmt_angle_map, key=lambda x: (x[0])) return self.pmt_angle_map def get_bin_edges(self): """Function to define the variable angular bin edges of the histograms Returns: bin_edges (array) : array of bin edges Creates self.bin_edges dependend on the number of PMTs self.n covered by each angle from the list self.pmt_angle_map """ #set first entry to 0 self.bin_edges.append(0.0) #set PMT counter num_pmt = 1 #loop through all entries in the list of angles and pmts for i in range(0, len(self.pmt_angle_map) + 1): #if PMT counter smaller than required number of PMTS, add 1 if num_pmt < self.n: num_pmt += 1 #if PMT counter equal to required number of PMTs, reset counter elif num_pmt == self.n: num_pmt = 1 #add equivalent angle to the bin_edges array bin_edge = self.pmt_angle_map[i][0] self.bin_edges.append(bin_edge) return self.bin_edges def normalise_bins(self, angle_pmt_hist, angle_hist): """Function to normalise the angle histogram by number of working PMTs in bin Args: angle_pmt_hist (TH2D) : 2D histogram angle vs PMT angle_hist (TH1D) : 1D angle histogram Returns: angle_hist (TH1D) : normalised 1D angle histogram """ #loop through all angles in 2D histogram for i in range(0, angle_pmt_hist.GetNbinsY()): #set PMT counter pmtcontent = 0 #for each angle scan through all PMTs for j in range(0, angle_pmt_hist.GetNbinsX()): #if entry is found add 1 to counter if angle_pmt_hist.GetBinContent(j, i) != 0: pmtcontent += 1 #if counter is not 0, normalise hist content at this angle by number found by PMT counter if pmtcontent != 0: angle_hist.SetBinContent( i, angle_hist.GetBinContent(i) / pmtcontent) return angle_hist
#fsac = open('AvgSac.dat', 'r') #for line in fsac.readlines(): # x1 = float(line.split(' ')[3]) # x2 = float(line.split(' ')[2]) #Get data from directory wide input_path = args.input_path input_file_list = [file for file in os.listdir(input_path)] #initialize totals; contamination is not additive (I think) A_total = 0 B_total = 0 C_total = 0 D_total = 0 for ntuple in input_file_list: #loop over files in a directory eCorr = rat.utility().Get().GetReconCorrector() eCalib = rat.utility().Get().GetReconCalibrator() #Get data from files full_path = str(input_path + ntuple) #get the full path name to the file data = rr.rootreader( full_path ) #root reader generates a python library whose keys are parameters in the ntuple #Make pathological cuts ('preliminary cuts') PathPass = [] PathTrigPassIndices = np.where((data.triggerWord & Trig_path) == 0)[0] PathDCPassIndices = np.where((data.dcFlagged & DC_path) == DC_path)[0] PathMaskTotalPassIndices = np.intersect1d(PathTrigPassIndices, PathDCPassIndices)