Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
BdtBeamParticleIdTool.cc
Go to the documentation of this file.
1
10
12
17
18using namespace pandora;
19
20namespace lar_content
21{
22
24 m_useTrainingMode(false),
25 m_trainingOutputFile(""),
26 m_minPurity(0.8f),
27 m_minCompleteness(0.8f),
28 m_adaBoostDecisionTree(AdaBoostDecisionTree()),
29 m_filePathEnvironmentVariable("FW_SEARCH_PATH"),
30 m_maxNeutrinos(std::numeric_limits<int>::max()),
31 m_minAdaBDTScore(0.f),
32 m_sliceFeatureParameters(SliceFeatureParameters())
33{
34}
35
36//------------------------------------------------------------------------------------------------------------------------------------------
37
39{
40 // Get global LArTPC geometry information
41 const LArTPCMap &larTPCMap(this->GetPandora().GetGeometry()->GetLArTPCMap());
42 const LArTPC *const pFirstLArTPC(larTPCMap.begin()->second);
43 float parentMinX(pFirstLArTPC->GetCenterX() - 0.5f * pFirstLArTPC->GetWidthX());
44 float parentMaxX(pFirstLArTPC->GetCenterX() + 0.5f * pFirstLArTPC->GetWidthX());
45 float parentMinY(pFirstLArTPC->GetCenterY() - 0.5f * pFirstLArTPC->GetWidthY());
46 float parentMaxY(pFirstLArTPC->GetCenterY() + 0.5f * pFirstLArTPC->GetWidthY());
47 float parentMinZ(pFirstLArTPC->GetCenterZ() - 0.5f * pFirstLArTPC->GetWidthZ());
48 float parentMaxZ(pFirstLArTPC->GetCenterZ() + 0.5f * pFirstLArTPC->GetWidthZ());
49
50 for (const LArTPCMap::value_type &mapEntry : larTPCMap)
51 {
52 const LArTPC *const pLArTPC(mapEntry.second);
53 parentMinX = std::min(parentMinX, pLArTPC->GetCenterX() - 0.5f * pLArTPC->GetWidthX());
54 parentMaxX = std::max(parentMaxX, pLArTPC->GetCenterX() + 0.5f * pLArTPC->GetWidthX());
55 parentMinY = std::min(parentMinY, pLArTPC->GetCenterY() - 0.5f * pLArTPC->GetWidthY());
56 parentMaxY = std::max(parentMaxY, pLArTPC->GetCenterY() + 0.5f * pLArTPC->GetWidthY());
57 parentMinZ = std::min(parentMinZ, pLArTPC->GetCenterZ() - 0.5f * pLArTPC->GetWidthZ());
58 parentMaxZ = std::max(parentMaxZ, pLArTPC->GetCenterZ() + 0.5f * pLArTPC->GetWidthZ());
59 }
60
61 try
62 {
63 m_sliceFeatureParameters.Initialize(parentMinX, parentMaxX, parentMinY, parentMaxY, parentMinZ, parentMaxZ);
64 }
65 catch (const StatusCodeException &statusCodeException)
66 {
67 std::cout << "BdtBeamParticleIdTool::Initialize - unable to initialize LArTPC geometry parameters" << std::endl;
68 return STATUS_CODE_FAILURE;
69 }
70
71 return STATUS_CODE_SUCCESS;
72}
73
74//------------------------------------------------------------------------------------------------------------------------------------------
75
76void BdtBeamParticleIdTool::SelectOutputPfos(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &nuSliceHypotheses,
77 const SliceHypotheses &crSliceHypotheses, PfoList &selectedPfos)
78{
79 if (nuSliceHypotheses.size() != crSliceHypotheses.size())
80 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
81
82 const unsigned int nSlices(nuSliceHypotheses.size());
83 if (nSlices == 0)
84 return;
85
86 SliceFeaturesVector sliceFeaturesVector;
87 this->GetSliceFeatures(nuSliceHypotheses, crSliceHypotheses, sliceFeaturesVector);
88
90 {
91 // ATTN in training mode, just return everything as a cosmic-ray
92 this->SelectAllPfos(pAlgorithm, crSliceHypotheses, selectedPfos);
93
94 pandora::IntVector bestSliceIndices;
95 this->GetBestMCSliceIndices(pAlgorithm, nuSliceHypotheses, crSliceHypotheses, bestSliceIndices);
96
97 for (unsigned int sliceIndex = 0; sliceIndex < nSlices; ++sliceIndex)
98 {
99 const SliceFeatures &features(sliceFeaturesVector.at(sliceIndex));
100 if (!features.IsFeatureVectorAvailable())
101 continue;
102
103 LArMvaHelper::MvaFeatureVector featureVector;
104
105 try
106 {
107 features.FillFeatureVector(featureVector);
108 }
109 catch (const StatusCodeException &statusCodeException)
110 {
111 std::cout << "BdtBeamParticleIdTool::SelectOutputPfos - unable to fill feature vector" << std::endl;
112 continue;
113 }
114
115 bool isGoodTrainingSlice(false);
116 if (std::find(bestSliceIndices.begin(), bestSliceIndices.end(), sliceIndex) != bestSliceIndices.end())
117 isGoodTrainingSlice = true;
118
119 LArMvaHelper::ProduceTrainingExample(m_trainingOutputFile, isGoodTrainingSlice, featureVector);
120 }
121
122 return;
123 }
124
125 this->SelectPfosByAdaBDTScore(pAlgorithm, nuSliceHypotheses, crSliceHypotheses, sliceFeaturesVector, selectedPfos);
126}
127
128//------------------------------------------------------------------------------------------------------------------------------------------
129
131 const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses, SliceFeaturesVector &sliceFeaturesVector) const
132{
133 for (unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
134 sliceFeaturesVector.push_back(SliceFeatures(nuSliceHypotheses.at(sliceIndex), crSliceHypotheses.at(sliceIndex), m_sliceFeatureParameters));
135}
136
137//------------------------------------------------------------------------------------------------------------------------------------------
138
139void BdtBeamParticleIdTool::SelectAllPfos(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &hypotheses, PfoList &selectedPfos) const
140{
141 for (const PfoList &pfos : hypotheses)
142 {
143 for (const ParticleFlowObject *const pPfo : pfos)
144 {
146 metadata.m_propertiesToAdd["TestBeamScore"] = -1.f;
147 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
148 }
149
150 this->SelectPfos(pfos, selectedPfos);
151 }
152}
153
154//------------------------------------------------------------------------------------------------------------------------------------------
155
156void BdtBeamParticleIdTool::SelectPfos(const PfoList &pfos, PfoList &selectedPfos) const
157{
158 selectedPfos.insert(selectedPfos.end(), pfos.begin(), pfos.end());
159}
160
161//------------------------------------------------------------------------------------------------------------------------------------------
162
163void BdtBeamParticleIdTool::GetBestMCSliceIndices(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &nuSliceHypotheses,
164 const SliceHypotheses &crSliceHypotheses, pandora::IntVector &bestSliceIndices) const
165{
166 // Get all hits in all slices to find true number of mc hits
167 const CaloHitList *pAllReconstructedCaloHitList(nullptr);
168 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*pAlgorithm, m_caloHitListName, pAllReconstructedCaloHitList));
169
170 const MCParticleList *pMCParticleList(nullptr);
171 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*pAlgorithm, m_mcParticleListName, pMCParticleList));
172
173 // Obtain map: [mc particle -> primary mc particle]
174 LArMCParticleHelper::MCRelationMap mcToPrimaryMCMap;
175 LArMCParticleHelper::GetMCPrimaryMap(pMCParticleList, mcToPrimaryMCMap);
176
177 // Remove non-reconstructable hits, e.g. those downstream of a neutron
178 CaloHitList reconstructableCaloHitList;
180 LArMCParticleHelper::SelectCaloHits(pAllReconstructedCaloHitList, mcToPrimaryMCMap, reconstructableCaloHitList,
181 parameters.m_selectInputHits, parameters.m_maxPhotonPropagation);
182
183 MCParticleToIntMap mcParticleToReconstructableHitsMap;
184 this->PopulateMCParticleToHitsMap(mcParticleToReconstructableHitsMap, reconstructableCaloHitList);
185
186 const CaloHitSet reconstructableCaloHitSet(reconstructableCaloHitList.begin(), reconstructableCaloHitList.end());
187
188 for (unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
189 {
190 // All hits in a slice - No double counting
191 CaloHitList reconstructedCaloHitList;
192 this->Collect2DHits(crSliceHypotheses.at(sliceIndex), reconstructedCaloHitList, reconstructableCaloHitSet);
193
194 if (nuSliceHypotheses.at(sliceIndex).size() == 1)
195 {
196 const PfoList &nuFinalStates(nuSliceHypotheses.at(sliceIndex).front()->GetDaughterPfoList());
197 this->Collect2DHits(nuFinalStates, reconstructedCaloHitList, reconstructableCaloHitSet);
198 }
199
200 const unsigned int nRecoHits(reconstructedCaloHitList.size());
201
202 // MCParticle to hits in slice map
203 MCParticleToIntMap mcParticleToHitsInSliceMap;
204 this->PopulateMCParticleToHitsMap(mcParticleToHitsInSliceMap, reconstructedCaloHitList);
205
206 if (mcParticleToHitsInSliceMap.empty())
207 continue;
208
209 // Get best mc particle for slice
210 const MCParticle *pBestMCParticle(nullptr);
211 unsigned int nSharedHits(0);
212
213 for (const auto &iter : mcParticleToHitsInSliceMap)
214 {
215 if (iter.second > static_cast<int>(nSharedHits))
216 {
217 pBestMCParticle = iter.first;
218 nSharedHits = iter.second;
219 }
220 }
221
222 // Only consider if target beam particles
223 if (2001 != LArMCParticleHelper::GetNuanceCode(pBestMCParticle))
224 continue;
225
226 const unsigned int nMCHits(mcParticleToReconstructableHitsMap.at(pBestMCParticle));
227 const float purity(nRecoHits > 0 ? static_cast<float>(nSharedHits) / static_cast<float>(nRecoHits) : 0.f);
228 const float completeness(nMCHits > 0 ? static_cast<float>(nSharedHits) / static_cast<float>(nMCHits) : 0.f);
229
230 if (this->PassesQualityCuts(purity, completeness))
231 bestSliceIndices.push_back(sliceIndex);
232 }
233 return;
234}
235
236//------------------------------------------------------------------------------------------------------------------------------------------
237
239{
240 for (const CaloHit *const pCaloHit : caloHitList)
241 {
242 try
243 {
245 MCParticleToIntMap::iterator iter(mcParticleToIntMap.find(pParentMCParticle));
246
247 if (iter != mcParticleToIntMap.end())
248 {
249 (*iter).second += 1;
250 }
251 else
252 {
253 mcParticleToIntMap.insert(MCParticleToIntMap::value_type(pParentMCParticle, 1));
254 }
255 }
256 catch (const StatusCodeException &statusCodeException)
257 {
258 if (STATUS_CODE_NOT_INITIALIZED != statusCodeException.GetStatusCode())
259 throw statusCodeException;
260 }
261 }
262}
263
264//------------------------------------------------------------------------------------------------------------------------------------------
265
266void BdtBeamParticleIdTool::Collect2DHits(const PfoList &pfos, CaloHitList &reconstructedCaloHitList, const CaloHitSet &reconstructableCaloHitSet) const
267{
268 CaloHitList collectedHits;
269 LArPfoHelper::GetCaloHits(pfos, TPC_VIEW_U, collectedHits);
270 LArPfoHelper::GetCaloHits(pfos, TPC_VIEW_V, collectedHits);
271 LArPfoHelper::GetCaloHits(pfos, TPC_VIEW_W, collectedHits);
272
273 for (const CaloHit *const pCaloHit : collectedHits)
274 {
275 // ATTN hits collected from Pfos are copies of hits passed from master instance, we need to access their parent to use MC info
276 const CaloHit *pParentCaloHit(static_cast<const CaloHit *>(pCaloHit->GetParentAddress()));
277
278 if (!reconstructableCaloHitSet.count(pParentCaloHit))
279 continue;
280
281 // Ensure no hits have been double counted
282 if (std::find(reconstructedCaloHitList.begin(), reconstructedCaloHitList.end(), pParentCaloHit) == reconstructedCaloHitList.end())
283 reconstructedCaloHitList.push_back(pParentCaloHit);
284 }
285}
286
287//------------------------------------------------------------------------------------------------------------------------------------------
288
289bool BdtBeamParticleIdTool::PassesQualityCuts(const float purity, const float completeness) const
290{
291 if ((purity < m_minPurity) || (completeness < m_minCompleteness))
292 return false;
293
294 return true;
295}
296
297//------------------------------------------------------------------------------------------------------------------------------------------
298
299void BdtBeamParticleIdTool::SelectPfosByAdaBDTScore(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &nuSliceHypotheses,
300 const SliceHypotheses &crSliceHypotheses, const SliceFeaturesVector &sliceFeaturesVector, PfoList &selectedPfos) const
301{
302 // Calculate the probability of each slice that passes the minimum probability cut
303 std::vector<UintFloatPair> sliceIndexAdaBDTScorePairs;
304 for (unsigned int sliceIndex = 0, nSlices = nuSliceHypotheses.size(); sliceIndex < nSlices; ++sliceIndex)
305 {
306 const float nuAdaBDTScore(sliceFeaturesVector.at(sliceIndex).GetAdaBoostDecisionTreeScore(m_adaBoostDecisionTree));
307
308 for (const ParticleFlowObject *const pPfo : crSliceHypotheses.at(sliceIndex))
309 {
311 metadata.m_propertiesToAdd["TestBeamScore"] = nuAdaBDTScore;
312 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
313 }
314
315 for (const ParticleFlowObject *const pPfo : nuSliceHypotheses.at(sliceIndex))
316 {
318 metadata.m_propertiesToAdd["TestBeamScore"] = nuAdaBDTScore;
319 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*pAlgorithm, pPfo, metadata));
320 }
321
322 if (nuAdaBDTScore < m_minAdaBDTScore)
323 {
324 this->SelectPfos(crSliceHypotheses.at(sliceIndex), selectedPfos);
325 continue;
326 }
327
328 sliceIndexAdaBDTScorePairs.push_back(UintFloatPair(sliceIndex, nuAdaBDTScore));
329 }
330
331 // Sort the slices by probability
332 std::sort(sliceIndexAdaBDTScorePairs.begin(), sliceIndexAdaBDTScorePairs.end(),
333 [](const UintFloatPair &a, const UintFloatPair &b) { return (a.second > b.second); });
334
335 // Select the first m_maxNeutrinos as neutrinos, and the rest as cosmic
336 unsigned int nNuSlices(0);
337 for (const UintFloatPair &slice : sliceIndexAdaBDTScorePairs)
338 {
339 if (nNuSlices < m_maxNeutrinos)
340 {
341 this->SelectPfos(nuSliceHypotheses.at(slice.first), selectedPfos);
342 nNuSlices++;
343 continue;
344 }
345
346 this->SelectPfos(crSliceHypotheses.at(slice.first), selectedPfos);
347 }
348}
349
350//------------------------------------------------------------------------------------------------------------------------------------------
351//------------------------------------------------------------------------------------------------------------------------------------------
352
354 m_unitNormal(0.f, 0.f, 0.f),
355 m_point(point),
356 m_d(-1. * static_cast<double>(normal.GetDotProduct(point)))
357{
358 try
359 {
360 m_unitNormal = normal.GetUnitVector();
361 }
362 catch (const StatusCodeException &statusCodeException)
363 {
364 std::cout << "BdtBeamParticleIdTool::Plane::Plane - normal vector to plane has a magnitude of zero" << std::endl;
365 throw statusCodeException;
366 }
367}
368
369//------------------------------------------------------------------------------------------------------------------------------------------
370
372{
373 if (std::fabs(direction.GetDotProduct(m_unitNormal)) < std::numeric_limits<float>::epsilon())
374 return CartesianVector(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
375
376 const float denominator(direction.GetDotProduct(m_unitNormal));
377
378 if (std::fabs(denominator) < std::numeric_limits<float>::epsilon())
379 throw StatusCodeException(STATUS_CODE_OUT_OF_RANGE);
380
381 const double t(-1. * (static_cast<double>(point.GetDotProduct(m_unitNormal)) + m_d) / static_cast<double>(denominator));
382 return (point + (direction * t));
383}
384
385//------------------------------------------------------------------------------------------------------------------------------------------
386//------------------------------------------------------------------------------------------------------------------------------------------
387
389 m_larTPCMinX(std::numeric_limits<float>::max()),
390 m_larTPCMaxX(std::numeric_limits<float>::max()),
391 m_larTPCMinY(std::numeric_limits<float>::max()),
392 m_larTPCMaxY(std::numeric_limits<float>::max()),
393 m_larTPCMinZ(std::numeric_limits<float>::max()),
394 m_larTPCMaxZ(std::numeric_limits<float>::max()),
395 m_beamLArTPCIntersection(0.f, 0.f, 0.f),
396 m_beamDirection(0.f, 0.f, 0.f),
397 m_selectedFraction(10.f),
398 m_nSelectedHits(100),
399 m_containmentLimit(0.01f)
400{
401}
402
403//------------------------------------------------------------------------------------------------------------------------------------------
404
405void BdtBeamParticleIdTool::SliceFeatureParameters::Initialize(const float larTPCMinX, const float larTPCMaxX, const float larTPCMinY,
406 const float larTPCMaxY, const float larTPCMinZ, const float larTPCMaxZ)
407{
408 m_larTPCMinX = larTPCMinX;
409 m_larTPCMaxX = larTPCMaxX;
410 m_larTPCMinY = larTPCMinY;
411 m_larTPCMaxY = larTPCMaxY;
412 m_larTPCMinZ = larTPCMinZ;
413 m_larTPCMaxZ = larTPCMaxZ;
414
415 const CartesianVector normalTop(0.f, 0.f, 1.f), pointTop(0.f, 0.f, m_larTPCMaxZ);
416 const CartesianVector normalBottom(0.f, 0.f, -1.f), pointBottom(0.f, 0.f, m_larTPCMinZ);
417 const CartesianVector normalRight(1.f, 0.f, 0.f), pointRight(m_larTPCMaxX, 0.f, 0.f);
418 const CartesianVector normalLeft(-1.f, 0.f, 0.f), pointLeft(m_larTPCMinX, 0.f, 0.f);
419 const CartesianVector normalBack(0.f, 1.f, 0.f), pointBack(0.f, m_larTPCMaxY, 0.f);
420 const CartesianVector normalFront(0.f, -1.f, 0.f), pointFront(0.f, m_larTPCMinY, 0.f);
421
422 m_larTPCPlanes.emplace_back(normalTop, pointTop);
423 m_larTPCPlanes.emplace_back(normalBottom, pointBottom);
424 m_larTPCPlanes.emplace_back(normalRight, pointRight);
425 m_larTPCPlanes.emplace_back(normalLeft, pointLeft);
426 m_larTPCPlanes.emplace_back(normalBack, pointBack);
427 m_larTPCPlanes.emplace_back(normalFront, pointFront);
428}
429
430//------------------------------------------------------------------------------------------------------------------------------------------
431//------------------------------------------------------------------------------------------------------------------------------------------
432
433BdtBeamParticleIdTool::SliceFeatures::SliceFeatures(const PfoList &pfosNu, const PfoList &pfosCr, const SliceFeatureParameters &sliceFeatureParameters) :
434 m_isAvailable(false),
435 m_sliceFeatureParameters(sliceFeatureParameters)
436{
437 try
438 {
439 double closestDistanceNu(std::numeric_limits<double>::max()), closestDistanceCr(std::numeric_limits<double>::max()),
440 supplementaryAngleToBeamNu(std::numeric_limits<double>::max()), supplementaryAngleToBeamCr(std::numeric_limits<double>::max()),
441 separationNu(std::numeric_limits<double>::max()), separationCr(std::numeric_limits<double>::max());
442 ;
443 CaloHitList caloHitList3DNu, caloHitList3DCr, selectedCaloHitListNu, selectedCaloHitListCr;
444 PfoList allConnectedPfoListNu, allConnectedPfoListCr;
445 LArPcaHelper::EigenValues eigenValuesNu(0.f, 0.f, 0.f);
446 LArPcaHelper::EigenValues eigenValuesCr(0.f, 0.f, 0.f);
447
448 LArPfoHelper::GetAllConnectedPfos(pfosNu, allConnectedPfoListNu);
449 LArPfoHelper::GetAllConnectedPfos(pfosCr, allConnectedPfoListCr);
450 LArPfoHelper::GetCaloHits(allConnectedPfoListNu, TPC_3D, caloHitList3DNu);
451 LArPfoHelper::GetCaloHits(allConnectedPfoListCr, TPC_3D, caloHitList3DCr);
452
453 this->GetLeadingCaloHits(caloHitList3DNu, selectedCaloHitListNu, closestDistanceNu);
454 this->GetLeadingCaloHits(caloHitList3DCr, selectedCaloHitListCr, closestDistanceCr);
455
456 if (!selectedCaloHitListNu.empty() && !selectedCaloHitListCr.empty())
457 {
458 float maxYNu(-std::numeric_limits<float>::max()), maxYCr(-std::numeric_limits<float>::max());
459 CartesianVector centroidNu(0.f, 0.f, 0.f), interceptOneNu(0.f, 0.f, 0.f), interceptTwoNu(0.f, 0.f, 0.f),
460 centroidCr(0.f, 0.f, 0.f), interceptOneCr(0.f, 0.f, 0.f), interceptTwoCr(0.f, 0.f, 0.f);
461
462 // Beam
463 LArPcaHelper::EigenVectors eigenVecsNu;
464 LArPcaHelper::RunPca(selectedCaloHitListNu, centroidNu, eigenValuesNu, eigenVecsNu);
465 const CartesianVector &majorAxisNu(eigenVecsNu.front());
466 supplementaryAngleToBeamNu = majorAxisNu.GetOpeningAngle(m_sliceFeatureParameters.GetBeamDirection());
467
468 this->GetLArTPCIntercepts(centroidNu, majorAxisNu, interceptOneNu, interceptTwoNu);
469 const double separationOneNu((interceptOneNu - m_sliceFeatureParameters.GetBeamLArTPCIntersection()).GetMagnitude());
470 const double separationTwoNu((interceptTwoNu - m_sliceFeatureParameters.GetBeamLArTPCIntersection()).GetMagnitude());
471 separationNu = std::min(separationOneNu, separationTwoNu);
472
473 // Cosmic
474 LArPcaHelper::EigenVectors eigenVecsCr;
475 LArPcaHelper::RunPca(selectedCaloHitListCr, centroidCr, eigenValuesCr, eigenVecsCr);
476 const CartesianVector &majorAxisCr(eigenVecsCr.front());
477 supplementaryAngleToBeamCr = majorAxisCr.GetOpeningAngle(m_sliceFeatureParameters.GetBeamDirection());
478
479 this->GetLArTPCIntercepts(centroidCr, majorAxisCr, interceptOneCr, interceptTwoCr);
480 const double separationOneCr((interceptOneCr - m_sliceFeatureParameters.GetBeamLArTPCIntersection()).GetMagnitude());
481 const double separationTwoCr((interceptTwoCr - m_sliceFeatureParameters.GetBeamLArTPCIntersection()).GetMagnitude());
482 separationCr = std::min(separationOneCr, separationTwoCr);
483
484 for (const CaloHit *pCaloHit : caloHitList3DNu)
485 {
486 if (maxYNu < pCaloHit->GetPositionVector().GetY())
487 maxYNu = pCaloHit->GetPositionVector().GetY();
488 }
489
490 for (const CaloHit *pCaloHit : caloHitList3DCr)
491 {
492 if (maxYCr < pCaloHit->GetPositionVector().GetY())
493 maxYCr = pCaloHit->GetPositionVector().GetY();
494 }
495
496 m_featureVector.push_back(closestDistanceNu);
497 m_featureVector.push_back(supplementaryAngleToBeamNu);
498 m_featureVector.push_back(separationNu);
499 m_featureVector.push_back(eigenValuesNu.GetX());
500 m_featureVector.push_back(eigenValuesNu.GetY());
501 m_featureVector.push_back(eigenValuesNu.GetZ());
502 m_featureVector.push_back(maxYNu);
503 m_featureVector.push_back(allConnectedPfoListNu.size());
504
505 m_featureVector.push_back(closestDistanceCr);
506 m_featureVector.push_back(supplementaryAngleToBeamCr);
507 m_featureVector.push_back(separationCr);
508 m_featureVector.push_back(eigenValuesCr.GetX());
509 m_featureVector.push_back(eigenValuesCr.GetY());
510 m_featureVector.push_back(eigenValuesCr.GetZ());
511 m_featureVector.push_back(maxYCr);
512 m_featureVector.push_back(allConnectedPfoListCr.size());
513
514 m_isAvailable = true;
515 }
516 }
517 catch (const StatusCodeException &)
518 {
519 return;
520 }
521}
522
523//------------------------------------------------------------------------------------------------------------------------------------------
524
526 const CaloHitList &inputCaloHitList, CaloHitList &outputCaloHitList, double &closestHitToFaceDistance) const
527{
528 if (inputCaloHitList.empty())
529 {
530 std::cout << "BdtBeamParticleIdTool::SliceFeatures::GetLeadingCaloHits - empty calo hit list" << std::endl;
531 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
532 }
533
534 typedef std::pair<const CaloHit *, float> HitDistancePair;
535 typedef std::vector<HitDistancePair> HitDistanceVector;
536 HitDistanceVector hitDistanceVector;
537
538 for (const CaloHit *const pCaloHit : inputCaloHitList)
539 hitDistanceVector.emplace_back(
540 pCaloHit, (pCaloHit->GetPositionVector() - m_sliceFeatureParameters.GetBeamLArTPCIntersection()).GetMagnitudeSquared());
541
542 std::sort(hitDistanceVector.begin(), hitDistanceVector.end(),
543 [](const HitDistancePair &lhs, const HitDistancePair &rhs) -> bool { return (lhs.second < rhs.second); });
544
545 if (hitDistanceVector.front().second < 0.f)
546 {
547 std::cout << "BdtBeamParticleIdTool::SliceFeatures::GetLeadingCaloHits - unphysical magnitude of a vector" << std::endl;
548 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
549 }
550
551 closestHitToFaceDistance = std::sqrt(hitDistanceVector.front().second);
552
553 const unsigned int nInputHits(inputCaloHitList.size());
554 const unsigned int nSelectedCaloHits(
556 ? nInputHits
557 : static_cast<unsigned int>(std::ceil(static_cast<float>(nInputHits) * m_sliceFeatureParameters.GetSelectedFraction() / 100.f)));
558
559 for (const HitDistancePair &hitDistancePair : hitDistanceVector)
560 {
561 outputCaloHitList.push_back(hitDistancePair.first);
562
563 if (outputCaloHitList.size() >= nSelectedCaloHits)
564 break;
565 }
566}
567
568//------------------------------------------------------------------------------------------------------------------------------------------
569
571 const CartesianVector &a0, const CartesianVector &lineDirection, CartesianVector &interceptOne, CartesianVector &interceptTwo) const
572{
573 CartesianPointVector intercepts;
574 CartesianVector lineUnitVector(0.f, 0.f, 0.f);
575
576 try
577 {
578 lineUnitVector = lineDirection.GetUnitVector();
579 }
580 catch (const StatusCodeException &statusCodeException)
581 {
582 std::cout << "BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - normal vector to plane has a magnitude of zero" << std::endl;
583 throw statusCodeException;
584 }
585
586 for (const Plane &plane : m_sliceFeatureParameters.GetPlanes())
587 {
588 const CartesianVector intercept(plane.GetLineIntersection(a0, lineUnitVector));
589
590 if (this->IsContained(intercept, m_sliceFeatureParameters.GetContainmentLimit()))
591 intercepts.push_back(intercept);
592 }
593
594 if (intercepts.size() > 1)
595 {
596 float maximumSeparationSquared(0.f);
597 bool interceptsSet(false);
598
599 for (unsigned int i = 0; i < intercepts.size(); i++)
600 {
601 for (unsigned int j = i + 1; j < intercepts.size(); j++)
602 {
603 const CartesianVector &candidateInterceptOne(intercepts.at(i));
604 const CartesianVector &candidateInterceptTwo(intercepts.at(j));
605 const float separationSquared((candidateInterceptOne - candidateInterceptTwo).GetMagnitudeSquared());
606
607 if (separationSquared > maximumSeparationSquared)
608 {
609 maximumSeparationSquared = separationSquared;
610 interceptOne = candidateInterceptOne;
611 interceptTwo = candidateInterceptTwo;
612 interceptsSet = true;
613 }
614 }
615 }
616
617 if (!interceptsSet)
618 {
619 std::cout << "BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - unable to set the intercepts between a line and the LArTPC"
620 << std::endl;
621 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
622 }
623 }
624 else
625 {
626 std::cout << "BdtBeamParticleIdTool::SliceFeatures::GetLArTPCIntercepts - inconsistent number of intercepts between a line and the LArTPC"
627 << std::endl;
628 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
629 }
630}
631
632//------------------------------------------------------------------------------------------------------------------------------------------
633
634bool BdtBeamParticleIdTool::SliceFeatures::IsContained(const CartesianVector &spacePoint, const float limit) const
635{
636 if ((m_sliceFeatureParameters.GetLArTPCMinX() - spacePoint.GetX() > limit) ||
637 (spacePoint.GetX() - m_sliceFeatureParameters.GetLArTPCMaxX() > limit) ||
638 (m_sliceFeatureParameters.GetLArTPCMinY() - spacePoint.GetY() > limit) ||
639 (spacePoint.GetY() - m_sliceFeatureParameters.GetLArTPCMaxY() > limit) ||
640 (m_sliceFeatureParameters.GetLArTPCMinZ() - spacePoint.GetZ() > limit) ||
641 (spacePoint.GetZ() - m_sliceFeatureParameters.GetLArTPCMaxZ() > limit))
642 {
643 return false;
644 }
645
646 return true;
647}
648
649//------------------------------------------------------------------------------------------------------------------------------------------
650
652{
653 if (!m_isAvailable)
654 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
655
656 if (!featureVector.empty())
657 {
658 std::cout << "BdtBeamParticleIdTool::SliceFeatures::FillFeatureVector - feature vector already populated" << std::endl;
659 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
660 }
661
662 featureVector.insert(featureVector.end(), m_featureVector.begin(), m_featureVector.end());
663}
664
665//------------------------------------------------------------------------------------------------------------------------------------------
666
668{
669 // ATTN if one or more of the features can not be calculated, then default to calling the slice a cosmic ray. -1.f is the minimum score
670 // possible for a weighted bdt.
671 if (!this->IsFeatureVectorAvailable())
672 return -1.f;
673
674 LArMvaHelper::MvaFeatureVector featureVector;
675
676 try
677 {
678 this->FillFeatureVector(featureVector);
679 }
680 catch (const StatusCodeException &statusCodeException)
681 {
682 std::cout << "BdtBeamParticleIdTool::SliceFeatures::GetAdaBoostDecisionTreeScore - unable to fill feature vector" << std::endl;
683 return -1.f;
684 }
685
686 return LArMvaHelper::CalculateClassificationScore(adaBoostDecisionTree, featureVector);
687}
688
689//------------------------------------------------------------------------------------------------------------------------------------------
690//------------------------------------------------------------------------------------------------------------------------------------------
691
693{
694 // BDT Settings
695 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "UseTrainingMode", m_useTrainingMode));
696
698 {
699 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "TrainingOutputFileName", m_trainingOutputFile));
700
701 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "CaloHitListName", m_caloHitListName));
702
703 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MCParticleListName", m_mcParticleListName));
704 }
705 else
706 {
707 std::string bdtName;
708 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "BdtName", bdtName));
709
710 std::string bdtFileName;
711 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "BdtFileName", bdtFileName));
712
713 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "MinAdaBDTScore", m_minAdaBDTScore));
714
715 const std::string fullBdtFileName(LArFileHelper::FindFileInPath(bdtFileName, m_filePathEnvironmentVariable));
716 const StatusCode statusCode(m_adaBoostDecisionTree.Initialize(fullBdtFileName, bdtName));
717
718 if (STATUS_CODE_SUCCESS != statusCode)
719 {
720 std::cout << "BdtBeamParticleIdTool::ReadSettings - unable to load bdt" << std::endl;
721 return statusCode;
722 }
723 }
724
725 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinimumPurity", m_minPurity));
726
728 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinimumCompleteness", m_minCompleteness));
729
730 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
731 XmlHelper::ReadValue(xmlHandle, "FilePathEnvironmentVariable", m_filePathEnvironmentVariable));
732
733 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaximumNeutrinos", m_maxNeutrinos));
734
735 // Geometry Information for training
736 FloatVector beamLArTPCIntersection;
737 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
738 XmlHelper::ReadVectorOfValues(xmlHandle, "BeamTPCIntersection", beamLArTPCIntersection));
739
740 if (3 == beamLArTPCIntersection.size())
741 {
742 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(
743 beamLArTPCIntersection.at(0), beamLArTPCIntersection.at(1), beamLArTPCIntersection.at(2));
744 m_sliceFeatureParameters.SetBeamLArTPCIntersection(beamLArTPCIntersectionCartesianVector);
745 }
746 else if (!beamLArTPCIntersection.empty())
747 {
748 std::cout << "BdtBeamParticleIdTool::ReadSettings - invalid BeamTPCIntersection specified " << std::endl;
749 return STATUS_CODE_INVALID_PARAMETER;
750 }
751 else
752 {
753 // Default for protoDUNE.
754 pandora::CartesianVector beamLArTPCIntersectionCartesianVector(-33.051f, 461.06f, 0.f);
755 m_sliceFeatureParameters.SetBeamLArTPCIntersection(beamLArTPCIntersectionCartesianVector);
756 }
757
758 FloatVector beamDirection;
760 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadVectorOfValues(xmlHandle, "BeamDirection", beamDirection));
761
762 if (3 == beamDirection.size())
763 {
764 CartesianVector beamDirectionCartesianVector(beamDirection.at(0), beamDirection.at(1), beamDirection.at(2));
765 m_sliceFeatureParameters.SetBeamDirection(beamDirectionCartesianVector);
766 }
767 else if (!beamDirection.empty())
768 {
769 std::cout << "BdtBeamParticleIdTool::ReadSettings - invalid BeamDirection specified " << std::endl;
770 return STATUS_CODE_INVALID_PARAMETER;
771 }
772 else
773 {
774 // Default for protoDUNE.
775 const float thetaXZ0(-11.844f * M_PI / 180.f);
776 CartesianVector beamDirectionCartesianVector(std::sin(thetaXZ0), 0.f, std::cos(thetaXZ0));
777 m_sliceFeatureParameters.SetBeamDirection(beamDirectionCartesianVector);
778 }
779
780 float selectedFraction(0.f);
781
782 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SelectedFraction", selectedFraction));
783
784 if (selectedFraction > std::numeric_limits<float>::epsilon())
786
787 unsigned int nSelectedHits(0);
788
789 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NSelectedHits", nSelectedHits));
790
791 if (nSelectedHits > 0)
793
794 float containmentLimit(0.f);
795
796 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "ContainmentLimit", containmentLimit));
797
798 if (containmentLimit < 0.f)
799 {
800 std::cout << "BdtBeamParticleIdTool::ReadSettings - invalid ContainmentLimit specified " << std::endl;
801 return STATUS_CODE_INVALID_PARAMETER;
802 }
803 else if (containmentLimit > 0.f)
804 {
806 }
807
808 return STATUS_CODE_SUCCESS;
809}
810
811} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the beam particle id tool class.
Header file for the file helper class.
Header file for the lar monte carlo particle helper helper class.
Header file for the principal curve analysis helper class.
Header file for the pfo helper class.
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:43
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:19
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
pandora::StatusCode Initialize(const std::string &parameterLocation, const std::string &bdtName)
Initialize the bdt model.
pandora::CartesianVector m_unitNormal
Unit normal to plane.
Plane(const pandora::CartesianVector &normal, const pandora::CartesianVector &point)
Constructor, using equation of plane: m_a*x + m_b*y + m_c*z + m_d = 0.
pandora::CartesianVector GetLineIntersection(const pandora::CartesianVector &point, const pandora::CartesianVector &direction) const
Return the intersection between the plane and a line.
void SetBeamDirection(const pandora::CartesianVector &beamDirection)
Set m_beamDirection.
void SetBeamLArTPCIntersection(const pandora::CartesianVector &beamLArTPCIntersection)
Set m_beamLArTPCIntersection.
const pandora::CartesianVector & GetBeamDirection() const
Get the beam direction.
const pandora::CartesianVector & GetBeamLArTPCIntersection() const
Get the beam LArTPC intersection.
const PlaneVector & GetPlanes() const
Get vector of planes.
void SetNSelectedHits(const unsigned int nSelectedHits)
Set m_nSelectedHits.
void SetContainmentLimit(const float containmentLimit)
Set m_containmentLimit.
void Initialize(const float larTPCMinX, const float larTPCMaxX, const float larTPCMinY, const float larTPCMaxY, const float larTPCMinZ, const float larTPCMaxZ)
Set LArTPC geometry information.
void SetSelectedFraction(const float selectedFraction)
Set m_selectedFraction.
void GetLeadingCaloHits(const pandora::CaloHitList &inputCaloHitList, pandora::CaloHitList &outputCaloHitList, double &closestHitToFaceDistance) const
Select a given fraction of a slice's calo hits that are closest to the beam spot.
const SliceFeatureParameters m_sliceFeatureParameters
Geometry information block.
bool m_isAvailable
Is the feature vector available.
bool IsFeatureVectorAvailable() const
Check if all features were calculable.
SliceFeatures(const pandora::PfoList &nuPfos, const pandora::PfoList &crPfos, const SliceFeatureParameters &sliceFeatureParameters)
Constructor.
float GetAdaBoostDecisionTreeScore(const AdaBoostDecisionTree &adaBoostDecisionTree) const
Get the probability that this slice contains a beam particle.
bool IsContained(const pandora::CartesianVector &spacePoint, const float limit) const
Check if a given 3D spacepoint is inside the global LArTPC volume.
void FillFeatureVector(LArMvaHelper::MvaFeatureVector &featureVector) const
Get the feature vector for the SVM.
void GetLArTPCIntercepts(const pandora::CartesianVector &a0, const pandora::CartesianVector &majorAxis, pandora::CartesianVector &interceptOne, pandora::CartesianVector &interceptTwo) const
Find the intercepts of a line with the protoDUNE detector.
LArMvaHelper::MvaFeatureVector m_featureVector
The MVA feature vector.
bool m_useTrainingMode
Should use training mode. If true, training examples will be written to the output file.
void SelectPfos(const pandora::PfoList &pfos, pandora::PfoList &selectedPfos) const
Add the given pfos to the selected Pfo list.
AdaBoostDecisionTree m_adaBoostDecisionTree
The adaptive boost decision tree.
pandora::StatusCode Initialize()
Perform any operations that must occur after reading settings, but before running the process.
void Collect2DHits(const pandora::PfoList &pfos, pandora::CaloHitList &caloHitList, const pandora::CaloHitSet &reconstructableCaloHitSet) const
Collect all 2D hits in a supplied list of Pfos and push them on to an existing hit list,...
void SelectPfosByAdaBDTScore(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses, const SliceFeaturesVector &sliceFeaturesVector, pandora::PfoList &selectedPfos) const
Select pfos based on the AdaBDT score that the slice contains a beam particle interaction.
SliceFeatureParameters m_sliceFeatureParameters
Geometry information block.
void SelectAllPfos(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &hypotheses, pandora::PfoList &selectedPfos) const
Select all pfos under the same hypothesis.
float m_minPurity
Minimum purity of the best slice to use event for training.
std::string m_mcParticleListName
Name of input MC particle list.
void GetSliceFeatures(const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses, SliceFeaturesVector &sliceFeaturesVector) const
Get the features of each slice.
unsigned int m_maxNeutrinos
The maximum number of neutrinos to select in any one event.
std::string m_caloHitListName
Name of input calo hit list.
bool PassesQualityCuts(const float purity, const float completeness) const
Determine if the event passes the selection cuts for training.
std::unordered_map< const pandora::MCParticle *, int > MCParticleToIntMap
float m_minAdaBDTScore
Minimum score required to classify a slice as a beam particle.
void GetBestMCSliceIndices(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses, pandora::IntVector &bestSliceIndices) const
Get the slice with the most neutrino induced hits using Monte-Carlo information.
std::string m_trainingOutputFile
Output file name for training examples.
std::pair< unsigned int, float > UintFloatPair
void PopulateMCParticleToHitsMap(MCParticleToIntMap &mcParticleToIntMap, const pandora::CaloHitList &caloHitList) const
Fill mc particle to nHits map from calo hit list.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
std::string m_filePathEnvironmentVariable
The environment variable providing a list of paths to bdt files.
void SelectOutputPfos(const pandora::Algorithm *const pAlgorithm, const SliceHypotheses &beamSliceHypotheses, const SliceHypotheses &crSliceHypotheses, pandora::PfoList &selectedPfos)
Select which reconstruction hypotheses to use; neutrino outcomes or cosmic-ray muon outcomes for each...
std::vector< SliceFeatures > SliceFeaturesVector
float m_minCompleteness
Minimum completeness of the best slice to use event for training.
static std::string FindFileInPath(const std::string &unqualifiedFileName, const std::string &environmentVariable, const std::string &delimiter=":")
Find the fully-qualified file name by searching through a list of delimiter-separated paths in a name...
float m_maxPhotonPropagation
the maximum photon propagation length
static unsigned int GetNuanceCode(const pandora::MCParticle *const pMCParticle)
Get the nuance code of an MCParticle.
static const pandora::MCParticle * GetParentMCParticle(const pandora::MCParticle *const pMCParticle)
Get the parent mc particle.
static void SelectCaloHits(const pandora::CaloHitList *const pCaloHitList, const MCRelationMap &mcToTargetMCMap, pandora::CaloHitList &selectedCaloHitList, const bool selectInputHits, const float maxPhotonPropagation)
Select a subset of calo hits representing those that represent "reconstructable" regions of the event...
std::unordered_map< const pandora::MCParticle *, const pandora::MCParticle * > MCRelationMap
static void GetMCPrimaryMap(const pandora::MCParticleList *const pMCParticleList, MCRelationMap &mcPrimaryMap)
Get mapping from individual mc particles (in a provided list) and their primary parent mc particles.
MvaTypes::MvaFeatureVector MvaFeatureVector
static double CalculateClassificationScore(const MvaInterface &classifier, TCONTAINER &&featureContainer)
Use the trained classifer to calculate the classification score of an example (>0 means boolean class...
static pandora::StatusCode ProduceTrainingExample(const std::string &trainingOutputFile, const bool result, TCONTAINER &&featureContainer)
Produce a training example with the given features and result.
std::vector< pandora::CartesianVector > EigenVectors
static void RunPca(const T &t, pandora::CartesianVector &centroid, EigenValues &outputEigenValues, EigenVectors &outputEigenVectors)
Run principal component analysis using input calo hits (TPC_VIEW_U,V,W or TPC_3D; all treated as 3D p...
static void GetAllConnectedPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively including all daughters and parents associated with those pf...
static void GetCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of calo hits of a particular hit type from a list of pfos.
Algorithm class. Algorithm addresses are held only by the algorithm manager. They have a fully define...
Definition Algorithm.h:21
CaloHit class.
Definition CaloHit.h:26
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
CartesianVector GetUnitVector() const
Get a unit vector in the direction of the cartesian vector.
float GetZ() const
Get the cartesian z coordinate.
float GetDotProduct(const CartesianVector &rhs) const
Get the dot product of the cartesian vector with a second cartesian vector.
float GetOpeningAngle(const CartesianVector &rhs) const
Get the opening angle of the cartesian vector with respect to a second cartesian vector.
float GetY() const
Get the cartesian y coordinate.
LArTPC class.
Definition LArTPC.h:26
float GetCenterY() const
Get center in y, units mm.
Definition LArTPC.h:182
float GetWidthZ() const
Get the width in z, units mm.
Definition LArTPC.h:210
float GetCenterZ() const
Get center in z, units mm.
Definition LArTPC.h:189
float GetCenterX() const
Get center in x, units mm.
Definition LArTPC.h:175
float GetWidthX() const
Get the width in x, units mm.
Definition LArTPC.h:196
float GetWidthY() const
Get the width in y, units mm.
Definition LArTPC.h:203
static const MCParticle * GetMainMCParticle(const T *const pT)
Find the mc particle making the largest contribution to a specified calo hit, track or cluster.
MCParticle class.
Definition MCParticle.h:26
ParticleFlowObject class.
StatusCode AlterMetadata(const object_creation::ParticleFlowObject::Metadata &metadata)
Alter particle flow object metadata parameters.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
StatusCodeException class.
StatusCode GetStatusCode() const
Get status code.
static StatusCode ReadVectorOfValues(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, std::vector< T > &vector)
Read a vector of values from a (space separated) list in an xml element.
Definition XmlHelper.h:229
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
std::vector< pandora::PfoList > SliceHypotheses
MANAGED_CONTAINER< const MCParticle * > MCParticleList
std::vector< int > IntVector
std::vector< CartesianVector > CartesianPointVector
std::unordered_set< const CaloHit * > CaloHitSet
std::map< unsigned int, const LArTPC * > LArTPCMap
MANAGED_CONTAINER< const CaloHit * > CaloHitList
std::vector< float > FloatVector
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList