def analyze_event(self, event): # Initialize empty list for each output observable self.initialize_output_lists() # Create list of fastjet::PseudoJets (separately for jet shower particles and holes) fj_hadrons_positive = self.fill_fastjet_constituents(event, select_status='+') fj_hadrons_negative = self.fill_fastjet_constituents(event, select_status='-') # Create list of charged particles fj_hadrons_positive_charged = self.fill_fastjet_constituents(event, select_status='+', select_charged=True) fj_hadrons_negative_charged = self.fill_fastjet_constituents(event, select_status='-', select_charged=True) # Fill hadron histograms for jet shower particles self.fill_hadron_histograms(fj_hadrons_positive, status='+') self.fill_hadron_histograms(fj_hadrons_negative, status='-') # Loop through specified jet R for jetR in self.jet_R: # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector = fj.SelectorPtMin(self.min_jet_pt) & fj.SelectorAbsRapMax(self.max_jet_y) # Full jets # ----------------- cs = fj.ClusterSequence(fj_hadrons_positive, jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) # Fill inclusive full jet histograms [self.analyze_inclusive_jet(jet, fj_hadrons_positive, fj_hadrons_negative, jetR, full_jet=True) for jet in jets_selected] # Charged jets # ----------------- cs_charged = fj.ClusterSequence(fj_hadrons_positive_charged, jet_def) jets_charged = fj.sorted_by_pt(cs_charged.inclusive_jets()) jets_selected_charged = jet_selector(jets_charged) # Fill inclusive charged jet histograms [self.analyze_inclusive_jet(jet, fj_hadrons_positive_charged, fj_hadrons_negative_charged, jetR, full_jet=False) for jet in jets_selected_charged] # Fill semi-inclusive jet correlations if self.semi_inclusive_chjet_observables: if self.sqrts == 2760: jetR_list = self.semi_inclusive_chjet_observables['IAA_alice']['jet_R']+self.semi_inclusive_chjet_observables['nsubjettiness_alice']['jet_R'] elif self.sqrts == 200: jetR_list = self.semi_inclusive_chjet_observables['IAA_star']['jet_R'] if jetR in jetR_list: self.fill_semi_inclusive_chjet_histograms(jets_selected_charged, fj_hadrons_positive_charged, fj_hadrons_negative_charged, jetR) # Fill dijet histograms if self.dijet_observables: self.fill_dijet_histograms(jets_selected, fj_hadrons_negative, jetR)
def analyze_event(self, event): # Create list of fastjet::PseudoJets (separately for jet shower particles and holes) fj_hadrons_positive_all = self.fill_fastjet_constituents(event, select_status='+') fj_hadrons_negative_all = self.fill_fastjet_constituents(event, select_status='-') # Create list of charged particles fj_hadrons_positive_charged_all = self.fill_fastjet_constituents(event, select_status='+', select_charged=True) fj_hadrons_negative_charged_all = self.fill_fastjet_constituents(event, select_status='-', select_charged=True) # Fill hadron histograms for jet shower particles self.fill_hadron_histograms(fj_hadrons_positive_all, status='+') self.fill_hadron_histograms(fj_hadrons_negative_all, status='-') # Loop through several different constituent thresholds for constituent_threshold in self.constituent_threshold: # Set constituent threshold fj_hadrons_positive = [hadron for hadron in fj_hadrons_positive_all if hadron.pt() > constituent_threshold] fj_hadrons_negative = [hadron for hadron in fj_hadrons_negative_all if hadron.pt() > constituent_threshold] fj_hadrons_positive_charged = [hadron for hadron in fj_hadrons_positive_charged_all if hadron.pt() > constituent_threshold] fj_hadrons_negative_charged = [hadron for hadron in fj_hadrons_negative_charged_all if hadron.pt() > constituent_threshold] # Loop through specified jet R for jetR in self.jet_R: # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector = fj.SelectorPtMin(self.min_jet_pt) & fj.SelectorAbsRapMax(self.max_jet_y) if self.debug_level > 0: print('jet definition is:', jet_def) print('jet selector is:', jet_selector, '\n') # Full jets # ----------------- cs = fj.ClusterSequence(fj_hadrons_positive, jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) # Fill inclusive full jet histograms [self.analyze_inclusive_jet(jet, fj_hadrons_positive, fj_hadrons_negative, jetR, constituent_threshold, charged=False) for jet in jets_selected] # Charged jets # ----------------- cs_charged = fj.ClusterSequence(fj_hadrons_positive_charged, jet_def) jets_charged = fj.sorted_by_pt(cs_charged.inclusive_jets()) jets_selected_charged = jet_selector(jets_charged) # Fill inclusive charged jet histograms [self.analyze_inclusive_jet(jet, fj_hadrons_positive_charged, fj_hadrons_negative_charged, jetR, constituent_threshold, charged=True) for jet in jets_selected_charged] # Fill jet correlations self.fill_semi_inclusive_chjet_histograms(jets_selected_charged, fj_hadrons_positive_charged, fj_hadrons_negative_charged, jetR, constituent_threshold)
def analyze_event(self, fj_particles): # Perform constituent subtraction for each R_max (do this once, for all jetR) if not self.is_pp: fj_particles_subtracted = [ self.constituent_subtractor[i].process_event(fj_particles) for i, R_max in enumerate(self.max_distance) ] # Loop through jetR, and process event for each R for jetR in self.jetR_list: # Keep track of whether to fill R-independent histograms self.fill_R_indep_hists = (jetR == self.jetR_list[0]) # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector = fj.SelectorPtMin(5.0) & fj.SelectorAbsRapMax(0.9 - jetR) if self.debug_level > 2: print('jet definition is:', jet_def) print('jet selector is:', jet_selector, '\n') # Analyze if self.is_pp: # Do jet finding cs = fj.ClusterSequence(fj_particles, jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) self.analyze_jets(jets_selected, jetR) else: for i, R_max in enumerate(self.max_distance): if self.debug_level > 1: print('R_max: {}'.format(R_max)) # Keep track of whether to fill R_max-independent histograms self.fill_Rmax_indep_hists = (i == 0) # Perform constituent subtraction rho = self.constituent_subtractor[i].bge_rho.rho() if self.fill_R_indep_hists and self.fill_Rmax_indep_hists: getattr(self, 'hRho').Fill(rho) # Do jet finding (re-do each time, to make sure matching info gets reset) cs = fj.ClusterSequence(fj_particles_subtracted[i], jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) self.analyze_jets(jets_selected, jetR, R_max=R_max)
def fill_matched_jet_histograms(self, jetR, obs_setting, grooming_setting, obs_label, jet_p, jet_p_groomed_lund, jet_h, jet_h_groomed_lund, jet_ch, jet_ch_groomed_lund, jet_pt_p_ungroomed, jet_pt_h_ungroomed, jet_pt_ch_ungroomed, suffix): # Only need to fill full<-->charged response MPI = 'off' # For a given jet, find all inclusive subjets of a given subjet radius cs_subjet_ch = fj.ClusterSequence(jet_ch.constituents(), self.subjet_def[obs_setting]) subjets_ch = fj.sorted_by_pt(cs_subjet_ch.inclusive_jets()) cs_subjet_h = fj.ClusterSequence(jet_h.constituents(), self.subjet_def[obs_setting]) subjets_h = fj.sorted_by_pt(cs_subjet_h.inclusive_jets()) for observable in self.observable_list: # Fill inclusive subjets if 'inclusive' in observable: for subjet_ch in subjets_ch: for subjet_h in subjets_h: if subjet_ch.delta_R(subjet_h) < 0.6 * obs_setting: z_ch = self.z_r(subjet_ch, jet_pt_ch_ungroomed) z_h = self.z_r(subjet_h, jet_pt_h_ungroomed) self.fill_response(observable, 'h', 'ch', MPI, jetR, jet_pt_h_ungroomed, jet_pt_ch_ungroomed, z_h, z_ch, obs_label) # Fill leading subjets elif 'leading' in observable: leading_subjet_ch = self.leading_jet(subjets_ch) leading_subjet_h = self.leading_jet(subjets_h) z_ch = self.z_r(leading_subjet_ch, jet_pt_ch_ungroomed) z_h = self.z_r(leading_subjet_h, jet_pt_h_ungroomed) self.fill_response(observable, 'h', 'ch', MPI, jetR, jet_pt_h_ungroomed, jet_pt_ch_ungroomed, z_h, z_ch, obs_label) else: raise ValueError( f'fill_matched_jet_histograms: {observable} is not a recognized observable' )
def do_cs_event_wide(full_event, ptmin=100.): max_eta = 3. # background estimator bge = fj.GridMedianBackgroundEstimator(max_eta, 0.5) bge.set_particles(full_event) rho = bge.rho() rhom = bge.rho_m() subtractor = cs.ConstituentSubtractor() # enum Distance { # deltaR, # angle # } subtractor.set_distance_type(0) subtractor.set_max_distance(max_distance) subtractor.set_alpha(alpha) subtractor.set_ghost_area(ghost_area) subtractor.set_max_eta(max_eta) subtractor.set_background_estimator(bge) subtractor.set_scalar_background_density(rho, rhom) #sel_max_pt = fj.SelectorPtMax(10) #subtractor.set_particle_selector(sel_max_pt) subtractor.initialize() corrected_event = subtractor.subtract_event(full_event) jet_def = fj.JetDefinition(fj.antikt_algorithm, 0.4) clust_seq_corr = fj.ClusterSequence(corrected_event, jet_def) corrected_jets = clust_seq_corr.inclusive_jets(ptmin) return corrected_jets, clust_seq_corr
def analyze_event(self, event): # Get list of hadrons from the event, and fill some histograms hadrons = event.hadrons(min_track_pt=self.min_track_pt) self.fill_hadron_histograms(hadrons) # Get list of final-state partons from the event, and fill some histograms partons = event.final_partons() self.fill_parton_histograms(partons) # Create list of fastjet::PseudoJets fj_hadrons = [] fj_hadrons = self.fill_fastjet_constituents(hadrons) # Loop through specified jet R for jetR in self.jetR_list: # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector = fj.SelectorPtMin( self.min_jet_pt) & fj.SelectorAbsRapMax(5.) if self.debug_level > 0: print('jet definition is:', jet_def) print('jet selector is:', jet_selector, '\n') # Do jet finding jets = [] jets_selected = [] cs = fj.ClusterSequence(fj_hadrons, jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) # Fill some jet histograms self.fill_jet_histograms(jets_selected, jetR)
def analyze_event(self, event): # Create list of fastjet::PseudoJets (separately for jet shower particles and holes) fj_hadrons_positive = self.fill_fastjet_constituents(event, select_status='+') fj_hadrons_negative = self.fill_fastjet_constituents(event, select_status='-') # Fill hadron histograms for jet shower particles self.fill_hadron_histograms(fj_hadrons_positive, status='+') self.fill_hadron_histograms(fj_hadrons_negative, status='-') # Loop through specified jet R for jetR in self.jetR_list: # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector = fj.SelectorPtMin( self.min_jet_pt) & fj.SelectorAbsRapMax(5.) if self.debug_level > 0: print('jet definition is:', jet_def) print('jet selector is:', jet_selector, '\n') # Do jet finding cs = fj.ClusterSequence(fj_hadrons_positive, jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) # Fill some jet histograms self.fill_jet_histograms(jets_selected, fj_hadrons_negative, jetR)
def fill_jet_histograms(self, jet, jet_groomed_lund, jetR, obs_setting, grooming_setting, obs_label, jet_pt_ungroomed, suffix): if (jetR - obs_setting) < 1e-3: return # For a given jet, find inclusive subjets of a given subjet radius cs_subjet = fj.ClusterSequence(jet.constituents(), self.subjet_def[obs_setting]) subjets = fj.sorted_by_pt(cs_subjet.inclusive_jets()) for observable in self.observable_list: # Fill inclusive subjets if 'inclusive' in observable: for subjet in subjets: z = subjet.pt() / jet.pt() getattr( self, 'h_{}_JetPt_R{}_{}'.format( observable, jetR, obs_setting)).Fill(jet.pt(), z) # Fill leading subjets if 'leading' in observable: leading_subjet = self.utils.leading_jet(subjets) z_leading = leading_subjet.pt() / jet.pt() getattr( self, 'h_{}_JetPt_R{}_{}'.format(observable, jetR, obs_setting)).Fill( jet.pt(), z_leading)
def do_clustering(self): self.jet_def = fj.JetDefinition(self.algorithm, self.R) self.jet_cs = fj.ClusterSequence(self.particles, self.jet_def) jets = self.jet_cs.inclusive_jets(self.ptmin) self.jets = fj.sorted_by_pt(jets) return self.jets
def fill_observable_histograms(self, jet, jet_groomed_lund, jetR, level, MPI, obs_setting, grooming_setting, obs_label, jet_pt_ungroomed): # Only doing the MPI scaling at ch level, so ignore everything else if level != "ch": return # For a given jet, find all inclusive subjets of a given subjet radius cs_subjet = fj.ClusterSequence(jet.constituents(), self.subjet_def[obs_setting]) subjets = fj.sorted_by_pt(cs_subjet.inclusive_jets()) for observable in self.observable_list: # Fill inclusive subjets if 'inclusive' in observable: for subjet in subjets: z = self.z_r(subjet, jet_pt_ungroomed) self.fill_MPI_scaling_hist(observable, "ch", MPI, jetR, jet_pt_ungroomed, z, obs_label) # Fill leading subjets elif 'leading' in observable: leading_subjet = self.leading_jet(subjets) z = self.z_r(leading_subjet, jet_pt_ungroomed) self.fill_MPI_scaling_hist(observable, "ch", MPI, jetR, jet_pt_ungroomed, z, obs_label) else: raise ValueError( f'fill_observable_histograms: {observable} is not a recognized observable' )
def analyzeEvent(self, particles): fjHadrons = self.fillFastJetConstituents(particles) cs = fj.ClusterSequence(fjHadrons, self.jetDefinition) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = self.jetSelector(jets) fjHadrons = [ hadron for hadron in fjHadrons if loadParticleInfo(hadron.user_index())[0] in self.ids and withinInterval(hadron.pt(), self.heavypTCut) and withinInterval(hadron.eta(), self.heavyEtaCut) and withinInterval(hadron.rap(), self.heavyRapidityCut) ] for jet in jets_selected: jetpT = jet.pt() constituents = jet.constituents() for hadron in constituents: pid, status = loadParticleInfo(hadron.user_index()) if status < 0: jetpT -= hadron.pt() for hadron in fjHadrons: dr = np.sqrt((hadron.eta() - jet.eta())**2 + (hadron.phi() - jet.phi())**2) if dr < self.drCut: i = findIndex(self.pTBins, jetpT) if i >= 0: self.countStorage[self.pThatIndex][i] += 1 break
def process_file(filename): global jet_def, drjet # open file #logger.info('filename: %s',filename) reader.open(filename.strip()) outfilename = filename.replace('.slcio', '.bjets') if os.path.exists(outfilename): return outfile = open(outfilename, 'w') btagged = [] # loop over events file_event_counter = 0 for event in reader: # get truth particles mcps = event.getCollection('MCParticle') # build list of particles to include in jet finding jet_particles = get_jet_particles(mcps) # run fastjet cluster = fastjet.ClusterSequence(jet_particles, jet_def) jets = fastjet.sorted_by_pt(cluster.inclusive_jets()) # remove jets that overlap jets = id_tools.jet_overlap_removal(jets, drjet / 2.) event_btag = False # loop over jets and identify those that are b-jet candidates for jet in jets: cons = fastjet.sorted_by_pt(jet.constituents()) bjet_tag = False # loop over constituents and find b-hadrons for con in cons: if id_tools.hasBottom(con.user_index()): bjet_tag = True break # if this is a b-jet write output to file if bjet_tag: output = '%s %10d %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f\n' % ( filename, file_event_counter, jet.px(), jet.py(), jet.pz(), jet.eta(), jet.phi(), jet.e(), jet.m()) outfile.write(output) event_btag = True file_event_counter += 1 if event_btag: btagged.append(1) else: btagged.append(0) json.dump(btagged, open(filename.replace('.slcio', '.btagged.json'), 'w')) # close file reader.close()
def analyze_event(self, fj_particles_hard, fj_particles_combined_beforeCS): # Check that the entries exist appropriately if type(fj_particles_hard) != fj.vectorPJ or type( fj_particles_combined_beforeCS) != fj.vectorPJ: print('fj_particles type mismatch -- skipping event') return # Perform constituent subtraction for each R_max fj_particles_combined = [] for i, R_max in enumerate(self.max_distance): if R_max == 0: fj_particles_combined.append(fj_particles_combined_beforeCS) else: fj_particles_combined.append( self.constituent_subtractor[i].process_event( fj_particles_combined_beforeCS)) # Loop through jetR, and process event for each R for jetR in self.jetR_list: # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector = fj.SelectorPtMin( self.min_jet_pt) & fj.SelectorAbsRapMax(self.eta_max - jetR) for i, R_max in enumerate(self.max_distance): #print() #print(R_max) #print('Total number of combined particles: {}'.format(len([p.pt() for p in fj_particles_combined_beforeCS]))) #print('After constituent subtraction {}: {}'.format(i, len([p.pt() for p in fj_particles_combined[i]]))) # Do jet finding (re-do each time, to make sure matching info gets reset) cs_combined = fj.ClusterSequence(fj_particles_combined[i], jet_def) jets_combined = fj.sorted_by_pt(cs_combined.inclusive_jets()) jets_combined_selected = jet_selector(jets_combined) cs_hard = fj.ClusterSequence(fj_particles_hard, jet_def) jets_hard = fj.sorted_by_pt(cs_hard.inclusive_jets()) jets_hard_selected = jet_selector(jets_hard) self.analyze_jets(jets_combined_selected, jets_hard_selected, jetR, R_max=R_max)
def analyze_subjets(self, jet, jetR, subjetR): cs_subjet = fj.ClusterSequence(jet.constituents(), self.subjet_def[subjetR]) subjets = fj.sorted_by_pt(cs_subjet.inclusive_jets()) for subjet in subjets: z = subjet.pt() / jet.pt() getattr(self, 'h_subjet_z_JetPt_R{}_{}'.format(jetR, subjetR)).Fill( jet.pt(), z)
def next(self): """ Calls Pythia to create the next event. If successful, clusters both the truth level data and the smeared data, and returns true. Otherwise, returns false """ self.gen_jet = [] self.det_jet = [] self.truth_particles.clear() self.cluster_seq.clear() if not self.gen.next(): return False # build our list of final state particles self.truth_particles = [ MakePseudoJet(p) for p in self.gen.event if p.isFinal() and p.isVisible() ] # build "detector level" tracks by smearing the truth particles # if the user has selected some sort of modification self.smear_tracks() # perform jetfinding for truth and detector jets truth_cluster = fastjet.ClusterSequence(self.truth_particles, self.jet_def) det_cluster = fastjet.ClusterSequence(self.detector_particles, self.jet_def) self.gen_jet = fastjet.sorted_by_pt( self.jet_selector(truth_cluster.inclusive_jets())) self.det_jet = fastjet.sorted_by_pt( self.jet_selector(det_cluster.inclusive_jets())) self.cluster_seq.append(truth_cluster) self.cluster_seq.append(det_cluster) return
def fill_jet_histograms(self, jet, jet_groomed_lund, jetR, obs_setting, grooming_setting, obs_label, jet_pt_ungroomed, suffix): if (jetR - obs_setting) < 1e-3: return # For a given jet, find all inclusive subjets of a given subjet radius cs_subjet = fj.ClusterSequence(jet.constituents(), self.subjet_def[obs_setting]) subjets = fj.sorted_by_pt(cs_subjet.inclusive_jets()) for observable in self.observable_list: # Fill inclusive subjets if 'inclusive' in observable: for subjet in subjets: z = subjet.pt() / jet.pt() # If z=1, it will be default be placed in overflow bin -- prevent this if np.isclose(z, 1.): z = 0.999 getattr( self, 'h_{}_JetPt_R{}_{}{}'.format( observable, jetR, obs_setting, suffix)).Fill(jet.pt(), z) # Fill leading subjets if 'leading' in observable: leading_subjet = self.utils.leading_jet(subjets) z_leading = leading_subjet.pt() / jet.pt() # If z=1, it will be default be placed in overflow bin -- prevent this if np.isclose(z_leading, 1.): z_leading = 0.999 getattr( self, 'h_{}_JetPt_R{}_{}{}'.format(observable, jetR, obs_setting, suffix)).Fill( jet.pt(), z_leading) # Fill z of subjet constituents for z~1 subjets if z_leading > 0.99: name = 'h_{}_zconst_R{}_{}_z099_1{}'.format( observable, jetR, obs_setting, suffix) for p in leading_subjet.constituents(): z = p.pt() / leading_subjet.pt() if np.isclose(z, 1.): z = 0.999 getattr(self, name).Fill(jet.pt(), z)
def fill_jet_histograms(self, jet, jet_groomed_lund, jetR, obs_setting, grooming_setting, obs_label, jet_pt_ungroomed, suffix=None, label=''): # Get hist names if not self.thermal_subtraction_method: name = f'h_{self.observable}_JetPt_R{jetR}_{obs_label}{label}' elif 'gridsub' in self.thermal_subtraction_method.lower(): name = f'h_{self.observable}_JetPt_R{jetR}_{obs_label}_gridsub_{suffix}{label}' elif '4momsub' in self.thermal_subtraction_method.lower(): name = f'h_{self.observable}_JetPt_R{jetR}_{obs_label}_4momsub{label}' # Convert df of pt/eta/phi of thermal particles to list of fastjet particles, for convenience df_thermal = [] if len(self.event_bck_df) != 0: df_thermal = self.get_fjparticles(self.event_bck_df) # Correct the jet pt by subtracting thermal particles within R of jet axis holes_in_jet = [] negative_pt = 0. for thermal_particle in df_thermal: if jet.delta_R(thermal_particle) < jetR: if np.random.uniform() >= self.thermal_rejection_fraction: negative_pt += thermal_particle.pt() holes_in_jet.append(thermal_particle) jet_pt = jet.pt() - negative_pt # corrected pt: shower+recoil-holes # For a given jet, find all inclusive subjets of a given subjet radius cs_subjet = fj.ClusterSequence(jet.constituents(), self.subjet_def[obs_setting]) subjets = fj.sorted_by_pt(cs_subjet.inclusive_jets()) # Get leading subjet (accounts for holes) _, leading_subjet_pt = self.leading_jet(subjets, holes_in_jet, obs_setting) z = leading_subjet_pt / jet_pt # If z=1, it will be default be placed in overflow bin -- prevent this if np.isclose(z, 1.): z = 0.999 getattr(self, name).Fill(jet_pt, z)
def analyze_event(self, fj_particles): # Cluster each jet with R=infinity jetR = fj.JetDefinition.max_allowable_R jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) cs = fj.ClusterSequence(fj_particles, jet_def) jet = fj.sorted_by_pt(cs.inclusive_jets())[0] # Compute N-subjetiness axis_definition = fjcontrib.KT_Axes() for i,N in enumerate(self.N_list): beta = self.beta_list[i] measure_definition = fjcontrib.UnnormalizedMeasure(beta) n_subjettiness_calculator = fjcontrib.Nsubjettiness(N, axis_definition, measure_definition) n_subjettiness = n_subjettiness_calculator.result(jet)/jet.pt() self.jet_variables['n_subjettiness_N{}_beta{}'.format(N, beta)].append(n_subjettiness)
def analyzeEvent(self, particles): fjHadrons = self.fillFastJetConstituents(particles) cs = fj.ClusterSequence(fjHadrons, self.jetDefinition) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = self.jetSelector(jets) for jet in jets_selected: #constituents = jet.constituents() for hadron in fjHadrons: dr = np.sqrt((hadron.eta() - jet.eta())**2 + (hadron.phi() - jet.phi())**2) if hadron.user_index() in self.ids \ and withinInterval(hadron.pt(), self.heavypTCut) \ and withinInterval(hadron.eta(), self.heavyEtaCut) \ and withinInterval(hadron.rap(), self.heavyRapidityCut): i = findIndex(self.rBins, dr) if i >= 0: self.countStorage[self.pThatIndex][i] += 1 break
def analyzeEvent(self, particles): fjHadrons = self.fillFastJetConstituents(particles) cs = fj.ClusterSequence(fjHadrons, self.jetDefinition) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = self.jetSelector(jets) for jet in jets_selected: constituents = jet.constituents() for hadron in constituents: pid, status = loadParticleInfo(hadron.user_index()) dr = np.sqrt((hadron.eta() - jet.eta())**2 + (hadron.phi() - jet.phi())**2) i = findIndex(self.rBins, dr) if i > 0: if status >= 0: self.countStorage[self.pThatIndex][i] += hadron.pt() / \ jet.pt() else: self.countStorage[self.pThatIndex][i] -= hadron.pt() / \ jet.pt()
def analyzeJets(self, fj_particles, jet_def, jet_selector, alpha): # Do jet finding cs = fj.ClusterSequence(fj_particles, jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) # Loop through jets jetR = jet_def.R() for jet in jets_selected: if self.debug_level > 1: print('jet:') print(jet) # Check additional acceptance criteria if not self.utils.is_det_jet_accepted(jet): continue # Fill histograms self.fillJetHistograms(jet, jetR, alpha)
def do_cs_iterative(full_event, ptmin=100.): max_eta = 3. bge = fj.GridMedianBackgroundEstimator(3., 0.5) bge.set_particles(full_event) rho = bge.rho() rhom = bge.rho_m() subtractor = ics.IterativeConstituentSubtractor() subtractor.set_distance_type(0) max_distances_vec = ics.DoubleVec() max_distances_vec.push_back(max_distances[0]) max_distances_vec.push_back(max_distances[1]) alphas_vec = ics.DoubleVec() alphas_vec.push_back(alphas[0]) alphas_vec.push_back(alphas[1]) subtractor.set_parameters(max_distances_vec, alphas_vec) subtractor.set_ghost_removal(True) subtractor.set_ghost_area(ghost_area) subtractor.set_max_eta(max_eta) subtractor.set_background_estimator(bge) subtractor.set_scalar_background_density(rho, rhom) #sel_max_pt = fj.SelectorPtMax(10) #subtractor.set_particle_selector(sel_max_pt) subtractor.initialize() # clustering corrected_event = subtractor.subtract_event(full_event) jet_def = fj.JetDefinition(fj.antikt_algorithm, 0.4) clust_seq_corr = fj.ClusterSequence(corrected_event, jet_def) corrected_jets = clust_seq_corr.inclusive_jets(ptmin) return corrected_jets, clust_seq_corr
def analyzeEvent(self, particles): holes = [x for x in particles if x.status < 0] particles = [x for x in particles if x.status >= 0] fjHadrons = self.fillFastJetConstituents(particles) cs = fj.ClusterSequence(fjHadrons, self.jetDefinition) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = self.jetSelector(jets) Njet = len(jets_selected) for jet in jets_selected: constituents = jet.constituents() for hadron in constituents: pid, status = loadParticleInfo(hadron.user_index()) dr = np.sqrt((hadron.eta() - jet.eta())**2 + (hadron.phi() - jet.phi())**2) z = hadron.pt() * np.cos(dr) / jet.pt() if self.usepT: i = findIndex(self.bins, hadron.pt()) else: i = findIndex(self.bins, z) if i > 0: diff = self.bins[i + 1] - self.bins[i] self.countStorage[self.pThatIndex][i] += 1 / diff / Njet for hole in holes: dr = np.sqrt((hole.eta - jet.eta())**2 + (hole.phi - jet.phi())**2) z = hole.pT * np.cos(dr) / jet.pt() if self.usepT: i = findIndex(self.bins, hole.pT) else: i = findIndex(self.bins, z) if i > 0: diff = self.bins[i + 1] - self.bins[i] self.countStorage[self.pThatIndex][i] -= 1 / diff / Njet
def analyzeEvent(self, particles): holes = [x for x in particles if x.status < 0] particles = [x for x in particles if x.status >= 0] fjHadrons = self.fillFastJetConstituents(particles) cs = fj.ClusterSequence(fjHadrons, self.jetDefinition) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = self.jetSelector(jets) for jet in jets_selected: jetpT = jet.pt() constituents = jet.constituents() for hole in holes: dr = np.sqrt((hole.eta - jet.eta())**2 + (hole.phi - jet.phi())**2) if dr <= self.jetRadius: jetpT -= hole.pT i = findIndex(self.pTBins, jetpT) if i >= 0: self.countStorage[self.pThatIndex][i] += 1
def eval_model(model, dataset, config, outdir): ibatch = 0 jetdef = fastjet.JetDefinition(fastjet.antikt_algorithm, 0.4) for elem in tqdm(dataset, desc="Evaluating model"): y_pred = model.predict(elem["X"], verbose=False) np_outfile = "{}/pred_batch{}.npz".format(outdir, ibatch) ygen = unpack_target(elem["ygen"], config["dataset"]["num_output_classes"], config) ycand = unpack_target(elem["ycand"], config["dataset"]["num_output_classes"], config) outs = {} for key in y_pred.keys(): outs["gen_{}".format(key)] = ygen[key].numpy() outs["cand_{}".format(key)] = ycand[key].numpy() outs["pred_{}".format(key)] = y_pred[key] jets_coll = {} jets_const = {} for typ in ["gen", "cand", "pred"]: cls_id = np.argmax(outs["{}_cls".format(typ)], axis=-1) valid = cls_id != 0 pt = awkward.from_iter( [y[m][:, 0] for y, m in zip(outs["{}_pt".format(typ)], valid)]) eta = awkward.from_iter([ y[m][:, 0] for y, m in zip(outs["{}_eta".format(typ)], valid) ]) phi = np.arctan2(outs["{}_sin_phi".format(typ)], outs["{}_cos_phi".format(typ)]) phi = awkward.from_iter([y[m][:, 0] for y, m in zip(phi, valid)]) e = awkward.from_iter([ y[m][:, 0] for y, m in zip(outs["{}_energy".format(typ)], valid) ]) vec = vector.arr({"pt": pt, "eta": eta, "phi": phi, "e": e}) cluster = fastjet.ClusterSequence(vec.to_xyzt(), jetdef) jets = cluster.inclusive_jets() jet_constituents = cluster.constituent_index() jets_coll[typ] = jets[jets.pt > 5.0] jets_const[typ] = jet_constituents[jets.pt > 5.0] for key in ["pt", "eta", "phi", "energy"]: outs["jets_gen_{}".format(key)] = awkward.to_numpy( awkward.flatten(getattr(jets_coll["gen"], key))) outs["jets_cand_{}".format(key)] = awkward.to_numpy( awkward.flatten(getattr(jets_coll["cand"], key))) outs["jets_pred_{}".format(key)] = awkward.to_numpy( awkward.flatten(getattr(jets_coll["pred"], key))) # DeltaR match between genjets and PF/MLPF jets cart = awkward.cartesian([jets_coll["gen"], jets_coll["pred"]], nested=True) jets_a, jets_b = awkward.unzip(cart) drs = deltar(jets_a, jets_b) match_gen_to_pred = [awkward.where(d < 0.1) for d in drs] m0 = awkward.from_iter([m[0] for m in match_gen_to_pred]) m1 = awkward.from_iter([m[1] for m in match_gen_to_pred]) j1s = jets_coll["gen"][m0] j2s = jets_coll["pred"][m1] outs["jets_pt_gen_to_pred"] = np.stack([ awkward.to_numpy(awkward.flatten(j1s.pt)), awkward.to_numpy(awkward.flatten(j2s.pt)) ], axis=-1) cart = awkward.cartesian([jets_coll["gen"], jets_coll["cand"]], nested=True) jets_a, jets_b = awkward.unzip(cart) drs = deltar(jets_a, jets_b) match_gen_to_pred = [awkward.where(d < 0.1) for d in drs] m0 = awkward.from_iter([m[0] for m in match_gen_to_pred]) m1 = awkward.from_iter([m[1] for m in match_gen_to_pred]) j1s = jets_coll["gen"][m0] j2s = jets_coll["cand"][m1] outs["jets_pt_gen_to_cand"] = np.stack([ awkward.to_numpy(awkward.flatten(j1s.pt)), awkward.to_numpy(awkward.flatten(j2s.pt)) ], axis=-1) np.savez(np_outfile, X=elem["X"], **outs) ibatch += 1
def jetdisplay(): outputfile = "Jetdisplay" displayfile = TFile(outputfile+".root","RECREATE") inputfile = "wwlj1k.root" inputfile = TFile(inputfile) print "Analyzing: "+str(inputfile)+" \n" tree = TTree() inputfile.GetObject("B4", tree) graph = TH1F("energyjet", "energyjet", 100, 0., 200.) graph2 = TH1F("energycherjet", "energycherjet", 100, 0., 200.) graph3 = TH1F("energyscinjet", "energyscinjet", 100, 0., 200.) graphmass = TH1F("mass_jet", "mass_jet", 100, 0., 200.) graph4 = TH1F("energy", "energy", 100, 0., 200.) graph5 = TH1F("energycher", "energycher", 100, 0., 200.) graph6 = TH1F("energyscin", "energyscin", 100, 0., 200.) #loop over events for Event in range(tree.GetEntries()): tree.GetEntry(Event) #Set values of the tree PrimaryParticleName = tree.PrimaryParticleName # MC truth: primary particle Geant4 name PrimaryParticleEnergy = tree.PrimaryParticleEnergy EnergyTot = tree.EnergyTot # Total energy deposited in calorimeter Energyem = tree.Energyem # Energy deposited by the em component EnergyScin = tree.EnergyScin # Energy deposited in Scin fibers (not Birk corrected) EnergyCher = tree.EnergyCher # Energy deposited in Cher fibers (not Birk corrected) NofCherenkovDetected = tree.NofCherenkovDetected # Total Cher p.e. detected BarrelR_VectorSignals = tree.VectorSignalsR # Vector of energy deposited in Scin fibers (Birk corrected) BarrelL_VectorSignals = tree.VectorSignalsL # Vector of energy deposited in Scin fibers (Birk corrected) BarrelR_VectorSignalsCher = tree.VectorSignalsCherR # Vector of Cher p.e. detected in Cher fibers BarrelL_VectorSignalsCher = tree.VectorSignalsCherL VectorR = tree.VectorR VectorL = tree.VectorL Calib_BarrelL_VectorSignals = calibration.calibscin(BarrelL_VectorSignals) Calib_BarrelR_VectorSignals = calibration.calibscin(BarrelR_VectorSignals) Calib_BarrelL_VectorSignalsCher = calibration.calibcher(BarrelL_VectorSignalsCher) Calib_BarrelR_VectorSignalsCher = calibration.calibcher(BarrelR_VectorSignalsCher) energy = float(sum(Calib_BarrelR_VectorSignals)+sum(Calib_BarrelL_VectorSignals)) energycher = float(sum(Calib_BarrelR_VectorSignalsCher)+sum(Calib_BarrelL_VectorSignalsCher)) threshold = 0.0 #(GeV) if energy>70.: #event displays with signals (p.e.) #if Event < 1: #displayfile.cd() #ROOTHistograms.create_eventdisplay_scin("Jet", BarrelR_VectorSignals, BarrelL_VectorSignals, "signal"+str(Event)) #ROOTHistograms.create_eventdisplay_cher("Jet", BarrelR_VectorSignalsCher, BarrelL_VectorSignalsCher, "signal"+str(Event)) #event displays with energy (GeV) if Event<10: displayfile.cd() ROOTHistograms.create_eventdisplay_scin("Jet_energy", Calib_BarrelR_VectorSignals, Calib_BarrelL_VectorSignals, "energy"+str(Event), threshold) ROOTHistograms.create_eventdisplay_cher("Jet_energy", Calib_BarrelR_VectorSignalsCher, Calib_BarrelL_VectorSignalsCher, "energy"+str(Event), threshold) inputparticles_scin = [] inputparticles_cher = [] #right part for towerindex in range(75*36): theta, phi, eta = newmap.maptower(towerindex, "right") energy_scin = Calib_BarrelR_VectorSignals[towerindex] pt_scin = energy_scin*np.sin(theta*math.pi/180.) energy_cher = Calib_BarrelR_VectorSignalsCher[towerindex] pt_cher = energy_cher*np.sin(theta*math.pi/180.) towerscin = TLorentzVector() towerscin.SetPtEtaPhiM(pt_scin, eta, phi*math.pi/180., 0.) towercher = TLorentzVector() towercher.SetPtEtaPhiM(pt_cher, eta, phi*math.pi/180., 0.) if energy_scin > threshold: #print "truth towers: "+str(energy_scin)+" "+str(eta)+" "+str(phi) inputparticles_scin.append(fastjet.PseudoJet(towerscin.Px(), towerscin.Py(), towerscin.Pz(), towerscin.E())) inputparticles_cher.append(fastjet.PseudoJet(towercher.Px(), towercher.Py(), towercher.Pz(), towercher.E())) #left part for towerindex in range(75*36): theta, phi, eta = newmap.maptower(towerindex, "left") energy_scin = Calib_BarrelL_VectorSignals[towerindex] pt_scin = energy_scin*np.sin(theta*math.pi/180.) energy_cher = Calib_BarrelL_VectorSignalsCher[towerindex] pt_cher = energy_cher*np.sin(theta*math.pi/180.) towerscin = TLorentzVector() towerscin.SetPtEtaPhiM(pt_scin, eta, phi*math.pi/180., 0.) towercher = TLorentzVector() towercher.SetPtEtaPhiM(pt_cher, eta, phi*math.pi/180., 0.) if energy_scin > threshold: #print "truth towers: "+str(energy_scin)+" "+str(eta)+" "+str(phi) inputparticles_scin.append(fastjet.PseudoJet(towerscin.Px(), towerscin.Py(), towerscin.Pz(), towerscin.E())) inputparticles_cher.append(fastjet.PseudoJet(towercher.Px(), towercher.Py(), towercher.Pz(), towercher.E())) jet_def = fastjet.JetDefinition(fastjet.ee_genkt_algorithm, 2*math.pi, 1.) clust_seq = fastjet.ClusterSequence(inputparticles_scin, jet_def) print "Event: "+str(Event)+" energy (GeV): "+str(energy)+" n-jets: "+str(len(clust_seq.exclusive_jets(int(2))))+" truth: "+str(len(inputparticles_scin)) clust_seq_cher = fastjet.ClusterSequence(inputparticles_cher, jet_def) jet1_scin = fastjet.sorted_by_E(clust_seq.exclusive_jets(int(2)))[0] jet2_scin = fastjet.sorted_by_E(clust_seq.exclusive_jets(int(2)))[1] jet1_cher = fastjet.sorted_by_E(clust_seq_cher.exclusive_jets(int(2)))[0] jet2_cher = fastjet.sorted_by_E(clust_seq_cher.exclusive_jets(int(2)))[1] print "DeltaR jet1_scin: "+str(jet1_scin.delta_R(jet1_cher))+" "+str(jet1_scin.delta_R(jet2_cher)) c = 0.34 #chi factor jet1, jet2 = mergejet(jet1_scin, jet2_scin, jet1_cher, jet2_cher) graph.Fill(jet1.e()+jet2.e()) graph3.Fill(jet1_scin.e()+jet2_scin.e()) graph2.Fill(jet1_cher.e()+jet2_cher.e()) j = jet1+jet2 graphmass.Fill(j.m()) graph4.Fill((energy-c*energycher)/(1.-c)) graph5.Fill(energycher) graph6.Fill(energy) graph.Write() graph2.Write() graph3.Write() graph4.Write() graph5.Write() graph6.Write() graphmass.Write()
def analyze_event(self, fj_particles, gridsize=None, diagnostic=False): self.event_bck_df = None self.event_bck_df = self.bck_df[self.bck_df['ev_id'] == self.ev_idx[ self.event_number]] #print(self.event_number) self.event_number += 1 if self.event_number > self.nEvents: return if len(fj_particles) > 1: if np.abs(fj_particles[0].eta() - fj_particles[1].eta()) < 1e-10: if fj_particles[0].pt() < 1e-5: print( 'WARNING: Duplicate DUMMY particles may be present in event', self.event_number) else: print( 'WARNING: Duplicate JET particles may be present in event', self.event_number) #[print(p.eta(),p.pt()) for p in fj_particles] # If constituent subtraction is enabled, perform subtraction on the event if self.constituent_subtractor: # Convert df of pt/eta/phi of thermal particles to list of fastjet particles, for convenience thermal_particles = [] if len(self.event_bck_df) != 0: thermal_particles = self.get_fjparticles(self.event_bck_df) # Drop specified fraction of thermal particles -- loop manually since the wrapped functions are a bit funky thermal_particles_selected = [] for i, p in enumerate(thermal_particles): if np.random.uniform() >= self.thermal_rejection_fraction: thermal_particles_selected.append(p) #print(f'n_thermals before: {len(thermal_particles)}') #print(f'n_thermals after: {len(thermal_particles_selected)}') # Determine rho from thermal particles self.constituent_subtractor.bge_rho.set_particles( thermal_particles_selected) # Perform subtraction over full event (jet+recoil) fj_particles = self.constituent_subtractor.subtractor.subtract_event( fj_particles) #rho = self.constituent_subtractor.bge_rho.rho() #print(f'rho: {rho}') #print() # Loop through jetR, and process event for each R for jetR in self.jetR_list: # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector = fj.SelectorPtMin(5.0) & fj.SelectorAbsRapMax(0.9 - jetR) # Do jet finding jets_selected = None cs = fj.ClusterSequence(fj_particles, jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) # If no jets were selected, move on to next event if len(jets_selected) == 0: continue #---------------------------------------------- fj_subtracted_constituents = None subtracted_jets = [] if not self.thermal_subtraction_method: subtracted_jets = jets_selected elif '4momsub' in self.thermal_subtraction_method.lower(): ''' ------------------------------------------------ Thermal subtraction using 4MomSub method ------------------------------------------------ 1. Cluster the initial jet collection from the final state particles (including dummies). 2. Compile a list of the thermal momenta (particles in the HepMC event record with status code 3). For each jet, get the list of thermal momenta that have DeltaR < 1x10-5 with one of the jet constituents, i.e a dummy particle. 4. Sum up the four-momenta of the matched thermal momenta. This constitutes the background. 5. For each jet subtract the background four-momentum from the jet's four momentum, this provides the corrected jet collection. 6. Calculate jet observables from corrected jet four-momenta. ''' for jet in jets_selected: fj_subtracted_constituents = None fj_subtracted_constituents = self.subtract_thermal_4momsub( jet, jetR) jet_def_largerR = fj.JetDefinition(fj.antikt_algorithm, 2. * jetR) cs_largerR = fj.ClusterSequence(fj_subtracted_constituents, jet_def_largerR) subtracted_jets = fj.sorted_by_pt( cs_largerR.inclusive_jets()) if len(subtracted_jets) > 1: print( 'WARNING: Got more than one subtracted jet out of one input jet' ) elif 'gridsub' in self.thermal_subtraction_method.lower(): ''' ------------------------------------------------ Thermal subtraction using GridSub1 method ------------------------------------------------ 1. Cluster the initial jet collection from the final state particles. 2. Compile a list of the thermal momenta (particles in the HepMC event record with status code 3). 3. Define the grid resolution and place grid over jets. 4. Inside each cell sum the jet constituents' four-momenta and subtract the thermal four-momenta that fall into the cell (note: no matching is required, thermal four momenta with distance DeltaR < R from the jet axis are considered), providing a single four momentum for each cell. 5. In case a cell contains more thermal momentum than jet constituents, the cells is set to have zero four-momentum. This is deemed to be the case when the (scalar) pT of the thermal component is larger than the pT of the particle component. 6. Re-cluster the jets with the cell four-momenta as input to get the final, subtracted jets. 7. Calculate jet observables from re-clustered jets. ''' fj_subtracted_constituents = self.subtract_thermal_gridsub1( jets_selected, jetR, gridsize, diagnostic) if not fj_subtracted_constituents: continue cs = fj.ClusterSequence(fj_subtracted_constituents, jet_def) subtracted_jets = fj.sorted_by_pt(cs.inclusive_jets()) #---------------------------------------------- result = [ self.analyze_accepted_jet(jet, jetR, gridsize, diagnostic) for jet in subtracted_jets ]
def analyze_event(self, fj_particles_det, fj_particles_truth, fj_particles_det_holes=None, fj_particles_truth_holes=None): self.event_number += 1 if self.event_number > self.event_number_max: return if self.debug_level > 1: print('-------------------------------------------------') print('event {}'.format(self.event_number)) # Check that the entries exist appropriately # (need to check how this can happen -- but it is only a tiny fraction of events) if type(fj_particles_det) != fj.vectorPJ or type( fj_particles_truth) != fj.vectorPJ: print('fj_particles type mismatch -- skipping event') return if self.jetscape: if type(fj_particles_det_holes) != fj.vectorPJ or type( fj_particles_truth_holes) != fj.vectorPJ: print('fj_particles_holes type mismatch -- skipping event') return if len(fj_particles_truth) > 1: if np.abs(fj_particles_truth[0].pt() - fj_particles_truth[1].pt()) < 1e-10: print('WARNING: Duplicate particles may be present') print([p.user_index() for p in fj_particles_truth]) print([p.pt() for p in fj_particles_truth]) # If Pb-Pb, construct embedded event (do this once, for all jetR) if not self.is_pp: # If thermal model, generate a thermal event and add it to the det-level particle list if self.thermal_model: fj_particles_combined_beforeCS = self.thermal_generator.load_event( ) # Form the combined det-level event # The pp-det tracks are each stored with a unique user_index >= 0 # (same index in fj_particles_combined and fj_particles_det -- which will be used in prong-matching) # The thermal tracks are each stored with a unique user_index < 0 [ fj_particles_combined_beforeCS.push_back(p) for p in fj_particles_det ] # Main case: Get Pb-Pb event and embed it into the det-level particle list else: fj_particles_combined_beforeCS = self.process_io_emb.load_event( ) # Form the combined det-level event # The pp-det tracks are each stored with a unique user_index >= 0 # (same index in fj_particles_combined and fj_particles_det -- which will be used in prong-matching) # The Pb-Pb tracks are each stored with a unique user_index < 0 [ fj_particles_combined_beforeCS.push_back(p) for p in fj_particles_det ] # Perform constituent subtraction for each R_max fj_particles_combined = [ self.constituent_subtractor[i].process_event( fj_particles_combined_beforeCS) for i, R_max in enumerate(self.max_distance) ] if self.debug_level > 3: print([p.user_index() for p in fj_particles_truth]) print([p.pt() for p in fj_particles_truth]) print([p.user_index() for p in fj_particles_det]) print([p.pt() for p in fj_particles_det]) print([p.user_index() for p in fj_particles_combined_beforeCS]) print([p.pt() for p in fj_particles_combined_beforeCS]) if self.dry_run: return # Loop through jetR, and process event for each R for jetR in self.jetR_list: # Keep track of whether to fill R-independent histograms self.fill_R_indep_hists = (jetR == self.jetR_list[0]) # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector_det = fj.SelectorPtMin(5.0) & fj.SelectorAbsRapMax( 0.9 - jetR) jet_selector_truth_matched = fj.SelectorPtMin( 5.0) & fj.SelectorAbsRapMax(0.9) if self.debug_level > 2: print('') print('jet definition is:', jet_def) print('jet selector for det-level is:', jet_selector_det) print('jet selector for truth-level matches is:', jet_selector_truth_matched) # Analyze if self.is_pp: # Find pp det and truth jets cs_det = fj.ClusterSequence(fj_particles_det, jet_def) jets_det_pp = fj.sorted_by_pt(cs_det.inclusive_jets()) jets_det_pp_selected = jet_selector_det(jets_det_pp) cs_truth = fj.ClusterSequence(fj_particles_truth, jet_def) jets_truth = fj.sorted_by_pt(cs_truth.inclusive_jets()) jets_truth_selected = jet_selector_det(jets_truth) jets_truth_selected_matched = jet_selector_truth_matched( jets_truth) self.analyze_jets(jets_det_pp_selected, jets_truth_selected, jets_truth_selected_matched, jetR) else: for i, R_max in enumerate(self.max_distance): if self.debug_level > 1: print('') print('R_max: {}'.format(R_max)) print('Total number of combined particles: {}'.format( len([ p.pt() for p in fj_particles_combined_beforeCS ]))) print('After constituent subtraction {}: {}'.format( i, len([p.pt() for p in fj_particles_combined[i]]))) # Keep track of whether to fill R_max-independent histograms self.fill_Rmax_indep_hists = (i == 0) # Perform constituent subtraction on det-level, if applicable self.fill_background_histograms( fj_particles_combined_beforeCS, fj_particles_combined[i], jetR, i) # Do jet finding (re-do each time, to make sure matching info gets reset) cs_det = fj.ClusterSequence(fj_particles_det, jet_def) jets_det_pp = fj.sorted_by_pt(cs_det.inclusive_jets()) jets_det_pp_selected = jet_selector_det(jets_det_pp) cs_truth = fj.ClusterSequence(fj_particles_truth, jet_def) jets_truth = fj.sorted_by_pt(cs_truth.inclusive_jets()) jets_truth_selected = jet_selector_det(jets_truth) jets_truth_selected_matched = jet_selector_truth_matched( jets_truth) cs_combined = fj.ClusterSequence(fj_particles_combined[i], jet_def) jets_combined = fj.sorted_by_pt( cs_combined.inclusive_jets()) jets_combined_selected = jet_selector_det(jets_combined) self.analyze_jets( jets_combined_selected, jets_truth_selected, jets_truth_selected_matched, jetR, jets_det_pp_selected=jets_det_pp_selected, R_max=R_max, fj_particles_det_holes=fj_particles_det_holes, fj_particles_truth_holes=fj_particles_truth_holes)
def analyze_jets(self, fj_particles_det, fj_particles_truth, jet_def, jet_selector_det, jet_selector_truth_matched): # Check that the entries exist appropriately # (need to check how this can happen -- but it is only a tiny fraction of events) if type(fj_particles_det) != fj.vectorPJ or type(fj_particles_truth) != fj.vectorPJ: print('fj_particles type mismatch -- skipping event') return # Perform constituent subtraction on det-level, if applicable if self.do_constituent_subtraction: fj_particles_det = self.constituent_subtractor.process_event(fj_particles_det) rho = self.constituent_subtractor.bge_rho.rho() # Do jet finding cs_det = fj.ClusterSequence(fj_particles_det, jet_def) jets_det = fj.sorted_by_pt(cs_det.inclusive_jets()) jets_det_selected = jet_selector_det(jets_det) cs_truth = fj.ClusterSequence(fj_particles_truth, jet_def) jets_truth = fj.sorted_by_pt(cs_truth.inclusive_jets()) jets_truth_selected = jet_selector_det(jets_truth) jets_truth_selected_matched = jet_selector_truth_matched(jets_truth) jetR = jet_def.R() # Fill det-level jet histograms (before matching) for jet_det in jets_det_selected: # Check additional acceptance criteria # skip event if not satisfied -- since first jet in event is highest pt if not self.utils.is_det_jet_accepted(jet_det): self.hNevents.Fill(0) if self.debug_level > 1: print('event rejected due to jet acceptance') return #self.fill_det_before_matching(jet_det, jetR) # Fill truth-level jet histograms (before matching) for jet_truth in jets_truth_selected: self.fill_truth_before_matching(jet_truth, jetR) # Loop through jets and set jet matching candidates for each jet in user_info hname_deltaR = "hDeltaR_All_R%s" % str(jetR).replace('.', '') for jet_det in jets_det_selected: for jet_truth in jets_truth_selected_matched: self.set_matching_candidates(jet_det, jet_truth, jetR, hname_deltaR) # Loop through jets and set accepted matches hname_QA = 'hJetMatchingQA_R%s' % str(jetR).replace('.', '') for jet_det in jets_det_selected: self.set_matches_pp(jet_det, hname_QA) # Fill matching histograms if jet_det.has_user_info(): jet_truth = jet_det.python_info().match if jet_truth: self.fill_matching_histograms(jet_det, jet_truth, jetR) # Fill response matrices for each subobservable for alpha in self.alpha_list: self.fill_response_histograms(jet_det, jet_truth, jetR, alpha)
def analyze_event(self, fj_particles): self.event_number += 1 if self.event_number > self.event_number_max: return if self.debug_level > 1: print('-------------------------------------------------') print('event {}'.format(self.event_number)) if len(fj_particles) > 1: if np.abs(fj_particles[0].pt() - fj_particles[1].pt()) < 1e-10: print('WARNING: Duplicate particles may be present') print([p.user_index() for p in fj_particles]) print([p.pt() for p in fj_particles]) # Perform constituent subtraction for each R_max (do this once, for all jetR) if not self.is_pp: fj_particles_subtracted = { R_max : cs.process_event(fj_particles) for \ R_max, cs in self.constituent_subtractor.items() } # Loop through jetR, and process event for each R for jetR in self.jetR_list: # Keep track of whether to fill R-independent histograms self.fill_R_indep_hists = (jetR == self.jetR_list[0]) # Set jet definition and a jet selector jet_def = fj.JetDefinition(fj.antikt_algorithm, jetR) jet_selector = fj.SelectorPtMin(5.0) & fj.SelectorAbsRapMax(0.9 - jetR) if self.debug_level > 2: print('jet definition is:', jet_def) print('jet selector is:', jet_selector,'\n') # Analyze if self.is_pp or self.include_no_subtraction: # Do jet finding cs = fj.ClusterSequence(fj_particles, jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) self.analyze_jets(jets_selected, jetR) if not self.is_pp: max_distance = self.max_distance if isinstance(self.max_distance, list) else \ self.max_distance[jetR] for R_max in max_distance: if self.debug_level > 1: print('R_max: {}'.format(R_max)) # Keep track of whether to fill R_max-independent histograms self.fill_Rmax_indep_hists = (R_max == max_distance[0]) # Perform constituent subtraction rho = self.constituent_subtractor[R_max].bge_rho.rho() if self.fill_R_indep_hists and self.fill_Rmax_indep_hists: getattr(self, 'hRho').Fill(rho) # Do jet finding (re-do each time, to make sure matching info gets reset) cs = fj.ClusterSequence(fj_particles_subtracted[R_max], jet_def) jets = fj.sorted_by_pt(cs.inclusive_jets()) jets_selected = jet_selector(jets) self.analyze_jets(jets_selected, jetR, R_max = R_max)