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>
26#include <boost/algorithm/string/predicate.hpp>
45 setDescription(
"Module uses offline two component fit results to compute pulse shape discrimation variables for particle identification.");
48 "Hadron component energy threshold to identify as hadron digit.(GeV)", 0.003);
50 "Hadron component intensity threshold to identify as hadron digit.", 0.005);
63 if (not(boost::ends_with(identifier,
".root") or boost::ends_with(identifier,
".xml"))) {
64 weightFileRepresentation = std::unique_ptr<DBObjPtr<DatabaseRepresentationOfWeightfile>>(
new
86 if (weightFileRepresentation) {
88 if (weightFileRepresentation->hasChanged()) {
89 std::stringstream ss((*weightFileRepresentation)->m_data);
104 B2FATAL(
"Expecting " <<
m_numMVAvariables <<
" variables, found " << general_options.m_variables.size());
106 expert = supported_interfaces[general_options.m_method]->getExpert();
107 expert->load(weightfile);
111 std::vector<float> dummy(general_options.m_variables.size(), 0);
129 auto relatedDigits = cluster->getRelationsTo<
ECLCalDigit>();
132 std::vector<std::tuple<double, unsigned int>> EnergyToSort;
134 for (
unsigned int iRel = 0; iRel < relatedDigits.size(); iRel++) {
136 const auto caldigit = relatedDigits.object(iRel);
140 if (digitChi2 < 0)
continue;
150 EnergyToSort.emplace_back(caldigit->getTwoComponentTotalEnergy(), iRel);
155 std::sort(EnergyToSort.begin(), EnergyToSort.end(), std::greater<>());
158 const double showerR = cluster->getR();
159 const double showerTheta = cluster->getTheta();
160 const double showerPhi = cluster->getPhi();
165 size_t input_index{0};
168 for (
unsigned int digit = 0; digit <
maxdigits; ++digit) {
170 if (digit >= EnergyToSort.size())
break;
172 const auto [digitEnergy, next] = EnergyToSort[digit];
174 const auto caldigit = relatedDigits.object(next);
175 const double digitHadronEnergy = caldigit->getTwoComponentHadronEnergy();
176 const double digitOnlineEnergy = caldigit->getEnergy();
177 const double digitWeight = relatedDigits.weight(next);
179 const int digitFitType = digitFitType1;
180 const int cellId = caldigit->getCellId();
181 B2Vector3D calDigitPosition = geometry->GetCrystalPos(cellId - 1);
182 ROOT::Math::XYZVector tempP = showerPosition - calDigitPosition;
183 const double Rval = tempP.R();
184 const double theVal = tempP.
Z() / tempP.R();
185 const double phiVal = cos(tempP.Phi());
187 input[input_index++] = theVal;
188 input[input_index++] = phiVal;
189 input[input_index++] = Rval;
190 input[input_index++] = digitOnlineEnergy;
191 input[input_index++] = digitEnergy;
192 input[input_index++] = (digitHadronEnergy / digitEnergy);
193 input[input_index++] = digitFitType;
194 input[input_index++] = digitWeight;
199 while (input_index < input.size()) {
200 if (((input_index - 6) % 8) != 0) {
201 input[input_index++] = 0.0;
203 input[input_index++] = -1.0;
220 auto relatedDigits = shower.getRelationsTo<
ECLCalDigit>();
222 double cluster2CTotalEnergy = 0;
223 double cluster2CHadronEnergy = 0;
224 double numberofHadronDigits = 0;
225 double nWaveforminCluster = 0;
227 for (
unsigned int iRel = 0; iRel < relatedDigits.size(); iRel++) {
229 const auto weight = relatedDigits.weight(iRel);
231 const auto caldigit = relatedDigits.object(iRel);
232 const double digit2CChi2 = caldigit->getTwoComponentChi2();
234 if (digit2CChi2 < 0)
continue;
244 const double digit2CTotalEnergy = caldigit->getTwoComponentTotalEnergy();
245 const double digit2CHadronComponentEnergy = caldigit->getTwoComponentHadronEnergy();
247 cluster2CTotalEnergy += digit2CTotalEnergy;
248 cluster2CHadronEnergy += digit2CHadronComponentEnergy;
250 if (digit2CTotalEnergy < 0.6) {
253 const double digitHadronComponentIntensity = digit2CHadronComponentEnergy / digit2CTotalEnergy;
257 nWaveforminCluster += weight;
261 if (nWaveforminCluster > 0) {
262 if (cluster2CTotalEnergy != 0) shower.setShowerHadronIntensity(cluster2CHadronEnergy / cluster2CTotalEnergy);
265 shower.setPulseShapeDiscriminationMVA(mvaout);
267 shower.setNumberOfHadronDigits(numberofHadronDigits);
271 shower.setShowerHadronIntensity(0);
272 shower.setPulseShapeDiscriminationMVA(0.5);
273 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.
double getTwoComponentChi2() const
Get two component chi2.
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 initliazes all supported interfaces, has to be called once before getSupportedI...
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.
void getOptions(Options &options) const
Fills an Option object from the xml tree.
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.
Abstract base class for different kinds of events.