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[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.
virtual void endRun() override
end run.
virtual void terminate() override
terminate.
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()
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 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.