10#include <ecl/modules/eclClusterPSD/ECLClusterPSD.h>
13#include <ecl/dataobjects/ECLCalDigit.h>
14#include <ecl/dataobjects/ECLShower.h>
15#include <ecl/geometry/ECLGeometryPar.h>
18#include <framework/logging/Logger.h>
19#include <framework/geometry/B2Vector3.h>
20#include <mva/dataobjects/DatabaseRepresentationOfWeightfile.h>
21#include <mva/interface/Expert.h>
22#include <mva/interface/Interface.h>
23#include <mva/interface/Weightfile.h>
42 setDescription(
"Module uses offline two component fit results to compute pulse shape discrimation variables for particle identification.");
45 "Hadron component energy threshold to identify as hadron digit.(GeV)", 0.003);
47 "Hadron component intensity threshold to identify as hadron digit.", 0.005);
60 if (not(identifier.ends_with(
".root") or identifier.ends_with(
".xml"))) {
61 weightFileRepresentation = std::unique_ptr<DBObjPtr<DatabaseRepresentationOfWeightfile>>(
new
83 if (weightFileRepresentation) {
85 if (weightFileRepresentation->hasChanged()) {
86 std::stringstream ss((*weightFileRepresentation)->m_data);
97 weightfile.getOptions(general_options);
101 B2FATAL(
"Expecting " <<
m_numMVAvariables <<
" variables, found " << general_options.m_variables.size());
103 expert = supported_interfaces.at(general_options.m_method)->getExpert();
104 expert->load(weightfile);
108 std::vector<float> dummy(general_options.m_variables.size(), 0);
126 auto relatedDigits = cluster->getRelationsTo<
ECLCalDigit>();
129 std::vector<std::tuple<double, unsigned int>> EnergyToSort;
131 for (
unsigned int iRel = 0; iRel < relatedDigits.size(); iRel++) {
133 const auto caldigit = relatedDigits.object(iRel);
136 const double digitChi2 = caldigit->getTwoComponentChi2();
137 if (digitChi2 < 0)
continue;
147 EnergyToSort.emplace_back(caldigit->getTwoComponentTotalEnergy(), iRel);
152 std::sort(EnergyToSort.begin(), EnergyToSort.end(), std::greater<>());
155 const double showerR = cluster->getR();
156 const double showerTheta = cluster->getTheta();
157 const double showerPhi = cluster->getPhi();
162 size_t input_index{0};
165 for (
unsigned int digit = 0; digit <
maxdigits; ++digit) {
167 if (digit >= EnergyToSort.size())
break;
169 const auto [digitEnergy, next] = EnergyToSort[digit];
171 const auto caldigit = relatedDigits.object(next);
172 const double digitHadronEnergy = caldigit->getTwoComponentHadronEnergy();
173 const double digitOnlineEnergy = caldigit->getEnergy();
174 const double digitWeight = relatedDigits.weight(next);
176 const int digitFitType = digitFitType1;
177 const int cellId = caldigit->getCellId();
179 ROOT::Math::XYZVector tempP = showerPosition - calDigitPosition;
180 const double Rval = tempP.R();
181 const double theVal = tempP.
Z() / tempP.R();
182 const double phiVal = cos(tempP.Phi());
184 input[input_index++] = theVal;
185 input[input_index++] = phiVal;
186 input[input_index++] = Rval;
187 input[input_index++] = digitOnlineEnergy;
188 input[input_index++] = digitEnergy;
189 input[input_index++] = (digitHadronEnergy / digitEnergy);
190 input[input_index++] = digitFitType;
191 input[input_index++] = digitWeight;
196 while (input_index < input.size()) {
197 if (((input_index - 6) % 8) != 0) {
198 input[input_index++] = 0.0;
200 input[input_index++] = -1.0;
217 auto relatedDigits = shower.getRelationsTo<
ECLCalDigit>();
219 double cluster2CTotalEnergy = 0;
220 double cluster2CHadronEnergy = 0;
221 double numberofHadronDigits = 0;
222 double nWaveforminCluster = 0;
224 for (
unsigned int iRel = 0; iRel < relatedDigits.size(); iRel++) {
226 const auto weight = relatedDigits.weight(iRel);
228 const auto caldigit = relatedDigits.object(iRel);
229 const double digit2CChi2 = caldigit->getTwoComponentChi2();
231 if (digit2CChi2 < 0)
continue;
241 const double digit2CTotalEnergy = caldigit->getTwoComponentTotalEnergy();
242 const double digit2CHadronComponentEnergy = caldigit->getTwoComponentHadronEnergy();
244 cluster2CTotalEnergy += digit2CTotalEnergy;
245 cluster2CHadronEnergy += digit2CHadronComponentEnergy;
247 if (digit2CTotalEnergy < 0.6) {
250 const double digitHadronComponentIntensity = digit2CHadronComponentEnergy / digit2CTotalEnergy;
254 nWaveforminCluster += weight;
258 if (nWaveforminCluster > 0) {
259 if (cluster2CTotalEnergy != 0) shower.setShowerHadronIntensity(cluster2CHadronEnergy / cluster2CTotalEnergy);
262 shower.setPulseShapeDiscriminationMVA(mvaout);
264 shower.setNumberOfHadronDigits(numberofHadronDigits);
268 shower.setShowerHadronIntensity(0);
269 shower.setPulseShapeDiscriminationMVA(0.5);
270 shower.setNumberOfHadronDigits(0);
DataType Z() const
access variable Z (= .at(2) without boundary check)
void SetMagThetaPhi(DataType mag, DataType theta, DataType phi)
setter with mag, theta, phi
Class for accessing objects in the database.
Class to store calibrated ECLDigits: ECLCalDigits.
virtual const char * eclShowerArrayName() const
ECLShowers array name.
ECLClusterPSDModule()
Constructor.
StoreArray< ECLShower > m_eclShowers
ECLShower's.
std::unique_ptr< MVA::SingleDataset > m_dataset
Pointer to the current dataset.
virtual void initialize() override
Initialize variables.
virtual void event() override
event per event.
std::unique_ptr< MVA::Expert > m_expert
Pointer to the current MVA Expert.
const unsigned int maxdigits
Max number of digits mva can include.
const unsigned int m_numMVAvariables
number of variables expected in the MVA weightfile
std::unique_ptr< DBObjPtr< DatabaseRepresentationOfWeightfile > > m_weightfile_representation
Database pointer to the Database representation of the MVA weightfile.
virtual void beginRun() override
begin run.
void initializeMVAweightFile(const std::string &identifier, std::unique_ptr< DBObjPtr< DatabaseRepresentationOfWeightfile > > &weightFileRepresentation)
initialize MVA weight file from DB
double m_CrystalHadronEnergyThreshold
hadron component energy threshold to classify as hadron.
std::string m_MVAidentifier
MVA - weight-file.
virtual const char * eclCalDigitArrayName() const
ECLCalDigits array name.
double evaluateMVA(const ECLShower *cluster)
Evaluates mva.
~ECLClusterPSDModule() override
Destructor.
StoreArray< ECLCalDigit > m_eclCalDigits
ECLCalDigit's.
void initializeMVA(const std::string &identifier, std::unique_ptr< DBObjPtr< DatabaseRepresentationOfWeightfile > > &weightFileRepresentation, std::unique_ptr< MVA::Expert > &expert)
Load MVA weight file and set pointer of expert.
double m_CrystalHadronIntensityThreshold
hadron component intensity threshold to classify as hadron.
TwoComponentFitType
Offline two component fit type.
@ poorChi2
All offline fit attempts were greater than chi2 threshold.
@ photonDiodeCrossing
photon + diode template fit
Class to store ECL Showers.
@ c_hasPulseShapeDiscrimination
bit 2: Shower has pulse shape discrimination variables.
The Class for ECL Geometry Parameters.
static ECLGeometryPar * Instance()
Static method to get a reference to the ECLGeometryPar instance.
static void initSupportedInterfaces()
Static function which initializes all supported interfaces, has to be called once before getSupported...
static const std::map< std::string, AbstractInterface * > & getSupportedInterfaces()
Returns interfaces supported by the MVA Interface.
General options which are shared by all MVA trainings.
Wraps the data of a single event into a Dataset.
The Weightfile class serializes all information about a training into an xml tree.
static Weightfile loadFromStream(std::istream &stream)
Static function which deserializes a Weightfile from a stream.
static Weightfile loadFromFile(const std::string &filename)
Static function which loads a Weightfile from a file.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
B2Vector3< double > B2Vector3D
typedef for common usage with double
Common code concerning the geometry representation of the detector.
Abstract base class for different kinds of events.