#!/usr/bin/env python3
# -*- coding: utf-8 -*-
##########################################################################
# basf2 (Belle II Analysis Software Framework) #
# Author: The Belle II Collaboration #
# #
# See git log for contributors and copyright holders. #
# This file is licensed under LGPL-3.0, see LICENSE.md. #
##########################################################################
"""
Skim list building functions for charm analyses.
.. Note::
The Hp, Hm and Jm in the function name represent arbitrary charged particles with
positive or negative charge. The Hp and Jm in `XToD0_D0ToHpJm`, mean a positive particle
and a negative particle that could be either conjugate or non-conjugate. The Hp and Hm
in `EarlyData_DstToD0Pi_D0ToHpHmPi0`, mean a positive particle and a negative particle that
must be conjugate.
.. Note::
Although reconstructDecay() would automatically include charged conjugate channel, and D0
is not distinguishable from anti-D0 in XToD0 skim, both :math:`D^0 \\to f` and :math:`D^0 \\to \\overline{f}`
mode should be written explicitly in XToD0 skim, because later in the DstToD0Pi skim, the D0 decay strings
in XToD0 skim would be directly combined with pi+. For example, if one only include D0 -> K+ pi- in XToD0_D0ToHpJm
skim, then in DstToD0Pi_D0ToHpJm skim, only the D*+ -> [D0 -> K+ pi-] pi+ would be included, and
D*+ -> [D0 -> K- pi+] pi+ would not be included.
"""
from functools import lru_cache
import basf2 as b2
import modularAnalysis as ma
from skim import BaseSkim, fancy_skim_header
from stdCharged import stdE, stdK, stdMu, stdPi, stdPr, stdCharged
from stdPhotons import loadStdSkimPhoton
from stdPi0s import loadStdSkimPi0
from stdV0s import stdKshorts
__liaison__ = "Kaikai He <20214008001@stu.suda.edu.cn>"
_VALIDATION_SAMPLE = "mdst14.root"
[docs]@lru_cache # Avoid loading the list multiple time on the same path
def charm_skim_std_charged(particle_type, path):
"""
Provides a list of charged particles to be used by charm skims named
``<particle_type>+:charmSkim``, with basic cuts applied:
``dr < 1 and abs(dz) < 3 and thetaInCDCAcceptance``.
"""
if particle_type not in ['pi', 'K', 'p', 'e', 'mu']:
raise ValueError(f"Unknown particle type {particle_type!r}")
stdCharged(particle_type, 'all', path=path)
ma.cutAndCopyList(
f"{particle_type}+:charmSkim", f"{particle_type}+:all",
"dr < 1 and abs(dz) < 3 and thetaInCDCAcceptance", path=path)
[docs]@fancy_skim_header
class XToD0_D0ToHpJm(BaseSkim):
"""
Skims :math:`D^0`'s reconstructed by `XToD0_D0ToHpJm.D0ToHpJm`.
"""
__authors__ = ["Giulia Casarosa"]
__description__ = "Skim list for D0 to two charged FSPs."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
# Cached static method, so that its contents are only executed once for a single path.
# Factored out into a separate function here, so it is available to other skims.
[docs] @staticmethod
@lru_cache()
def D0ToHpJm(path):
"""
**Decay Modes**:
* :math:`D^{0}\\to \\pi^+ \\pi^-`,
* :math:`D^{0}\\to K^+ \\pi^-`,
* :math:`D^{0}\\to K^- \\pi^+`,
* :math:`D^{0}\\to K^+ K^-`,
**Selection Criteria**:
* Tracks: ``abs(d0) < 1, abs(z0) < 3, 0.296706 < theta < 2.61799``
* ``1.66 < M(D0) < 2.06``
* ``pcms(D0) > 2.0``
* For more details, please check the source code of this skim.
**Parameters**:
* path (basf2.Path): Skim path to be processed.
**Returns**:
* List of D0 particle list names.
"""
mySel = "abs(d0) < 1 and abs(z0) < 3"
mySel += " and 0.296706 < theta < 2.61799"
ma.fillParticleList("pi+:mygood", mySel, path=path)
ma.fillParticleList("K+:mygood", mySel, path=path)
charmcuts = "1.66 < M < 2.06 and useCMSFrame(p)>2.0"
D0_Channels = [
"pi+:mygood pi-:mygood",
"K+:mygood pi-:mygood",
"K-:mygood pi+:mygood",
"K+:mygood K-:mygood",
]
D0List = []
for chID, channel in enumerate(D0_Channels):
ma.reconstructDecay("D0:HpJm" + str(chID) + " -> " + channel, charmcuts, chID, path=path)
D0List.append("D0:HpJm" + str(chID))
return D0List
[docs] def build_lists(self, path):
"""Builds :math:`D^0` skim lists defined in `XToD0_D0ToHpJm.D0ToHpJm`."""
return self.D0ToHpJm(path)
[docs]@fancy_skim_header
class XToD0_D0ToNeutrals(BaseSkim):
"""
Skims :math:`D^0`'s reconstructed by `XToD0_D0ToNeutrals.D0ToNeutrals`.
"""
__authors__ = ["Giulia Casarosa"]
__description__ = "Skim list for D0 to neutral FSPs."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
[docs] def load_standard_lists(self, path):
loadStdSkimPi0(path=path)
stdKshorts(path=path)
# Cached static method, so that its contents are only executed once for a single path
# Factored out into a separate function here, so it is available to other skims.
[docs] @staticmethod
@lru_cache()
def D0ToNeutrals(path):
"""
**Decay Modes**:
* :math:`D^{0}\\to \\pi^{0} \\pi^{0}`
* :math:`D^{0}\\to K_{S} \\pi^{0}`
* :math:`D^{0}\\to K_{S} K_{S}`
**Selection Criteria**:
* Use :math:`\\pi^{0}` from `stdPi0s.loadStdSkimPi0`
* Use :math:`K_{S}` from `stdV0s.stdKshorts`
* ``1.66 < M(D0) < 2.06, pcms(D0) > 2.0``
* For more details, please check the source code of this skim.
* (Maybe in the future, we can add a loose ECL cluster timing cut
to :math:`\\pi^{0}` in this skim.)
**Parameters**:
* path (basf2.Path): Skim path to be processed.
**Returns**:
* List of D0 particle list names.
"""
charmcuts = "1.66 < M < 2.06 and useCMSFrame(p)>2.0"
D0_Channels = ["pi0:skim pi0:skim",
"K_S0:merged pi0:skim",
"K_S0:merged K_S0:merged",
]
D0List = []
for chID, channel in enumerate(D0_Channels):
ma.reconstructDecay("D0:2Nbdy" + str(chID) + " -> " + channel, charmcuts, chID, path=path)
D0List.append("D0:2Nbdy" + str(chID))
return D0List
[docs] def build_lists(self, path):
"""Builds :math:`D^0` skim lists defined in `XToD0_D0ToNeutrals.D0ToNeutrals`."""
return self.D0ToNeutrals(path)
[docs]@fancy_skim_header
class DstToD0Pi_D0ToRare(BaseSkim):
"""
**Decay Modes**:
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\gamma \\gamma`,
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to ee`,
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to e^+ \\mu^-`,
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to e^- \\mu^+`,
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\mu \\mu`,
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\pi^+ \\pi^-`,
**Selection Criteria**:
* Use photons from `stdPhotons.loadStdSkimPhoton`
* Use electrons, muons and pions from loose lists in `stdCharged`
* ``1.66 < M(D0) < 2.06``
* No cut on the slow pion
* ``0 < Q < 0.02``
* ``pcms(D*) > 2.0``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Doris Yangsoo Kim", "Jaeyeon Kim"]
__description__ = "Skim list for D*+ to pi+ D0, D0 to rare decay."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
[docs] def load_standard_lists(self, path):
stdE("loose", path=path)
stdMu("loose", path=path)
stdPi("loose", path=path)
loadStdSkimPhoton(path=path)
loadStdSkimPi0(path=path)
[docs] def build_lists(self, path):
charmcuts = "1.66 < M < 2.06"
Dstcuts = "0 < Q < 0.02 and 2.0 < useCMSFrame(p)"
D0_Channels = ["gamma:skim gamma:skim",
"e+:loose e-:loose",
"e+:loose mu-:loose",
"e-:loose mu+:loose",
"mu+:loose mu-:loose",
"pi+:loose pi-:loose"]
DstList = []
for chID, channel in enumerate(D0_Channels):
ma.reconstructDecay("D0:Rare" + str(chID) + " -> " + channel, charmcuts, chID, path=path)
ma.reconstructDecay("D*+:" + str(chID) + " -> pi+:all D0:Rare" + str(chID),
Dstcuts, chID, path=path)
DstList.append("D*+:" + str(chID))
return DstList
[docs]@fancy_skim_header
class XToDp_DpToKsHp(BaseSkim):
"""
**Decay Modes**:
* :math:`D^+_{(S)} \\to K_{S} \\pi^+`,
* :math:`D^+_{(S)} \\to K_{S} K^+`,
**Selection Criteria**:
* Tracks not from :math:`K_{S}`: ``abs(d0) < 1, abs(z0) < 3,
0.296706 < theta < 2.61799``
* Use :math:`K_{S}` from `stdV0s.stdKshorts` and require
``flightDistance/flightDistanceErr > 2``
* ``1.67 < M(D+) < 2.17, pcms(D+) > 2.0``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Guanda Gong"]
__description__ = "Skim list for D_(s)+ to Ks h+."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
stdK("all", path=path)
stdPi("all", path=path)
stdKshorts(path=path)
[docs] def build_lists(self, path):
mySel = "abs(d0) < 1 and abs(z0) < 3"
mySel += " and 0.296706 < theta < 2.61799"
ma.fillParticleList("pi+:kshp", mySel, path=path)
ma.fillParticleList("K+:kshp", mySel, path=path)
ma.cutAndCopyList('K_S0:kshp', 'K_S0:merged', 'formula(flightDistance/flightDistanceErr) > 2', path=path)
Dpcuts = "1.67 < M < 2.17 and useCMSFrame(p) > 2.0"
Dp_Channels = ["K_S0:kshp pi+:kshp",
"K_S0:kshp K+:kshp",
]
DpList = []
for chID, channel in enumerate(Dp_Channels):
ma.reconstructDecay("D+:KsHp" + str(chID) + " -> " + channel, Dpcuts, chID, path=path)
DpList.append("D+:KsHp" + str(chID))
return DpList
[docs]@fancy_skim_header
class DpToPipepem(BaseSkim):
"""
**Decay Modes**:
* :math:`D^+ \\to \\pi^+ e^- e^+`,
**Selection Criteria**:
* Use tracks from the charm lists in `charm_skim_std_charged`
* ``1.67 < M(D+) < 2.17, pcms(D+) > 2.0`` and loose cuts for ee
* For more details, please check the source code of this skim.
"""
__authors__ = ["Andrej Lozar"]
__description__ = "Skim list for D+ to pi+ e+ e-."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
charm_skim_std_charged("pi", path=path)
charm_skim_std_charged("e", path=path)
ma.cutAndCopyList("e+:mySel", "e+:charmSkim", "electronID_noSVD_noTOP > 0.01", path=path)
[docs] def build_lists(self, path):
Dpcuts = "1.67 < M < 2.17 and useCMSFrame(p) > 2.0"
DpList = []
ma.reconstructDecay("D+:Pipepem -> pi+:charmSkim e+:mySel e-:mySel", Dpcuts, 1, path=path)
DpList.append("D+:Pipepem")
return DpList
[docs]@fancy_skim_header
class DpToPipmupmum(BaseSkim):
"""
**Decay Modes**:
* :math:`D^+ \\to \\pi^+ \\mu^- \\mu^+`
**Selection Criteria**:
* Use tracks from the charm lists in `charm_skim_std_charged`
* ``1.67 < M(D+) < 2.17, pcms(D+) > 2.0`` and loose cuts for mumu
* For more details, please check the source code of this skim.
"""
__authors__ = ["Andrej Lozar"]
__description__ = "Skim list for D+ to pi+ mu+ mu-."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
charm_skim_std_charged("pi", path=path)
charm_skim_std_charged("mu", path=path)
ma.cutAndCopyList("mu+:mySel", "mu+:charmSkim", "muonID_noSVD > 0.01", path=path)
[docs] def build_lists(self, path):
Dpcuts = "1.67 < M < 2.17 and useCMSFrame(p) > 2.0"
DpList = []
ma.reconstructDecay("D+:Pipmupmum -> pi+:charmSkim mu+:mySel mu-:mySel", Dpcuts, 1, path=path)
DpList.append("D+:Pipmupmum")
return DpList
[docs]@fancy_skim_header
class DpToPipKpKm(BaseSkim):
"""
**Decay Modes**:
* :math:`D^+ \\to \\pi^+ K^- K^+`
**Selection Criteria**:
* Use tracks from the charm lists in `charm_skim_std_charged`
* ``1.67 < M(D+) < 2.17, pcms(D+) > 2.0`` and loose cuts for KK
* For more details, please check the source code of this skim.
"""
__authors__ = ["Andrej Lozar"]
__description__ = "Skim list for D+ to pi+ K+ K-."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
charm_skim_std_charged("pi", path=path)
charm_skim_std_charged("K", path=path)
ma.cutAndCopyList("K+:mySel", "K+:charmSkim", "kaonID > 0.1", path=path)
[docs] def build_lists(self, path):
Dpcuts = "1.67 < M < 2.17 and useCMSFrame(p) > 2.0"
DpList = []
ma.reconstructDecay("D+:PipKpKm -> pi+:charmSkim K+:mySel K-:mySel", Dpcuts, 1, path=path)
DpList.append("D+:PipKpKm")
return DpList
[docs]@fancy_skim_header
class XToDp_DpToHpHmJp(BaseSkim):
"""
**Decay Modes**:
* :math:`D^+_{(S)} \\to \\pi^+ \\pi^- \\pi^+`,
* :math:`D^+_{(S)} \\to \\pi^+ \\pi^- K^+`,
* :math:`D^+_{(S)} \\to \\pi^+ K^- K^+`,
* :math:`D^+_{(S)} \\to K^+ K^- K^+`,
* For :math:`D^+_{(S)} \\to K_{S} h^+`, which includes a :math:`K_{S}` vertex,
please check `XToDp_DpToKsHp`
**Selection Criteria**:
* Use tracks from the loose lists in `stdCharged`
* ``1.67 < M(D+) < 2.17, pcms(D+) > 2.0``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Aman Sangal"]
__description__ = "Skim list for D_(s)+ to h+ h- j+."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
stdK("loose", path=path)
stdPi("loose", path=path)
[docs] def build_lists(self, path):
Dpcuts = "1.67 < M < 2.17 and useCMSFrame(p) > 2.0"
Dp_Channels = ["pi+:loose pi-:loose pi+:loose",
"pi+:loose pi-:loose K+:loose",
"pi+:loose K-:loose K+:loose",
"K+:loose K-:loose pi+:loose",
]
DpList = []
for chID, channel in enumerate(Dp_Channels):
ma.reconstructDecay("D+:HpHmJp" + str(chID) + " -> " + channel, Dpcuts, chID, path=path)
DpList.append("D+:HpHmJp" + str(chID))
return DpList
[docs]@fancy_skim_header
class LambdacTopHpJm(BaseSkim):
"""
**Decay Modes**:
* :math:`\\Lambda_c^+ \\to p \\pi^- \\pi^+`
* :math:`\\Lambda_c^+ \\to p K^- \\pi^+`
* :math:`\\Lambda_c^+ \\to p \\pi^- K^+`
* :math:`\\Lambda_c^+ \\to p K^- K^+`
**Selection Criteria**:
* Use tracks from the loose lists in `stdCharged`
* ``2.2 < M(Lambda_c) < 2.4, pcms(Lambda_c) > 2.0``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Justin Guilliams"]
__description__ = "Skim list for Lambda_c+ -> p K- pi+."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
stdK("all", path=path)
stdPi("all", path=path)
stdPr("loose", path=path)
[docs] def build_lists(self, path):
LambdacCuts = "2.2 < M < 2.4 and useCMSFrame(p) > 2.0"
LambdacChannels = ["p+:loose pi-:all pi+:all",
"p+:loose K-:all pi+:all",
"p+:loose pi-:all K+:all",
"p+:loose K-:all K+:all",
]
LambdacList = []
for chID, channel in enumerate(LambdacChannels):
ma.reconstructDecay("Lambda_c+:pHpJm" + str(chID) + " -> " + channel, LambdacCuts, chID, path=path)
LambdacList.append("Lambda_c+:pHpJm" + str(chID))
return LambdacList
[docs]@fancy_skim_header
class DstToDpPi0_DpToHpPi0(BaseSkim):
"""
**Decay Modes**:
* :math:`D^{*+}\\to \\pi^{0} D^{+}, D^+ \\to \\pi^+ \\pi^0`
**Selection Criteria**:
* Tracks: ``abs(d0) < 1, abs(z0) < 3, 0.296706 < theta < 2.61799``
* Use :math:`\\pi^{0}` from `stdPi0s.loadStdSkimPi0`
* ``1.67 < M(D+) < 2.07, pcms(D+) > 2.0``
* ``0 < Q < 0.018``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Johannes Brand"]
__description__ = "Skim list for D*+ to D+ pi0, D+ to h+ pi0."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
[docs] def load_standard_lists(self, path):
stdPi("all", path=path)
loadStdSkimPi0(path=path)
[docs] def build_lists(self, path):
mySel = "abs(d0) < 1 and abs(z0) < 3"
mySel += " and 0.296706 < theta < 2.61799"
ma.fillParticleList("pi+:hppi0", mySel, path=path)
Dpcuts = "1.67 < M < 2.07 and useCMSFrame(p) > 2.0"
Dp_Channels = ["pi+:hppi0 pi0:skim",
]
DstList = []
for chID, channel in enumerate(Dp_Channels):
ma.reconstructDecay("D+:HpPi0" + str(chID) + " -> " + channel, Dpcuts, chID, path=path)
ma.reconstructDecay("D*+:HpPi0" + str(chID) + " -> D+:HpPi0" + str(chID) + " pi0:skim", "0 < Q < 0.018", path=path)
DstList.append("D*+:HpPi0" + str(chID))
return DstList
[docs]@fancy_skim_header
class DstToD0Pi_D0ToHpJm(XToD0_D0ToHpJm):
"""
**Decay Modes**:
* :math:`D^{*+}\\to D^{0} \\pi^+`, where :math:`D^{0}` is reconstructed by `XToD0_D0ToHpJm.D0ToHpJm`
**Selection Criteria**:
* Apply the cuts in `XToD0_D0ToHpJm`
* No cut on the slow pion
* ``0 < Q < 0.018``
* For more details, please check the source code of this skim.
"""
__authors__ = "Giulia Casarosa"
__description__ = "Same as `XToD0_D0ToHpJm`, but requiring the D0 is from D*+ -> D0 pi+ process."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
stdK("all", path=path)
stdPi("all", path=path)
[docs] def build_lists(self, path):
D0List = self.D0ToHpJm(path)
Dstcuts = '0 < Q < 0.018'
DstList = []
for chID, channel in enumerate(D0List):
ma.reconstructDecay('D*+:HpJm' + str(chID) + ' -> D0:HpJm' + str(chID) + ' pi+:all', Dstcuts, chID, path=path)
DstList.append('D*+:HpJm' + str(chID))
return DstList
[docs]@fancy_skim_header
class DstToD0Pi_D0ToHpJmPi0(BaseSkim):
"""
**Decay Modes**: :math:`D^{*\\pm}\\to D^{0} \\pi^\\pm` with
* :math:`D^{0}\\to K^\\mp \\pi^\\pm \\pi^0` (and CC)
* :math:`D^{0}\\to \\pi^+ \\pi^- \\pi^0` (and CC)
* :math:`D^{0}\\to K^+ K^- \\pi^0` (and CC)
**Selection Criteria**:
* Tracks: ``charmSkim`` lists from `charm_skim_std_charged`
* Pions: ``pionIDNN > 0.1``
* Kaons: ``kaonIDNN > 0.1``
* :math:`\\pi^{0}`: from `stdPi0s.loadStdSkimPi0`
* ``1.70 < M(D0) < 2.10``
* ``M(D*)-M(D0) < 0.16``
* ``pCM(D*) > 2.0``
.. Note::
The neural-network based PID variables ``pionIDNN`` and ``kaonIDNN``
require the analysis globaltag to be set (e.g. via
``b2skim-run --analysis-globaltag ANALYSIS_GT_NAME ...``). In case
calibrated weights are not ready for the skimming campaign, this skim
must be modified to use :b2:var:`binaryPID_noSVD` or
:b2:var:`binaryPID` instead (this will have some impact on skim
performance, although small, and needs to be tested).
"""
__authors__ = ["Ludovico Massaccesi", "Emma Oxford"]
__description__ = (
"Skim list for D*-tagged D0 to pi0 and two charged hadrons"
" (any combination of kaons and pions)."
)
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def additional_setup(self, path):
if self.analysisGlobaltag is None:
b2.B2FATAL(f"The analysis globaltag is not set in the {self.name} skim.")
b2.conditions.prepend_globaltag(self.analysisGlobaltag)
[docs] def load_standard_lists(self, path):
charm_skim_std_charged('pi', path=path)
charm_skim_std_charged('K', path=path)
loadStdSkimPi0(path=path)
[docs] def build_lists(self, path):
D0_cuts = "1.70 < M < 2.10"
Dst_cuts = "massDifference(0) < 0.16 and useCMSFrame(p) > 2"
ma.cutAndCopyList('pi+:charmSkim_pid', 'pi+:charmSkim', 'pionIDNN > 0.1', path=path)
ma.cutAndCopyList('K+:charmSkim_pid', 'K+:charmSkim', 'kaonIDNN > 0.1', path=path)
Dst_lists = []
for h1, h2 in [('pi', 'pi'), ('pi', 'K'), ('K', 'K')]:
lst = f"{h1}{h2}Pi0"
ma.reconstructDecay(f"D0:{lst} -> {h1}+:charmSkim_pid {h2}-:charmSkim_pid pi0:skim", D0_cuts, path=path)
ma.reconstructDecay(f"D*+:{lst}_RS -> D0:{lst} pi+:charmSkim_pid", Dst_cuts, path=path)
ma.reconstructDecay(f"D*-:{lst}_WS -> D0:{lst} pi-:charmSkim_pid", Dst_cuts, path=path)
ma.copyLists(f"D*+:{lst}", [f"D*+:{lst}_RS", f"D*+:{lst}_WS"], path=path)
Dst_lists.append(f"D*+:{lst}")
return Dst_lists
[docs]@fancy_skim_header
class DstToD0Pi_D0ToKsOmega(BaseSkim):
"""
**Decay Modes**:
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to K_{S} \\pi^+ \\pi^- \\pi^{0}`
**Selection Criteria**:
* Tracks from :math:`D^{0}`:
``abs(d0) < 1, abs(z0) < 3, 0.296706 < theta < 2.61799``
* Use :math:`\\pi^{0}` from `stdPi0s.loadStdSkimPi0`, then require ``0.11 < M(pi0) < 0.15, p(pi0) > 0.25``
* ``1.66 < M(D0) < 2.06, pcms(D0) > 2.0``
* ``Q < 0.018``
* For more details, please check the source code of this skim.
"""
__authors__ = []
__description__ = "Skim list for D*+ to pi+ D0, D0 to Ks pi+ pi- pi0."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
stdPi("all", path=path)
loadStdSkimPi0(path=path)
stdKshorts(path=path)
[docs] def build_lists(self, path):
mySel = "abs(d0) < 1 and abs(z0) < 3"
mySel += " and 0.296706 < theta < 2.61799"
ma.fillParticleList("pi+:ksomega", mySel, path=path)
ma.cutAndCopyList("pi0:mypi0", "pi0:skim", "0.11 < M < 0.15 and p > 0.25 ", path=path)
ma.reconstructDecay("omega:3pi -> pi+:ksomega pi-:ksomega pi0:mypi0", "", path=path)
charmcuts = "1.66 < M < 2.06 and useCMSFrame(p) > 2.0"
ma.reconstructDecay("D0:KsOmega -> K_S0:merged omega:3pi", charmcuts, path=path)
DstList = []
ma.reconstructDecay("D*+:KsOmega -> D0:KsOmega pi+:all", "0 < Q < 0.018", path=path)
DstList.append("D*+:KsOmega")
return DstList
[docs]@fancy_skim_header
class DstToD0Pi_D0ToHpHmHpJm(BaseSkim):
"""
**Decay Modes**:
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\pi^+ \\pi^- \\pi^+ \\pi^-`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\pi^+ \\pi^- \\pi^+ K^-`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\pi^+ \\pi^- K^+ K^-`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\pi^+ K^- K^+ K^-`
**Selection Criteria**:
* Tracks from :math:`D^{0}`:
``abs(d0) < 1, abs(z0) < 3, 0.296706 < theta < 2.61799``
* ``1.66 < M(D0) < 2.06``
* No cut on the slow pion
* ``Q < 0.022, pcms(D*+) > 2.0``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Kavita Lalwani, Chanchal Sharma"]
__description__ = "Skim list for D*+ to K- pi+ pi- pi+."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
stdPi("all", path=path)
stdK("all", path=path)
[docs] def build_lists(self, path):
mySel = "abs(d0) < 1 and abs(z0) < 3"
mySel += " and 0.296706 < theta < 2.61799"
ma.fillParticleList("pi+:hphmhpjm", mySel, path=path)
ma.fillParticleList("K+:hphmhpjm", mySel, path=path)
D0_Channels = [
"pi+:hphmhpjm pi-:hphmhpjm pi+:hphmhpjm pi-:hphmhpjm",
"pi+:hphmhpjm pi-:hphmhpjm pi+:hphmhpjm K-:hphmhpjm",
"pi+:hphmhpjm pi-:hphmhpjm K+:hphmhpjm K-:hphmhpjm",
"pi+:hphmhpjm K-:hphmhpjm K+:hphmhpjm K-:hphmhpjm",
]
D0cuts = "1.66 < M < 2.06"
Dstcuts = "0 < Q < 0.022 and useCMSFrame(p) > 2.0"
DstList = []
for chID, channel in enumerate(D0_Channels):
ma.reconstructDecay("D0:HpHmHpJm" + str(chID) + " -> " + channel, D0cuts, chID, path=path)
ma.reconstructDecay("D*+:HpHmHpJm" + str(chID) + " -> pi+:all D0:HpHmHpJm" + str(chID), Dstcuts, chID, path=path)
DstList.append("D*+:HpHmHpJm" + str(chID))
return DstList
[docs]@fancy_skim_header
class DstToD0Pi_D0ToNeutrals(XToD0_D0ToNeutrals):
"""
**Decay Modes**:
* :math:`D^{*+}\\to \\pi^+ D^{0}`, where the :math:`D^{0}` is reconstructed
by `XToD0_D0ToNeutrals.D0ToNeutrals`.
**Selection Criteria**:
* Apply the cuts in `XToD0_D0ToNeutrals`
* No cut on the slow pion
* ``Q < 0.02``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Giulia Casarosa", "Emma Oxford"]
__description__ = "Same as `XToD0_D0ToNeutrals`, but requiring that the D0 is from D* decay."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
[docs] def load_standard_lists(self, path):
stdPi("all", path=path)
loadStdSkimPi0(path=path)
stdKshorts(path=path)
[docs] def build_lists(self, path):
D0List = self.D0ToNeutrals(path)
Dstcuts = "0 < Q < 0.02"
DstList = []
for chID, channel in enumerate(D0List):
ma.reconstructDecay("D*+:2Nbdy" + str(chID) + " -> pi+:all " + channel, Dstcuts, chID, path=path)
DstList.append("D*+:2Nbdy" + str(chID))
return DstList
[docs]@fancy_skim_header
class DstToD0Pi_D0ToHpJmKs(BaseSkim):
"""
**Decay Modes**:
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to K_{S} \\pi^+ \\pi^-`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to K_{S} \\pi^+ K^-`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to K_{S} K^+ \\pi^-`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to K_{S} K^+ K^-`
**Selection Criteria**:
* Tracks from :math:`D^{0}`:
``abs(d0) < 1, abs(z0) < 3, 0.296706 < theta < 2.61799``
* Use :math:`K_{S}` from `stdV0s.stdKshorts`
* ``1.66 < M(D0) < 2.06``
* No cut on the slow pion
* ``Q < 0.022``
* ``pcms(D*) > 2.0``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Yeqi Chen"]
__description__ = "Skim list for D*+ to pi+ D0, D0 to Ks and two conjugate charged FSPs."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
stdKshorts(path=path)
[docs] def build_lists(self, path):
mySel = "abs(d0) < 1 and abs(z0) < 3"
mySel += " and 0.296706 < theta < 2.61799"
ma.fillParticleList("pi+:hpjmks", mySel, path=path)
ma.fillParticleList("K+:hpjmks", mySel, path=path)
D0cuts = "1.66 < M < 2.06"
Dstcuts = "0 < Q < 0.022 and useCMSFrame(p) > 2.0"
D0_Channels = ["pi-:hpjmks pi+:hpjmks K_S0:merged",
"K-:hpjmks pi+:hpjmks K_S0:merged",
"pi-:hpjmks K+:hpjmks K_S0:merged",
"K-:hpjmks K+:hpjmks K_S0:merged",
]
DstList = []
for chID, channel in enumerate(D0_Channels):
ma.reconstructDecay("D0:HpJmKs" + str(chID) + " -> " + channel, D0cuts, chID, path=path)
ma.reconstructDecay("D*+:HpJmKs" + str(chID) + " -> pi+:all D0:HpJmKs" + str(chID), Dstcuts, chID, path=path)
DstList.append("D*+:HpJmKs" + str(chID))
return DstList
[docs]@fancy_skim_header
class EarlyData_DstToD0Pi_D0ToHpJmPi0(BaseSkim):
"""
Cut criteria are not finally decided, and could be changed. Please check the
code in the master branch to get up-to-date information.
"""
__authors__ = []
__description__ = "An special version of `DstToD0Pi_D0ToHpJmPi0` to deal with Early Data."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
loadStdSkimPhoton(path=path)
loadStdSkimPi0(path=path)
[docs] def build_lists(self, path):
mySel = "abs(d0) < 0.5 and abs(z0) < 1.0" # IP cut, tighter than previous skims
mySel += " and 0.296706 < theta < 2.61799" # CDC acceptance cut
ma.fillParticleList("pi+:myhjp0", mySel, path=path)
ma.fillParticleList("K+:myhjp0", mySel, path=path)
ma.cutAndCopyList("pi0:myhjp0", "pi0:skim", "", path=path) # see analysis/scripts/stdPi0s.py for cuts
D0cuts = "1.70 < M < 2.10"
Dstcuts = "massDifference(0) < 0.160 and useCMSFrame(p) > 2.0"
eventcuts = "nCleanedTracks(abs(d0) < 0.5 and abs(z0) < 1.0) >= 3"
path = self.skim_event_cuts(eventcuts, path=path)
DstList = []
ma.reconstructDecay("D0:HpJmPi0 -> K-:myhjp0 pi+:myhjp0 pi0:myhjp0", D0cuts, path=path)
ma.reconstructDecay("D*+:HpJmPi0RS -> D0:HpJmPi0 pi+:myhjp0", Dstcuts, path=path)
ma.reconstructDecay("D*-:HpJmPi0WS -> D0:HpJmPi0 pi-:myhjp0", Dstcuts, path=path)
ma.copyLists("D*+:HpJmPi0", ["D*+:HpJmPi0RS", "D*+:HpJmPi0WS"], path=path)
DstList.append("D*+:HpJmPi0")
return DstList
[docs]@fancy_skim_header
class EarlyData_DstToD0Pi_D0ToHpHmPi0(BaseSkim):
"""
Cut criteria are not finally decided, and could be changed. Please check the
code in the master branch to get up-to-date information.
"""
__authors__ = []
__description__ = "A special version of ``DstToD0Pi_D0ToHpHmPi0`` to deal with Early Data."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = True
[docs] def load_standard_lists(self, path):
loadStdSkimPi0(path=path)
[docs] def build_lists(self, path):
mySel = "abs(d0) < 0.5 and abs(z0) < 1.0" # IP cut, tighter than previous skims
mySel += " and 0.296706 < theta < 2.61799" # CDC acceptance cut
ma.fillParticleList("pi+:myhhp0", mySel, path=path)
ma.fillParticleList("K+:myhhp0", mySel, path=path)
ma.cutAndCopyList("pi0:myhhp0", "pi0:skim", "", path=path) # see analysis/scripts/stdPi0s.py for cuts
D0cuts = "1.70 < M < 2.10"
Dstcuts = "massDifference(0) < 0.160 and useCMSFrame(p) > 2.0"
eventcuts = "nCleanedTracks(abs(d0) < 0.5 and abs(z0) < 1.0) >= 3"
path = self.skim_event_cuts(eventcuts, path=path)
D0_Channels = ["pi+:myhhp0 pi-:myhhp0 pi0:myhhp0",
"K+:myhhp0 K-:myhhp0 pi0:myhhp0",
]
DstList = []
for chID, channel in enumerate(D0_Channels):
ma.reconstructDecay("D0:HpHmPi0" + str(chID) + " -> " + channel, D0cuts, chID, path=path)
ma.reconstructDecay("D*+:HpHmPi0" + str(chID) + " -> D0:HpHmPi0" + str(chID) + " pi+:myhhp0",
Dstcuts, chID, path=path)
DstList.append("D*+:HpHmPi0" + str(chID))
return DstList
[docs]@fancy_skim_header
class DstToD0Pi_D0ToVGamma(BaseSkim):
"""
**Decay Modes**:
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\phi \\gamma`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\rho^{0} \\gamma`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\bar K^{*0} \\gamma`
* :math:`D^{*+}\\to \\pi^+ D^{0}, D^{0}\\to \\omega \\gamma`
**Selection Criteria**:
* Use charged tracks from the loose lists in `stdCharged` to reconstruct :math:`D^{0}`
* Use :math:`\\gamma` from `stdPhotons.loadStdSkimPhoton`
* Use :math:`\\pi^{0}` from `stdPi0s.loadStdSkimPi0`
* Cut on :math:`\\phi`:
``abs(dM) < 0.03``
* Cut on :math:`\\rho^{0}`:
``abs(dM) < 0.3675``
* Cut on :math:`\\bar K^{*0}`:
``abs(dM) < 0.33``
* Cut on :math:`\\omega`:
``abs(dM) < 0.045``
* Cut on :math:`D^{0}`:
``abs(dM) < 0.225 and useCMSFrame(p) > 2``
* Cut on :math:`D^{*+}`:
``massDifference(0) < 0.160``
* For more details, please check the source code of this skim.
"""
__authors__ = ["Jaeyoung Kim"]
__description__ = "A select of DstToD0Pi_D0ToVGamma, V is the vector meson, including phi, rho0, anti-K*0 and omega."
__contact__ = __liaison__
__category__ = "physics, charm"
NoisyModules = ["ParticleLoader", "RootOutput"]
ApplyHLTHadronCut = False
[docs] def load_standard_lists(self, path):
stdK("loose", path=path)
stdPi("loose", path=path)
loadStdSkimPhoton(path=path)
loadStdSkimPi0(path=path)
[docs] def build_lists(self, path):
omegacut = "abs(dM) < 0.045"
phicut = "abs(dM) < 0.03"
rhocut = "abs(dM) < 0.3675"
antiKstarcut = "abs(dM) < 0.33"
D0cuts = "abs(dM) < 0.225 and useCMSFrame(p) > 2"
Dstcuts = "massDifference(0) < 0.160"
DstList = []
# Omega mode
ma.reconstructDecay(decayString="omega:myOmega -> pi+:loose pi-:loose pi0:skim", cut=omegacut, path=path)
ma.reconstructDecay(decayString="D0:ch1 -> omega:myOmega gamma:loose", cut=D0cuts, path=path)
ma.reconstructDecay(decayString="D*+:ch1 -> D0:ch1 pi+:loose", cut=Dstcuts, dmID=1, path=path)
# Phi mode
ma.reconstructDecay(decayString="phi:myPhi -> K+:loose K-:loose", cut=phicut, path=path)
ma.reconstructDecay(decayString="D0:ch2 -> phi:myPhi gamma:loose", cut=D0cuts, path=path)
ma.reconstructDecay(decayString="D*+:ch2 -> D0:ch2 pi+:loose", cut=Dstcuts, dmID=2, path=path)
# Rho0 mode
ma.reconstructDecay(decayString="rho0:myRho -> pi+:loose pi-:loose", cut=rhocut, path=path)
ma.reconstructDecay(decayString="D0:ch3 -> rho0:myRho gamma:loose", cut=D0cuts, path=path)
ma.reconstructDecay(decayString="D*+:ch3 -> D0:ch3 pi+:loose", cut=Dstcuts, dmID=3, path=path)
# anti-K*0 mode
ma.reconstructDecay(decayString="anti-K*0:myantiKstar -> K-:loose pi+:loose", cut=antiKstarcut, path=path)
ma.reconstructDecay(decayString="D0:ch4 -> anti-K*0:myantiKstar gamma:loose", cut=D0cuts, path=path)
ma.reconstructDecay(decayString="D*+:ch4 -> D0:ch4 pi+:loose", cut=Dstcuts, dmID=4, path=path)
ma.copyLists(outputListName="D*+:all", inputListNames=["D*+:ch1", "D*+:ch2", "D*+:ch3", "D*+:ch4"], path=path)
eventCuts = "nParticlesInList(D*+:all) > 0"
path = self.skim_event_cuts(eventCuts, path=path)
DstList.append("D*+:all")
return DstList