9#include <analysis/modules/NeutralHadronMatcher/NeutralHadronMatcherModule.h>
11#include <analysis/dataobjects/ParticleList.h>
12#include <analysis/variables/MCTruthVariables.h>
14#include <framework/datastore/StoreArray.h>
15#include <framework/datastore/StoreObjPtr.h>
16#include <framework/gearbox/Const.h>
17#include <mdst/dataobjects/MCParticle.h>
28NeutralHadronMatcherModule::NeutralHadronMatcherModule() :
Module()
30 setDescription(
"Perform geometrical match between MC neutral hadron (given by mcPDG) and ECL clusters from the particleLists");
31 setPropertyFlags(c_ParallelProcessingCertified);
32 addParam(
"particleLists", m_ParticleLists,
"Input particle list");
33 addParam(
"efficiencyCorrection", m_effcorr,
"data/mc efficiency ratio", 0.83);
34 addParam(
"distanceCut", m_distance,
"Matching distance", 15.0);
35 addParam(
"mcPDGcode", m_mcPDG,
"MC PDG code of the neutral hadron",
Const::Klong.getPDGCode());
36 addParam(
"ignoreClustersWithPDGcodes", m_PDGignore,
"Do not attempt to match clusters that are already matched with specific codes",
49 B2FATAL(
"Unsupported mcPDG value: " <<
m_mcPDG);
56 B2WARNING(
"No MCParticles array found. Do you call the NeutralHadronMatcher with real data?");
67 B2FATAL(
"Missing mcparticles list for MC");
74 const size_t nPart = particleList->getListSize();
75 for (
size_t iPart = 0; iPart < nPart; iPart++) {
76 auto particle = particleList->getParticle(iPart);
83 std::vector< std::pair<MCParticle*, bool> > primaryMCParticles;
84 for (
int i = 0; i < mcparticles.
getEntries(); i++) {
85 auto mcPart = mcparticles[i];
86 if (mcPart->isPrimaryParticle() && abs(mcPart->getPDG()) ==
m_mcPDG) {
87 bool AddInefficiency = (gRandom->Uniform() >
m_effcorr);
88 primaryMCParticles.push_back(std::pair(mcPart, AddInefficiency));
92 const size_t nMCPart = primaryMCParticles.size();
102 const size_t nPart = particleList->getListSize();
103 for (
size_t iPart = 0; iPart < nPart; iPart++) {
105 auto particle = particleList->getParticle(iPart);
106 auto bestMatch = Variable::particleClusterBestMCPDGCode(particle);
112 const ECLCluster* eclcluster = particle->getECLCluster();
113 if (!eclcluster)
continue;
116 std::vector< std::pair <double, bool> > distances;
117 distances.resize(nMCPart);
120 for (
size_t iMCPart = 0; iMCPart < nMCPart; iMCPart++) {
122 auto mcPart = primaryMCParticles[iMCPart].first;
124 auto vtx = mcPart->getProductionVertex();
125 auto momentum = mcPart->getMomentum();
128 double R = eclcluster->
getR();
129 double phi = eclcluster->
getPhi();
130 double theta = eclcluster->
getTheta();
131 double zcl =
R / tan(theta);
132 double xcl =
R * cos(phi);
133 double ycl =
R * sin(phi);
136 double z = vtx.Z() + rECL / tan(momentum.Theta());
137 double x = vtx.X() + rECL * cos(momentum.Phi());
138 double y = vtx.Y() + rECL * sin(momentum.Phi());
140 double dist =
sqrt((x - xcl) * (x - xcl) + (y - ycl) * (y - ycl) + (z - zcl) * (z - zcl));
141 distances[iMCPart] = std::pair(dist, primaryMCParticles[iMCPart].second);
144 auto it_distMin = std::min_element(distances.begin(), distances.end(),
145 [](
const auto & a,
const auto & b) { return a.first < b.first;});
146 double distMin = (*it_distMin).first;
147 bool AddInefficiency = (*it_distMin).second;
148 if ((distMin <
m_distance) && AddInefficiency)
154 particle->setExtraInfo(
m_matchedId, primaryMCParticles[std::distance(distances.begin(), it_distMin)].first->getArrayIndex());
int getPDGCode() const
PDG code.
static const ParticleType neutron
neutron particle
static const ParticleType Klong
K^0_L particle.
static const ParticleType photon
photon particle
double getPhi() const
Return Corrected Phi of Shower (radian).
double getR() const
Return R.
double getTheta() const
Return Corrected Theta of Shower (radian).
std::vector< std::string > m_ParticleLists
input particle lists name
virtual void initialize() override final
Overridden initialize method.
double m_effcorr
input efficiency correction
double m_distance
3d matching parameter
std::string m_infoName
extra info variable for distance
virtual void event() override final
Overridden event method.
std::string m_matchedId
extra info variable for matched MC
int m_mcPDG
input mcPDG value
std::vector< int > m_PDGignore
ignore clusters that are matched with the following PDG codes
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Accessor to arrays stored in the data store.
bool isValid() const
Check whether the array was registered.
int getEntries() const
Get the number of objects in the array.
Type-safe access to single objects in the data store.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.