9#include <analysis/modules/NeutralHadronMatcher/NeutralHadronMatcherModule.h>
10#include <framework/dataobjects/EventExtraInfo.h>
11#include <framework/core/Environment.h>
12#include <framework/datastore/StoreArray.h>
13#include <framework/datastore/StoreObjPtr.h>
15#include <analysis/variables/MCTruthVariables.h>
24NeutralHadronMatcherModule::NeutralHadronMatcherModule() :
Module()
26 setDescription(
"Perform geometrical match between MC neutral hadron (given by mcPDG) and ECL clusters from the particleLists");
27 addParam(
"particleLists", m_ParticleLists,
"Input particle list");
28 addParam(
"efficiencyCorrection", m_effcorr,
"data/mc efficiency ratio", 0.83);
29 addParam(
"distanceCut", m_distance,
"Matching distance", 15.0);
30 addParam(
"mcPDGcode", m_mcPDG,
"MC PDG code of the neutral hadron",
Const::Klong.getPDGCode());
31 addParam(
"ignoreClustersWithPDGcodes", m_PDGignore,
"Do not attempt to match clusters that are already matched with specific codes",
44 B2FATAL(
"Unsupported mcPDG value: " <<
m_mcPDG);
51 B2WARNING(
"No MCParticles array found. Do you call the NeutralHadronMatcher with real data?");
62 B2FATAL(
"Missing mcparticles list for MC");
69 const size_t nPart = particleList->getListSize();
70 for (
size_t iPart = 0; iPart < nPart; iPart++) {
71 auto particle = particleList->getParticle(iPart);
78 std::vector< std::pair<MCParticle*, bool> > primaryMCParticles;
79 for (
int i = 0; i < mcparticles.
getEntries(); i++) {
80 auto mcPart = mcparticles[i];
81 if (mcPart->isPrimaryParticle() && abs(mcPart->getPDG()) ==
m_mcPDG) {
82 bool AddInefficiency = (gRandom->Uniform() >
m_effcorr);
83 primaryMCParticles.push_back(std::pair(mcPart, AddInefficiency));
87 const size_t nMCPart = primaryMCParticles.size();
97 const size_t nPart = particleList->getListSize();
98 for (
size_t iPart = 0; iPart < nPart; iPart++) {
100 auto particle = particleList->getParticle(iPart);
101 auto bestMatch = Variable::particleClusterBestMCPDGCode(particle);
107 const ECLCluster* eclcluster = particle->getECLCluster();
108 if (!eclcluster)
continue;
111 std::vector< std::pair <double, bool> > distances;
112 distances.resize(nMCPart);
115 for (
size_t iMCPart = 0; iMCPart < nMCPart; iMCPart++) {
117 auto mcPart = primaryMCParticles[iMCPart].first;
119 auto vtx = mcPart->getProductionVertex();
120 auto momentum = mcPart->getMomentum();
123 double R = eclcluster->
getR();
124 double phi = eclcluster->
getPhi();
125 double theta = eclcluster->
getTheta();
126 double zcl =
R / tan(theta);
127 double xcl =
R * cos(phi);
128 double ycl =
R * sin(phi);
131 double z = vtx.Z() + rECL / tan(momentum.Theta());
132 double x = vtx.X() + rECL * cos(momentum.Phi());
133 double y = vtx.Y() + rECL * sin(momentum.Phi());
135 double dist =
sqrt((x - xcl) * (x - xcl) + (y - ycl) * (y - ycl) + (z - zcl) * (z - zcl));
136 distances[iMCPart] = std::pair(dist, primaryMCParticles[iMCPart].second);
139 auto it_distMin = std::min_element(distances.begin(), distances.end(),
140 [](
const auto & a,
const auto & b) { return a.first < b.first;});
141 double distMin = (*it_distMin).first;
142 bool AddInefficiency = (*it_distMin).second;
143 if ((distMin <
m_distance) && AddInefficiency)
149 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 wether 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.