9 #include <analysis/modules/TrackIsoCalculator/TrackIsoCalculatorModule.h>
10 #include <analysis/DecayDescriptor/DecayDescriptorParticle.h>
23 R
"DOC(Calculate track isolation variables on the charged stable particles, or selected charged daughters, of the input ParticleList.)DOC");
28 "The name of the input charged stable particle list, e.g. ``mu+:all``, or a composite particle w/ charged stable daughters for which distances are to be calculated, e.g. ``D0 -> ^K- pi+``. Note that in the latter case we allow only one daughter to be selected in the decay string per module instance.");
31 "The name of the input ParticleList of reference tracks. Must be a charged stable particle as defined in Const::chargedStableSet.");
34 "The name of the detector at whose (cylindrical) surface(s) we extrapolate each helix's polar and azimuthal angle. Allowed values: {CDC, TOP, ARICH, ECL, KLM}.");
37 "If this option is set, the helix extrapolation for the target and reference particles will use the track fit result for the most probable mass hypothesis, namely, the one that gives the highest chi2Prob of the fit.",
60 B2ERROR(
"More than one daughter is selected in the decay string " <<
m_decayString <<
".");
65 B2INFO(
"Calculating track-based isolation variables at " <<
m_detSurface <<
" surface for the decay string "
70 " is not that of a valid particle in Const::chargedStableSet!");
74 B2INFO(
"Will use track fit result for the most probable mass hypothesis in helix extrapolation.");
100 std::unordered_map<unsigned int, const Particle*> targetParticles;
101 targetParticles.reserve(nMotherParticles);
103 for (
unsigned int iPart(0); iPart < nMotherParticles; ++iPart) {
114 targetParticles.insert({iDaughter->getMdstArrayIndex(), iDaughter});
120 targetParticles.insert({iParticle->getMdstArrayIndex(), iParticle});
124 const auto nParticlesTarget = targetParticles.size();
127 B2DEBUG(11,
"Detector surface: " <<
m_detSurface <<
"\n"
128 <<
"nMotherParticles: " << nMotherParticles <<
"\n"
129 <<
"nParticlesTarget: " << nParticlesTarget <<
"\n"
130 <<
"nParticlesReference: " << nParticlesReference);
132 double dummyDist(-1.0);
136 std::map<std::pair<unsigned int, unsigned int>,
double> particleMdstIdxPairsToDist;
138 for (
const auto& targetParticle : targetParticles) {
139 auto iMdstIdx = targetParticle.first;
140 auto iParticle = targetParticle.second;
142 for (
unsigned int jPart(0); jPart < nParticlesReference; ++jPart) {
145 auto jMdstIdx = jParticle->getMdstArrayIndex();
147 auto partMdstIdxPair = std::make_pair(iMdstIdx, jMdstIdx);
150 if (iMdstIdx == jMdstIdx) {
151 particleMdstIdxPairsToDist[partMdstIdxPair] = dummyDist;
161 if (particleMdstIdxPairsToDist.count({jMdstIdx, iMdstIdx})) {
162 particleMdstIdxPairsToDist[partMdstIdxPair] = particleMdstIdxPairsToDist[ {jMdstIdx, iMdstIdx}];
167 particleMdstIdxPairsToDist[partMdstIdxPair] = this->
getDistAtDetSurface(iParticle, jParticle);
172 for (
const auto& targetParticle : targetParticles) {
173 auto iMdstIdx = targetParticle.first;
174 auto iParticle = targetParticle.second;
176 std::vector<double> iDistances;
177 for (
const auto& [mdstIdxs, dist] : particleMdstIdxPairsToDist) {
178 if (mdstIdxs.first == iMdstIdx) {
179 if (!std::isnan(dist) && dist >= 0) {
180 iDistances.push_back(dist);
185 if (!iDistances.size()) {
189 const auto minDist = *std::min_element(std::begin(iDistances), std::end(iDistances));
191 B2DEBUG(10,
"Particle w/ mdstIndex[" << iMdstIdx <<
"] (PDG = "
192 << iParticle->getPDGCode() <<
"). Closest charged partner at "
193 <<
m_detSurface <<
" surface is found at D = " << minDist <<
" [cm]"
221 std::string nameExtTheta =
"helixExtTheta(" + std::to_string(rho) +
"," + std::to_string(zfwd) +
"," + std::to_string(zbwd) +
")";
223 nameExtTheta.replace(nameExtTheta.size() - 1, 1,
", 1)");
228 std::string nameExtPhi =
"helixExtPhi(" + std::to_string(rho) +
"," + std::to_string(zfwd) +
"," + std::to_string(zbwd) +
")";
230 nameExtPhi.replace(nameExtPhi.size() - 1, 1,
", 1)");
235 const auto iExtInBarrel = (iExtTheta >= th_fwd_brl && iExtTheta < th_bwd_brl);
236 const auto jExtInBarrel = (jExtTheta >= th_fwd_brl && jExtTheta < th_bwd_brl);
238 const auto iExtInFWDEndcap = (iExtTheta >= th_fwd && iExtTheta < th_fwd_brl);
239 const auto jExtInFWDEndcap = (jExtTheta >= th_fwd && jExtTheta < th_fwd_brl);
241 const auto iExtInBWDEndcap = (iExtTheta >= th_bwd_brl && iExtTheta < th_bwd);
242 const auto jExtInBWDEndcap = (jExtTheta >= th_bwd_brl && jExtTheta < th_bwd);
247 if (!iExtInBarrel || !jExtInBarrel) {
248 return std::numeric_limits<double>::quiet_NaN();
255 auto diffPhi = jExtPhi - iExtPhi;
256 if (std::abs(diffPhi) > M_PI) {
257 diffPhi = (diffPhi > M_PI) ? diffPhi - 2 * M_PI : 2 * M_PI + diffPhi;
260 return 2.0 * rho * sin(std::abs(diffPhi) / 2.0);
266 if (!iExtInFWDEndcap || !jExtInFWDEndcap) {
267 return std::numeric_limits<double>::quiet_NaN();
275 !(iExtInBarrel && jExtInBarrel) &&
276 !(iExtInFWDEndcap && jExtInFWDEndcap) &&
277 !(iExtInBWDEndcap && jExtInBWDEndcap)
279 return std::numeric_limits<double>::quiet_NaN();
293 const auto iExtR = (iExtTheta >= th_fwd_brl && iExtTheta < th_bwd_brl) ? rho / sin(iExtTheta) : ((iExtTheta >= th_fwd
294 && iExtTheta < th_fwd_brl) ? zfwd / cos(iExtTheta) : zbwd / cos(iExtTheta));
295 const auto jExtR = (jExtTheta >= th_fwd_brl && jExtTheta < th_bwd_brl) ? rho / sin(jExtTheta) : ((jExtTheta >= th_fwd
296 && jExtTheta < th_fwd_brl) ? zfwd / cos(jExtTheta) : zbwd / cos(jExtTheta));
298 return sqrt((iExtR * iExtR) + (jExtR * jExtR) - 2 * iExtR * jExtR * (sin(iExtTheta) * sin(jExtTheta) * cos(iExtPhi - jExtPhi)
299 + cos(iExtTheta) * cos(jExtTheta)));
303 return std::numeric_limits<double>::quiet_NaN();
309 bool checkPList =
false;
323 bool checkPListReference =
false;
328 return (checkPList and checkPListReference);
const ParticleType & find(int pdg) const
Returns particle in set with given PDG code, or invalidParticle if not found.
static const ParticleSet chargedStableSet
set of charged stable particles
static const ParticleType invalidParticle
Invalid particle, used internally.
Represents a particle in the DecayDescriptor.
int getPDGCode() const
Return PDG code.
std::string getFullName() const
returns the full name of the particle full_name = name:label
The DecayDescriptor stores information about a decay tree or parts of a decay tree.
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
const DecayDescriptorParticle * getMother() const
return mother.
std::vector< int > getSelectionPDGCodes()
Return list of PDG codes of selected particles.
std::vector< std::string > getSelectionNames()
Return list of human readable names of selected particles.
std::vector< const Particle * > getSelectionParticles(const Particle *particle)
Get a vector of pointers with selected daughters in the decay tree.
void setDescription(const std::string &description)
Sets the description of the module.
Class to store reconstructed particles.
std::unordered_map< std::string, DetSurfCylBoundaries > m_detSurfBoundaries
Map that associates to each detector its valid cylindrical surface layer's boundaries.
StoreObjPtr< EventMetaData > m_event_metadata
The event information.
~TrackIsoCalculatorModule() override
Destructor, use this to clean up anything you created in the constructor.
void initialize() override
Use this to initialize resources or memory your module needs.
void event() override
Called once for each event.
std::string m_decayString
The name of the input charged stable particle list, or composite particle w/ charged stable daughters...
StoreObjPtr< ParticleList > m_pListTarget
The input ParticleList object for which distances are to be calculated.
StoreArray< Particle > m_particles
StoreArray of Particles.
void terminate() override
Module terminate().
std::string m_pListReferenceName
The name of the input ParticleList of reference tracks.
bool onlySelectedStdChargedInDecay()
Check whether input particle list and reference list are of a valid charged stable particle.
DecayDescriptor m_decaydescriptor
< Decay descriptor of decays to look for.
std::unordered_map< std::string, bool > m_isSurfaceInDet
Associate the detector flag to a boolean flag to quickly tell which detector it belongs too.
TrackIsoCalculatorModule()
Constructor: Sets the description, the properties and the parameters of the module.
std::string m_extraInfoName
The name of the distance variable to be added to each particle as extraInfo.
double getDistAtDetSurface(const Particle *iParticle, const Particle *jParticle)
Calculate the distance between the points where the two input extrapolated track helices cross the gi...
unsigned short m_nSelectedDaughters
The number of selected daughters in the decay string.
StoreObjPtr< ParticleList > m_pListReference
The input ParticleList object of reference tracks.
std::string m_detSurface
The name of the detector at whose inner (cylindrical) surface we extrapolate each track's polar and a...
bool m_useHighestProbMassForExt
If this option is set, the helix extrapolation for the target and reference particles will use the tr...
static Manager & Instance()
get singleton instance.
REG_MODULE(B2BIIConvertBeamParams)
Register the module.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Abstract base class for different kinds of events.