def beginJob(self, outfname): # prepare output file self.outputFile = ROOT.TFile.Open(outfname, "RECREATE") # prepare output tree self.outputTree = ROOT.TTree( "Events", "Tree containing reconstructed quantities") self.outTree = OutputTree(self.outputFile, self.outputTree) self.autotree = AutoFillTreeProducer(self.outTree, self.options.scfullinfo) self.outTree.branch("run", "I") self.outTree.branch("event", "I") self.outTree.branch("pedestal_run", "I") if self.options.Save_MC_data: self.outTree.branch("MC_track_len", "F") self.outTree.branch("MC_px", "F") self.outTree.branch("MC_py", "F") self.outTree.branch("MC_pz", "F") self.outTree.branch("MC_x_vertex", "F") self.outTree.branch("MC_y_vertex", "F") self.outTree.branch("MC_z_vertex", "F") self.outTree.branch("MC_x_vertex_end", "F") self.outTree.branch("MC_y_vertex_end", "F") self.outTree.branch("MC_z_vertex_end", "F") self.outTree.branch("MC_3D_pathlength", "F") self.outTree.branch("MC_2D_pathlength", "F") if self.options.camera_mode: self.autotree.createCameraVariables() self.autotree.createClusterVariables('cl') self.autotree.createClusterVariables('sc') if self.options.pmt_mode: self.autotree.createPMTVariables()
def beginJob(self,outfname): # prepare output file self.outputFile = ROOT.TFile.Open(outfname, "RECREATE") # prepare output tree self.outputTree = ROOT.TTree("Events","Tree containing reconstructed quantities") self.outTree = OutputTree(self.outputFile,self.outputTree) self.autotree = AutoFillTreeProducer(self.outTree) self.outTree.branch("run", "I") self.outTree.branch("event", "I") if self.options.camera_mode: self.autotree.createCameraVariables() self.autotree.createClusterVariables('cl') self.autotree.createClusterVariables('sc') if self.options.pmt_mode: self.autotree.createPMTVariables()
class analysis: def __init__(self, options): self.xmax = 2048 self.rebin = options.rebin self.options = options self.pedfile_fullres_name = options.pedfile_fullres_name self.tmpname = options.tmpname if not os.path.exists(self.pedfile_fullres_name): print("WARNING: pedestal file with full resolution ", self.pedfile_fullres_name, " not existing. First calculate them...") self.calcPedestal(options, 1) if not options.justPedestal: print("Pulling pedestals...") # first the one for clustering with rebin ctools = cameraTools() # then the full resolution one pedrf_fr = ROOT.TFile.Open(self.pedfile_fullres_name) self.pedmap_fr = pedrf_fr.Get('pedmap').Clone() self.pedmap_fr.SetDirectory(0) self.pedarr_fr = hist2array(self.pedmap_fr) self.noisearr_fr = ctools.noisearray(self.pedmap_fr) pedrf_fr.Close() # the following is needed for multithreading def __call__(self, evrange=(-1, -1, -1)): if evrange[0] == -1: outfname = self.options.outFile else: outfname = '{base}_chunk{ij}.root'.format( base=self.options.outFile.split('.')[0], ij=evrange[0]) self.beginJob(outfname) self.reconstruct(evrange) self.endJob() def beginJob(self, outfname): # prepare output file self.outputFile = ROOT.TFile.Open(outfname, "RECREATE") # prepare output tree self.outputTree = ROOT.TTree( "Events", "Tree containing reconstructed quantities") self.outTree = OutputTree(self.outputFile, self.outputTree) self.autotree = AutoFillTreeProducer(self.outTree) self.outTree.branch("run", "I") self.outTree.branch("event", "I") self.outTree.branch("pedestal_run", "I") if self.options.camera_mode: self.autotree.createCameraVariables() self.autotree.createClusterVariables('cl') self.autotree.createClusterVariables('sc') if self.options.pmt_mode: self.autotree.createPMTVariables() def endJob(self): self.outTree.write() self.outputFile.Close() def getNEvents(self): tf = sw.swift_read_root_file( self.tmpname) #tf = ROOT.TFile.Open(self.rfile) ret = len(tf.GetListOfKeys()) if self.options.daq != 'midas' else int( len(tf.GetListOfKeys()) / 2) tf.Close() return ret def calcPedestal(self, options, alternativeRebin=-1): maxImages = options.maxEntries nx = ny = self.xmax rebin = self.rebin if alternativeRebin < 0 else alternativeRebin nx = int(nx / rebin) ny = int(ny / rebin) #pedfilename = 'pedestals/pedmap_ex%d_rebin%d.root' % (options.pedexposure,rebin) pedfilename = 'pedestals/pedmap_run%s_rebin%d.root' % (options.run, rebin) pedfile = ROOT.TFile.Open(pedfilename, 'recreate') pedmap = ROOT.TH2D('pedmap', 'pedmap', nx, 0, self.xmax, ny, 0, self.xmax) pedmapS = ROOT.TH2D('pedmapsigma', 'pedmapsigma', nx, 0, self.xmax, ny, 0, self.xmax) pedsum = np.zeros((nx, ny)) tf = sw.swift_read_root_file(self.tmpname) #tf = ROOT.TFile.Open(self.rfile) # first calculate the mean numev = 0 for i, e in enumerate(tf.GetListOfKeys()): iev = i if self.options.daq != 'midas' else i / 2 # when PMT is present if iev in self.options.excImages: continue if maxImages > -1 and i < len(tf.GetListOfKeys()) - maxImages: continue name = e.GetName() obj = e.ReadObj() if not obj.InheritsFrom('TH2'): continue print("Calc pedestal mean with event: ", name) if rebin > 1: obj.RebinX(rebin) obj.RebinY(rebin) arr = hist2array(obj) pedsum = np.add(pedsum, arr) numev += 1 pedmean = pedsum / float(numev) # now compute the rms (two separate loops is faster than one, yes) pedsqdiff = np.zeros((nx, ny)) for i, e in enumerate(tf.GetListOfKeys()): iev = i if self.options.daq != 'midas' else i / 2 # when PMT is present if iev in self.options.excImages: continue if maxImages > -1 and i < len(tf.GetListOfKeys()) - maxImages: continue name = e.GetName() obj = e.ReadObj() if not obj.InheritsFrom('TH2'): continue print("Calc pedestal rms with event: ", name) if rebin > 1: obj.RebinX(rebin) obj.RebinY(rebin) arr = hist2array(obj) pedsqdiff = np.add(pedsqdiff, np.square(np.add(arr, -1 * pedmean))) pedrms = np.sqrt(pedsqdiff / float(numev - 1)) # now save in a persistent ROOT object for ix in range(nx): for iy in range(ny): pedmap.SetBinContent(ix + 1, iy + 1, pedmean[ix, iy]) pedmap.SetBinError(ix + 1, iy + 1, pedrms[ix, iy]) pedmapS.SetBinContent(ix + 1, iy + 1, pedrms[ix, iy]) tf.Close() pedfile.cd() pedmap.Write() pedmapS.Write() pedmean1D = ROOT.TH1D('pedmean', 'pedestal mean', 500, 97, 103) pedrms1D = ROOT.TH1D('pedrms', 'pedestal RMS', 500, 0, 5) for ix in range(nx): for iy in range(ny): pedmean1D.Fill(pedmap.GetBinContent(ix, iy)) pedrms1D.Fill(pedmap.GetBinError(ix, iy)) pedmean1D.Write() pedrms1D.Write() pedfile.Close() print("Pedestal calculated and saved into ", pedfilename) def reconstruct(self, evrange=(-1, -1, -1)): ROOT.gROOT.Macro('rootlogon.C') ROOT.gStyle.SetOptStat(0) ROOT.gStyle.SetPalette(ROOT.kRainBow) savErrorLevel = ROOT.gErrorIgnoreLevel ROOT.gErrorIgnoreLevel = ROOT.kWarning tf = sw.swift_read_root_file(self.tmpname) #tf = ROOT.TFile.Open(self.rfile) #c1 = ROOT.TCanvas('c1','',600,600) ctools = cameraTools() print("Reconstructing event range: ", evrange[1], "-", evrange[2]) # loop over events (pictures) for iobj, key in enumerate(tf.GetListOfKeys()): iev = iobj if self.options.daq != 'midas' else int( iobj / 2) # when PMT is present #print("max entries = ",self.options.maxEntries) if self.options.maxEntries > 0 and iev == max( evrange[0], 0) + self.options.maxEntries: break if sum(evrange[1:]) > -2: if iev < evrange[1] or iev > evrange[2]: continue name = key.GetName() obj = key.ReadObj() # Routine to skip some images if needed if iev in self.options.excImages: continue if self.options.debug_mode == 1 and iev != self.options.ev: continue if obj.InheritsFrom('TH2'): if self.options.daq == 'btf': run, event = (int( name.split('_')[0].split('run')[-1].lstrip("0")), int(name.split('_')[-1].lstrip("0"))) elif self.options.daq == 'h5': run, event = (int(name.split('_')[0].split('run')[-1]), int(name.split('_')[-1])) else: run, event = (int( name.split('_')[1].split('run')[-1].lstrip("0")), int(name.split('_')[-1].split('ev')[-1])) print("Processing Run: ", run, "- Event ", event, "...") self.outTree.fillBranch("run", run) self.outTree.fillBranch("event", event) self.outTree.fillBranch("pedestal_run", int(self.options.pedrun)) if self.options.camera_mode: if obj.InheritsFrom('TH2'): pic_fullres = obj.Clone(obj.GetName() + '_fr') img_fr = hist2array(pic_fullres) # Upper Threshold full image img_cimax = np.where(img_fr < self.options.cimax, img_fr, 0) # zs on full image + saturation correction on full image if self.options.saturation_corr: #print("you are in saturation correction mode") img_fr_sub = ctools.pedsub(img_cimax, self.pedarr_fr) img_fr_satcor = ctools.satur_corr(img_fr_sub) img_fr_zs = ctools.zsfullres( img_fr_satcor, self.noisearr_fr, nsigma=self.options.nsigma) img_rb_zs = ctools.arrrebin(img_fr_zs, self.rebin) # skip saturation and set satcor =img_fr_sub else: #print("you are in poor mode") img_fr_sub = ctools.pedsub(img_cimax, self.pedarr_fr) img_fr_satcor = img_fr_sub img_fr_zs = ctools.zsfullres( img_fr_satcor, self.noisearr_fr, nsigma=self.options.nsigma) img_rb_zs = ctools.arrrebin(img_fr_zs, self.rebin) # Cluster reconstruction on 2D picture algo = 'DBSCAN' if self.options.type in ['beam', 'cosmics']: algo = 'HOUGH' snprod_inputs = { 'picture': img_rb_zs, 'pictureHD': img_fr_satcor, 'picturezsHD': img_fr_zs, 'pictureOri': img_fr, 'name': name, 'algo': algo } plotpy = options.jobs < 2 # for some reason on macOS this crashes in multicore snprod_params = { 'snake_qual': 3, 'plot2D': False, 'plotpy': False, 'plotprofiles': False } snprod = SnakesProducer(snprod_inputs, snprod_params, self.options) clusters, snakes = snprod.run() self.autotree.fillCameraVariables(img_fr_zs) self.autotree.fillClusterVariables(snakes, 'sc') self.autotree.fillClusterVariables(clusters, 'cl') if self.options.pmt_mode: if obj.InheritsFrom('TGraph'): # PMT waveform reconstruction from waveform import PeakFinder, PeaksProducer wform = tf.Get('wfm_' + '_'.join(name.split('_')[1:])) # sampling was 5 GHz (5/ns). Rebin by 5 (1/ns) pkprod_inputs = {'waveform': wform} pkprod_params = { 'threshold': options. threshold, # min threshold for a signal (baseline is -20 mV) 'minPeakDistance': options. minPeakDistance, # number of samples (1 sample = 1ns ) 'prominence': options. prominence, # noise after resampling very small 'width': options.width, # minimal width of the signal 'resample': options.resample, # to sample waveform at 1 GHz only 'rangex': (self.options.time_range[0], self.options.time_range[1]), 'plotpy': options.pmt_plotpy } pkprod = PeaksProducer(pkprod_inputs, pkprod_params, self.options) peaksfinder = pkprod.run() self.autotree.fillPMTVariables( peaksfinder, 0.2 * pkprod_params['resample']) # fill reco tree (just once/event, and the TGraph is analyses as last) if (self.options.daq == 'midas' and obj.InheritsFrom('TGraph')) or self.options.daq != 'midas': self.outTree.fill() ROOT.gErrorIgnoreLevel = savErrorLevel
def run(self): # prepare output file outputFile = ROOT.TFile.Open(self.outputFileName, "RECREATE") # prepare output tree outputTree = ROOT.TTree("Events", "Tree containing reconstructed pulses") outTree = OutputTree(outputFile, outputTree) self.beginJob(outTree) for run in self.runs: runi = int((os.path.basename(run).split('Run')[-1]).lstrip('0')) for chunk in xrange(self.nchunks): outTree.fillBranch("run", runi) outTree.fillBranch("event", chunk) for ic, channel in enumerate(['C1', 'C3', 'C4']): inputf = "%s/%sRun%05d.txt" % (run, channel, chunk) print "Analyzing pulse from ", inputf pulse = PulseTxtFile(inputf, self.options) if channel == 'C1': outTree.fillBranch("time_btf", pulse.time()) elif channel == 'C4': outTree.fillBranch("amplitude_calo", pulse.amplitude()) outTree.fillBranch("time_calo", pulse.time()) else: outTree.fillBranch("amplitude_pmt", pulse.amplitudes()) outTree.fillBranch("time_pmt", pulse.times()) outTree.fill() outTree.write() outputFile.Close()