9 #include <analysis/modules/ChargedParticleIdentificator/ChargedPidMVAModule.h>
12 #include <mva/interface/Interface.h>
13 #include <analysis/VariableManager/Utility.h>
14 #include <analysis/dataobjects/Particle.h>
15 #include <analysis/dataobjects/ParticleList.h>
18 #include <mdst/dataobjects/ECLCluster.h>
26 setDescription(
"This module evaluates the response of an MVA trained for binary charged particle identification between two hypotheses, S and B. For a given input set of (S,B) mass hypotheses, it takes the Particle objects in the appropriate charged stable particle's ParticleLists, calculates the MVA score using the appropriate xml weight file, and adds it as ExtraInfo to the Particle objects.");
28 setPropertyFlags(c_ParallelProcessingCertified);
30 addParam(
"sigHypoPDGCode",
32 "The input signal mass hypothesis' pdgId.",
34 addParam(
"bkgHypoPDGCode",
36 "The input background mass hypothesis' pdgId.",
38 addParam(
"particleLists",
40 "The input list of ParticleList names.",
41 std::vector<std::string>());
42 addParam(
"payloadName",
44 "The name of the database payload object with the MVA weights.",
45 std::string(
"ChargedPidMVAWeights"));
46 addParam(
"chargeIndependent",
48 "Specify whether to use a charge-independent training of the MVA.",
50 addParam(
"useECLOnlyTraining",
52 "Specify whether to use an ECL-only training of the MVA.",
57 ChargedPidMVAModule::~ChargedPidMVAModule() =
default;
60 void ChargedPidMVAModule::initialize()
79 " of the signal mass hypothesis is not that of a valid particle in Const::chargedStableSet! Aborting...");
83 " of the background mass hypothesis is not that of a valid particle in Const::chargedStableSet! Aborting...");
106 if (!pList) { B2FATAL(
"ParticleList: " << name <<
" could not be found. Aborting..."); }
109 int pdg = abs(pList->getPDGCode());
113 B2FATAL(
"PDG: " << pList->getPDGCode() <<
" of ParticleList: " << pList->getParticleListName() <<
114 " is not that of a valid particle in Const::chargedStableSet! Aborting...");
122 B2DEBUG(11,
"ParticleList: " << pList->getParticleListName() <<
" - N = " << pList->getListSize() <<
" particles.");
124 for (
unsigned int ipart(0); ipart < pList->getListSize(); ++ipart) {
126 Particle* particle = pList->getParticle(ipart);
128 B2DEBUG(11,
"\tParticle [" << ipart <<
"]");
132 const ECLCluster* eclCluster = particle->getECLCluster();
134 B2DEBUG(11,
"\t\tParticle has invalid Track-ECLCluster relation, skip MVA application...");
140 auto clusterTheta = eclCluster->
getTheta();
141 auto p = particle->getP();
144 int idx_theta, idx_p, idx_charge;
149 const auto cutstr = (!cuts->empty()) ? cuts->at(index) :
"";
151 B2DEBUG(11,
"\t\tclusterTheta = " << clusterTheta <<
" [rad]");
152 B2DEBUG(11,
"\t\tp = " << p <<
" [GeV/c]");
154 B2DEBUG(11,
"\t\tcharge = " << charge);
156 B2DEBUG(11,
"\t\tBrems corrected = " << particle->hasExtraInfo(
"bremsCorrectedPhotonEnergy"));
157 B2DEBUG(11,
"\t\tWeightfile idx = " << index <<
" - (clusterTheta, p, charge) = (" << idx_theta <<
", " << idx_p <<
", " <<
159 if (!cutstr.empty()) {
160 B2DEBUG(11,
"\tCategory cut: " << cutstr);
165 B2DEBUG(11,
"\tMVA variables:");
168 for (
unsigned int ivar(0); ivar < nvars; ++ivar) {
172 auto var = varobj->function(particle);
175 var = (std::isnan(var)) ? -999.0 : var;
177 B2DEBUG(11,
"\t\tvar[" << ivar <<
"] : " << varobj->name <<
" = " << var);
183 B2DEBUG(12,
"\tMVA spectators:");
186 for (
unsigned int ispec(0); ispec < nspecs; ++ispec) {
190 auto spec = specobj->function(particle);
192 B2DEBUG(12,
"\t\tspec[" << ispec <<
"] : " << specobj->name <<
" = " << spec);
194 m_datasets.at(index)->m_spectators[ispec] = spec;
199 if (!cutstr.empty()) {
203 if (!cut->check(particle)) {
204 B2WARNING(
"\tParticle didn't pass MVA category cut, skip MVA application...");
212 B2DEBUG(11,
"\tMVA score = " << score);
227 B2INFO(
"Run: " <<
m_event_metadata->getRun() <<
". Load supported MVA interfaces for binary charged particle identification...");
233 B2INFO(
"\tLoading weightfiles from the payload class for SIGNAL particle hypothesis: " <<
m_sig_pdg);
236 auto nfiles = serialized_weightfiles->size();
238 B2INFO(
"\tConstruct the MVA experts and datasets from N = " << nfiles <<
" weightfiles...");
247 for (
unsigned int idx(0); idx < nfiles; idx++) {
249 B2DEBUG(12,
"\t\tweightfile[" << idx <<
"]");
252 std::stringstream ss(serialized_weightfiles->at(idx));
256 weightfile.getOptions(general_options);
260 m_variables[idx] = manager.getVariables(general_options.m_variables);
261 m_spectators[idx] = manager.getVariables(general_options.m_spectators);
263 B2DEBUG(12,
"\t\tRetrieved N = " << general_options.m_variables.size()
264 <<
" variables, N = " << general_options.m_spectators.size()
268 m_experts[idx] = supported_interfaces[general_options.m_method]->getExpert();
271 B2DEBUG(12,
"\t\tweightfile loaded successfully into expert[" << idx <<
"]!");
274 std::vector<float> v(general_options.m_variables.size(), 0.0);
275 std::vector<float> s(general_options.m_spectators.size(), 0.0);
276 m_datasets[idx] = std::make_unique<MVA::SingleDataset>(general_options, v, 1.0, s);
278 B2DEBUG(12,
"\t\tdataset[" << idx <<
"] created successfully!");
StoreObjPtr< EventMetaData > m_event_metadata
The event information.
int m_bkg_pdg
The input background mass hypothesis' pdgId.
bool m_ecl_only
Flag to specify if we use an ECL-only based training.
std::string m_score_varname
The lookup name of the MVA score variable, given the input S, B mass hypotheses for the algorithm.
std::unique_ptr< DBObjPtr< ChargedPidMVAWeights > > m_weightfiles_representation
Interface to get the database payload with the MVA weight files.
DatasetsList m_datasets
List of MVA::SingleDataset objects.
bool m_charge_independent
Flag to specify if we use a charge-independent training.
virtual void event() override
Called once for each event.
int m_sig_pdg
The input signal mass hypothesis' pdgId.
virtual void beginRun() override
Called once before a new run begins.
VariablesLists m_variables
List of lists of feature variables.
ChargedPidMVAModule()
Constructor, for setting module description and parameters.
VariablesLists m_spectators
List of lists of spectator variables.
std::vector< std::string > m_particle_lists
The input list of names of ParticleList objects to which MVA weights will be applied.
ExpertsList m_experts
List of MVA::Expert objects.
std::string m_payload_name
The name of the database payload object with the MVA weights.
size_t size() const
Getter for number of detector IDs in this set.
static DetectorSet set()
Accessor function for the set of valid detectors.
double getTheta() const
Return Corrected Theta of Shower (radian).
static std::unique_ptr< GeneralCut > compile(const std::string &cut)
Creates an instance of a cut and returns a unique_ptr to it, if you need a copy-able object instead y...
static std::map< std::string, AbstractInterface * > getSupportedInterfaces()
Returns interfaces supported by the MVA Interface.
static void initSupportedInterfaces()
Static function which initliazes all supported interfaces, has to be called once before getSupportedI...
General options which are shared by all MVA trainings.
static Weightfile loadFromStream(std::istream &stream)
Static function which deserializes a Weightfile from a stream.
Class to store reconstructed particles.
Type-safe access to single objects in the data store.
Global list of available variables.
static Manager & Instance()
get singleton instance.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double charge(int pdgCode)
Returns electric charge of a particle with given pdg code.
Abstract base class for different kinds of events.