4 """ Skim list building functions for the dark sector physics working group """
17 import modularAnalysis
as ma
19 from skimExpertFunctions
import BaseSkim, fancy_skim_header, get_test_file
20 from stdCharged
import stdE, stdMu, stdPi, stdK
21 from stdPhotons
import stdPhotons
22 import vertex
as vertex
24 __liaison__ =
"Sascha Dreyer <sascha.dreyer@desy.de>"
30 **Physics channel**: ee → A'γ; A' → invisible
32 Skim list contains single photon candidates for the dark photon to invisible final
35 __authors__ = [
"Sam Cunliffe",
"Chris Hearty"]
36 __contact__ = __liaison__
37 __description__ =
"Single photon skim list for the dark photon analysis."
38 __category__ =
"physics, dark sector"
39 ApplyHLTHadronCut =
False
47 in_tracking_acceptance =
"0.296706 < theta < 2.61799"
49 "gamma:singlePhoton",
"gamma:all",
50 f
"useCMSFrame(E) > 0.5 and {in_tracking_acceptance}", path=path)
54 region_dependent =
" [clusterTheta < 1.65457213 and clusterTheta > 0.77143553] or "
55 region_dependent +=
"[clusterReg == 2 and useCMSFrame(E) > 1.0] or "
56 region_dependent +=
"[clusterReg == 1 and useCMSFrame(E) > 2.0] or "
57 region_dependent +=
"[clusterReg == 3 and useCMSFrame(E) > 2.0] or "
58 region_dependent +=
"[clusterReg == 11 and useCMSFrame(E) > 2.0] or "
59 region_dependent +=
"[clusterReg == 13 and useCMSFrame(E) > 2.0]"
60 ma.applyCuts(
"gamma:singlePhoton", region_dependent, path=path)
63 good_tracks =
'abs(dz) < 2.0 and abs(dr) < 0.5 and pt > 0.15'
65 f
"nParticlesInList(gamma:singlePhoton) == 1 and nCleanedTracks({good_tracks}) == 0",
73 not_in_signal_list =
"isInList(gamma:singlePhoton) < 1"
74 in_time =
"maxWeightedDistanceFromAverageECLTime < 1"
75 ma.cutAndCopyList(
"gamma:to_veto",
"gamma:all",
76 f
"E > 0.55 and {not_in_signal_list}", path=path)
77 ma.rankByHighest(
"gamma:to_veto",
"E", numBest=1, path=path)
78 ma.reconstructDecay(
"vpho:veto -> gamma:singlePhoton gamma:to_veto",
80 veto_additional_in_time_cluster =
'nParticlesInList(vpho:veto) < 1'
86 ma.applyCuts(
"gamma:singlePhoton", veto_additional_in_time_cluster, path=path)
92 __authors__ = [
"Michael De Nuccio"]
94 "Neutral dark sector skim list for the ALP 3-photon analysis: "
95 ":math:`ee\\to a(\\to\\gamma\\gamma)\\gamma`"
97 __contact__ = __liaison__
98 __category__ =
"physics, dark sector"
99 ApplyHLTHadronCut =
False
102 """Adds the ALP codes to the basf2 pdg instance """
108 An list builder function for the ALP decays. Part of the `ALP3Gamma` skim.
111 path (basf2.Path): the path to add the skim
114 list name of the ALP decays candidates
121 'gamma:cdcAndMinimumEnergy',
122 'E >= 0.1 and theta >= 0.297 and theta <= 2.618',
127 ALPchannels = [
'gamma:cdcAndMinimumEnergy gamma:cdcAndMinimumEnergy']
131 for chID, channel
in enumerate(ALPchannels):
132 mode =
'ALP:' + str(chID) +
' -> ' + channel
134 ma.reconstructDecay(mode, ALPcuts, chID, path=path)
136 ALPList.append(
'ALP:' + str(chID))
146 beamcuts =
"InvM >= formula(0.8 * Ecms) and InvM <= formula(1.05 * Ecms) and maxWeightedDistanceFromAverageECLTime <= 2"
151 ma.fillParticleList(
"gamma:minimumEnergy",
"E >= 0.1",
True, path=path)
156 for chID, channel
in enumerate(ALPList):
157 mode =
"beam:" + str(chID) +
" -> gamma:minimumEnergy " + channel
159 ma.reconstructDecay(mode, beamcuts, chID, path=path)
160 beamList.append(
"beam:" + str(chID))
167 **Physics channel**: :math:`e^{+}e^{-} \\to \\mu^{+}\\mu^{-} \\, +` missing energy.
169 __authors__ = [
"Giacomo De Pietro"]
171 "Dimuon + missing energy skim, needed for :math:`e^{+}e^{-} \\to \\mu^{+}\\mu^{-}"
172 "Z^{\\prime}; \\, Z^{\\prime} \\to \\mathrm{invisible}` and other searches."
174 __contact__ = __liaison__
175 __category__ =
"physics, dark sector"
176 ApplyHLTHadronCut =
False
179 stdMu(
"all", path=path)
183 skim_label =
"forDimuonMissingEnergySkim"
184 dimuon_name =
"Z0:" + skim_label
187 fromIP_cut =
"[abs(dz) < 5.0] and [abs(dr) < 2.0]"
188 muonID_cut =
"[muonID > 0.3]"
190 dimuon_cut =
"[nCleanedTracks(" + fromIP_cut +
") < 4]"
192 dimuon_cut +=
" and [useCMSFrame(pt) > 0.2]"
195 ma.cutAndCopyList(
"mu+:" + skim_label,
"mu+:all", fromIP_cut +
" and " + muonID_cut, path=path)
196 ma.reconstructDecay(dimuon_name +
" -> mu+:" + skim_label +
" mu-:" + skim_label, dimuon_cut, path=path)
199 dimuon_list.append(dimuon_name)
205 __authors__ = [
"Giacomo De Pietro"]
207 "Electron-muon pair + missing energy skim, needed for :math:`e^{+}e^{-} \\to "
208 "e^{\\pm}\\mu^{\\mp} Z^{\\prime}; \\, Z^{\\prime} \\to \\mathrm{invisible}` and other "
211 __contact__ = __liaison__
212 __category__ =
"physics, dark sector"
213 ApplyHLTHadronCut =
False
216 stdE(
"all", path=path)
217 stdMu(
"all", path=path)
221 **Physics channel**: :math:`e^{+}e^{-} \\to e^{\\pm}\\mu^{\\mp} \\, +` missing energy
224 skim_label =
"forElectronMuonMissingEnergySkim"
225 emu_name =
"Z0:" + skim_label
228 fromIP_cut =
"[abs(dz) < 5.0] and [abs(dr) < 2.0]"
229 electronID_cut =
"[electronID > 0.3]"
230 muonID_cut =
"[muonID > 0.3]"
232 theta_cut =
"[0.387 < theta < 2.421]"
234 emu_cut =
"[nCleanedTracks(" + fromIP_cut +
") < 4]"
236 emu_cut +=
" and [useCMSFrame(pt) > 0.2]"
239 ma.cutAndCopyList(
"e+:" + skim_label,
"e+:all", fromIP_cut +
" and " + electronID_cut +
" and " + theta_cut, path=path)
240 ma.cutAndCopyList(
"mu+:" + skim_label,
"mu+:all", fromIP_cut +
" and " + muonID_cut, path=path)
241 ma.reconstructDecay(emu_name +
" -> e+:" + skim_label +
" mu-:" + skim_label, emu_cut, path=path)
244 emu_list.append(emu_name)
250 __authors__ = [
"Ilya Komarov"]
251 __description__ =
"Lepton flavour violating Z' skim, Z' to visible FS."
252 __contact__ = __liaison__
253 __category__ =
"physics, dark sector"
254 ApplyHLTHadronCut =
False
257 stdE(
"all", path=path)
258 stdE(
"loose", path=path)
262 **Physics channel**: ee --> e mu Z'; Z' --> e mu
267 track_cuts =
"abs(dz) < 2.0 and abs(dr) < 0.5"
268 Event_cuts_vis =
"nCleanedTracks(abs(dz) < 2.0 and abs(dr) < 0.5) == 4"
270 ma.cutAndCopyList(
"e+:lfvzp",
"e+:all", track_cuts, path=path)
273 LFVZpVisChannel =
"e+:lfvzp e+:lfvzp e-:lfvzp e-:lfvzp"
275 ma.reconstructDecay(
"vpho:vislfvzp -> " + LFVZpVisChannel, Event_cuts_vis, path=path)
277 lfvzp_list.append(
"vpho:vislfvzp")
280 LFVZpVisChannel =
"e+:lfvzp e+:lfvzp e-:lfvzp"
281 Event_cuts_vis =
"nCleanedTracks(abs(dz) < 2.0 and abs(dr) < 0.5) == 3"
283 ma.reconstructDecay(
"vpho:3tr_vislfvzp -> " + LFVZpVisChannel, Event_cuts_vis, path=path, allowChargeViolation=
True)
285 lfvzp_list.append(
"vpho:3tr_vislfvzp")
288 LFVZpVisChannel =
"e+:lfvzp e+:lfvzp"
289 Event_cuts_vis =
"nCleanedTracks(abs(dz) < 2.0 and abs(dr) < 0.5) == 2"
290 ma.reconstructDecay(
"vpho:2tr_vislfvzp -> " + LFVZpVisChannel, Event_cuts_vis, path=path, allowChargeViolation=
True)
292 lfvzp_list.append(
"vpho:2tr_vislfvzp")
300 **Physics channel**: ee → eγ
303 __authors__ = [
"Sam Cunliffe",
"Torben Ferber"]
305 "Electron-gamma skim list for study of the ee backgrounds at high dark "
306 "photon mass, as part of the dark photon analysis"
308 __contact__ = __liaison__
309 __category__ =
"physics, dark sector, control-channel"
310 ApplyHLTHadronCut =
False
314 stdE(
"all", path=path)
319 internal_skim_label =
"forEGammaSkim"
320 skim_output_label =
"EGammaControl"
324 phys_perf_good_track =
'abs(dr) < 1 and abs(dz) < 3 and pt > 0.15'
325 one_good_track = f
'[nCleanedTracks({phys_perf_good_track}) == 1]'
328 photon_energy_cut =
'0.45'
329 good_photon =
'theta > 0.296706 and theta < 2.61799' +\
330 f
' and useCMSFrame(E) > {photon_energy_cut}'
331 ma.cutAndCopyList(f
'gamma:{internal_skim_label}',
'gamma:all', good_photon, path=path)
332 one_good_photon = f
'[eventCached(nParticlesInList(gamma:{internal_skim_label})) == 1]'
335 event_cuts = f
'{one_good_photon} and {one_good_track}'
339 good_track_w_hie_cluster_match =
'%s and clusterE > 2.0' % phys_perf_good_track
340 ma.cutAndCopyList(f
'e+:{internal_skim_label}',
'e+:all', good_track_w_hie_cluster_match, path=path)
344 f
'vpho:{skim_output_label} -> e+:{internal_skim_label} gamma:{internal_skim_label}',
345 '', 1, allowChargeViolation=
True, path=path)
346 self.
SkimLists = [f
"vpho:{skim_output_label}"]
352 **Physics channel**: ee → γγ
355 This skim can retain a lot of γγ events.
356 In case this becomes unacceptable, we provide prescale parameters.
357 Prescales are given in standard trigger convention (reciprocal),
358 so prescale of 100 is 1% of events kept, etc.
361 To prescale the higher-energy probe photons by 10%:
363 >>> from skim.dark import GammaGammaControlKLMDark
364 >>> Skim = GammaGammaControlKLMDark(prescale_high=10)
365 >>> Skim(path) # Add list-building function and uDST output module to path
369 __authors__ = [
"Sam Cunliffe",
"Miho Wakai"]
371 "Gamma gamma skim list for study of the KLM efficiency as part of "
372 "the dark photon analysis"
374 __contact__ = __liaison__
375 __category__ =
"physics, dark sector, control-channel"
376 ApplyHLTHadronCut =
False
381 TestFiles = [get_test_file(
"MC13_ggBGx1")]
383 def __init__(self, prescale_high=1, prescale_low=1, **kwargs):
386 prescale_high (int): the prescale for more energetic probe photon
387 prescale_low (int): the prescale for a less energetic probe photon
388 **kwargs: Passed to constructor of `BaseSkim`.
399 if (prescale_high, prescale_low)
is not (1, 1):
401 "GammaGammaControlKLMDarkList is prescaled. "
402 f
"prescale_high={prescale_high}, prescale_low={prescale_low}"
404 prescale_high = str(float(1.0 / prescale_high))
405 prescale_low = str(float(1.0 / prescale_low))
408 good_tracks =
"abs(dz) < 2.0 and abs(dr) < 0.5 and pt > 0.2"
409 no_good_tracks = f
"nCleanedTracks({good_tracks}) < 1"
414 "gamma:controlKLM",
"gamma:all",
"0.1 < useCMSFrame(clusterE) < 7", path=path)
415 ma.rankByHighest(
"gamma:controlKLM",
"useCMSFrame(clusterE)", numBest=2, path=path)
421 tag_daughter =
"daughterHighest(useCMSFrame(clusterE)) > 4.5"
427 probe_high = f
"[daughterLowest(useCMSFrame(clusterE)) > 4.5] and [eventRandom < {prescale_high}]"
428 probe_low = f
"[daughterLowest(useCMSFrame(clusterE)) < 4.5] and [eventRandom < {prescale_low}]"
429 prescale = f
"[ {probe_high} ] or [ {probe_low} ]"
432 delta_phi_cut =
"abs(daughterDiffOfPhiCMS(0, 1)) > 3.1066860685499065"
435 sum_th =
"daughterSumOf(useCMSFrame(theta))"
436 sum_th_cut = f
"3.1066860685499065 < {sum_th} < 3.1764992386296798"
439 cuts = [no_good_tracks, tag_daughter, prescale, delta_phi_cut, sum_th_cut]
440 cuts =
" and ".join([f
"[ {cut} ]" for cut
in cuts])
443 "vpho:singlePhotonControlKLM -> gamma:controlKLM gamma:controlKLM",
445 self.
SkimLists = [
"vpho:singlePhotonControlKLM"]
451 **Physics channel**: :math:`e^{+}e^{-} \\to e^{+}e^{-}`
454 This skim is currently deactivated, since the retention rate is too high.
457 __authors__ =
"Giacomo De Pietro"
459 "Dielectron skim, needed for :math:`e^{+}e^{-} \\to A^{\\prime} h^{\\prime};`"
460 ":math:`A^{\\prime} \\to e^{+}e^{-}; \\, h^{\\prime} \\to \\mathrm{invisible}` and other searches."
462 __contact__ = __liaison__
463 __category__ =
"physics, dark sector"
464 ApplyHLTHadronCut =
False
467 stdE(
"all", path=path)
469 TestFiles = [get_test_file(
"MC13_mumuBGx1")]
473 skim_label =
"forDielectronMissingEnergySkim"
474 dielectron_name = f
"Z0:{skim_label}"
477 fromIP_cut =
"[abs(dz) < 5.0] and [abs(dr) < 2.0]"
478 electronID_cut =
"[electronID > 0.2]"
480 theta_cut =
"[0.387 < theta < 2.421]"
482 dielectron_cut = f
"[nCleanedTracks({fromIP_cut}) == 2]"
484 dielectron_cut +=
" and [useCMSFrame(pt) > 0.2]"
487 electron_cuts =
" and ".join([fromIP_cut, electronID_cut, theta_cut])
488 ma.cutAndCopyList(f
"e+:{skim_label}",
"e+:all", electron_cuts, path=path)
489 ma.reconstructDecay(f
"{dielectron_name} -> e+:{skim_label} e-:{skim_label}", dielectron_cut, path=path)
492 dielectron_list.append(dielectron_name)
500 Control sample: :math:`e^{+}e^{-} \\to e^{+}e^{-}V^{0};`"
503 __authors__ =
"Savino Longo"
505 "iDM control sample skim. :math:`e^{+}e^{-} \\to e^{+}e^{-}V^{0};`"
507 __contact__ = __liaison__
508 __category__ =
"physics, dark sector"
509 ApplyHLTHadronCut =
False
513 stdE(
"all", path=path)
518 BhabhaTrackCuts =
'abs(dr)<0.5 and abs(dz)<2 and pt>0.2 and 0.8<clusterEoP<1.2 and p>1.0 and clusterReg==2 and nCDCHits>4'
519 BhabhaSystemCuts =
'4<M<10 and 0.5<pRecoilTheta<2.25'
520 V0TrackCuts =
'nCDCHits>4 and p<3.0'
522 PhotonVetoCuts =
'p>1.0'
524 ma.cutAndCopyList(
"gamma:HighEGammaVeto",
"gamma:all", PhotonVetoCuts, path=path)
525 ma.cutAndCopyList(
"e+:BhabhaTrack",
"e+:all", BhabhaTrackCuts, path=path)
526 ma.cutAndCopyList(
"e+:V0Track",
"e+:all", V0TrackCuts, path=path)
528 ma.reconstructDecay(
"vpho:BhabhaSysyem -> e+:BhabhaTrack e-:BhabhaTrack", BhabhaSystemCuts, path=path)
530 ma.reconstructDecay(
"vpho:V0System -> e+:V0Track e-:V0Track",
'', path=path)
532 ma.applyCuts(
'vpho:V0System', V0Cuts, path=path)
534 ma.reconstructDecay(
'vpho:Total -> vpho:BhabhaSysyem vpho:V0System',
'', path=path)
536 eventCuts = (
'nParticlesInList(gamma:HighEGammaVeto)<1 and '
537 'nParticlesInList(vpho:Total)>0')
547 Skim list contains events with no tracks from IP, no high E tracks and only one high E photon.
549 __authors__ = [
"Savino Longo"]
550 __contact__ = __liaison__
551 __description__ =
"iDM list for the iDM analysis."
552 __category__ =
"physics, dark sector"
553 ApplyHLTHadronCut =
False
557 stdE(
"all", path=path)
561 IPtrack =
'abs(dr) < 0.05'
562 HighEtrack =
'useCMSFrame(p)>3.0'
563 ma.cutAndCopyList(
"e+:TrackFromIP",
"e+:all", IPtrack, path=path)
564 ma.cutAndCopyList(
"e+:HighEnergyTrack",
"e+:all", HighEtrack, path=path)
566 signalPhoton =
"[clusterReg==2 and useCMSFrame(E) > 1.0] or "
567 signalPhoton +=
"[clusterReg == 1 and useCMSFrame(E) > 2.0] or "
568 signalPhoton +=
"[clusterReg == 3 and useCMSFrame(E) > 2.0] or "
569 signalPhoton +=
"[clusterReg == 11 and useCMSFrame(E) > 2.0] or "
570 signalPhoton +=
"[clusterReg == 13 and useCMSFrame(E) > 2.0] "
572 photonVetoHE1 =
'useCMSFrame(p) > 0.6'
573 photonVetoHE3 =
'p>0.5'
575 ma.cutAndCopyList(
"gamma:ISR",
"gamma:all", signalPhoton, path=path)
576 ma.cutAndCopyList(
"gamma:HighEnergyPhotons",
"gamma:all", photonVetoHE1, path=path)
577 ma.cutAndCopyList(
"gamma:MediumEnergyPhotons",
"gamma:all", photonVetoHE3, path=path)
579 idmEventCuts = (
'nParticlesInList(gamma:ISR)==1 and '
580 'nParticlesInList(e+:TrackFromIP)==0 and '
581 'nParticlesInList(e+:HighEnergyTrack) == 0 and '
582 'nParticlesInList(gamma:HighEnergyPhotons) == 1 and '
583 'nParticlesInList(gamma:MediumEnergyPhotons) < 4 and '
584 'HighLevelTrigger == 1')
594 Skim to select B+ decays to a K+ from the IP and a LLP with a vertex displaced from the IR decaying to two charged tracks.
596 __authors__ = [
"Sascha Dreyer"]
597 __contact__ = __liaison__
599 "B+ to K+ LLP analysis skim :math:`e^{+}e^{-} \\to \\Upsilon(4s) \\to [B^{+} \\to K^{+} LLP]B^{-}`"
601 __category__ =
"physics, dark sector"
602 ApplyHLTHadronCut =
False
605 stdPi(
"all", path=path)
606 stdK(
"all", path=path)
607 stdE(
"all", path=path)
608 stdMu(
"all", path=path)
614 minDisplacementCut =
"[dr > 0.05]"
616 ma.reconstructDecay(
"vpho:LLP_e" + btoksLbl +
" -> e+:all e-:all",
"", path=path)
617 ma.reconstructDecay(
"vpho:LLP_mu" + btoksLbl +
" -> mu+:all mu-:all",
"", path=path)
618 ma.reconstructDecay(
"vpho:LLP_pi" + btoksLbl +
" -> pi+:all pi-:all",
"", path=path)
619 ma.reconstructDecay(
"vpho:LLP_K" + btoksLbl +
" -> K+:all K-:all",
"", path=path)
621 ma.copyLists(outputListName=
"vpho:LLP" + btoksLbl,
622 inputListNames=[
"vpho:LLP_e" + btoksLbl,
"vpho:LLP_mu" + btoksLbl,
623 "vpho:LLP_pi" + btoksLbl,
"vpho:LLP_K" + btoksLbl],
626 vertex.treeFit(
"vpho:LLP" + btoksLbl, conf_level=0, updateAllDaughters=
True, path=path)
628 ma.applyCuts(
"vpho:LLP" + btoksLbl, minDisplacementCut, path=path)
630 ipKaon =
"[pt > 0.1] and [abs(dr) < 0.5] and [abs(dz) < 2.0]"
631 ma.cutAndCopyList(
"K+:TrackFromIP" + btoksLbl,
"K+:all", ipKaon, path=path)
633 kinematicCuts =
"[Mbc > 5.20] and [abs(deltaE) < 0.25]"
634 ma.reconstructDecay(
"B+:b" + btoksLbl +
" -> K+:TrackFromIP" + btoksLbl +
" vpho:LLP" + btoksLbl,
635 kinematicCuts, path=path)