def draw_jet(j, Rabs=0.4): # for the jet but not subjets pts = [p.perp() for p in fj.sorted_by_pt(j.constituents())] ys = [ j.rapidity() - p.rapidity() for p in fj.sorted_by_pt(j.constituents()) ] phis = [j.delta_phi_to(p) for p in fj.sorted_by_pt(j.constituents())] print("n | pt | z | phi | eta | dR") for i, p in enumerate(fj.sorted_by_pt(j.constituents())): print(i, p.perp(), p.perp() / j.perp(), p.phi(), p.eta(), p.delta_R(j)) phis.append(Rabs) phis.append(-Rabs) ys.append(Rabs) ys.append(-Rabs) pts.append(0) pts.append(0) zs = [pt / j.perp() for pt in pts] zs_sized = [z * 1000. for z in zs] cs = [int(z * 100.) for z in zs] fig = plt.figure() # plt.scatter(phis, ys, c=colors, s=zs_sized, alpha=0.4, cmap="PuOr") #cmap='viridis') # plt.scatter(phis, ys, c=cs, s=zs_sized, alpha=0.4, cmap="magma") #cmap='viridis') plt.scatter(phis, ys, c=cs, s=zs_sized, alpha=0.4, cmap='viridis') plt.xlabel('phi') plt.ylabel('y') # plt.colorbar(); # show color scale plt.show()
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, 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, 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 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 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 find_jets_fill_trees(self, parts_pythia_p, parts_pythia_h, parts_pythia_hch, iev, MPIon=False, ISRon=True): for jetR in self.jetR_list: jetR_str = str(jetR).replace('.', '') jet_selector = getattr(self, "jet_selector_R%s" % jetR_str) jet_def = getattr(self, "jet_def_R%s" % jetR_str) count1 = getattr(self, "count1_R%s" % jetR_str) count2 = getattr(self, "count2_R%s" % jetR_str) jets_p = fj.sorted_by_pt(jet_selector(jet_def(parts_pythia_p))) # parton level jets_h = fj.sorted_by_pt(jet_selector(jet_def(parts_pythia_h))) # full hadron level jets_ch = fj.sorted_by_pt(jet_selector(jet_def(parts_pythia_hch))) # charged hadron level # instance with multi-parton interactions turned on if MPIon and ISRon: for jet in jets_ch: self.fill_MPI_histograms(jetR, jet) continue for i,jchh in enumerate(jets_ch): # match hadron jets and charged jets drhh_list = [] for j, jh in enumerate(jets_h): drhh = jchh.delta_R(jh) if drhh < jetR / 2.: drhh_list.append((j,jh)) if len(drhh_list) != 1: count1 += 1 else: # Require unique match j, jh = drhh_list[0] # match parton level jet dr_list = [] for k, jp in enumerate(jets_p): dr = jh.delta_R(jp) if dr < jetR / 2.: dr_list.append((k, jp)) if len(dr_list) != 1: count2 += 1 else: k, jp = dr_list[0] self.fill_jet_histograms(jetR, jp, jh, jchh) setattr(self, "count1_R%s" % jetR_str, count1) setattr(self, "count2_R%s" % jetR_str, count2)
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 match_dR(j, partons, drmatch=0.1): mps = [p for p in partons if j.delta_R(p) < drmatch] # for p in fj.sorted_by_pt(mps)[0]: p = fj.sorted_by_pt(mps)[0] pyp = pythiafjext.getPythia8Particle(p) # print(p, pyp.id(), pyp.isQuark(), pyp.isGluon()) return pyp.id(), pyp.isQuark(), pyp.isGluon()
def fj_example_02_area(event): # cluster the event jet_def = fj.JetDefinition(fj.antikt_algorithm, 0.4) area_def = fj.AreaDefinition(fj.active_area, fj.GhostedAreaSpec(5.0)) cs = fj.ClusterSequenceArea(event, jet_def, area_def) jets = fj.SelectorPtMin(5.0)(fj.sorted_by_pt(cs.inclusive_jets())) print("jet def:", jet_def) print("area def:", area_def) print("#-------------------- initial jets --------------------") print_jets(jets) #---------------------------------------------------------------------- # estimate the background maxrap = 4.0 grid_spacing = 0.55 gmbge = fj.GridMedianBackgroundEstimator(maxrap, grid_spacing) gmbge.set_particles(event) print("#-------------------- background properties --------------------") print("rho = ", gmbge.rho()) print("sigma = ", gmbge.sigma()) print() #---------------------------------------------------------------------- # subtract the jets subtractor = fj.Subtractor(gmbge) subtracted_jets = subtractor(jets) print("#-------------------- subtracted jets --------------------") print_jets(subtracted_jets)
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 recluster(particles, Rjet, jetdef_tree): #---------------------------------------------- # Recluster the jet constituents and access the clustering history #set up our jet definition and a jet selector if jetdef_tree == 'antikt': tree_jet_def = fj.JetDefinition(fj.antikt_algorithm, Rjet) elif jetdef_tree == 'kt': tree_jet_def = fj.JetDefinition(fj.kt_algorithm, Rjet) elif jetdef_tree == 'CA': tree_jet_def = fj.JetDefinition(fj.cambridge_algorithm, Rjet) else: print('Missing jet definition') # selector = fj.SelectorPtMin(20.0) #We add extra constraints # out_jet = selector(fj.sorted_by_pt(tree_jet_def(preprocess_const_list)))[0] #Apply jet pT cut of 20 GeV and sort jets by pT. Recluster the jet constituents, they should give us only 1 jet if using the original jet radius. out_jet = fj.sorted_by_pt( tree_jet_def(particles) ) #Recluster the jet constituents, they should give us only 1 jet if using the original jet radius # print( 'jets=',jets) # print('jets const=',jets[0].constituents()) # print('----'*20) # print('Out_jet=',out_jet.px(),out_jet.py(),out_jet.pz(),out_jet.e(),out_jet.m(),out_jet.perp()) return out_jet
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 cluster(particle_list, Rjet, jetdef_tree): if jetdef_tree == 'antikt': tree_jet_def = fj.JetDefinition(fj.antikt_algorithm, Rjet) elif jetdef_tree == 'kt': tree_jet_def = fj.JetDefinition(fj.kt_algorithm, Rjet) elif jetdef_tree == 'CA': tree_jet_def = fj.JetDefinition(fj.cambridge_algorithm, Rjet) else: print('Missing jet definition') jets = [] out_jet = fj.sorted_by_pt(tree_jet_def(particle_list)) for i in range(len(out_jet)): if i == 0: trees, contents = cluster_h._traverse(out_jet[i]) tree = np.asarray([trees]) tree = np.asarray([np.asarray(e).reshape(-1, 2) for e in tree]) content = np.asarray([contents]) content = np.asarray( [np.asarray(e).reshape(-1, 4) for e in content]) masses = out_jet[i].m() pts = out_jet[i].pt() etas = out_jet[i].eta() phis = out_jet[i].phi() jets.append((tree, content, masses, pts, etas, phis)) return jets
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 analysis(self, df): djmm = fjtools.DJetMatchMaker() djmm.set_ch_pt_eta_phi(self.df_tracks['ParticlePt'].values, self.df_tracks['ParticleEta'].values, self.df_tracks['ParticlePhi'].values) djmm.set_Ds_pt_eta_phi_m(df['pt_cand'].values, df['eta_cand'].values, df['phi_cand'].values, df['inv_mass'].values) djmm.set_daughters0_pt_eta_phi(df['pt_prong0'].values, df['eta_prong0'].values, df['phi_prong0'].values) djmm.set_daughters1_pt_eta_phi(df['pt_prong1'].values, df['eta_prong1'].values, df['phi_prong1'].values) self.tw.fill_branches(dpsj=djmm.Ds) self.tw.fill_tree() for id0, d0 in enumerate(djmm.Ds): _parts_and_ds = djmm.match(0.005, id0) _parts_and_ds.push_back(d0) ja = jet_analysis.JetAnalysis(jet_R=0.4, particle_eta_max=0.9, jet_pt_min=2.0) ja.analyze_event(_parts_and_ds) if len(ja.jets) < 1: continue jets = ja.jets_as_psj_vector() djets = djmm.filter_D0_jets(jets) if len(djets) > 0: j = djets[0] dcand = djmm.get_Dcand_in_jet(j) sja = jet_analysis.JetAnalysis(jet_R=0.1, particle_eta_max=0.9, jet_pt_min=2.0) sja.analyze_event(j.constituents()) lsj = fj.sorted_by_pt(sja.jets_as_psj_vector()) if len(lsj) < 1: continue sj_dcand = djmm.get_Dcand_in_jet(lsj[0]) is_Dsj = 0 if len(sj_dcand) > 0: # if sj_dcand[0].m() == dcand[0].m() and sj_dcand[0].perp() == dcand[0].perp(): if sj_dcand[0].delta_R(dcand[0]) == 0.0: is_Dsj = 1 self.twjc.fill_branches(jet=j, dR=j.delta_R(dcand[0]), D=dcand[0], lsj=lsj[0], Dsj=is_Dsj, a10=fjext.angularity(j, 1.0, 0.4), a15=fjext.angularity(j, 0.5, 0.4), a20=fjext.angularity(j, 0.0, 0.4), a30=fjext.angularity(j, -1.0, 0.4)) self.twjc.fill_tree() if len(djets) > 1: perror("more than one jet per D candidate?") return True
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 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, 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 parton_splittings_parton_only(pythia, selected_jet, maxR=0.4): spinfo = SplitInfo(pythia) for p in fj.sorted_by_pt(selected_jet.constituents()): pyp = pythiafjext.getPythia8Particle(p) if pyp.isParton(): if p.delta_R(selected_jet) < maxR: spinfo.find_split(p.user_index()) print (spinfo) else: continue
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 calc_n_lead(j, n=8): cs = fj.sorted_by_pt(j.constituents()) _sum_top_n = 0 _sum_all = 0 for i in range(len(cs)): _sum_all += cs[i].pt() if i < n: _sum_top_n += cs[i].pt() _fraction_pt = _sum_top_n / _sum_all return _sum_all, _sum_top_n, _fraction_pt
def analyze_event(self, parts): self.particles = self.particle_selector(parts) if len(self.particles) < 1: self.cs = None self.jets = [] else: self.cs = fj.ClusterSequenceArea(self.particles, self.jet_def, self.jet_area_def) self.jets = fj.sorted_by_pt( self.jet_selector(self.cs.inclusive_jets()))
def analyze_event(self, parts): if len(parts) < 1: self.rho = 0.0 self.cs = None self.jets = [] self.corr_jet_pt = [] else: self.bg_estimator.set_particles(parts) self.rho = self.bg_estimator.rho() self.cs = fj.ClusterSequenceArea(parts, self.jet_def, self.jet_area_def) self.jets = fj.sorted_by_pt(self.jet_selector(self.cs.inclusive_jets())) self.corr_jet_pt = [j.pt() - j.area() * self.rho for j in self.jets]
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 print_jets(jets): for ijet in range(len(jets)): jet = jets[ijet] constituents = jet.constituents() print("{0:>5s} {1:>10s} {2:>10s} {3:>10s} {4:>12s}".format( "jet #", "pt", "rap", "phi", "N particles")) print("{0:5d} {1:10.3f} {2:10.4f} {3:10.4f} {4:5d}".format( ijet, jet.pt(), jet.rap(), jet.phi(), len(constituents))) for c in fj.sorted_by_pt(constituents): _p = pyfj.getPythia8Particle(c) if _p: print( " - {0:>10s} id={1:5d} status={2:5d} pT={3:10.3f}".format( _p.name(), _p.id(), _p.status(), _p.pT()))
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 recluster(particles, Rjet, jetdef_tree): """Recluster the jet constituents""" # Recluster the jet constituents and access the clustering history #set up our jet definition and a jet selector if jetdef_tree == 'antikt': tree_jet_def = fj.JetDefinition(fj.antikt_algorithm, Rjet) elif jetdef_tree == 'kt': tree_jet_def = fj.JetDefinition(fj.kt_algorithm, Rjet) elif jetdef_tree == 'CA': tree_jet_def = fj.JetDefinition(fj.cambridge_algorithm, Rjet) else: logging.info('Missing jet definition') # Recluster the jet constituents, they should give us only 1 jet if using # the original jet radius out_jet = fj.sorted_by_pt(tree_jet_def(particles)) return out_jet
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)