LDMX Software
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
ecal::EcalVetoProcessor Class Reference

Determines if event is vetoable using ECAL hit information. More...

#include <EcalVetoProcessor.h>

Classes

struct  HitData
 

Public Types

typedef std::pair< ldmx::EcalID, float > CellEnergyPair
 
typedef std::pair< float, float > XYCoords
 

Public Member Functions

 EcalVetoProcessor (const std::string &name, framework::Process &process)
 
void configure (framework::config::Parameters &parameters) override
 Configure the processor using the given user specified parameters.
 
void produce (framework::Event &event) override
 Process the event and put new data products into it.
 
- Public Member Functions inherited from framework::Producer
 Producer (const std::string &name, Process &process)
 Class constructor.
 
virtual void beforeNewRun (ldmx::RunHeader &header)
 Handle allowing producers to modify run headers before the run begins.
 
- Public Member Functions inherited from framework::EventProcessor
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()
 Class destructor.
 
virtual void onNewRun (const ldmx::RunHeader &runHeader)
 Callback for the EventProcessor to take any necessary action when the run being processed changes.
 
virtual void onFileOpen (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
virtual void onProcessStart ()
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
virtual void onProcessEnd ()
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Member Functions

void clearProcessor ()
 
ldmx::EcalID GetShowerCentroidIDAndRMS (const std::vector< ldmx::EcalHit > &ecalRecHits, double &showerRMS)
 
void fillHitMap (const std::vector< ldmx::EcalHit > &ecalRecHits, std::map< ldmx::EcalID, float > &cellMap_)
 Function to load up empty vector of hit maps.
 
void fillIsolatedHitMap (const std::vector< ldmx::EcalHit > &ecalRecHits, ldmx::EcalID globalCentroid, std::map< ldmx::EcalID, float > &cellMap, std::map< ldmx::EcalID, float > &cellMapIso, bool doTight=false)
 
std::vector< XYCoords > getTrajectory (std::vector< double > momentum, std::vector< float > position)
 
void buildBDTFeatureVector (const ldmx::EcalVetoResult &result)
 
float distTwoLines (TVector3 v1, TVector3 v2, TVector3 w1, TVector3 w2)
 Returns the distance between the lines v and w, with v defined to pass through the points (v1,v2) (and similarly for w).
 
float distPtToLine (TVector3 h1, TVector3 p1, TVector3 p2)
 Return the minimum distance between the point h1 and the line passing through points p1 and p2.
 

Private Attributes

std::map< ldmx::EcalID, float > cellMap_
 
std::map< ldmx::EcalID, float > cellMapTightIso_
 
std::vector< float > ecalLayerEdepRaw_
 
std::vector< float > ecalLayerEdepReadout_
 
std::vector< float > ecalLayerTime_
 
std::vector< std::vector< double > > roc_range_values_
 
int nEcalLayers_ {0}
 
int nReadoutHits_ {0}
 
int deepestLayerHit_ {0}
 
double summedDet_ {0}
 
double summedTightIso_ {0}
 
double maxCellDep_ {0}
 
double showerRMS_ {0}
 
double xStd_ {0}
 
double yStd_ {0}
 
double avgLayerHit_ {0}
 
double stdLayerHit_ {0}
 
double ecalBackEnergy_ {0}
 
int nStraightTracks_ {0}
 Number of "straight" tracks found in the event.
 
int nLinregTracks_ {0}
 Number of "linreg" tracks found in the event.
 
int firstNearPhLayer_ {0}
 First ECal layer in which a hit is found near the photon.
 
int nNearPhHits_ {0}
 Number of hits near the photon trajectory.
 
float epAng_ {0}
 Angular separation between the projected photon and electron trajectories (currently unused)
 
float epSep_ {0}
 Distance between the projected photon and electron trajectories at the ECal face.
 
float epDot_ {0}
 Dot product of the photon and electron momenta unit vectors.
 
int photonTerritoryHits_ {0}
 Number of hits in the photon territory.
 
double bdtCutVal_ {0}
 
double beamEnergyMeV_ {0}
 
bool verbose_ {false}
 
std::string bdtFileName_
 
std::string rocFileName_
 
std::vector< float > bdtFeatures_
 
std::string featureListName_
 
std::string rec_pass_name_
 
std::string rec_coll_name_
 
std::string collectionName_ {"EcalVeto"}
 Name of the collection which will containt the results.
 
std::unique_ptr< ldmx::Ort::ONNXRuntimert_
 
const ldmx::EcalGeometrygeometry_
 handle to current geometry (to share with member functions)
 

Additional Inherited Members

- Static Public Member Functions inherited from framework::EventProcessor
static void declare (const std::string &classname, int classtype, EventProcessorMaker *)
 Internal function which is part of the PluginFactory machinery.
 
- Static Public Attributes inherited from framework::Producer
static const int CLASSTYPE {1}
 Constant used to track EventProcessor types by the PluginFactory.
 
- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramHelper histograms_
 Interface class for making and filling histograms.
 
NtupleManagerntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger theLog_
 The logger for this EventProcessor.
 

Detailed Description

Determines if event is vetoable using ECAL hit information.

Definition at line 32 of file EcalVetoProcessor.h.

Member Typedef Documentation

◆ CellEnergyPair

typedef std::pair<ldmx::EcalID, float> ecal::EcalVetoProcessor::CellEnergyPair

Definition at line 34 of file EcalVetoProcessor.h.

◆ XYCoords

typedef std::pair<float, float> ecal::EcalVetoProcessor::XYCoords

Definition at line 36 of file EcalVetoProcessor.h.

Constructor & Destructor Documentation

◆ EcalVetoProcessor()

ecal::EcalVetoProcessor::EcalVetoProcessor ( const std::string &  name,
framework::Process process 
)
inline

Definition at line 38 of file EcalVetoProcessor.h.

39 : Producer(name, process) {}
Producer(const std::string &name, Process &process)
Class constructor.

◆ ~EcalVetoProcessor()

virtual ecal::EcalVetoProcessor::~EcalVetoProcessor ( )
inlinevirtual

Definition at line 41 of file EcalVetoProcessor.h.

41{}

Member Function Documentation

◆ buildBDTFeatureVector()

void ecal::EcalVetoProcessor::buildBDTFeatureVector ( const ldmx::EcalVetoResult result)
private

Electron RoC variables

Photon RoC variables

Outside RoC variables

Definition at line 30 of file EcalVetoProcessor.cxx.

31 {
32 // Base variables
33 bdtFeatures_.push_back(result.getNReadoutHits());
34 bdtFeatures_.push_back(result.getSummedDet());
35 bdtFeatures_.push_back(result.getSummedTightIso());
36 bdtFeatures_.push_back(result.getMaxCellDep());
37 bdtFeatures_.push_back(result.getShowerRMS());
38 bdtFeatures_.push_back(result.getXStd());
39 bdtFeatures_.push_back(result.getYStd());
40 bdtFeatures_.push_back(result.getAvgLayerHit());
41 bdtFeatures_.push_back(result.getStdLayerHit());
42 bdtFeatures_.push_back(result.getDeepestLayerHit());
43 bdtFeatures_.push_back(result.getEcalBackEnergy());
44 // MIP tracking
45 bdtFeatures_.push_back(result.getNStraightTracks());
46 // bdtFeatures_.push_back(result.getNLinregTracks());
47 bdtFeatures_.push_back(result.getFirstNearPhLayer());
48 bdtFeatures_.push_back(result.getNNearPhHits());
49 bdtFeatures_.push_back(result.getPhotonTerritoryHits());
50 bdtFeatures_.push_back(result.getEPSep());
51 bdtFeatures_.push_back(result.getEPDot());
52 // Longitudinal segment variables
53 bdtFeatures_.push_back(result.getEnergySeg()[0]);
54 bdtFeatures_.push_back(result.getXMeanSeg()[0]);
55 bdtFeatures_.push_back(result.getYMeanSeg()[0]);
56 bdtFeatures_.push_back(result.getLayerMeanSeg()[0]);
57 bdtFeatures_.push_back(result.getEnergySeg()[1]);
58 bdtFeatures_.push_back(result.getYMeanSeg()[2]);
60 bdtFeatures_.push_back(result.getEleContEnergy()[0][0]);
61 bdtFeatures_.push_back(result.getEleContEnergy()[1][0]);
62 bdtFeatures_.push_back(result.getEleContYMean()[0][0]);
63 bdtFeatures_.push_back(result.getEleContEnergy()[0][1]);
64 bdtFeatures_.push_back(result.getEleContEnergy()[1][1]);
65 bdtFeatures_.push_back(result.getEleContYMean()[0][1]);
67 bdtFeatures_.push_back(result.getPhContNHits()[0][0]);
68 bdtFeatures_.push_back(result.getPhContYMean()[0][0]);
69 bdtFeatures_.push_back(result.getPhContNHits()[0][1]);
71 bdtFeatures_.push_back(result.getOutContEnergy()[0][0]);
72 bdtFeatures_.push_back(result.getOutContEnergy()[1][0]);
73 bdtFeatures_.push_back(result.getOutContEnergy()[2][0]);
74 bdtFeatures_.push_back(result.getOutContNHits()[0][0]);
75 bdtFeatures_.push_back(result.getOutContXMean()[0][0]);
76 bdtFeatures_.push_back(result.getOutContYMean()[0][0]);
77 bdtFeatures_.push_back(result.getOutContYMean()[1][0]);
78 bdtFeatures_.push_back(result.getOutContYStd()[0][0]);
79 bdtFeatures_.push_back(result.getOutContEnergy()[0][1]);
80 bdtFeatures_.push_back(result.getOutContEnergy()[1][1]);
81 bdtFeatures_.push_back(result.getOutContEnergy()[2][1]);
82 bdtFeatures_.push_back(result.getOutContLayerMean()[0][1]);
83 bdtFeatures_.push_back(result.getOutContLayerStd()[0][1]);
84 bdtFeatures_.push_back(result.getOutContEnergy()[0][2]);
85 bdtFeatures_.push_back(result.getOutContLayerMean()[0][2]);
86}
int getNStraightTracks() const
Number of straight tracks found.

References ldmx::EcalVetoResult::getNStraightTracks().

Referenced by produce().

◆ clearProcessor()

void ecal::EcalVetoProcessor::clearProcessor ( )
private

Definition at line 137 of file EcalVetoProcessor.cxx.

137 {
138 cellMap_.clear();
139 cellMapTightIso_.clear();
140 bdtFeatures_.clear();
141
142 nReadoutHits_ = 0;
143 summedDet_ = 0;
144 summedTightIso_ = 0;
145 maxCellDep_ = 0;
146 showerRMS_ = 0;
147 xStd_ = 0;
148 yStd_ = 0;
149 avgLayerHit_ = 0;
150 stdLayerHit_ = 0;
151 deepestLayerHit_ = 0;
152 ecalBackEnergy_ = 0;
153 // MIP tracking
155 nLinregTracks_ = 0;
157 nNearPhHits_ = 0;
158 epAng_ = 0;
159 epSep_ = 0;
160 epDot_ = 0;
162
163 std::fill(ecalLayerEdepRaw_.begin(), ecalLayerEdepRaw_.end(), 0);
164 std::fill(ecalLayerEdepReadout_.begin(), ecalLayerEdepReadout_.end(), 0);
165 std::fill(ecalLayerTime_.begin(), ecalLayerTime_.end(), 0);
166}
float epSep_
Distance between the projected photon and electron trajectories at the ECal face.
int photonTerritoryHits_
Number of hits in the photon territory.
float epAng_
Angular separation between the projected photon and electron trajectories (currently unused)
int nStraightTracks_
Number of "straight" tracks found in the event.
int nLinregTracks_
Number of "linreg" tracks found in the event.
int firstNearPhLayer_
First ECal layer in which a hit is found near the photon.
float epDot_
Dot product of the photon and electron momenta unit vectors.
int nNearPhHits_
Number of hits near the photon trajectory.

◆ configure()

void ecal::EcalVetoProcessor::configure ( framework::config::Parameters parameters)
overridevirtual

Configure the processor using the given user specified parameters.

Parameters
parametersSet of parameters used to configure this processor.

Reimplemented from framework::EventProcessor.

Definition at line 88 of file EcalVetoProcessor.cxx.

88 {
89 verbose_ = parameters.getParameter<bool>("verbose");
90 featureListName_ = parameters.getParameter<std::string>("feature_list_name");
91 // Load BDT ONNX file
92 rt_ = std::make_unique<ldmx::Ort::ONNXRuntime>(
93 parameters.getParameter<std::string>("bdt_file"));
94
95 // Read in arrays holding 68% containment radius per layer
96 // for different bins in momentum/angle
97 rocFileName_ = parameters.getParameter<std::string>("roc_file");
98 if (!std::ifstream(rocFileName_).good()) {
99 EXCEPTION_RAISE(
100 "EcalVetoProcessor",
101 "The specified RoC file '" + rocFileName_ + "' does not exist!");
102 } else {
103 std::ifstream rocfile(rocFileName_);
104 std::string line, value;
105
106 // Extract the first line in the file
107 std::getline(rocfile, line);
108 std::vector<double> values;
109
110 // Read data, line by line
111 while (std::getline(rocfile, line)) {
112 std::stringstream ss(line);
113 values.clear();
114 while (std::getline(ss, value, ',')) {
115 double f_value = (value != "") ? std::stof(value) : -1.0;
116 values.push_back(f_value);
117 }
118 roc_range_values_.push_back(values);
119 }
120 }
121
122 nEcalLayers_ = parameters.getParameter<int>("num_ecal_layers");
123
124 bdtCutVal_ = parameters.getParameter<double>("disc_cut");
125 ecalLayerEdepRaw_.resize(nEcalLayers_, 0);
126 ecalLayerEdepReadout_.resize(nEcalLayers_, 0);
127 ecalLayerTime_.resize(nEcalLayers_, 0);
128
129 beamEnergyMeV_ = parameters.getParameter<double>("beam_energy");
130
131 // Set the collection name as defined in the configuration
132 collectionName_ = parameters.getParameter<std::string>("collection_name");
133 rec_pass_name_ = parameters.getParameter<std::string>("rec_pass_name");
134 rec_coll_name_ = parameters.getParameter<std::string>("rec_coll_name");
135}
std::string collectionName_
Name of the collection which will containt the results.
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89

References collectionName_, and framework::config::Parameters::getParameter().

◆ distPtToLine()

float ecal::EcalVetoProcessor::distPtToLine ( TVector3  h1,
TVector3  p1,
TVector3  p2 
)
private

Return the minimum distance between the point h1 and the line passing through points p1 and p2.

Parameters
[in]h1Point to find the distance to
[in]p1An arbitrary point on the line
[in]p2A second, distinct point on the line
Returns
Minimum distance between h1 and the line

Definition at line 1260 of file EcalVetoProcessor.cxx.

1260 {
1261 return ((h1 - p1).Cross(h1 - p2)).Mag() / (p1 - p2).Mag();
1262}

Referenced by produce().

◆ distTwoLines()

float ecal::EcalVetoProcessor::distTwoLines ( TVector3  v1,
TVector3  v2,
TVector3  w1,
TVector3  w2 
)
private

Returns the distance between the lines v and w, with v defined to pass through the points (v1,v2) (and similarly for w).

Parameters
[in]v1An arbitrary point on line v
[in]v2A second, distinct point on line v
[in]w1An arbitrary point on line w
[in]w2A second, distinct point on line w
Returns
Closest distance of approach of lines u and v

Definition at line 1247 of file EcalVetoProcessor.cxx.

1248 {
1249 TVector3 e1 = v1 - v2;
1250 TVector3 e2 = w1 - w2;
1251 TVector3 crs = e1.Cross(e2);
1252 if (crs.Mag() == 0) {
1253 return 100.0; // arbitrary large number; edge case that shouldn't cause
1254 // problems.
1255 } else {
1256 return std::abs(crs.Dot(v1 - w1) / crs.Mag());
1257 }
1258}

Referenced by produce().

◆ fillHitMap()

void ecal::EcalVetoProcessor::fillHitMap ( const std::vector< ldmx::EcalHit > &  ecalRecHits,
std::map< ldmx::EcalID, float > &  cellMap_ 
)
private

Function to load up empty vector of hit maps.

Definition at line 1178 of file EcalVetoProcessor.cxx.

1180 {
1181 for (const ldmx::EcalHit &hit : ecalRecHits) {
1182 ldmx::EcalID id(hit.getID());
1183 cellMap.emplace(id, hit.getEnergy());
1184 }
1185}
Stores reconstructed hit information from the ECAL.
Definition EcalHit.h:19
Extension of DetectorID providing access to ECal layers and cell numbers in a hex grid.
Definition EcalID.h:20

Referenced by produce().

◆ fillIsolatedHitMap()

void ecal::EcalVetoProcessor::fillIsolatedHitMap ( const std::vector< ldmx::EcalHit > &  ecalRecHits,
ldmx::EcalID  globalCentroid,
std::map< ldmx::EcalID, float > &  cellMap,
std::map< ldmx::EcalID, float > &  cellMapIso,
bool  doTight = false 
)
private

Definition at line 1187 of file EcalVetoProcessor.cxx.

1190 {
1191 for (const ldmx::EcalHit &hit : ecalRecHits) {
1192 auto isolatedHit = std::make_pair(true, ldmx::EcalID());
1193 ldmx::EcalID id(hit.getID());
1194 if (doTight) {
1195 // Disregard hits that are on the centroid.
1196 if (id == globalCentroid) continue;
1197
1198 // Skip hits that are on centroid inner ring
1199 if (geometry_->isNN(globalCentroid, id)) {
1200 continue;
1201 }
1202 }
1203
1204 // Skip hits that have a readout neighbor
1205 // Get neighboring cell id's and try to look them up in the full cell map
1206 // (constant speed algo.)
1207 // these ideas are only cell/module (must ignore layer)
1208 std::vector<ldmx::EcalID> cellNbrIds = geometry_->getNN(id);
1209
1210 for (int k = 0; k < cellNbrIds.size(); k++) {
1211 // update neighbor ID to the current layer
1212 cellNbrIds[k] = ldmx::EcalID(id.layer(), cellNbrIds[k].module(),
1213 cellNbrIds[k].cell());
1214 // look in cell hit map to see if it is there
1215 if (cellMap.find(cellNbrIds[k]) != cellMap.end()) {
1216 isolatedHit = std::make_pair(false, cellNbrIds[k]);
1217 break;
1218 }
1219 }
1220 if (!isolatedHit.first) {
1221 continue;
1222 }
1223 // Insert isolated hit
1224 cellMapIso.emplace(id, hit.getEnergy());
1225 }
1226}
const ldmx::EcalGeometry * geometry_
handle to current geometry (to share with member functions)
std::vector< EcalID > getNN(EcalID id) const
Get the Nearest Neighbors of the input ID.
bool isNN(EcalID centroid, EcalID probe) const
Check if the probe id is one of the nearest neightbors of the centroid id.

◆ GetShowerCentroidIDAndRMS()

ldmx::EcalID ecal::EcalVetoProcessor::GetShowerCentroidIDAndRMS ( const std::vector< ldmx::EcalHit > &  ecalRecHits,
double &  showerRMS 
)
private

Definition at line 1131 of file EcalVetoProcessor.cxx.

1132 {
1133 auto wgtCentroidCoords = std::make_pair<float, float>(0., 0.);
1134 float sumEdep = 0;
1135 ldmx::EcalID returnCellId;
1136
1137 // Calculate Energy Weighted Centroid
1138 for (const ldmx::EcalHit &hit : ecalRecHits) {
1139 ldmx::EcalID id(hit.getID());
1140 CellEnergyPair cell_energy_pair = std::make_pair(id, hit.getEnergy());
1141 auto [x, y, z] = geometry_->getPosition(id);
1142 XYCoords centroidCoords = std::make_pair(x, y);
1143 wgtCentroidCoords.first = wgtCentroidCoords.first +
1144 centroidCoords.first * cell_energy_pair.second;
1145 wgtCentroidCoords.second = wgtCentroidCoords.second +
1146 centroidCoords.second * cell_energy_pair.second;
1147 sumEdep += cell_energy_pair.second;
1148 }
1149 wgtCentroidCoords.first = (sumEdep > 1E-6) ? wgtCentroidCoords.first / sumEdep
1150 : wgtCentroidCoords.first;
1151 wgtCentroidCoords.second = (sumEdep > 1E-6)
1152 ? wgtCentroidCoords.second / sumEdep
1153 : wgtCentroidCoords.second;
1154 // Find Nearest Cell to Centroid
1155 float maxDist = 1e6;
1156 for (const ldmx::EcalHit &hit : ecalRecHits) {
1157 auto [x, y, z] = geometry_->getPosition(hit.getID());
1158 XYCoords centroidCoords = std::make_pair(x, y);
1159
1160 float deltaR =
1161 pow(pow((centroidCoords.first - wgtCentroidCoords.first), 2) +
1162 pow((centroidCoords.second - wgtCentroidCoords.second), 2),
1163 .5);
1164 showerRMS += deltaR * hit.getEnergy();
1165 if (deltaR < maxDist) {
1166 maxDist = deltaR;
1167 returnCellId = ldmx::EcalID(hit.getID());
1168 }
1169 }
1170 if (sumEdep > 0) showerRMS = showerRMS / sumEdep;
1171 // flatten
1172 return ldmx::EcalID(0, returnCellId.module(), returnCellId.cell());
1173}
std::tuple< double, double, double > getPosition(EcalID id) const
Get a cell's position from its ID number.
int cell() const
Get the value of the cell field from the ID.
Definition EcalID.h:111
int module() const
Get the value of the module field from the ID.
Definition EcalID.h:87

◆ getTrajectory()

std::vector< std::pair< float, float > > ecal::EcalVetoProcessor::getTrajectory ( std::vector< double >  momentum,
std::vector< float >  position 
)
private

Definition at line 1230 of file EcalVetoProcessor.cxx.

1231 {
1232 std::vector<XYCoords> positions;
1233 for (int iLayer = 0; iLayer < nEcalLayers_; iLayer++) {
1234 float posX =
1235 position[0] + (momentum[0] / momentum[2]) *
1236 (geometry_->getZPosition(iLayer) - position[2]);
1237 float posY =
1238 position[1] + (momentum[1] / momentum[2]) *
1239 (geometry_->getZPosition(iLayer) - position[2]);
1240 positions.push_back(std::make_pair(posX, posY));
1241 }
1242 return positions;
1243}
double getZPosition(int layer) const
Get the z-coordinate given the layer id.

◆ produce()

void ecal::EcalVetoProcessor::produce ( framework::Event event)
overridevirtual

Process the event and put new data products into it.

Parameters
eventThe Event to process.

Implements framework::Producer.

Definition at line 168 of file EcalVetoProcessor.cxx.

168 {
169 // Get the Ecal Geometry
170 geometry_ = &getCondition<ldmx::EcalGeometry>(
171 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
172
174
175 clearProcessor();
176
177 // Get the collection of Ecal scoring plane hits. If it doesn't exist,
178 // don't bother adding any truth tracking information.
179
180 std::vector<double> recoilP;
181 std::vector<float> recoilPos;
182 std::vector<double> recoilPAtTarget;
183 std::vector<float> recoilPosAtTarget;
184
185 if (verbose_) {
186 ldmx_log(debug) << " Loop through all of the sim particles and find the "
187 "recoil electron";
188 }
189
190 if (event.exists("EcalScoringPlaneHits")) {
191 //
192 // Loop through all of the sim particles and find the recoil electron.
193 //
194
195 // Get the collection of simulated particles from the event
196 auto particleMap{event.getMap<int, ldmx::SimParticle>("SimParticles")};
197
198 // Search for the recoil electron
199 auto [recoilTrackID, recoilElectron] = Analysis::getRecoil(particleMap);
200
201 // Find ECAL SP hit for recoil electron
202 auto ecalSpHits{
203 event.getCollection<ldmx::SimTrackerHit>("EcalScoringPlaneHits")};
204 float pmax = 0;
205 for (ldmx::SimTrackerHit &spHit : ecalSpHits) {
206 ldmx::SimSpecialID hit_id(spHit.getID());
207 if (hit_id.plane() != 31 || spHit.getMomentum()[2] <= 0) continue;
208
209 if (spHit.getTrackID() == recoilTrackID) {
210 if (sqrt(pow(spHit.getMomentum()[0], 2) +
211 pow(spHit.getMomentum()[1], 2) +
212 pow(spHit.getMomentum()[2], 2)) > pmax) {
213 recoilP = spHit.getMomentum();
214 recoilPos = spHit.getPosition();
215 pmax = sqrt(pow(recoilP[0], 2) + pow(recoilP[1], 2) +
216 pow(recoilP[2], 2));
217 }
218 }
219 }
220
221 // Find target SP hit for recoil electron
222 if (event.exists("TargetScoringPlaneHits")) {
223 std::vector<ldmx::SimTrackerHit> targetSpHits =
224 event.getCollection<ldmx::SimTrackerHit>("TargetScoringPlaneHits");
225 pmax = 0;
226 for (ldmx::SimTrackerHit &spHit : targetSpHits) {
227 ldmx::SimSpecialID hit_id(spHit.getID());
228 if (hit_id.plane() != 1 || spHit.getMomentum()[2] <= 0) continue;
229
230 if (spHit.getTrackID() == recoilTrackID) {
231 if (sqrt(pow(spHit.getMomentum()[0], 2) +
232 pow(spHit.getMomentum()[1], 2) +
233 pow(spHit.getMomentum()[2], 2)) > pmax) {
234 recoilPAtTarget = spHit.getMomentum();
235 recoilPosAtTarget = spHit.getPosition();
236 pmax =
237 sqrt(pow(recoilPAtTarget[0], 2) + pow(recoilPAtTarget[1], 2) +
238 pow(recoilPAtTarget[2], 2));
239 }
240 }
241 }
242 }
243 }
244
245 if (verbose_) {
246 ldmx_log(debug) << " Get projected trajectories for electron and photon";
247 }
248 // Get projected trajectories for electron and photon
249 std::vector<XYCoords> ele_trajectory, photon_trajectory;
250 if (recoilP.size() > 0) {
251 ele_trajectory = getTrajectory(recoilP, recoilPos);
252 std::vector<double> pvec = recoilPAtTarget.size()
253 ? recoilPAtTarget
254 : std::vector<double>{0.0, 0.0, 0.0};
255 std::vector<float> posvec = recoilPosAtTarget.size()
256 ? recoilPosAtTarget
257 : std::vector<float>{0.0, 0.0, 0.0};
258 photon_trajectory =
259 getTrajectory({-pvec[0], -pvec[1], beamEnergyMeV_ - pvec[2]}, posvec);
260 }
261
262 float recoilPMag =
263 recoilP.size()
264 ? sqrt(pow(recoilP[0], 2) + pow(recoilP[1], 2) + pow(recoilP[2], 2))
265 : -1.0;
266 float recoilTheta =
267 recoilPMag > 0 ? acos(recoilP[2] / recoilPMag) * 180.0 / M_PI : -1.0;
268
269 if (verbose_) {
270 ldmx_log(debug) << " Build Radii of containment (ROC)";
271 }
272 // Use the appropriate containment radii for the recoil electron
273 std::vector<double> roc_values_bin0(roc_range_values_[0].begin() + 4,
274 roc_range_values_[0].end());
275 std::vector<double> ele_radii = roc_values_bin0;
276 double theta_min, theta_max, p_min, p_max;
277 bool inrange;
278
279 for (int i = 0; i < roc_range_values_.size(); i++) {
280 theta_min = roc_range_values_[i][0];
281 theta_max = roc_range_values_[i][1];
282 p_min = roc_range_values_[i][2];
283 p_max = roc_range_values_[i][3];
284 inrange = true;
285
286 if (theta_min != -1.0) {
287 inrange = inrange && (recoilTheta >= theta_min);
288 }
289 if (theta_max != -1.0) {
290 inrange = inrange && (recoilTheta < theta_max);
291 }
292 if (p_min != -1.0) {
293 inrange = inrange && (recoilPMag >= p_min);
294 }
295 if (p_max != -1.0) {
296 inrange = inrange && (recoilPMag < p_max);
297 }
298 if (inrange) {
299 std::vector<double> roc_values_bini(roc_range_values_[i].begin() + 4,
300 roc_range_values_[i].end());
301 ele_radii = roc_values_bini;
302 }
303 }
304 // Use default RoC bin for photon
305 std::vector<double> photon_radii = roc_values_bin0;
306
307 // Get the collection of digitized Ecal hits from the event.
308 const std::vector<ldmx::EcalHit> ecalRecHits =
309 event.getCollection<ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
310
311 ldmx::EcalID globalCentroid =
312 GetShowerCentroidIDAndRMS(ecalRecHits, showerRMS_);
313 /* ~~ Fill the hit map ~~ O(n) */
314 fillHitMap(ecalRecHits, cellMap_);
315 bool doTight = true;
316 /* ~~ Fill the isolated hit maps ~~ O(n) */
317 fillIsolatedHitMap(ecalRecHits, globalCentroid, cellMap_, cellMapTightIso_,
318 doTight);
319
320 // Loop over the hits from the event to calculate the rest of the important
321 // quantities
322
323 float wavgLayerHit = 0;
324 float xMean = 0;
325 float yMean = 0;
326
327 // Containment variables
328 unsigned int nregions = 5;
329 std::vector<float> electronContainmentEnergy(nregions, 0.0);
330 std::vector<float> photonContainmentEnergy(nregions, 0.0);
331 std::vector<float> outsideContainmentEnergy(nregions, 0.0);
332 std::vector<int> outsideContainmentNHits(nregions, 0);
333 std::vector<float> outsideContainmentXmean(nregions, 0.0);
334 std::vector<float> outsideContainmentYmean(nregions, 0.0);
335 std::vector<float> outsideContainmentXstd(nregions, 0.0);
336 std::vector<float> outsideContainmentYstd(nregions, 0.0);
337 // Longitudinal segmentation
338 std::vector<int> segLayers = {0, 6, 17, 34};
339 unsigned int nsegments = segLayers.size() - 1;
340 std::vector<float> energySeg(nsegments, 0.0);
341 std::vector<float> xMeanSeg(nsegments, 0.0);
342 std::vector<float> xStdSeg(nsegments, 0.0);
343 std::vector<float> yMeanSeg(nsegments, 0.0);
344 std::vector<float> yStdSeg(nsegments, 0.0);
345 std::vector<float> layerMeanSeg(nsegments, 0.0);
346 std::vector<float> layerStdSeg(nsegments, 0.0);
347 std::vector<std::vector<float>> eContEnergy(
348 nregions, std::vector<float>(nsegments, 0.0));
349 std::vector<std::vector<float>> eContXMean(
350 nregions, std::vector<float>(nsegments, 0.0));
351 std::vector<std::vector<float>> eContYMean(
352 nregions, std::vector<float>(nsegments, 0.0));
353 std::vector<std::vector<float>> gContEnergy(
354 nregions, std::vector<float>(nsegments, 0.0));
355 std::vector<std::vector<int>> gContNHits(nregions,
356 std::vector<int>(nsegments, 0));
357 std::vector<std::vector<float>> gContXMean(
358 nregions, std::vector<float>(nsegments, 0.0));
359 std::vector<std::vector<float>> gContYMean(
360 nregions, std::vector<float>(nsegments, 0.0));
361 std::vector<std::vector<float>> oContEnergy(
362 nregions, std::vector<float>(nsegments, 0.0));
363 std::vector<std::vector<int>> oContNHits(nregions,
364 std::vector<int>(nsegments, 0));
365 std::vector<std::vector<float>> oContXMean(
366 nregions, std::vector<float>(nsegments, 0.0));
367 std::vector<std::vector<float>> oContYMean(
368 nregions, std::vector<float>(nsegments, 0.0));
369 std::vector<std::vector<float>> oContXStd(nregions,
370 std::vector<float>(nsegments, 0.0));
371 std::vector<std::vector<float>> oContYStd(nregions,
372 std::vector<float>(nsegments, 0.0));
373 std::vector<std::vector<float>> oContLayerMean(
374 nregions, std::vector<float>(nsegments, 0.0));
375 std::vector<std::vector<float>> oContLayerStd(
376 nregions, std::vector<float>(nsegments, 0.0));
377
378 // MIP tracking: vector of hits to be used in the MIP tracking algorithm. All
379 // hits inside the electron ROC (or all hits in the ECal if the event is
380 // missing an electron) will be included.
381 std::vector<HitData> trackingHitList;
382
383 if (verbose_) {
384 ldmx_log(debug)
385 << " Loop over the hits from the event to calculate the BDT features";
386 }
387
388 for (const ldmx::EcalHit &hit : ecalRecHits) {
389 // Layer-wise quantities
390 ldmx::EcalID id(hit.getID());
391 ecalLayerEdepRaw_[id.layer()] =
392 ecalLayerEdepRaw_[id.layer()] + hit.getEnergy();
393 if (id.layer() >= 20) ecalBackEnergy_ += hit.getEnergy();
394 if (maxCellDep_ < hit.getEnergy()) maxCellDep_ = hit.getEnergy();
395 if (hit.getEnergy() > 0) {
396 nReadoutHits_++;
397 ecalLayerEdepReadout_[id.layer()] += hit.getEnergy();
398 ecalLayerTime_[id.layer()] += (hit.getEnergy()) * hit.getTime();
399 auto [x, y, z] = geometry_->getPosition(id);
400 xMean += x * hit.getEnergy();
401 yMean += y * hit.getEnergy();
402 avgLayerHit_ += id.layer();
403 wavgLayerHit += id.layer() * hit.getEnergy();
404 if (deepestLayerHit_ < id.layer()) {
405 deepestLayerHit_ = id.layer();
406 }
407 XYCoords xy_pair = std::make_pair(x, y);
408 float distance_ele_trajectory =
409 ele_trajectory.size()
410 ? sqrt(
411 pow((xy_pair.first - ele_trajectory[id.layer()].first), 2) +
412 pow((xy_pair.second - ele_trajectory[id.layer()].second),
413 2))
414 : -1.0;
415 float distance_photon_trajectory =
416 photon_trajectory.size()
417 ? sqrt(
418 pow((xy_pair.first - photon_trajectory[id.layer()].first),
419 2) +
420 pow((xy_pair.second - photon_trajectory[id.layer()].second),
421 2))
422 : -1.0;
423
424 // Decide which longitudinal segment the hit is in and add to sums
425 for (unsigned int iseg = 0; iseg < nsegments; iseg++) {
426 if (id.layer() >= segLayers[iseg] &&
427 id.layer() <= segLayers[iseg + 1] - 1) {
428 energySeg[iseg] += hit.getEnergy();
429 xMeanSeg[iseg] += xy_pair.first * hit.getEnergy();
430 yMeanSeg[iseg] += xy_pair.second * hit.getEnergy();
431 layerMeanSeg[iseg] += id.layer() * hit.getEnergy();
432
433 // Decide which containment region the hit is in and add to sums
434 for (unsigned int ireg = 0; ireg < nregions; ireg++) {
435 if (distance_ele_trajectory >= ireg * ele_radii[id.layer()] &&
436 distance_ele_trajectory < (ireg + 1) * ele_radii[id.layer()]) {
437 eContEnergy[ireg][iseg] += hit.getEnergy();
438 eContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
439 eContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
440 }
441 if (distance_photon_trajectory >= ireg * photon_radii[id.layer()] &&
442 distance_photon_trajectory <
443 (ireg + 1) * photon_radii[id.layer()]) {
444 gContEnergy[ireg][iseg] += hit.getEnergy();
445 gContNHits[ireg][iseg] += 1;
446 gContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
447 gContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
448 }
449 if (distance_ele_trajectory > (ireg + 1) * ele_radii[id.layer()] &&
450 distance_photon_trajectory >
451 (ireg + 1) * photon_radii[id.layer()]) {
452 oContEnergy[ireg][iseg] += hit.getEnergy();
453 oContNHits[ireg][iseg] += 1;
454 oContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
455 oContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
456 oContLayerMean[ireg][iseg] += id.layer() * hit.getEnergy();
457 }
458 }
459 }
460 }
461
462 // Decide which containment region the hit is in and add to sums
463 for (unsigned int ireg = 0; ireg < nregions; ireg++) {
464 if (distance_ele_trajectory >= ireg * ele_radii[id.layer()] &&
465 distance_ele_trajectory < (ireg + 1) * ele_radii[id.layer()])
466 electronContainmentEnergy[ireg] += hit.getEnergy();
467 if (distance_photon_trajectory >= ireg * photon_radii[id.layer()] &&
468 distance_photon_trajectory < (ireg + 1) * photon_radii[id.layer()])
469 photonContainmentEnergy[ireg] += hit.getEnergy();
470 if (distance_ele_trajectory > (ireg + 1) * ele_radii[id.layer()] &&
471 distance_photon_trajectory >
472 (ireg + 1) * photon_radii[id.layer()]) {
473 outsideContainmentEnergy[ireg] += hit.getEnergy();
474 outsideContainmentNHits[ireg] += 1;
475 outsideContainmentXmean[ireg] += xy_pair.first * hit.getEnergy();
476 outsideContainmentYmean[ireg] += xy_pair.second * hit.getEnergy();
477 }
478 }
479
480 // MIP tracking: Decide whether hit should be added to trackingHitList
481 // If inside e- RoC or if etraj is missing, use the hit for tracking:
482 if (distance_ele_trajectory >= ele_radii[id.layer()] ||
483 distance_ele_trajectory == -1.0) {
484 HitData hd;
485 hd.pos = TVector3(xy_pair.first, xy_pair.second,
486 geometry_->getZPosition(id.layer()));
487 hd.layer = id.layer();
488 trackingHitList.push_back(hd);
489 }
490 }
491 } // end loop over rechits
492
493 for (const auto &[id, energy] : cellMapTightIso_) {
494 if (energy > 0) summedTightIso_ += energy;
495 }
496
497 for (int iLayer = 0; iLayer < ecalLayerEdepReadout_.size(); iLayer++) {
498 ecalLayerTime_[iLayer] =
499 ecalLayerTime_[iLayer] / ecalLayerEdepReadout_[iLayer];
500 summedDet_ += ecalLayerEdepReadout_[iLayer];
501 }
502
503 if (nReadoutHits_ > 0) {
504 avgLayerHit_ /= nReadoutHits_;
505 wavgLayerHit /= summedDet_;
506 xMean /= summedDet_;
507 yMean /= summedDet_;
508 } else {
509 wavgLayerHit = 0;
510 avgLayerHit_ = 0;
511 xMean = 0;
512 yMean = 0;
513 }
514
515 // If necessary, quotient out the total energy from the means
516 for (unsigned int iseg = 0; iseg < nsegments; iseg++) {
517 if (energySeg[iseg] > 0) {
518 xMeanSeg[iseg] /= energySeg[iseg];
519 yMeanSeg[iseg] /= energySeg[iseg];
520 layerMeanSeg[iseg] /= energySeg[iseg];
521 }
522 for (unsigned int ireg = 0; ireg < nregions; ireg++) {
523 if (eContEnergy[ireg][iseg] > 0) {
524 eContXMean[ireg][iseg] /= eContEnergy[ireg][iseg];
525 eContYMean[ireg][iseg] /= eContEnergy[ireg][iseg];
526 }
527 if (gContEnergy[ireg][iseg] > 0) {
528 gContXMean[ireg][iseg] /= gContEnergy[ireg][iseg];
529 gContYMean[ireg][iseg] /= gContEnergy[ireg][iseg];
530 }
531 if (oContEnergy[ireg][iseg] > 0) {
532 oContXMean[ireg][iseg] /= oContEnergy[ireg][iseg];
533 oContYMean[ireg][iseg] /= oContEnergy[ireg][iseg];
534 oContLayerMean[ireg][iseg] /= oContEnergy[ireg][iseg];
535 }
536 }
537 }
538
539 for (unsigned int ireg = 0; ireg < nregions; ireg++) {
540 if (outsideContainmentEnergy[ireg] > 0) {
541 outsideContainmentXmean[ireg] /= outsideContainmentEnergy[ireg];
542 outsideContainmentYmean[ireg] /= outsideContainmentEnergy[ireg];
543 }
544 }
545
546 // Loop over hits a second time to find the standard deviations.
547 for (const ldmx::EcalHit &hit : ecalRecHits) {
548 ldmx::EcalID id(hit.getID());
549 auto [x, y, z] = geometry_->getPosition(id);
550 if (hit.getEnergy() > 0) {
551 xStd_ += pow((x - xMean), 2) * hit.getEnergy();
552 yStd_ += pow((y - yMean), 2) * hit.getEnergy();
553 stdLayerHit_ += pow((id.layer() - wavgLayerHit), 2) * hit.getEnergy();
554 }
555 XYCoords xy_pair = std::make_pair(x, y);
556 float distance_ele_trajectory =
557 ele_trajectory.size()
558 ? sqrt(pow((xy_pair.first - ele_trajectory[id.layer()].first), 2) +
559 pow((xy_pair.second - ele_trajectory[id.layer()].second), 2))
560 : -1.0;
561 float distance_photon_trajectory =
562 photon_trajectory.size()
563 ? sqrt(pow((xy_pair.first - photon_trajectory[id.layer()].first),
564 2) +
565 pow((xy_pair.second - photon_trajectory[id.layer()].second),
566 2))
567 : -1.0;
568
569 for (unsigned int iseg = 0; iseg < nsegments; iseg++) {
570 if (id.layer() >= segLayers[iseg] &&
571 id.layer() <= segLayers[iseg + 1] - 1) {
572 xStdSeg[iseg] +=
573 pow((xy_pair.first - xMeanSeg[iseg]), 2) * hit.getEnergy();
574 yStdSeg[iseg] +=
575 pow((xy_pair.second - yMeanSeg[iseg]), 2) * hit.getEnergy();
576 layerStdSeg[iseg] +=
577 pow((id.layer() - layerMeanSeg[iseg]), 2) * hit.getEnergy();
578
579 for (unsigned int ireg = 0; ireg < nregions; ireg++) {
580 if (distance_ele_trajectory > (ireg + 1) * ele_radii[id.layer()] &&
581 distance_photon_trajectory >
582 (ireg + 1) * photon_radii[id.layer()]) {
583 oContXStd[ireg][iseg] +=
584 pow((xy_pair.first - oContXMean[ireg][iseg]), 2) *
585 hit.getEnergy();
586 oContYStd[ireg][iseg] +=
587 pow((xy_pair.second - oContYMean[ireg][iseg]), 2) *
588 hit.getEnergy();
589 oContLayerStd[ireg][iseg] +=
590 pow((id.layer() - oContLayerMean[ireg][iseg]), 2) *
591 hit.getEnergy();
592 }
593 }
594 }
595 }
596
597 for (unsigned int ireg = 0; ireg < nregions; ireg++) {
598 if (distance_ele_trajectory > (ireg + 1) * ele_radii[id.layer()] &&
599 distance_photon_trajectory > (ireg + 1) * photon_radii[id.layer()]) {
600 outsideContainmentXstd[ireg] +=
601 pow((xy_pair.first - outsideContainmentXmean[ireg]), 2) *
602 hit.getEnergy();
603 outsideContainmentYstd[ireg] +=
604 pow((xy_pair.second - outsideContainmentYmean[ireg]), 2) *
605 hit.getEnergy();
606 }
607 }
608 } // end loop over rechits (2nd time)
609
610 if (nReadoutHits_ > 0) {
611 xStd_ = sqrt(xStd_ / summedDet_);
612 yStd_ = sqrt(yStd_ / summedDet_);
613 stdLayerHit_ = sqrt(stdLayerHit_ / summedDet_);
614 } else {
615 xStd_ = 0;
616 yStd_ = 0;
617 stdLayerHit_ = 0;
618 }
619
620 // Quotient out the total energies from the standard deviations if possible
621 // and take root
622 for (unsigned int iseg = 0; iseg < nsegments; iseg++) {
623 if (energySeg[iseg] > 0) {
624 xStdSeg[iseg] = sqrt(xStdSeg[iseg] / energySeg[iseg]);
625 yStdSeg[iseg] = sqrt(yStdSeg[iseg] / energySeg[iseg]);
626 layerStdSeg[iseg] = sqrt(layerStdSeg[iseg] / energySeg[iseg]);
627 }
628 for (unsigned int ireg = 0; ireg < nregions; ireg++) {
629 if (oContEnergy[ireg][iseg] > 0) {
630 oContXStd[ireg][iseg] =
631 sqrt(oContXStd[ireg][iseg] / oContEnergy[ireg][iseg]);
632 oContYStd[ireg][iseg] =
633 sqrt(oContYStd[ireg][iseg] / oContEnergy[ireg][iseg]);
634 oContLayerStd[ireg][iseg] =
635 sqrt(oContLayerStd[ireg][iseg] / oContEnergy[ireg][iseg]);
636 }
637 }
638 }
639
640 for (unsigned int ireg = 0; ireg < nregions; ireg++) {
641 if (outsideContainmentEnergy[ireg] > 0) {
642 outsideContainmentXstd[ireg] =
643 sqrt(outsideContainmentXstd[ireg] / outsideContainmentEnergy[ireg]);
644 outsideContainmentYstd[ireg] =
645 sqrt(outsideContainmentYstd[ireg] / outsideContainmentEnergy[ireg]);
646 }
647 }
648
649 if (verbose_) {
650 ldmx_log(debug) << " Find out if the recoil electron is fiducial";
651 }
652
653 // Find the location of the recoil electron
654 // Ecal face is not where the first layer starts,
655 // defined in DetDescr/python/EcalGeometry.py
656 const float dz_from_face{7.932};
657 float drifted_recoil_x{-9999.};
658 float drifted_recoil_y{-9999.};
659 if (recoilP.size() > 0) {
660 drifted_recoil_x =
661 (dz_from_face * (recoilP[0] / recoilP[2])) + recoilPos[0];
662 drifted_recoil_y =
663 (dz_from_face * (recoilP[1] / recoilP[2])) + recoilPos[1];
664 }
665 const int recoil_layer_index = 0;
666
667 // Check if it's fiducial
668 bool inside{false};
669 // At module level
670 const auto ecalID = geometry_->getID(drifted_recoil_x, drifted_recoil_y,
671 recoil_layer_index, true);
672 if (!ecalID.null()) {
673 // If fiducial at module level, check at cell level
674 const auto cellID =
675 geometry_->getID(drifted_recoil_x, drifted_recoil_y, recoil_layer_index,
676 ecalID.getModuleID(), true);
677 if (!cellID.null()) {
678 inside = true;
679 }
680 }
681
682 if (!inside) {
683 ldmx_log(info) << "This event is non-fiducial in ECAL";
684 }
685
686 // ------------------------------------------------------
687 // MIP tracking starts here
688
689 /* Goal: Calculate
690 * nStraightTracks (self-explanatory),
691 * nLinregTracks (tracks found by linreg algorithm),
692 */
693
694 // Find epAng and epSep, and prepare EP trajectory vectors:
695 TVector3 e_traj_start;
696 TVector3 e_traj_end;
697 TVector3 p_traj_start;
698 TVector3 p_traj_end;
699 if (ele_trajectory.size() > 0 && photon_trajectory.size() > 0) {
700 // Create TVector3s marking the start and endpoints of each projected
701 // trajectory
702 e_traj_start.SetXYZ(ele_trajectory[0].first, ele_trajectory[0].second,
704 e_traj_end.SetXYZ(ele_trajectory[(nEcalLayers_ - 1)].first,
705 ele_trajectory[(nEcalLayers_ - 1)].second,
706 geometry_->getZPosition((nEcalLayers_ - 1)));
707 p_traj_start.SetXYZ(photon_trajectory[0].first, photon_trajectory[0].second,
709 p_traj_end.SetXYZ(photon_trajectory[(nEcalLayers_ - 1)].first,
710 photon_trajectory[(nEcalLayers_ - 1)].second,
711 geometry_->getZPosition((nEcalLayers_ - 1)));
712
713 TVector3 evec = e_traj_end - e_traj_start;
714 TVector3 e_norm = evec.Unit();
715 TVector3 pvec = p_traj_end - p_traj_start;
716 TVector3 p_norm = pvec.Unit();
717 epDot_ = e_norm.Dot(p_norm);
718 epAng_ = acos(epDot_) * 180.0 / M_PI;
719 epSep_ = sqrt(pow(e_traj_start.X() - p_traj_start.X(), 2) +
720 pow(e_traj_start.Y() - p_traj_start.Y(), 2));
721 } else {
722 // Electron trajectory is missing, so all hits in the Ecal are fair game.
723 // Pick e/ptraj so that they won't restrict the tracking algorithm (place
724 // them far outside the ECal).
725 e_traj_start = TVector3(999, 999, geometry_->getZPosition(0)); // 0);
726 e_traj_end = TVector3(
727 999, 999, geometry_->getZPosition((nEcalLayers_ - 1))); // 999);
728 p_traj_start = TVector3(1000, 1000, geometry_->getZPosition(0)); // 0);
729 p_traj_end = TVector3(
730 1000, 1000, geometry_->getZPosition((nEcalLayers_ - 1))); // 1000);
731 /*ensures event will not be vetoed by angle/separation cut */
732 epAng_ = 999.;
733 epSep_ = 999.;
734 epDot_ = 999.;
735 }
736
737 // Near photon step: Find the first layer of the ECal where a hit near the
738 // projected photon trajectory is found Currently unusued pending further
739 // study; performance has dropped between v9 and v12. Currently used in
740 // segmipBDT
741 firstNearPhLayer_ = nEcalLayers_ - 1;
742
743 if (photon_trajectory.size() !=
744 0) { // If no photon trajectory, leave this at the default (ECal back)
745 for (std::vector<HitData>::iterator it = trackingHitList.begin();
746 it != trackingHitList.end(); ++it) {
747 float ehDist =
748 sqrt(pow((*it).pos.X() - photon_trajectory[(*it).layer].first, 2) +
749 pow((*it).pos.Y() - photon_trajectory[(*it).layer].second, 2));
750 if (ehDist < 8.7) {
751 nNearPhHits_++;
752 if ((*it).layer < firstNearPhLayer_) {
753 firstNearPhLayer_ = (*it).layer;
754 }
755 }
756 }
757 }
758
759 // Territories limited to trackingHitList
760 TVector3 gToe = (e_traj_start - p_traj_start).Unit();
761 TVector3 origin = p_traj_start + 0.5 * 8.7 * gToe;
762 if (ele_trajectory.size() > 0) {
763 for (auto &hitData : trackingHitList) {
764 TVector3 hitPos = hitData.pos;
765 TVector3 hitPrime = hitPos - origin;
766 if (hitPrime.Dot(gToe) <= 0) {
768 }
769 }
770 } else {
771 photonTerritoryHits_ = nReadoutHits_;
772 }
773
774 // ------------------------------------------------------
775 // Find straight MIP tracks:
776
777 std::sort(trackingHitList.begin(), trackingHitList.end(),
778 [](HitData ha, HitData hb) { return ha.layer > hb.layer; });
779 // For merging tracks: Need to keep track of existing tracks
780 // Candidate tracks to merge in will always be in front of the current track
781 // (lower z), so only store the last hit 3-layer vector: each track = vector
782 // of 3-tuples (xy+layer).
783 std::vector<std::vector<HitData>> track_list;
784
785 // print trackingHitList
786 if (verbose_) {
787 ldmx_log(debug) << "====== Tracking hit list (original) length "
788 << trackingHitList.size() << " ======";
789 for (int i = 0; i < trackingHitList.size(); i++) {
790 std::cout << "[" << trackingHitList[i].pos.X() << ", "
791 << trackingHitList[i].pos.Y() << ", "
792 << trackingHitList[i].layer << "], ";
793 }
794 std::cout << std::endl;
795 ldmx_log(debug) << "====== END OF Tracking hit list ======";
796 }
797
798 // in v14 minR is 4.17 mm
799 // while maxR is 4.81 mm
800 float cellWidth = 2 * geometry_->getCellMaxR();
801 for (int iHit = 0; iHit < trackingHitList.size(); iHit++) {
802 // list of hit numbers in track (34 = maximum theoretical length)
803 int track[34];
804 int currenthit{iHit};
805 int trackLen{1};
806
807 track[0] = iHit;
808
809 // Search for hits to add to the track:
810 // repeatedly find hits in the front two layers with same x & y positions
811 // but since v14 the odd layers are offset, so we allow half a cellWidth
812 // deviation and then add to track until no more hits are found
813 int jHit = iHit;
814 while (jHit < trackingHitList.size()) {
815 if ((trackingHitList[jHit].layer ==
816 trackingHitList[currenthit].layer - 1 ||
817 trackingHitList[jHit].layer ==
818 trackingHitList[currenthit].layer - 2) &&
819 abs(trackingHitList[jHit].pos.X() -
820 trackingHitList[currenthit].pos.X()) <= 0.5 * cellWidth &&
821 abs(trackingHitList[jHit].pos.Y() -
822 trackingHitList[currenthit].pos.Y()) <= 0.5 * cellWidth) {
823 track[trackLen] = jHit;
824 trackLen++;
825 currenthit = jHit;
826 }
827 jHit++;
828 }
829
830 // Confirm that the track is valid:
831 if (trackLen < 2) continue; // Track must contain at least 2 hits
832 float closest_e = distTwoLines(trackingHitList[track[0]].pos,
833 trackingHitList[track[trackLen - 1]].pos,
834 e_traj_start, e_traj_end);
835 float closest_p = distTwoLines(trackingHitList[track[0]].pos,
836 trackingHitList[track[trackLen - 1]].pos,
837 p_traj_start, p_traj_end);
838 // Make sure that the track is near the photon trajectory and away from the
839 // electron trajectory Details of these constraints may be revised
840 if (closest_p > cellWidth and closest_e < 2 * cellWidth) continue;
841 if (trackLen < 4 and closest_e > closest_p) continue;
842 if (verbose_) {
843 ldmx_log(debug) << "====== After rejection for MIP tracking ======";
844 ldmx_log(debug) << "current hit: [" << trackingHitList[iHit].pos.X()
845 << ", " << trackingHitList[iHit].pos.Y() << ", "
846 << trackingHitList[iHit].layer << "]";
847
848 for (int k = 0; k < trackLen; k++) {
849 ldmx_log(debug) << "track[" << k << "] position = ["
850 << trackingHitList[track[k]].pos.X() << ", "
851 << trackingHitList[track[k]].pos.Y() << ", "
852 << trackingHitList[track[k]].layer << "]";
853 }
854 }
855
856 // if track found, increment nStraightTracks and remove all hits in track
857 // from future consideration
858 if (trackLen >= 2) {
859 std::vector<HitData> temp_track_list;
860 int n_remove = 0;
861 for (int kHit = 0; kHit < trackLen; kHit++) {
862 temp_track_list.push_back(trackingHitList[track[kHit] - n_remove]);
863 trackingHitList.erase(trackingHitList.begin() + track[kHit] - n_remove);
864 n_remove++;
865 }
866 // print trackingHitList
867 if (verbose_) {
868 ldmx_log(debug) << "====== Tracking hit list (after erase) length "
869 << trackingHitList.size() << " ======";
870 for (int i = 0; i < trackingHitList.size(); i++) {
871 std::cout << "[" << trackingHitList[i].pos.X() << ", "
872 << trackingHitList[i].pos.Y() << ", "
873 << trackingHitList[i].layer << "] ";
874 }
875 std::cout << std::endl;
876 ldmx_log(debug) << "====== END OF Tracking hit list ======";
877 }
878
879 track_list.push_back(temp_track_list);
880 // The *current* hit will have been removed, so iHit is currently pointing
881 // to the next hit. Decrement iHit so no hits will get skipped by iHit++
882 iHit--;
883 }
884 }
885
886 ldmx_log(debug) << "Straight tracks found (before merge): "
887 << track_list.size();
888 if (verbose_) {
889 for (int iTrack = 0; iTrack < track_list.size(); iTrack++) {
890 ldmx_log(debug) << "Track " << iTrack << ":";
891 for (int iHit = 0; iHit < track_list[iTrack].size(); iHit++) {
892 std::cout << " Hit " << iHit << ": ["
893 << track_list[iTrack][iHit].pos.X() << ", "
894 << track_list[iTrack][iHit].pos.Y() << ", "
895 << track_list[iTrack][iHit].layer << "]" << std::endl;
896 }
897 std::cout << std::endl;
898 }
899 }
900
901 // Optional addition: Merge nearby straight tracks. Not necessary for veto.
902 // Criteria: consider tail of track. Merge if head of next track is 1/2
903 // layers behind, within 1 cell of xy position.
904 ldmx_log(debug) << "Beginning track merging using " << track_list.size()
905 << " tracks";
906
907 for (int track_i = 0; track_i < track_list.size(); track_i++) {
908 // for each track, check the remainder of the track list for compatible
909 // tracks
910 std::vector<HitData> base_track = track_list[track_i];
911 HitData tail_hitdata = base_track.back(); // xylayer of last hit in track
912 if (verbose_) ldmx_log(debug) << " Considering track " << track_i;
913 for (int track_j = track_i + 1; track_j < track_list.size(); track_j++) {
914 std::vector<HitData> checking_track = track_list[track_j];
915 HitData head_hitdata = checking_track.front();
916 // if 1-2 layers behind, and xy within one cell...
917 if ((head_hitdata.layer == tail_hitdata.layer + 1 ||
918 head_hitdata.layer == tail_hitdata.layer + 2) &&
919 pow(pow(head_hitdata.pos.X() - tail_hitdata.pos.X(), 2) +
920 pow(head_hitdata.pos.Y() - tail_hitdata.pos.Y(), 2),
921 0.5) <= cellWidth) {
922 // ...then append the second track to the first one and delete it
923 // NOTE: TO ADD: (trackingHitList[iHit].pos -
924 // trackingHitList[jHit].pos).Mag()
925 if (verbose_) {
926 ldmx_log(debug) << " ** Compatible track found at index "
927 << track_j;
928 ldmx_log(debug) << " Tail xylayer: " << head_hitdata.pos.X()
929 << "," << head_hitdata.pos.Y() << ","
930 << head_hitdata.layer;
931 ldmx_log(debug) << " Head xylayer: " << tail_hitdata.pos.X()
932 << "," << tail_hitdata.pos.Y() << ","
933 << tail_hitdata.layer;
934 }
935 for (int hit_k = 0; hit_k < checking_track.size(); hit_k++) {
936 base_track.push_back(track_list[track_j][hit_k]);
937 }
938 track_list[track_i] = base_track;
939 track_list.erase(track_list.begin() + track_j);
940 break;
941 }
942 }
943 }
944 nStraightTracks_ = track_list.size();
945 // print the track list
946 ldmx_log(debug) << "Straight tracks found (after merge): "
948 for (int track_i = 0; track_i < track_list.size(); track_i++) {
949 ldmx_log(debug) << "Track " << track_i << ":";
950 for (int hit_i = 0; hit_i < track_list[track_i].size(); hit_i++) {
951 ldmx_log(debug) << " Hit " << hit_i << ": ["
952 << track_list[track_i][hit_i].pos.X() << ", "
953 << track_list[track_i][hit_i].pos.Y() << ", "
954 << track_list[track_i][hit_i].layer << "]";
955 }
956 }
957
958 // ------------------------------------------------------
959 // Linreg tracking:
960 ldmx_log(debug) << "Finding linreg tracks from " << trackingHitList.size()
961 << " hits";
962
963 for (int iHit = 0; iHit < trackingHitList.size(); iHit++) {
964 int track[34];
965 int trackLen{0};
966 // Hits being considered at one time
967 // TODO: This is currently not used, but it really should be!
968 // int hitsInRegion[50];
969 // Number of hits under consideration
970 int nHitsInRegion{1};
971 TMatrixD Vm(3, 3);
972 TMatrixD hdt(3, 3);
973 TVector3 slopeVec;
974 TVector3 hmean;
975 TVector3 hpoint;
976 float r_corr_best{0.0};
977 int hitNums[3];
978
979 // hitsInRegion[0] = iHit; // TODO
980 // Find all hits within 2 cells of the primary hit:
981 for (int jHit = 0; jHit < trackingHitList.size(); jHit++) {
982 // Dont try to put hits on the same layer to the lin-reg track
983 if (trackingHitList[iHit].pos(2) == trackingHitList[jHit].pos(2)) {
984 continue;
985 }
986 float dstToHit =
987 (trackingHitList[iHit].pos - trackingHitList[jHit].pos).Mag();
988 // This distance needs to be optimized in a future study //TODO
989 // Current 2*cellWidth has no particular meaning
990 if (dstToHit <= 2 * cellWidth) {
991 // hitsInRegion[nHitsInRegion] = jHit; // TODO
992 nHitsInRegion++;
993 }
994 }
995
996 // Look at combinations of hits within the region (do not consider the same
997 // combination twice):
998 hitNums[0] = iHit;
999 for (int jHit = 1; jHit < nHitsInRegion - 1; jHit++) {
1000 if (trackingHitList.size() < 3) break;
1001 hitNums[1] = jHit;
1002 for (int kHit = jHit + 1; kHit < nHitsInRegion; kHit++) {
1003 hitNums[2] = kHit;
1004 for (int hInd = 0; hInd < 3; hInd++) {
1005 // hmean = geometric mean, subtract off from hits to improve SVD
1006 // performance
1007 hmean(hInd) = (trackingHitList[hitNums[0]].pos(hInd) +
1008 trackingHitList[hitNums[1]].pos(hInd) +
1009 trackingHitList[hitNums[2]].pos(hInd)) /
1010 3.0;
1011 }
1012 for (int hInd = 0; hInd < 3; hInd++) {
1013 for (int lInd = 0; lInd < 3; lInd++) {
1014 hdt(hInd, lInd) =
1015 trackingHitList[hitNums[hInd]].pos(lInd) - hmean(lInd);
1016 }
1017 }
1018
1019 // Perform "linreg" on selected points
1020 // Calculate the determinant of the matrix
1021 double determinant =
1022 hdt(0, 0) * (hdt(1, 1) * hdt(2, 2) - hdt(1, 2) * hdt(2, 1)) -
1023 hdt(0, 1) * (hdt(1, 0) * hdt(2, 2) - hdt(1, 2) * hdt(2, 0)) +
1024 hdt(0, 2) * (hdt(1, 0) * hdt(2, 1) - hdt(1, 1) * hdt(2, 0));
1025 // Exit early if the matrix is singular (i.e. det = 0)
1026 if (determinant == 0) continue;
1027 // Perform matrix decomposition with SVD
1028 TDecompSVD svdObj(hdt);
1029 bool decomposed = svdObj.Decompose();
1030 if (!decomposed) continue;
1031
1032 // First col of V matrix is the slope of the best-fit line
1033 Vm = svdObj.GetV();
1034 for (int hInd = 0; hInd < 3; hInd++) {
1035 slopeVec(hInd) = Vm[0][hInd];
1036 }
1037 // hmean, hpoint are points on the best-fit line
1038 hpoint = slopeVec + hmean;
1039 // linreg complete: Now have best-fit line for 3 hits under
1040 // consideration Check whether the track is valid: r^2 must be high,
1041 // and the track must plausibly originate from the photon
1042 float closest_e = distTwoLines(hmean, hpoint, e_traj_start, e_traj_end);
1043 float closest_p = distTwoLines(hmean, hpoint, p_traj_start, p_traj_end);
1044 // Projected track must be close to the photon; details may change after
1045 // future study.
1046 if (closest_p > cellWidth or closest_e < 1.5 * cellWidth) continue;
1047 // find r^2
1048 // ~variance
1049 float vrnc = (trackingHitList[hitNums[0]].pos - hmean).Mag() +
1050 (trackingHitList[hitNums[1]].pos - hmean).Mag() +
1051 (trackingHitList[hitNums[2]].pos - hmean).Mag();
1052 // sum of |errors|
1053 float sumerr =
1054 distPtToLine(trackingHitList[hitNums[0]].pos, hmean, hpoint) +
1055 distPtToLine(trackingHitList[hitNums[1]].pos, hmean, hpoint) +
1056 distPtToLine(trackingHitList[hitNums[2]].pos, hmean, hpoint);
1057 float r_corr = 1 - sumerr / vrnc;
1058 // Check whether r^2 exceeds a low minimum r_corr: "Fake" tracks are
1059 // still much more common in background, so making the algorithm
1060 // oversensitive doesn't lower performance significantly
1061 if (r_corr > r_corr_best and r_corr > .6) {
1062 r_corr_best = r_corr;
1063 trackLen = 0;
1064 // Only looking for 3-hit tracks currently
1065 for (int k = 0; k < 3; k++) {
1066 track[k] = hitNums[k];
1067 trackLen++;
1068 }
1069 }
1070 } // end loop on hits in the region
1071 } // end 2nd loop on hits in the region
1072
1073 // Continue early if not hits on track
1074 if (trackLen == 0) continue;
1075
1076 // Ordinarily, additional hits in line w/ track would be added here.
1077 // However, this doesn't affect the results of the simple veto. Exclude all
1078 // hits in a found track from further consideration:
1079 if (trackLen >= 2) {
1081 for (int kHit = 0; kHit < trackLen; kHit++) {
1082 trackingHitList.erase(trackingHitList.begin() + track[kHit]);
1083 }
1084 iHit--;
1085 }
1086 } // end loop on all hits
1087
1088 ldmx_log(info) << " MIP tracking completed; found " << nStraightTracks_
1089 << " straight tracks and " << nLinregTracks_
1090 << " lin-reg tracks";
1091
1092 result.setVariables(
1093 nReadoutHits_, deepestLayerHit_, summedDet_, summedTightIso_, maxCellDep_,
1094 showerRMS_, xStd_, yStd_, avgLayerHit_, stdLayerHit_, ecalBackEnergy_,
1096 photonTerritoryHits_, epAng_, epSep_, epDot_, electronContainmentEnergy,
1097 photonContainmentEnergy, outsideContainmentEnergy,
1098 outsideContainmentNHits, outsideContainmentXstd, outsideContainmentYstd,
1099 energySeg, xMeanSeg, yMeanSeg, xStdSeg, yStdSeg, layerMeanSeg,
1100 layerStdSeg, eContEnergy, eContXMean, eContYMean, gContEnergy, gContNHits,
1101 gContXMean, gContYMean, oContEnergy, oContNHits, oContXMean, oContYMean,
1102 oContXStd, oContYStd, oContLayerMean, oContLayerStd,
1103 ecalLayerEdepReadout_, recoilP, recoilPos);
1104
1105 buildBDTFeatureVector(result);
1106 ldmx::Ort::FloatArrays inputs({bdtFeatures_});
1107 float pred = rt_->run({featureListName_}, inputs, {"probabilities"})[0].at(1);
1108 // Other considerations were (nLinregTracks_ == 0) && (firstNearPhLayer_ >=
1109 // 6)
1110 // && (epAng_ > 3.0 && epAng_ < 900 || epSep_ > 10.0 && epSep_ < 900)
1111 bool passesTrackingVeto = (nStraightTracks_ < 3);
1112 result.setVetoResult(pred > bdtCutVal_ && passesTrackingVeto);
1113 result.setDiscValue(pred);
1114 ldmx_log(debug) << " The pred > bdtCutVal = " << (pred > bdtCutVal_);
1115
1116 // Persist in the event if the recoil ele is fiducial
1117 result.setFiducial(inside);
1118
1119 // If the event passes the veto, keep it. Otherwise,
1120 // drop the event.
1121 if (result.passesVeto()) {
1123 } else {
1125 }
1126
1127 event.add(collectionName_, result);
1128}
std::tuple< int, const ldmx::SimParticle * > getRecoil(const std::map< int, ldmx::SimParticle > &particleMap)
Find and return the sim particle associated with the recoil electron.
float distTwoLines(TVector3 v1, TVector3 v2, TVector3 w1, TVector3 w2)
Returns the distance between the lines v and w, with v defined to pass through the points (v1,...
void buildBDTFeatureVector(const ldmx::EcalVetoResult &result)
float distPtToLine(TVector3 h1, TVector3 p1, TVector3 p2)
Return the minimum distance between the point h1 and the line passing through points p1 and p2.
void fillHitMap(const std::vector< ldmx::EcalHit > &ecalRecHits, std::map< ldmx::EcalID, float > &cellMap_)
Function to load up empty vector of hit maps.
void setStorageHint(framework::StorageControl::Hint hint)
Mark the current event as having the given storage control hint from this module.
bool exists(const std::string &name, const std::string &passName="", bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Definition Event.cxx:92
EcalID getID(double x, double y, double z, bool fallible=false) const
Get a cell's ID number from its position.
double getCellMaxR() const
Get the center-to-corner radius of the cell hexagons.
void setVariables(int nReadoutHits, int deepestLayerHit, float summedDet, float summedTightIso, float maxCellDep, float showerRMS, float xStd, float yStd, float avgLayerHit, float stdLayerHit, float ecalBackEnergy, int nStraightTracks, int nLinregTracks, int firstNearPhLayer, int nNearPhHits, int photonTerritoryHits, float epAng, float epSep, float epDot, std::vector< float > electronContainmentEnergy, std::vector< float > photonContainmentEnergy, std::vector< float > outsideContainmentEnergy, std::vector< int > outsideContainmentNHits, std::vector< float > outsideContainmentXStd, std::vector< float > outsideContainmentYStd, std::vector< float > energySeg, std::vector< float > xMeanSeg, std::vector< float > yMeanSeg, std::vector< float > xStdSeg, std::vector< float > yStdSeg, std::vector< float > layerMeanSeg, std::vector< float > layerStdSeg, std::vector< std::vector< float > > eContEnergy, std::vector< std::vector< float > > eContXMean, std::vector< std::vector< float > > eContYMean, std::vector< std::vector< float > > gContEnergy, std::vector< std::vector< int > > gContNHits, std::vector< std::vector< float > > gContXMean, std::vector< std::vector< float > > gContYMean, std::vector< std::vector< float > > oContEnergy, std::vector< std::vector< int > > oContNHits, std::vector< std::vector< float > > oContXMean, std::vector< std::vector< float > > oContYMean, std::vector< std::vector< float > > oContXStd, std::vector< std::vector< float > > oContYStd, std::vector< std::vector< float > > oContLayerMean, std::vector< std::vector< float > > oContLayerStd, std::vector< float > EcalLayerEdepReadout, std::vector< double > recoilP, std::vector< float > recoilPos)
Set the sim particle and 'is findable' flag.
bool passesVeto() const
Checks if the event passes the Ecal veto.
Class representing a simulated particle.
Definition SimParticle.h:23
Implements detector ids for special simulation-derived hits like scoring planes.
Represents a simulated tracker hit in the simulation.
constexpr StorageControl::Hint hint_shouldKeep
storage control hint alias for backwards compatibility
constexpr StorageControl::Hint hint_shouldDrop
storage control hint alias for backwards compatibility

References buildBDTFeatureVector(), collectionName_, distPtToLine(), distTwoLines(), epAng_, epDot_, epSep_, framework::Event::exists(), fillHitMap(), firstNearPhLayer_, geometry_, ldmx::EcalGeometry::getCellMaxR(), ldmx::EcalGeometry::getID(), ldmx::EcalGeometry::getPosition(), ldmx::EcalGeometry::getZPosition(), framework::hint_shouldDrop, framework::hint_shouldKeep, nLinregTracks_, nNearPhHits_, nStraightTracks_, ldmx::EcalVetoResult::passesVeto(), photonTerritoryHits_, ldmx::SimSpecialID::plane(), framework::EventProcessor::setStorageHint(), and ldmx::EcalVetoResult::setVariables().

Member Data Documentation

◆ avgLayerHit_

double ecal::EcalVetoProcessor::avgLayerHit_ {0}
private

Definition at line 125 of file EcalVetoProcessor.h.

125{0};

◆ bdtCutVal_

double ecal::EcalVetoProcessor::bdtCutVal_ {0}
private

Definition at line 148 of file EcalVetoProcessor.h.

148{0};

◆ bdtFeatures_

std::vector<float> ecal::EcalVetoProcessor::bdtFeatures_
private

Definition at line 156 of file EcalVetoProcessor.h.

◆ bdtFileName_

std::string ecal::EcalVetoProcessor::bdtFileName_
private

Definition at line 154 of file EcalVetoProcessor.h.

◆ beamEnergyMeV_

double ecal::EcalVetoProcessor::beamEnergyMeV_ {0}
private

Definition at line 150 of file EcalVetoProcessor.h.

150{0};

◆ cellMap_

std::map<ldmx::EcalID, float> ecal::EcalVetoProcessor::cellMap_
private

Definition at line 106 of file EcalVetoProcessor.h.

◆ cellMapTightIso_

std::map<ldmx::EcalID, float> ecal::EcalVetoProcessor::cellMapTightIso_
private

Definition at line 107 of file EcalVetoProcessor.h.

◆ collectionName_

std::string ecal::EcalVetoProcessor::collectionName_ {"EcalVeto"}
private

Name of the collection which will containt the results.

Definition at line 163 of file EcalVetoProcessor.h.

163{"EcalVeto"};

Referenced by configure(), and produce().

◆ deepestLayerHit_

int ecal::EcalVetoProcessor::deepestLayerHit_ {0}
private

Definition at line 117 of file EcalVetoProcessor.h.

117{0};

◆ ecalBackEnergy_

double ecal::EcalVetoProcessor::ecalBackEnergy_ {0}
private

Definition at line 127 of file EcalVetoProcessor.h.

127{0};

◆ ecalLayerEdepRaw_

std::vector<float> ecal::EcalVetoProcessor::ecalLayerEdepRaw_
private

Definition at line 109 of file EcalVetoProcessor.h.

◆ ecalLayerEdepReadout_

std::vector<float> ecal::EcalVetoProcessor::ecalLayerEdepReadout_
private

Definition at line 110 of file EcalVetoProcessor.h.

◆ ecalLayerTime_

std::vector<float> ecal::EcalVetoProcessor::ecalLayerTime_
private

Definition at line 111 of file EcalVetoProcessor.h.

◆ epAng_

float ecal::EcalVetoProcessor::epAng_ {0}
private

Angular separation between the projected photon and electron trajectories (currently unused)

Definition at line 139 of file EcalVetoProcessor.h.

139{0};

Referenced by produce().

◆ epDot_

float ecal::EcalVetoProcessor::epDot_ {0}
private

Dot product of the photon and electron momenta unit vectors.

Definition at line 144 of file EcalVetoProcessor.h.

144{0};

Referenced by produce().

◆ epSep_

float ecal::EcalVetoProcessor::epSep_ {0}
private

Distance between the projected photon and electron trajectories at the ECal face.

Definition at line 142 of file EcalVetoProcessor.h.

142{0};

Referenced by produce().

◆ featureListName_

std::string ecal::EcalVetoProcessor::featureListName_
private

Definition at line 157 of file EcalVetoProcessor.h.

◆ firstNearPhLayer_

int ecal::EcalVetoProcessor::firstNearPhLayer_ {0}
private

First ECal layer in which a hit is found near the photon.

Definition at line 134 of file EcalVetoProcessor.h.

134{0};

Referenced by produce().

◆ geometry_

const ldmx::EcalGeometry* ecal::EcalVetoProcessor::geometry_
private

handle to current geometry (to share with member functions)

Definition at line 168 of file EcalVetoProcessor.h.

Referenced by produce().

◆ maxCellDep_

double ecal::EcalVetoProcessor::maxCellDep_ {0}
private

Definition at line 121 of file EcalVetoProcessor.h.

121{0};

◆ nEcalLayers_

int ecal::EcalVetoProcessor::nEcalLayers_ {0}
private

Definition at line 115 of file EcalVetoProcessor.h.

115{0};

◆ nLinregTracks_

int ecal::EcalVetoProcessor::nLinregTracks_ {0}
private

Number of "linreg" tracks found in the event.

Definition at line 132 of file EcalVetoProcessor.h.

132{0};

Referenced by produce().

◆ nNearPhHits_

int ecal::EcalVetoProcessor::nNearPhHits_ {0}
private

Number of hits near the photon trajectory.

Definition at line 136 of file EcalVetoProcessor.h.

136{0};

Referenced by produce().

◆ nReadoutHits_

int ecal::EcalVetoProcessor::nReadoutHits_ {0}
private

Definition at line 116 of file EcalVetoProcessor.h.

116{0};

◆ nStraightTracks_

int ecal::EcalVetoProcessor::nStraightTracks_ {0}
private

Number of "straight" tracks found in the event.

Definition at line 130 of file EcalVetoProcessor.h.

130{0};

Referenced by produce().

◆ photonTerritoryHits_

int ecal::EcalVetoProcessor::photonTerritoryHits_ {0}
private

Number of hits in the photon territory.

Definition at line 146 of file EcalVetoProcessor.h.

146{0};

Referenced by produce().

◆ rec_coll_name_

std::string ecal::EcalVetoProcessor::rec_coll_name_
private

Definition at line 160 of file EcalVetoProcessor.h.

◆ rec_pass_name_

std::string ecal::EcalVetoProcessor::rec_pass_name_
private

Definition at line 159 of file EcalVetoProcessor.h.

◆ roc_range_values_

std::vector<std::vector<double> > ecal::EcalVetoProcessor::roc_range_values_
private

Definition at line 113 of file EcalVetoProcessor.h.

◆ rocFileName_

std::string ecal::EcalVetoProcessor::rocFileName_
private

Definition at line 155 of file EcalVetoProcessor.h.

◆ rt_

std::unique_ptr<ldmx::Ort::ONNXRuntime> ecal::EcalVetoProcessor::rt_
private

Definition at line 165 of file EcalVetoProcessor.h.

◆ showerRMS_

double ecal::EcalVetoProcessor::showerRMS_ {0}
private

Definition at line 122 of file EcalVetoProcessor.h.

122{0};

◆ stdLayerHit_

double ecal::EcalVetoProcessor::stdLayerHit_ {0}
private

Definition at line 126 of file EcalVetoProcessor.h.

126{0};

◆ summedDet_

double ecal::EcalVetoProcessor::summedDet_ {0}
private

Definition at line 119 of file EcalVetoProcessor.h.

119{0};

◆ summedTightIso_

double ecal::EcalVetoProcessor::summedTightIso_ {0}
private

Definition at line 120 of file EcalVetoProcessor.h.

120{0};

◆ verbose_

bool ecal::EcalVetoProcessor::verbose_ {false}
private

Definition at line 152 of file EcalVetoProcessor.h.

152{false};

◆ xStd_

double ecal::EcalVetoProcessor::xStd_ {0}
private

Definition at line 123 of file EcalVetoProcessor.h.

123{0};

◆ yStd_

double ecal::EcalVetoProcessor::yStd_ {0}
private

Definition at line 124 of file EcalVetoProcessor.h.

124{0};

The documentation for this class was generated from the following files: