Belle II Software  release-05-01-25
systematics.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 """ Skim list building functions for systematics studies """
5 
6 __authors__ = [
7  "Sam Cunliffe",
8  "Torben Ferber",
9  "Ilya Komarov",
10  "Yuji Kato"
11 ]
12 
13 import basf2 as b2
14 import modularAnalysis as ma
15 import variables as va
16 import vertex
17 from skimExpertFunctions import BaseSkim, CombinedSkim, fancy_skim_header, get_test_file
18 from stdCharged import stdE, stdK, stdMu, stdPi, stdPr
19 from stdPhotons import stdPhotons
20 from stdPi0s import stdPi0s
21 from stdV0s import stdKshorts, stdLambdas
22 
23 # TODO: Add liaison name and email address
24 __liaison__ = ""
25 __liaison_leptonID__ = "Marcel Hohmann"
26 
27 
28 @fancy_skim_header
30  """
31  Primarily used for hadron and lepton ID studies.
32  Lists in this skim are those defined in `PiKFromDstarList`.
33  """
34  __authors__ = ["Sam Cunliffe", "Torben Ferber", "Ilya Komarov", "Yuji Kato", "Racha Cheaib"]
35  __description__ = ""
36  __contact__ = __liaison__
37  __category__ = "systematics"
38 
39  def load_standard_lists(self, path):
40  stdK("all", path=path)
41  stdPi("all", path=path)
42 
43  TestFiles = [get_test_file("MC13_ccbarBGx1")]
44 
45  def build_lists(self, path):
46  lists = [
47  self.PiKFromDstarList(path),
48  ]
49 
50  # Flatten the list of lists
51  self.SkimLists = [s for li in lists for s in li]
52 
53  def PiKFromDstarList(self, path):
54  """Build PiKFromDstarList lists for systematics skims."""
55  D0Cuts = "1.75 < M < 2.0"
56  DstarCuts = "massDifference(0)<0.16 and useCMSFrame(p) > 1.5"
57 
58  ma.cutAndCopyList("K-:syst", "K-:all", "dr<2 and abs(dz)<4", path=path)
59  ma.cutAndCopyList("pi+:syst", "pi+:all", "dr<2 and abs(dz)<4", path=path)
60 
61  D0Channel = ["K-:syst pi+:syst"]
62 
63  D0List = []
64  for chID, channel in enumerate(D0Channel):
65  ma.reconstructDecay(f"D0:syst{chID} -> {channel}", D0Cuts, chID, path=path)
66  D0List.append(f"D0:syst{chID}")
67 
68  DstarChannel = []
69  for channel in D0List:
70  DstarChannel.append(f"{channel} pi+:syst")
71 
72  DstarList = []
73  for chID, channel in enumerate(DstarChannel):
74  ma.reconstructDecay(f"D*+:syst{chID} -> {channel}", DstarCuts, chID, path=path)
75  DstarList.append(f"D*+:syst{chID}")
76 
77  return DstarList
78 
79 
80 @fancy_skim_header
82  """
83  Lists in this skim are those defined in `BtoDStarPiList` and `DstarToD0PiPartList`.
84  """
85  __authors__ = ["Sam Cunliffe", "Torben Ferber", "Ilya Komarov", "Yuji Kato"]
86  __description__ = ""
87  __contact__ = __liaison__
88  __category__ = "systematics"
89 
90  def load_standard_lists(self, path):
91  stdK("loose", path=path)
92  stdPi("loose", path=path)
93  stdPi0s("eff40_Jan2020", path=path)
94 
95  def build_lists(self, path):
96  lists = [
97  self.BtoDStarPiList(path),
98  self.DstarToD0PiPartList(path)
99  ]
100 
101  # Flatten the list of lists
102  self.SkimLists = [s for li in lists for s in li]
103 
104  def BtoDStarPiList(self, path):
105  """Build BtoDStarPiList lists for systematics skims."""
106  D0Cuts = "1.835 < M < 1.895"
107  DstarCuts = "massDifference(0)<0.16"
108  B0Cuts = "Mbc > 5.2 and abs(deltaE) < 0.3"
109 
110  # D0
111  D0Channel = ["K+:loose pi-:loose", "K+:loose pi-:loose pi-:loose pi+:loose", "K+:loose pi-:loose pi0:eff40_Jan2020"]
112 
113  D0List = []
114  for chID, channel in enumerate(D0Channel):
115  resonanceName = "anti-D0:loose" + str(chID)
116  ma.reconstructDecay(resonanceName + " -> " + channel, D0Cuts, chID, path=path)
117  # vertex.raveFit(resonanceName, 0.0, path=path)
118  ma.matchMCTruth(resonanceName, path=path)
119  ma.copyLists("anti-D0:loose", ["anti-D0:loose0", "anti-D0:loose1", "anti-D0:loose2"], path=path)
120  D0List.append("anti-D0:loose")
121 
122  # Dstar
123  DstarChannel = []
124  for channel in D0List:
125  DstarChannel.append(channel + " pi-:loose")
126 
127  DstarList = []
128  for chID, channel in enumerate(DstarChannel):
129  resonanceName = "D*-:loose" + str(chID)
130  ma.reconstructDecay(resonanceName + " -> " + channel, DstarCuts, chID, path=path)
131  # vertex.raveFit(resonanceName, 0.0)
132  DstarList.append(resonanceName)
133  ma.matchMCTruth(resonanceName, path=path)
134 
135  # B0
136  B0Channel = []
137  for channel in DstarList:
138  B0Channel.append(channel + " pi+:loose")
139 
140  B0List = []
141  for chID, channel in enumerate(B0Channel):
142  resonanceName = "B0:sys" + str(chID)
143  ma.reconstructDecay(resonanceName + " -> " + channel, B0Cuts, chID, path=path)
144  B0List.append(resonanceName)
145  # vertex.raveFit(resonanceName, 0.0)
146  ma.matchMCTruth(resonanceName, path=path)
147 
148  return B0List
149 
150  def DstarToD0PiPartList(self, path):
151  """Build DstarToD0PiPartList lists for systematics skims."""
152  ma.fillParticleList("pi+:fromks", "chiProb > 0.001 and pionID > 0.1 and d0 > 0.1", path=path)
153 
154  # D-
155  DminusCuts = "1.0 < M < 1.75"
156  DminusChannel = ["pi-:fromks pi+:loose pi-:loose"]
157 
158  for chID, channel in enumerate(DminusChannel):
159  resonanceName = "D-:loose" + str(chID)
160  ma.reconstructDecay(resonanceName + " -> " + channel, DminusCuts, chID, path=path)
161 
162  # Dstar
163  DstarCuts = "massDifference(0)<0.2 and useCMSFrame(p) > 2.0"
164  DstarChannel = []
165  DstarChannel.append("D-:loose0" + " pi+:loose")
166 
167  DstarList = []
168  for chID, channel in enumerate(DstarChannel):
169  resonanceName = "D*0:loose" + str(chID)
170  ma.reconstructDecay(resonanceName + " -> " + channel, DstarCuts, chID, path=path)
171  DstarList.append(resonanceName)
172  ma.matchMCTruth(resonanceName, path=path)
173 
174  return DstarList
175 
176 
177 @fancy_skim_header
179  """
180  Lists in this skim are those defined in `getDsList`, `getDstarList`,
181  `getSigmacList`, `getmumugList`, `getBZeroList`, and `getBPlusList`.
182  """
183  __authors__ = ["Sam Cunliffe", "Torben Ferber", "Ilya Komarov", "Yuji Kato"]
184  __description__ = ""
185  __contact__ = __liaison__
186  __category__ = "systematics"
187 
188  def load_standard_lists(self, path):
189  stdK("loose", path=path)
190  stdMu("loose", path=path)
191  stdPi("loose", path=path)
192  stdPr("loose", path=path)
193  stdPi0s("eff40_Jan2020Fit", path=path)
194 
195  def build_lists(self, path):
196  lists = [
197  self.getDsList(path),
198  self.getDstarList(path),
199  self.getSigmacList(path),
200  self.getmumugList(path),
201  self.getBZeroList(path),
202  self.getBPlusList(path),
203  ]
204 
205  # Flatten the list of lists
206  self.SkimLists = [s for li in lists for s in li]
207 
208  def getDsList(self, path):
209  """Build Ds list for systematics skims."""
210  DsCuts = "1.90 < M < 2.04"
211 
212  ma.reconstructDecay("phi:res -> K+:loose K-:loose", "1.01 < M < 1.03", path=path)
213  ma.reconstructDecay("K*0:res -> K+:loose pi-:loose", "0.7 < M < 1.1", path=path)
214 
215  DsChannel = ["phi:res pi+:loose"]
216  DsList = []
217  for chID, channel in enumerate(DsChannel):
218  particlename = "D_s+:Resonance%d" % (chID)
219  ma.reconstructDecay(particlename + " -> " + channel, DsCuts, chID, path=path)
220  ma.matchMCTruth(particlename, path)
221  DsList.append(particlename)
222 
223  return DsList
224 
225  def getDstarList(self, path):
226  """Build Dstar list for systematics skims."""
227  DplusCuts = "1.8 < M < 1.93"
228  DstarCuts = "massDifference(0)<0.16 and useCMSFrame(p)>2.0"
229 
230  DplusChannel = ["K-:loose pi+:loose pi+:loose"]
231 
232  DplusList = []
233  for chID, channel in enumerate(DplusChannel):
234  ma.reconstructDecay("D+:resonance" + str(chID) + " -> " + channel, DplusCuts, chID, path=path)
235  vertex.raveFit("D+:resonance" + str(chID), 0.0, path=path)
236  DplusList.append("D+:resonance" + str(chID))
237 
238  DstarChannel = []
239  for channel in DplusList:
240  DstarChannel.append(channel + " pi0:eff40_Jan2020")
241 
242  DstarList = []
243  for chID, channel in enumerate(DstarChannel):
244  ma.reconstructDecay("D*+:resonance" + str(chID) + " -> " + channel, DstarCuts, chID, path=path)
245  DstarList.append("D*+:resonance" + str(chID))
246  ma.matchMCTruth("D*+:resonance0", path=path)
247 
248  return DstarList
249 
250  def getSigmacList(self, path):
251  """Build Sigmac list for systematics skims."""
252  LambdacCuts = "2.24 < M < 2.33"
253  SigmacCuts = "massDifference(0)<0.28 and useCMSFrame(p) > 2.5"
254 
255  LambdacChannel = ["p+:loose K-:loose pi+:loose"]
256  LambdacList = []
257  for chID, channel in enumerate(LambdacChannel):
258  ma.reconstructDecay("Lambda_c+:resonance" + str(chID) + " -> " + channel, LambdacCuts, chID, path=path)
259  vertex.raveFit("Lambda_c+:resonance" + str(chID), 0.0, path=path)
260  LambdacList.append("Lambda_c+:resonance" + str(chID))
261 
262  SigmacList = []
263  SigmacPlusChannel = []
264  # Sigma_c++
265  for channel in LambdacList:
266  SigmacPlusChannel.append(channel + " pi+:loose")
267 
268  for chID, channel in enumerate(SigmacPlusChannel):
269  ma.reconstructDecay("Sigma_c++:resonance" + str(chID) + " -> " + channel, SigmacCuts, chID, path=path)
270  SigmacList.append("Sigma_c++:resonance" + str(chID))
271  ma.matchMCTruth("Sigma_c++:resonance0", path=path)
272 
273  # Sigma_c0
274  Sigmac0Channel = []
275  for channel in LambdacList:
276  Sigmac0Channel.append(channel + " pi-:loose")
277 
278  Sigmac0List = []
279  for chID, channel in enumerate(Sigmac0Channel):
280  ma.reconstructDecay("Sigma_c0:resonance" + str(chID) + " -> " + channel, SigmacCuts, chID, path=path)
281  Sigmac0List.append("Sigma_c0:resonance" + str(chID))
282  ma.matchMCTruth("Sigma_c0:resonance0", path=path)
283 
284  return SigmacList
285 
286  def getmumugList(self, path):
287  """Build mumug list for systematics skims."""
288  vphoChannel = ["mu+:loose mu-:loose"]
289  vphocuts = ""
290  vphoList = []
291  for chID, channel in enumerate(vphoChannel):
292  resonanceName = "vpho:resonance" + str(chID)
293  ma.reconstructDecay("vpho:resonance" + str(chID) + " -> " + channel, vphocuts, chID, path=path)
294  ma.applyCuts(resonanceName, "nTracks == 2 and M < formula(Ecms*0.9877)", path=path)
295  ma.matchMCTruth(resonanceName, path=path)
296  vertex.raveFit(resonanceName, 0.0, path=path)
297  ma.applyCuts(resonanceName, "M < formula(Ecms*0.9877)", path=path)
298  vphoList.append(resonanceName)
299 
300  return vphoList
301 
302  def getBZeroList(self, path):
303  """Build BZero list for systematics skims."""
304  BZeroCuts = "Mbc > 5.2 and abs(deltaE) < 0.3"
305  BZeroChannel = ["D-:resonance0 pi+:loose"]
306  BZeroList = []
307 
308  for chID, channel in enumerate(BZeroChannel):
309  resonanceName = "B0:resonance" + str(chID)
310  ma.reconstructDecay(resonanceName + " -> " + channel, BZeroCuts, chID, path=path)
311  BZeroList.append(resonanceName)
312  ma.matchMCTruth(resonanceName, path=path)
313 
314  return BZeroList
315 
316  def getBPlusList(self, path):
317  """Build Bplus list for systematics skims."""
318  antiDZeroCut = "1.82 < M < 1.90"
319  antiDZeroChannel = ["K+:loose pi-:loose"]
320  antiDZeroList = []
321 
322  for chID, channel in enumerate(antiDZeroChannel):
323  resonanceName = "anti-D0:resonance" + str(chID)
324  ma.reconstructDecay(resonanceName + " -> " + channel, antiDZeroCut, chID, path=path)
325  vertex.raveFit(resonanceName, 0.0, path=path)
326  antiDZeroList.append(resonanceName)
327 
328  BPlusChannel = []
329  for channel in antiDZeroList:
330  BPlusChannel.append(channel + " pi+:loose")
331 
332  BPlusCuts = "Mbc > 5.2 and abs(deltaE) < 0.3"
333  BPlusList = []
334  for chID, channel in enumerate(BPlusChannel):
335  ma.reconstructDecay("B+:resonance" + str(chID) + " -> " + channel, BPlusCuts, chID, path=path)
336  BPlusList.append("B+:resonance" + str(chID))
337  ma.matchMCTruth("B+:resonance" + str(chID), path=path)
338 
339  return BPlusList
340 
341 
342 @fancy_skim_header
344  """
345  We require one cluster-matched electron (the other is not required to match a
346  cluster). No selection on the photon as the sample must be unbiased.
347  """
348  __authors__ = ["Torben Ferber"]
349  __description__ = (
350  "Skim of radiative muon pairs (:math:`ee\\to\\mu\\mu(\\gamma)`) "
351  "for photon systematics."
352  )
353  __contact__ = __liaison__
354  __category__ = "systematics, photon calibration"
355 
356  def load_standard_lists(self, path):
357  stdMu("all", path=path)
358 
359  def build_lists(self, path):
360  # the tight selection starts with all muons, but they must be cluster-matched and not be an electron
361  MuonTightSelection = ("abs(dz) < 2.0 and abs(dr) < 0.5 and nCDCHits > 0 and "
362  "clusterE > 0.0 and clusterE < 1.0")
363  ma.cutAndCopyList("mu+:skimtight", "mu+:all", MuonTightSelection, path=path)
364 
365  # for the loose selection starts with all muons, but we accept tracks that
366  # are not matched to a cluster, but if they are, they must not be an
367  # electron
368  MuonLooseSelection = "abs(dz) < 2.0 and abs(dr) < 0.5 and nCDCHits > 0 and clusterE < 1.0"
369  ma.cutAndCopyList("mu+:skimloose", "mu+:all", MuonLooseSelection, path=path)
370 
371  # create a list of possible selections
372  radmumulist = []
373 
374  # selection ID0:
375  # the radiative muon pair must be selected without looking at the photon.
376  # exclude events with more than two good tracks
377  RadMuMuSelection = "pRecoil > 0.075 and pRecoilTheta > 0.296706 and pRecoilTheta < 2.61799"
378  RadMuMuPairChannel = "mu+:skimtight mu-:skimloose"
379  chID = 0
380  ma.reconstructDecay("vpho:radmumu" + str(chID) + " -> " + RadMuMuPairChannel,
381  RadMuMuSelection, chID, path=path)
382  eventCuts = "nCleanedTracks(abs(dz) < 2.0 and abs(dr) < 0.5) == 2"
383  ma.applyCuts("vpho:radmumu" + str(chID), eventCuts, path=path)
384  radmumulist.append("vpho:radmumu" + str(chID))
385 
386  # selection Id1:
387  # todo: include pair conversions?
388 
389  self.SkimLists = radmumulist
390 
391 
392 @fancy_skim_header
394  __authors__ = ["Ilya Komarov"]
395  __description__ = "Systematics skim of :math:`ee\\to ee\\ell\\ell`"
396  __contact__ = __liaison__
397  __category__ = "systematics, lepton ID"
398 
399  def load_standard_lists(self, path):
400  stdE("all", path=path)
401 
402  def build_lists(self, path):
403  # At skim level we avoid any PID-like requirements and just select events
404  # with two good tracks coming from the interavtion region.
405  eLooseSelection = "abs(dz) < 2.0 and abs(dr) < 0.5 and p > 0.3"
406  ma.cutAndCopyList("e+:skimloose", "e+:all", eLooseSelection, path=path)
407 
408  # create a list of possible selections
409  eelllist = []
410 
411  # Lepon pair tracks are back-to-back-like
412  EELLSelection = "useCMSFrame(pt)<0.3"
413  eventCuts = "nCleanedTracks(abs(dz) < 2.0 and abs(dr) < 0.5) < 4"
414  ma.reconstructDecay("gamma:eell -> e+:skimloose e-:skimloose",
415  EELLSelection + " and " + eventCuts, path=path)
416  eelllist.append("gamma:eell")
417 
418  self.SkimLists = eelllist
419 
420 
421 @fancy_skim_header
423  """
424  Constructed skim list contains radiative electron pairs for photon systematics. In
425  particular this is for the endcaps where we have no track triggers, we require one
426  cluster-matched electron (the other is not required to match a cluster). No
427  selection on the photon as the sample must be unbiased.
428 
429  As this retains a lot of bhabha events (by construction) we allow for prescaling
430  (and prefer prescaled rather than a biased sampe by requiring any selection on the
431  photon or too much of a cut on the recoil momentum).
432 
433  Prescales are given in standard trigger terms (reciprocal), so prescale of 100 is 1%
434  of events kept, *etc*.
435  """
436 
437  __authors__ = ["Sam Cunliffe"]
438  __description__ = "Radiative electron pairs for photon systematics"
439  __contact__ = __liaison__
440  __category__ = "systematics, photon calibration"
441 
442  def load_standard_lists(self, path):
443  stdE("all", path=path)
444 
445  def __init__(self, prescale_all=1, prescale_fwd_electron=1, **kwargs):
446  """
447  Parameters:
448  prescale_all (int): the global prescale for this skim
449  prescale_fwd_electron (int): the prescale electrons (e-) in
450  the forward endcap
451  **kwargs: Passed to constructor of `BaseSkim`.
452  """
453  # Redefine __init__ to allow for additional optional arguments
454  super().__init__(**kwargs)
455  self.prescale_all = prescale_all
456  self.prescale_fwd_electron = prescale_fwd_electron
457 
458  def build_lists(self, path):
459  # convert prescales from trigger convention
460  prescale_all = str(float(1.0 / self.prescale_all))
461  prescale_fwd_electron = str(float(1.0 / self.prescale_fwd_electron))
462 
463  # require a pair of good electrons one of which must be cluster-matched
464  # with 3 GeV of energy
465  goodtrack = "abs(dz) < 2.0 and abs(dr) < 0.5 and nCDCHits > 0"
466  goodtrackwithcluster = "%s and clusterE > 3.0" % goodtrack
467  ma.cutAndCopyList("e+:skimtight", "e+:all", goodtrackwithcluster, path=path)
468  ma.cutAndCopyList("e+:skimloose", "e+:all", goodtrack, path=path)
469 
470  # a minimum momentum of 75 MeV/c recoiling against the pair,
471  # and require that the recoil is within the CDC acceptance
472  recoil = "pRecoil > 0.075 and 0.296706 < pRecoilTheta < 2.61799" # GeV/c, rad
473  ma.reconstructDecay("vpho:radee -> e+:skimtight e-:skimloose", recoil, path=path)
474 
475  # apply event cuts (exactly two clean tracks in the event, and prescale
476  # the whole event regardless of where the electron went)
477  event_cuts = "[nCleanedTracks(abs(dz) < 2.0 and abs(dr) < 0.5) == 2]" # cm, cm
478  event_cuts += " and [eventRandom <= %s]" % prescale_all
479 
480  # now prescale the *electron* (e-) in the forward endcap (for bhabhas)
481  # note this is all done with cut strings to circumnavigate BII-3607
482  fwd_encap_border = "0.5480334" # rad (31.4 deg)
483  electron_is_first = "daughter(0, charge) < 0"
484  first_in_fwd_endcap = "daughter(0, theta) < %s" % fwd_encap_border
485  first_not_in_fwd_endcap = "daughter(0, theta) > %s" % fwd_encap_border
486  electron_is_second = "daughter(1, charge) < 0"
487  second_in_fwd_endcap = "daughter(1, theta) < %s" % fwd_encap_border
488  second_not_in_fwd_endcap = "daughter(1, theta) > %s" % fwd_encap_border
489  passes_prescale = "eventRandom <= %s" % prescale_fwd_electron
490  #
491  # four possible scenarios:
492  # 1) electron first in the decaystring and in fwd endcap: prescale these
493  prescale_logic = "[%s and %s and %s]" \
494  % (electron_is_first, first_in_fwd_endcap, passes_prescale)
495  # 2) electron second in string and in fwd endcap: prescale these
496  prescale_logic += " or [%s and %s and %s]" \
497  % (electron_is_second, second_in_fwd_endcap, passes_prescale)
498  # 3) electron first in string and not in fwd endcap (no prescale)
499  prescale_logic += " or [%s and %s]" % (electron_is_first, first_not_in_fwd_endcap)
500  # 4) electron second in string and not in fwd endcap (no prescale)
501  prescale_logic += " or [%s and %s]" % (electron_is_second, second_not_in_fwd_endcap)
502 
503  # final candidate building with cuts and prescales
504  prescale_logic = "[%s]" % prescale_logic
505  ma.applyCuts("vpho:radee", event_cuts + " and " + prescale_logic, path=path)
506 
507  self.SkimLists = ["vpho:radee"]
508 
509 
510 @fancy_skim_header
512  __authors__ = ["Sam Cunliffe", "Torben Ferber", "Ilya Komarov", "Yuji Kato", "Jake Bennett"]
513  __description__ = ""
514  __contact__ = __liaison__
515  __category__ = "systematics"
516 
517  def load_standard_lists(self, path):
518  stdLambdas(path=path)
519 
520  def build_lists(self, path):
521  va.variables.addAlias("fsig", "formula(flightDistance/flightDistanceErr)")
522  va.variables.addAlias("pMom", "daughter(0,p)")
523  va.variables.addAlias("piMom", "daughter(1,p)")
524  va.variables.addAlias("daughtersPAsym", "formula((pMom-piMom)/(pMom+piMom))")
525 
526  LambdaList = []
527  ma.cutAndCopyList("Lambda0:syst0", "Lambda0:merged", "fsig>10 and daughtersPAsym>0.41", path=path)
528  LambdaList.append("Lambda0:syst0")
529 
530  self.SkimLists = LambdaList
531 
532 
533 @fancy_skim_header
535  """
536  Uses the ``gamma:loose`` list and a cut on the number of tracks.
537 
538  Cuts applied:
539 
540  * :math:`E_{\\gamma}> 3\\,\\text{GeV}` AND
541  * :math:`E_{\\gamma}< 8\\,\\text{GeV}`
542  * :math:`n_{\\text{tracks}} \\geq 2` AND :math:`n_{\\text{tracks}} \\leq 4`
543  * at least 1 candidate in the K_S0:merged or in the phi->K+:all K-:all lists
544  """
545  __authors__ = ["Giuseppe Finocchiaro", "Benjamin Oberhof"]
546  __description__ = (
547  "Skim for ISR - phi gamma analyses, "
548  ":math:`e^+ e^- \\to \\phi \\gamma ` and "
549  ":math:`\\phi` decays into two charged tracks "
550  "(:math: `K^+K^-` or :math:`K_S K_L` with :math:`K_S\\to \\pi^+\\pi^-`)"
551  )
552  __contact__ = __liaison__
553  __category__ = "systematics"
554 
555  def load_standard_lists(self, path):
556  stdPhotons("loose", path=path)
557  stdK("all", path=path)
558  stdKshorts(path=path)
559 
560  TestFiles = [get_test_file("phigamma_neutral")]
561 
562  def build_lists(self, path):
563  EventCuts = [
564  "[nTracks>=2] and [nTracks<=4]",
565  "[nParticlesInList(gamma:PhiSystematics) > 0]",
566  "[[nParticlesInList(phi:charged) > 0] or [nParticlesInList(K_S0:PhiSystematics) > 0]]"
567  ]
568 
569  ma.cutAndCopyList("gamma:PhiSystematics", "gamma:loose", "3 < E < 8", writeOut=True, path=path)
570  ma.reconstructDecay('phi:charged -> K+:all K-:all', '0.9 < M < 1.2', path=path)
571  ma.copyList('K_S0:PhiSystematics', 'K_S0:merged', writeOut=True, path=path)
572 
573  path = self.skim_event_cuts(" and ".join(EventCuts), path=path)
574  self.SkimLists = ["gamma:PhiSystematics"]
575 
576 
577 @fancy_skim_header
579  __authors__ = "Phil Grace"
580  __contact__ = "Phil Grace <philip.grace@adelaide.edu.au>"
581  __description__ = "Random skim to select a fixed fraction of events."
582  __category__ = "systematics, random"
583 
584  def __init__(self, KeepPercentage=10, seed=None, **kwargs):
585  """
586  Parameters:
587  KeepPercentage (float): Percentage of events to be kept.
588  seed (int): Set random seed to given number. If this argument is not given,
589  this skim will not alter the random seed.
590  **kwargs: Passed to constructor of `BaseSkim`.
591  """
592  super().__init__(**kwargs)
593  self.KeepPercentage = KeepPercentage
594  self.seed = seed
595 
596  def additional_setup(self, path):
597  if self.seed is not None:
598  b2.set_random_seed(int(self.seed))
599 
600  def load_standard_lists(self, path):
601  stdPi("all", path=path)
602  stdPhotons("all", path=path)
603 
604  def build_lists(self, path):
605  # Select one photon/track per event with no other cuts, so that all events are
606  # captured in the skim list if KeepPercentage=100.
607  label = "RandomSkim"
608  ma.copyList(f"pi+:{label}", "pi+:all", path=path)
609  ma.copyList(f"gamma:{label}", "gamma:all", path=path)
610  ma.applyRandomCandidateSelection(f"pi+:{label}", path=path)
611  ma.applyRandomCandidateSelection(f"gamma:{label}", path=path)
612 
613  # Select fraction of events
614  path = self.skim_event_cuts(
615  f"eventRandom <= {self.KeepPercentage/100}", path=path
616  )
617 
618  self.SkimLists = [f"pi+:{label}", f"gamma:{label}"]
619 
620 
621 @fancy_skim_header
623  __authors__ = "Marcel Hohmann"
624  __contact__ = __liaison_leptonID__
625  __description__ = "Skim to select all events that pass the HLT Four Lepton skim for lepton ID studies"
626  __category__ = "systematics, leptonID"
627  ApplyHLTHadronCut = False
628 
629  def load_standard_lists(self, path):
630  stdPi("all", path=path)
631 
632  def build_lists(self, path):
633  label = "FourLeptonHLT"
634  ma.copyList(f"pi+:{label}", "pi+:all", path=path)
635  ma.rankByLowest(f"pi+:{label}", "random", 1, "systematicsFourLeptonHLT_randomRank", path=path)
636 
637  path = self.skim_event_cuts(
638  f"SoftwareTriggerResult(software_trigger_cut&skim&accept_fourlep) == 1", path=path
639  )
640 
641  self.SkimLists = [f"pi+:{label}"]
642 
643 
644 @fancy_skim_header
646  __authors__ = "Marcel Hohmann"
647  __contact__ = __liaison_leptonID__
648  __description__ = "Skim to select all events that pass the HLT RadMuMu skim for lepton ID studies"
649  __category__ = "systematics, leptonID"
650  ApplyHLTHadronCut = False
651 
652  def load_standard_lists(self, path):
653  stdPi("all", path=path)
654 
655  def build_lists(self, path):
656  label = "RadMuMuLeptonID"
657  ma.copyList(f"pi+:{label}", "pi+:all", path=path)
658  ma.rankByLowest(f"pi+:{label}", "random", 1, "systematicsRadMuMuLeptonID_randomRank", path=path)
659 
660  path = self.skim_event_cuts(
661  f"SoftwareTriggerResult(software_trigger_cut&skim&accept_radmumu) == 1", path=path
662  )
663  self.SkimLists = [f"pi+:{label}"]
664 
665 
666 @fancy_skim_header
668  """
669  J/psi skim for lepton ID systematics studies. Lists in this skim are those defined in `JpsimumuTagProbe`, `JpsieeTagProbe`.
670  """
671  __authors__ = ["Sam Cunliffe", "Torben Ferber", "Ilya Komarov", "Yuji Kato", "Racha Cheaib", "Marcel Hohmann"]
672  __description__ = ""
673  __contact__ = __liaison_leptonID__
674  __category__ = "systematics, leptonID"
675 
676  def load_standard_lists(self, path):
677  stdMu("all", path=path)
678  stdE("all", path=path)
679  stdPhotons("all", path=path)
680 
681  TestFiles = [get_test_file("MC13_ccbarBGx1")]
682  ApplyHLTHadronCut = True
683 
684  def build_lists(self, path):
685  self.SkimLists = [
686  self.JpsimumuTagProbe(path),
687  self.JpsieeTagProbe(path),
688  ]
689 
690  def JpsimumuTagProbe(self, path):
691  """Build JpsimumuTagProbe lists for systematics skims."""
692  Cuts = "2.7 < M < 3.4"
693  ma.reconstructDecay(
694  "J/psi:systematics_mumu -> mu+:all mu-:all",
695  f'{Cuts} and [daughter(0,muonID)>0.1 or daughter(1,muonID)>0.1]',
696  path=path)
697  return "J/psi:systematics_mumu"
698 
699  def JpsieeTagProbe(self, path):
700  """Build JpsieeTagProbe lists for systematics skims."""
701 
702  Cuts = "2.7 < M < 3.4"
703  ma.cutAndCopyList('gamma:brems', 'gamma:all', 'E<1', path=path)
704  ma.correctBrems('e+:brems_corrected', 'e+:all', 'gamma:brems', path=path)
705  ma.reconstructDecay(
706  "J/psi:systematics_ee -> e+:brems_corrected e-:brems_corrected",
707  f'{Cuts} and [daughter(0,electronID_noTOP)>0.1 or daughter(1,electronID_noTOP)>0.1]',
708  path=path)
709  return "J/psi:systematics_ee"
710 
711 
712 @fancy_skim_header
714  """
715  K-short skim for hadron and lepton ID systematics studies.
716  As K-short candidates are abundant this skim has a high retention.
717  To meet the retention criteria a prescale is added. The prescale is given in standard trigger terms (reciprocal).
718  A prescale of 50 will keep 2% of events, etc.
719  """
720  __authors__ = ["Marcel Hohmann"]
721  __description__ = "Skim for K-short events for performance studies"
722  __contact__ = __liaison_leptonID__
723  __category__ = "performance, leptonID"
724 
725  ApplyHLTHadronCut = True
726 
727  def __init__(self, prescale=1, **kwargs):
728  """
729  Parameters:
730  prescale (int): the global prescale for this skim.
731  **kwargs: Passed to constructor of `BaseSkim`.
732  """
733  self.prescale = prescale
734  super().__init__(**kwargs)
735 
736  def load_standard_lists(self, path):
737  stdPi("all", path=path)
738 
739  def build_lists(self, path):
740 
741  ma.reconstructDecay(
742  'K_S0:reco -> pi+:all pi-:all',
743  '[0.30 < M < 0.70]',
744  path=path)
745 
746  vertex.treeFit('K_S0:reco', 0.0, path=path)
747  ma.applyCuts('K_S0:reco', '0.4 < M < 0.6', path=path)
748 
749  ma.fillParticleList('K_S0:V0 -> pi+ pi-',
750  '[0.30 < M < 0.70]',
751  True,
752  path=path)
753  vertex.treeFit('K_S0:V0', 0.0, path=path)
754  ma.applyCuts('K_S0:V0', '0.4 < M < 0.6', path=path)
755 
756  ma.mergeListsWithBestDuplicate('K_S0:merged', ['K_S0:V0', 'K_S0:reco'],
757  variable='particleSource', preferLowest=True, path=path)
758 
759  KS_cut = '[[cosAngleBetweenMomentumAndVertexVector>0.998] or '\
760  ' [formula(flightDistance/flightDistanceErr)>11] or '\
761  ' [flightTime>0.007]]' # and '\
762  # '[useAlternativeDaughterHypothesis(M, 0:p+) > 1.13068 and useAlternativeDaughterHypothesis(M, 0:pi-, 1:p+) > 1.13068]'
763 
764  ma.cutAndCopyList("K_S0:skim", "K_S0:merged", KS_cut, path=path)
765  path = self.skim_event_cuts(f'eventRandom < {(1/self.prescale):.6f}', path=path)
766  self.SkimLists = ['K_S0:skim']
767 
768 
769 @fancy_skim_header
771  """
772  Skim for selecting Bhabha events for leptonID studies.
773  In case the retention exceeds 10% a prescale can be added.
774  The prescale is given in standard trigger terms (reciprocal).
775  """
776  __authors__ = ["Justin Skorupa"]
777  __description__ = "Skim for Bhabha events for lepton ID study"
778  __contact__ = __liaison_leptonID__
779  __category__ = "performance, leptonID"
780 
781  ApplyHLTHadronCut = False
782 
783  def __init__(self, prescale=1, **kwargs):
784  """
785  Parameters:
786  prescale (int): the global prescale for this skim.
787  **kwargs: Passed to constructor of `BaseSkim`.
788  """
789  self.prescale = prescale
790  super().__init__(**kwargs)
791 
792  def load_standard_lists(self, path):
793  stdE("all", path=path)
794 
795  def build_lists(self, path):
796  goodtrack = "abs(dz) < 5 and abs(dr) < 2"
797  goodtrackwithPID = f"{goodtrack} and electronID_noTOP > 0.95 and clusterTheta > 0.59"\
798  " and clusterTheta < 2.15 and useCMSFrame(clusterE) > 2"
799  ma.cutAndCopyList("e+:tight", "e+:all", goodtrackwithPID, path=path)
800  ma.cutAndCopyList("e+:loose", "e+:all", goodtrack, path=path)
801 
802  ma.reconstructDecay(
803  "vpho:bhabha -> e+:tight e-:loose", "", path=path)
804 
805  event_cuts = "[nCleanedTracks(abs(dz) < 5 and abs(dr) < 2) == 2]"\
806  f" and eventRandom < {(1/self.prescale):.6f}"
807 
808  ma.applyCuts("vpho:bhabha", event_cuts, path=path)
809 
810  self.SkimLists = ["vpho:bhabha"]
811 
812 
813 @fancy_skim_header
815  """
816  Combined systematics skim for the four hadronic channels:
817  SystematicsKshort,
818  SystematicsJpsi,
819  SystematicsDstar,
820  SystemmaticsLambda.
821 
822  This is required for technical (data production) reasons, as it keeps the number of files low.
823  See the definitions of the individual skims for the details.
824  """
825  __authors__ = ["Marcel Hohmann"]
826  __description__ = "Combined Skim of the systematic hadronic skims: Kshort, Jpsi, Dstar, Lambda."
827  __contact__ = __liaison_leptonID__
828  __category__ = "performance, leptonID"
829  __name__ = "SystematicsCombinedHadronic"
830 
831  def __init__(self, prescale_kshort=1, mdstOutput=True, **kwargs):
832  """ Initialiser.
833 
834  Args:
835  prescale_kshort (Optional[int]): offline prescale factor for KS skim.
836  **kwargs: key-worded arguments. See CombinedSkim.__init__()
837  """
838 
839  kwargs.update(mdstOutput=mdstOutput, CombinedSkimName=self.__name__)
840  kwargs.setdefault('udstOutput', False)
841 
842  skims_list = [SystematicsKshort(prescale=prescale_kshort), SystematicsDstar(), SystematicsLambda(), SystematicsJpsi()]
843  super().__init__(*skims_list, **kwargs)
844 
845 
846 @fancy_skim_header
848  """
849  Combined systematics skim for the four low multi channels:
850  SystematicsFourLeptonFromHLTFlag,
851  SystematicsRadmumuFromHLTFlag,
852  SystematicsBhabha,
853  ThauThrust.
854 
855  This is required for technical (data production) reasons, as it keeps the number of files low.
856  See the definitions of the individual skims for the details.
857  """
858  __authors__ = ["Marcel Hohmann"]
859  __description__ = "Combined Skim of the systematic low multi skims: FourLepton, Radmumu, Bhabha, TauThrust."
860  __contact__ = __liaison_leptonID__
861  __category__ = "performance, leptonID"
862  __name__ = "SystematicsCombinedLowMulti"
863 
864  def __init__(self, prescale_kshort=1, mdstOutput=True, **kwargs):
865  """ Initialiser.
866 
867  Args:
868  **kwargs: key-worded arguments. See CombinedSkim.__init__()
869  """
870 
871  kwargs.update(mdstOutput=mdstOutput, CombinedSkimName=self.__name__)
872  kwargs.setdefault('udstOutput', False)
873 
874  from skim.taupair import TauThrust
876  super().__init__(*skims_list, **kwargs)
skim.systematics.SystematicsCombinedHadronic.__init__
def __init__(self, prescale_kshort=1, mdstOutput=True, **kwargs)
Definition: systematics.py:831
skim.systematics.SystematicsFourLeptonFromHLTFlag.SkimLists
SkimLists
Definition: systematics.py:641
skim.systematics.SystematicsPhiGamma.SkimLists
SkimLists
Definition: systematics.py:574
skimExpertFunctions.BaseSkim.skim_event_cuts
def skim_event_cuts(self, cut, *path)
Definition: skimExpertFunctions.py:716
skim.systematics.SystematicsDstar.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:39
skim.systematics.SystematicsJpsi.SkimLists
SkimLists
Definition: systematics.py:685
skim.systematics.SystematicsRadMuMuFromHLTFlag.SkimLists
SkimLists
Definition: systematics.py:663
vertex.raveFit
def raveFit(list_name, conf_level, fit_type='vertex', decay_string='', constraint='', daughtersUpdate=False, path=None, silence_warning=False)
Definition: vertex.py:128
skim.systematics.SystematicsEELL.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:399
skim.systematics.SystematicsTracking.BtoDStarPiList
def BtoDStarPiList(self, path)
Definition: systematics.py:104
skim.systematics.SystematicsJpsi.build_lists
def build_lists(self, path)
Definition: systematics.py:684
skim.systematics.Resonance.SkimLists
SkimLists
Definition: systematics.py:206
skim.systematics.SystematicsEELL
Definition: systematics.py:393
skim.systematics.SystematicsTracking.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:90
skim.systematics.Resonance.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:188
skim.systematics.SystematicsJpsi.JpsimumuTagProbe
def JpsimumuTagProbe(self, path)
Definition: systematics.py:690
skim.systematics.SystematicsTracking.SkimLists
SkimLists
Definition: systematics.py:102
skim.systematics.SystematicsRadMuMuFromHLTFlag.build_lists
def build_lists(self, path)
Definition: systematics.py:655
skim.systematics.SystematicsBhabha.build_lists
def build_lists(self, path)
Definition: systematics.py:795
skim.systematics.SystematicsTracking.build_lists
def build_lists(self, path)
Definition: systematics.py:95
stdPhotons
Definition: stdPhotons.py:1
skim.systematics.SystematicsDstar.SkimLists
SkimLists
Definition: systematics.py:51
skim.systematics.SystematicsLambda.build_lists
def build_lists(self, path)
Definition: systematics.py:520
skim.systematics.Random.KeepPercentage
KeepPercentage
Definition: systematics.py:593
skim.systematics.SystematicsRadEE.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:442
skim.systematics.SystematicsDstar.build_lists
def build_lists(self, path)
Definition: systematics.py:45
skim.systematics.SystematicsRadMuMu.build_lists
def build_lists(self, path)
Definition: systematics.py:359
skim.systematics.SystematicsCombinedLowMulti.__init__
def __init__(self, prescale_kshort=1, mdstOutput=True, **kwargs)
Definition: systematics.py:864
skim.systematics.Resonance.getmumugList
def getmumugList(self, path)
Definition: systematics.py:286
skim.systematics.Random.__init__
def __init__(self, KeepPercentage=10, seed=None, **kwargs)
Definition: systematics.py:584
skim.systematics.SystematicsKshort.SkimLists
SkimLists
Definition: systematics.py:766
skim.systematics.Resonance.build_lists
def build_lists(self, path)
Definition: systematics.py:195
skim.systematics.Random
Definition: systematics.py:578
skim.systematics.Random.SkimLists
SkimLists
Definition: systematics.py:618
skim.systematics.SystematicsBhabha.SkimLists
SkimLists
Definition: systematics.py:810
skim.systematics.SystematicsBhabha.prescale
prescale
Definition: systematics.py:789
skim.systematics.Random.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:600
stdPi0s
Definition: stdPi0s.py:1
skim.systematics.SystematicsPhiGamma.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:555
skimExpertFunctions.BaseSkim
Definition: skimExpertFunctions.py:504
skim.systematics.SystematicsEELL.SkimLists
SkimLists
Definition: systematics.py:418
skim.systematics.SystematicsJpsi
Definition: systematics.py:667
skim.systematics.SystematicsKshort
Definition: systematics.py:713
skim.systematics.SystematicsRadEE
Definition: systematics.py:422
skim.systematics.SystematicsRadMuMuFromHLTFlag.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:652
skim.systematics.SystematicsEELL.build_lists
def build_lists(self, path)
Definition: systematics.py:402
skim.systematics.Random.seed
seed
Definition: systematics.py:594
skim.systematics.SystematicsCombinedLowMulti
Definition: systematics.py:847
skim.systematics.SystematicsRadMuMu.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:356
skim.systematics.SystematicsBhabha.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:792
skim.systematics.SystematicsFourLeptonFromHLTFlag.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:629
skim.systematics.Resonance.getDsList
def getDsList(self, path)
Definition: systematics.py:208
skim.systematics.SystematicsRadMuMu
Definition: systematics.py:343
skim.systematics.SystematicsKshort.build_lists
def build_lists(self, path)
Definition: systematics.py:739
skim.taupair
Definition: taupair.py:1
skim.systematics.SystematicsKshort.prescale
prescale
Definition: systematics.py:733
skim.systematics.SystematicsPhiGamma
Definition: systematics.py:534
skim.systematics.SystematicsFourLeptonFromHLTFlag
Definition: systematics.py:622
skim.systematics.SystematicsBhabha.__init__
def __init__(self, prescale=1, **kwargs)
Definition: systematics.py:783
skim.systematics.Resonance.getDstarList
def getDstarList(self, path)
Definition: systematics.py:225
vertex.treeFit
def treeFit(list_name, conf_level=0.001, massConstraint=[], ipConstraint=False, updateAllDaughters=False, customOriginConstraint=False, customOriginVertex=[0.001, 0, 0.0116], customOriginCovariance=[0.0048, 0, 0, 0, 0.003567, 0, 0, 0, 0.0400], path=None)
Definition: vertex.py:191
skim.systematics.SystematicsRadMuMuFromHLTFlag
Definition: systematics.py:645
skim.systematics.SystematicsCombinedHadronic
Definition: systematics.py:814
skim.systematics.Resonance.getSigmacList
def getSigmacList(self, path)
Definition: systematics.py:250
skim.systematics.SystematicsDstar.PiKFromDstarList
def PiKFromDstarList(self, path)
Definition: systematics.py:53
skim.systematics.SystematicsKshort.__init__
def __init__(self, prescale=1, **kwargs)
Definition: systematics.py:727
skim.systematics.SystematicsKshort.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:736
skim.systematics.SystematicsRadEE.build_lists
def build_lists(self, path)
Definition: systematics.py:458
skim.systematics.SystematicsLambda.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:517
skim.systematics.SystematicsJpsi.load_standard_lists
def load_standard_lists(self, path)
Definition: systematics.py:676
skim.systematics.SystematicsPhiGamma.build_lists
def build_lists(self, path)
Definition: systematics.py:562
skim.systematics.SystematicsRadEE.__init__
def __init__(self, prescale_all=1, prescale_fwd_electron=1, **kwargs)
Definition: systematics.py:445
skim.systematics.SystematicsBhabha
Definition: systematics.py:770
skim.systematics.Resonance.getBZeroList
def getBZeroList(self, path)
Definition: systematics.py:302
skim.systematics.SystematicsTracking
Definition: systematics.py:81
skim.systematics.SystematicsCombinedLowMulti.__name__
string __name__
Definition: systematics.py:862
skimExpertFunctions.CombinedSkim
Definition: skimExpertFunctions.py:895
skim.systematics.SystematicsRadEE.SkimLists
SkimLists
Definition: systematics.py:507
skim.systematics.SystematicsRadEE.prescale_fwd_electron
prescale_fwd_electron
Definition: systematics.py:456
skim.systematics.SystematicsRadMuMu.SkimLists
SkimLists
Definition: systematics.py:389
skim.systematics.Random.build_lists
def build_lists(self, path)
Definition: systematics.py:604
skim.systematics.Random.additional_setup
def additional_setup(self, path)
Definition: systematics.py:596
skim.systematics.SystematicsFourLeptonFromHLTFlag.build_lists
def build_lists(self, path)
Definition: systematics.py:632
skim.systematics.SystematicsLambda.SkimLists
SkimLists
Definition: systematics.py:530
skim.systematics.SystematicsLambda
Definition: systematics.py:511
skim.systematics.SystematicsCombinedHadronic.__name__
string __name__
Definition: systematics.py:829
skim.systematics.Resonance
Definition: systematics.py:178
skim.systematics.SystematicsTracking.DstarToD0PiPartList
def DstarToD0PiPartList(self, path)
Definition: systematics.py:150
skim.systematics.Resonance.getBPlusList
def getBPlusList(self, path)
Definition: systematics.py:316
skim.systematics.SystematicsRadEE.prescale_all
prescale_all
Definition: systematics.py:455
skim.systematics.SystematicsJpsi.JpsieeTagProbe
def JpsieeTagProbe(self, path)
Definition: systematics.py:699
skim.systematics.SystematicsDstar
Definition: systematics.py:29