Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
MasterAlgorithm.cc
Go to the documentation of this file.
1
9#include "Api/PandoraApi.h"
10
12
15
21
24
27
29
30using namespace pandora;
31
32namespace lar_content
33{
34
36 m_workerInstancesInitialized(false),
37 m_larCaloHitVersion(1),
38 m_shouldRunAllHitsCosmicReco(true),
39 m_shouldRunStitching(true),
40 m_shouldRunCosmicHitRemoval(true),
41 m_shouldRunSlicing(true),
42 m_shouldRunNeutrinoRecoOption(true),
43 m_shouldRunCosmicRecoOption(true),
44 m_shouldPerformSliceId(true),
45 m_printOverallRecoStatus(false),
46 m_visualizeOverallRecoStatus(false),
47 m_shouldRemoveOutOfTimeHits(true),
48 m_pSlicingWorkerInstance(nullptr),
49 m_pSliceNuWorkerInstance(nullptr),
50 m_pSliceCRWorkerInstance(nullptr),
51 m_fullWidthCRWorkerWireGaps(true),
52 m_passMCParticlesToWorkerInstances(false),
53 m_filePathEnvironmentVariable("FW_SEARCH_PATH"),
54 m_inTimeMaxX0(1.f)
55{
56}
57
58//------------------------------------------------------------------------------------------------------------------------------------------
59
60void MasterAlgorithm::ShiftPfoHierarchy(const ParticleFlowObject *const pParentPfo, const PfoToLArTPCMap &pfoToLArTPCMap, const float x0) const
61{
62 if (!pParentPfo->GetParentPfoList().empty())
63 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
64
65 PfoToLArTPCMap::const_iterator larTPCIter(pfoToLArTPCMap.find(pParentPfo));
66
67 if (pfoToLArTPCMap.end() == larTPCIter)
68 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
69
70 PfoList pfoList;
71 LArPfoHelper::GetAllDownstreamPfos(pParentPfo, pfoList);
72
74 {
75 std::cout << "ShiftPfoHierarchy: x0 " << x0 << std::endl;
76 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &pfoList, "BeforeShiftCRPfos", GREEN));
77 }
78
79 for (const ParticleFlowObject *const pDaughterPfo : pfoList)
80 {
81 CaloHitList caloHitList;
82 for (const Cluster *const pCluster : pDaughterPfo->GetClusterList())
83 {
84 pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
85 caloHitList.insert(caloHitList.end(), pCluster->GetIsolatedCaloHitList().begin(), pCluster->GetIsolatedCaloHitList().end());
86 }
87
88 for (const CaloHit *const pCaloHit : caloHitList)
89 {
90 PandoraContentApi::CaloHit::Metadata metadata;
91 metadata.m_x0 = x0;
92 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CaloHit::AlterMetadata(*this, pCaloHit, metadata));
93 }
94
95 for (const Vertex *const pVertex : pDaughterPfo->GetVertexList())
96 {
97 PandoraContentApi::Vertex::Metadata metadata;
98 metadata.m_x0 = x0;
99 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::AlterMetadata(*this, pVertex, metadata));
100 }
101 }
102
104 {
105 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &pfoList, "AfterShiftCRPfos", RED));
106 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
107 }
108}
109
110//------------------------------------------------------------------------------------------------------------------------------------------
111
113 const ParticleFlowObject *const pPfoToEnlarge, const ParticleFlowObject *const pPfoToDelete, PfoToLArTPCMap &pfoToLArTPCMap) const
114{
115 if (pPfoToEnlarge == pPfoToDelete)
116 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
117
118 // ATTN Remove pfos from pfo to lar tpc map here, avoiding problems if stitching across multiple tpcs.
119 pfoToLArTPCMap.erase(pPfoToEnlarge);
120 pfoToLArTPCMap.erase(pPfoToDelete);
121
122 const PfoList daughterPfos(pPfoToDelete->GetDaughterPfoList());
123 const ClusterVector daughterClusters(pPfoToDelete->GetClusterList().begin(), pPfoToDelete->GetClusterList().end());
124 const VertexVector daughterVertices(pPfoToDelete->GetVertexList().begin(), pPfoToDelete->GetVertexList().end());
125
126 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, pPfoToDelete, m_recreatedPfoListName));
127
128 for (const ParticleFlowObject *const pDaughterPfo : daughterPfos)
129 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pPfoToEnlarge, pDaughterPfo));
130
131 for (const Vertex *const pDaughterVertex : daughterVertices)
132 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, pDaughterVertex, m_recreatedVertexListName));
133
134 for (const Cluster *const pDaughterCluster : daughterClusters)
135 {
136 const HitType daughterHitType(LArClusterHelper::GetClusterHitType(pDaughterCluster));
137 const Cluster *pParentCluster(PfoMopUpBaseAlgorithm::GetParentCluster(pPfoToEnlarge->GetClusterList(), daughterHitType));
138
139 if (pParentCluster)
140 {
141 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
143 }
144 else
145 {
146 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo(*this, pPfoToEnlarge, pDaughterCluster));
147 }
148 }
149}
150
151//------------------------------------------------------------------------------------------------------------------------------------------
152
154{
155 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Reset());
156
158 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->InitializeWorkerInstances());
159
161 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->CopyMCParticles());
162
163 PfoToFloatMap stitchedPfosToX0Map;
164 VolumeIdToHitListMap volumeIdToHitListMap;
165 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->GetVolumeIdToHitListMap(volumeIdToHitListMap));
166
168 {
169 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RunCosmicRayReconstruction(volumeIdToHitListMap));
170
171 PfoToLArTPCMap pfoToLArTPCMap;
172 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RecreateCosmicRayPfos(pfoToLArTPCMap));
173
175 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->StitchCosmicRayPfos(pfoToLArTPCMap, stitchedPfosToX0Map));
176 }
177
179 {
180 PfoList clearCosmicRayPfos, ambiguousPfos;
181 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->TagCosmicRayPfos(stitchedPfosToX0Map, clearCosmicRayPfos, ambiguousPfos));
182 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RunCosmicRayHitRemoval(ambiguousPfos));
183 }
184
185 SliceVector sliceVector;
186 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RunSlicing(volumeIdToHitListMap, sliceVector));
187
189 {
190 SliceHypotheses nuSliceHypotheses, crSliceHypotheses;
191 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RunSliceReconstruction(sliceVector, nuSliceHypotheses, crSliceHypotheses));
192 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->SelectBestSliceHypotheses(nuSliceHypotheses, crSliceHypotheses));
193 }
194
195 return STATUS_CODE_SUCCESS;
196}
197
198//------------------------------------------------------------------------------------------------------------------------------------------
199
201{
202 // ATTN Used to be in the regular Initialize callback, but detector gap list cannot be extracted in client app before the first event
204 return STATUS_CODE_ALREADY_INITIALIZED;
205
206 try
207 {
208 const LArTPCMap &larTPCMap(this->GetPandora().GetGeometry()->GetLArTPCMap());
209 const DetectorGapList &gapList(this->GetPandora().GetGeometry()->GetDetectorGapList());
210
211 for (const LArTPCMap::value_type &mapEntry : larTPCMap)
212 {
213 const unsigned int volumeId(mapEntry.second->GetLArTPCVolumeId());
214 m_crWorkerInstances.push_back(
215 this->CreateWorkerInstance(*(mapEntry.second), gapList, m_crSettingsFile, "CRWorkerInstance" + std::to_string(volumeId)));
216 }
217
219 m_pSlicingWorkerInstance = this->CreateWorkerInstance(larTPCMap, gapList, m_slicingSettingsFile, "SlicingWorker");
220
222 m_pSliceNuWorkerInstance = this->CreateWorkerInstance(larTPCMap, gapList, m_nuSettingsFile, "SliceNuWorker");
223
225 m_pSliceCRWorkerInstance = this->CreateWorkerInstance(larTPCMap, gapList, m_crSettingsFile, "SliceCRWorker");
226 }
227 catch (const StatusCodeException &statusCodeException)
228 {
229 std::cout << "MasterAlgorithm: Exception during initialization of worker instances " << statusCodeException.ToString() << std::endl;
230 return statusCodeException.GetStatusCode();
231 }
232
234 return STATUS_CODE_SUCCESS;
235}
236
237//------------------------------------------------------------------------------------------------------------------------------------------
238
240{
241 const MCParticleList *pMCParticleList(nullptr);
242 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_inputMCParticleListName, pMCParticleList));
243
244 PandoraInstanceList pandoraWorkerInstances(m_crWorkerInstances);
246 pandoraWorkerInstances.push_back(m_pSlicingWorkerInstance);
248 pandoraWorkerInstances.push_back(m_pSliceNuWorkerInstance);
250 pandoraWorkerInstances.push_back(m_pSliceCRWorkerInstance);
251
252 LArMCParticleFactory mcParticleFactory;
253
254 for (const Pandora *const pPandoraWorker : pandoraWorkerInstances)
255 {
256 for (const MCParticle *const pMCParticle : *pMCParticleList)
257 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Copy(pPandoraWorker, pMCParticle, &mcParticleFactory));
258 }
259
260 return STATUS_CODE_SUCCESS;
261}
262
263//------------------------------------------------------------------------------------------------------------------------------------------
264
266{
267 const LArTPCMap &larTPCMap(this->GetPandora().GetGeometry()->GetLArTPCMap());
268 const unsigned int nLArTPCs(larTPCMap.size());
269
270 const CaloHitList *pCaloHitList(nullptr);
271 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::GetList(*this, m_inputHitListName, pCaloHitList));
272
273 for (const CaloHit *const pCaloHit : *pCaloHitList)
274 {
275 const LArCaloHit *const pLArCaloHit(dynamic_cast<const LArCaloHit *>(pCaloHit));
276
277 if (!pLArCaloHit && (1 != nLArTPCs))
278 return STATUS_CODE_INVALID_PARAMETER;
279
280 const unsigned int volumeId(pLArCaloHit ? pLArCaloHit->GetLArTPCVolumeId() : 0);
281 const LArTPC *const pLArTPC(larTPCMap.at(volumeId));
282
283 LArTPCHitList &larTPCHitList(volumeIdToHitListMap[volumeId]);
284 larTPCHitList.m_allHitList.push_back(pCaloHit);
285
286 if (((pCaloHit->GetPositionVector().GetX() >= (pLArTPC->GetCenterX() - 0.5f * pLArTPC->GetWidthX())) &&
287 (pCaloHit->GetPositionVector().GetX() <= (pLArTPC->GetCenterX() + 0.5f * pLArTPC->GetWidthX()))))
288 {
289 larTPCHitList.m_truncatedHitList.push_back(pCaloHit);
290 }
291 }
292
293 return STATUS_CODE_SUCCESS;
294}
295
296//------------------------------------------------------------------------------------------------------------------------------------------
297
299{
300 unsigned int workerCounter(0);
301
302 for (const Pandora *const pCRWorker : m_crWorkerInstances)
303 {
304 const LArTPC &larTPC(pCRWorker->GetGeometry()->GetLArTPC());
305 VolumeIdToHitListMap::const_iterator iter(volumeIdToHitListMap.find(larTPC.GetLArTPCVolumeId()));
306
307 if (volumeIdToHitListMap.end() == iter)
308 continue;
309
310 for (const CaloHit *const pCaloHit : iter->second.m_allHitList)
311 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Copy(pCRWorker, pCaloHit));
312
314 std::cout << "Running cosmic-ray reconstruction worker instance " << ++workerCounter << " of " << m_crWorkerInstances.size() << std::endl;
315
316 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::ProcessEvent(*pCRWorker));
317 }
318
319 return STATUS_CODE_SUCCESS;
320}
321
322//------------------------------------------------------------------------------------------------------------------------------------------
323
325{
326 for (const Pandora *const pCRWorker : m_crWorkerInstances)
327 {
328 const PfoList *pCRPfos(nullptr);
329 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(*pCRWorker, pCRPfos));
330
331 PfoList newPfoList;
332 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Recreate(*pCRPfos, newPfoList));
333
334 const LArTPC &larTPC(pCRWorker->GetGeometry()->GetLArTPC());
335
336 for (const Pfo *const pNewPfo : newPfoList)
337 pfoToLArTPCMap[pNewPfo] = &larTPC;
338 }
339
340 return STATUS_CODE_SUCCESS;
341}
342
343//------------------------------------------------------------------------------------------------------------------------------------------
344
346{
347 const PfoList *pRecreatedCRPfos(nullptr);
348 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(this->GetPandora(), pRecreatedCRPfos));
349
351 {
352 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), pRecreatedCRPfos, "RecreatedCRPfos", GREEN));
353 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
354 }
355
356 for (StitchingBaseTool *const pStitchingTool : m_stitchingToolVector)
357 pStitchingTool->Run(this, pRecreatedCRPfos, pfoToLArTPCMap, stitchedPfosToX0Map);
358
360 {
361 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), pRecreatedCRPfos, "AfterStitchingCRPfos", RED));
362 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
363 }
364
365 return STATUS_CODE_SUCCESS;
366}
367
368//------------------------------------------------------------------------------------------------------------------------------------------
369
370StatusCode MasterAlgorithm::TagCosmicRayPfos(const PfoToFloatMap &stitchedPfosToX0Map, PfoList &clearCosmicRayPfos, PfoList &ambiguousPfos) const
371{
372 const PfoList *pRecreatedCRPfos(nullptr);
373 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(this->GetPandora(), pRecreatedCRPfos));
374
375 PfoList nonStitchedParentCosmicRayPfos;
376 for (const Pfo *const pPfo : *pRecreatedCRPfos)
377 {
378 if (!pPfo->GetParentPfoList().empty())
379 continue;
380
381 PfoToFloatMap::const_iterator pfoToX0Iter = stitchedPfosToX0Map.find(pPfo);
382 const float x0Shift((pfoToX0Iter != stitchedPfosToX0Map.end()) ? pfoToX0Iter->second : 0.f);
383 PfoList &targetList((std::fabs(x0Shift) > m_inTimeMaxX0) ? clearCosmicRayPfos : nonStitchedParentCosmicRayPfos);
384 targetList.push_back(pPfo);
385 }
386
387 for (CosmicRayTaggingBaseTool *const pCosmicRayTaggingTool : m_cosmicRayTaggingToolVector)
388 pCosmicRayTaggingTool->FindAmbiguousPfos(nonStitchedParentCosmicRayPfos, ambiguousPfos, this);
389
390 for (const Pfo *const pPfo : nonStitchedParentCosmicRayPfos)
391 {
392 const bool isClearCosmic(ambiguousPfos.end() == std::find(ambiguousPfos.begin(), ambiguousPfos.end(), pPfo));
393
394 if (isClearCosmic)
395 clearCosmicRayPfos.push_back(pPfo);
396 }
397
398 for (const Pfo *const pPfo : *pRecreatedCRPfos)
399 {
400 const bool isClearCosmic(ambiguousPfos.end() == std::find(ambiguousPfos.begin(), ambiguousPfos.end(), pPfo));
401 PandoraContentApi::ParticleFlowObject::Metadata metadata;
402 metadata.m_propertiesToAdd["IsClearCosmic"] = (isClearCosmic ? 1.f : 0.f);
403 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pPfo, metadata));
404 }
405
407 {
408 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &clearCosmicRayPfos, "ClearCRPfos", RED));
409 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), &ambiguousPfos, "AmbiguousCRPfos", BLUE));
410 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
411 }
412
413 return STATUS_CODE_SUCCESS;
414}
415
416//------------------------------------------------------------------------------------------------------------------------------------------
417
419{
420 PfoList allPfosToDelete;
421 LArPfoHelper::GetAllConnectedPfos(ambiguousPfos, allPfosToDelete);
422
423 for (const Pfo *const pPfoToDelete : allPfosToDelete)
424 {
425 const ClusterList clusterList(pPfoToDelete->GetClusterList());
426 const VertexList vertexList(pPfoToDelete->GetVertexList());
427
428 // ATTN: If an ambiguous pfo has been stitched, reset the calo hit positions in preparation for subsequent algorithm chains
430 {
431 CaloHitList caloHitList2D;
432 LArPfoHelper::GetCaloHits(pPfoToDelete, TPC_VIEW_U, caloHitList2D);
433 LArPfoHelper::GetCaloHits(pPfoToDelete, TPC_VIEW_V, caloHitList2D);
434 LArPfoHelper::GetCaloHits(pPfoToDelete, TPC_VIEW_W, caloHitList2D);
435 LArPfoHelper::GetIsolatedCaloHits(pPfoToDelete, TPC_VIEW_U, caloHitList2D);
436 LArPfoHelper::GetIsolatedCaloHits(pPfoToDelete, TPC_VIEW_V, caloHitList2D);
437 LArPfoHelper::GetIsolatedCaloHits(pPfoToDelete, TPC_VIEW_W, caloHitList2D);
438
439 for (const CaloHit *const pCaloHit : caloHitList2D)
440 {
441 PandoraContentApi::CaloHit::Metadata metadata;
442 metadata.m_x0 = 0.f;
443 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CaloHit::AlterMetadata(*this, pCaloHit, metadata));
444 }
445 }
446
447 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, pPfoToDelete));
448 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, &clusterList));
449 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Delete(*this, &vertexList));
450 }
451
452 return STATUS_CODE_SUCCESS;
453}
454
455//------------------------------------------------------------------------------------------------------------------------------------------
456
457StatusCode MasterAlgorithm::RunSlicing(const VolumeIdToHitListMap &volumeIdToHitListMap, SliceVector &sliceVector) const
458{
459 for (const VolumeIdToHitListMap::value_type &mapEntry : volumeIdToHitListMap)
460 {
461 for (const CaloHit *const pCaloHit : (m_shouldRemoveOutOfTimeHits ? mapEntry.second.m_truncatedHitList : mapEntry.second.m_allHitList))
462 {
463 if (!PandoraContentApi::IsAvailable(*this, pCaloHit))
464 continue;
465
466 const HitType hitType(pCaloHit->GetHitType());
467 if ((TPC_VIEW_U != hitType) && (TPC_VIEW_V != hitType) && (TPC_VIEW_W != hitType))
468 continue;
469
471 {
472 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Copy(m_pSlicingWorkerInstance, pCaloHit));
473 }
474 else
475 {
476 if (sliceVector.empty())
477 sliceVector.push_back(CaloHitList());
478 sliceVector.back().push_back(pCaloHit);
479 }
480 }
481 }
482
484 {
486 std::cout << "Running slicing worker instance" << std::endl;
487
488 const PfoList *pSlicePfos(nullptr);
491
493 {
494 PANDORA_MONITORING_API(VisualizeParticleFlowObjects(this->GetPandora(), pSlicePfos, "OnePfoPerSlice", BLUE));
495 PANDORA_MONITORING_API(ViewEvent(this->GetPandora()));
496 }
497
498 for (const Pfo *const pSlicePfo : *pSlicePfos)
499 {
500 sliceVector.push_back(CaloHitList());
501 LArPfoHelper::GetCaloHits(pSlicePfo, TPC_VIEW_U, sliceVector.back());
502 LArPfoHelper::GetCaloHits(pSlicePfo, TPC_VIEW_V, sliceVector.back());
503 LArPfoHelper::GetCaloHits(pSlicePfo, TPC_VIEW_W, sliceVector.back());
504 }
505 }
506
508 std::cout << "Identified " << sliceVector.size() << " slice(s)" << std::endl;
509
510 return STATUS_CODE_SUCCESS;
511}
512
513//------------------------------------------------------------------------------------------------------------------------------------------
514
515StatusCode MasterAlgorithm::RunSliceReconstruction(SliceVector &sliceVector, SliceHypotheses &nuSliceHypotheses, SliceHypotheses &crSliceHypotheses) const
516{
517 SliceVector selectedSliceVector;
519 {
520 SliceVector inputSliceVector(sliceVector);
521 for (SliceSelectionBaseTool *const pSliceSelectionTool : m_sliceSelectionToolVector)
522 {
523 pSliceSelectionTool->SelectSlices(this, inputSliceVector, selectedSliceVector);
524 inputSliceVector = selectedSliceVector;
525 }
526 }
527 else
528 {
529 selectedSliceVector = std::move(sliceVector);
530 }
531
532 unsigned int sliceCounter(0);
533
534 for (const CaloHitList &sliceHits : selectedSliceVector)
535 {
536 for (const CaloHit *const pSliceCaloHit : sliceHits)
537 {
538 // ATTN Must ensure we copy the hit actually owned by master instance; access differs with/without slicing enabled
539 const CaloHit *const pCaloHitInMaster(m_shouldRunSlicing ? static_cast<const CaloHit *>(pSliceCaloHit->GetParentAddress()) : pSliceCaloHit);
540
542 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Copy(m_pSliceNuWorkerInstance, pCaloHitInMaster));
543
545 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Copy(m_pSliceCRWorkerInstance, pCaloHitInMaster));
546 }
547
549 {
551 std::cout << "Running nu worker instance for slice " << (sliceCounter + 1) << " of " << selectedSliceVector.size() << std::endl;
552
553 const PfoList *pSliceNuPfos(nullptr);
556 nuSliceHypotheses.push_back(*pSliceNuPfos);
557
558 for (const ParticleFlowObject *const pPfo : *pSliceNuPfos)
559 {
560 PandoraContentApi::ParticleFlowObject::Metadata metadata;
561 metadata.m_propertiesToAdd["SliceIndex"] = sliceCounter;
562 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pPfo, metadata));
563 }
564 }
565
567 {
569 std::cout << "Running cr worker instance for slice " << (sliceCounter + 1) << " of " << selectedSliceVector.size() << std::endl;
570
571 const PfoList *pSliceCRPfos(nullptr);
574 crSliceHypotheses.push_back(*pSliceCRPfos);
575
576 for (const ParticleFlowObject *const pPfo : *pSliceCRPfos)
577 {
578 PandoraContentApi::ParticleFlowObject::Metadata metadata;
579 metadata.m_propertiesToAdd["SliceIndex"] = sliceCounter;
580 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pPfo, metadata));
581 }
582 }
583
584 ++sliceCounter;
585 }
586
587 // ATTN: If we swapped these objects at the start, be sure to swap them back in case we ever want to use sliceVector
588 // after this function
590 sliceVector = std::move(selectedSliceVector);
591
592 if (m_shouldRunNeutrinoRecoOption && m_shouldRunCosmicRecoOption && (nuSliceHypotheses.size() != crSliceHypotheses.size()))
593 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
594
595 return STATUS_CODE_SUCCESS;
596}
597
598//------------------------------------------------------------------------------------------------------------------------------------------
599
600StatusCode MasterAlgorithm::SelectBestSliceHypotheses(const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses) const
601{
603 std::cout << "Select best slice hypotheses" << std::endl;
604
605 PfoList selectedSlicePfos;
606
608 {
609 for (SliceIdBaseTool *const pSliceIdTool : m_sliceIdToolVector)
610 pSliceIdTool->SelectOutputPfos(this, nuSliceHypotheses, crSliceHypotheses, selectedSlicePfos);
611 }
613 {
614 const SliceHypotheses &sliceHypotheses(m_shouldRunNeutrinoRecoOption ? nuSliceHypotheses : crSliceHypotheses);
615
616 for (const PfoList &slice : sliceHypotheses)
617 selectedSlicePfos.insert(selectedSlicePfos.end(), slice.begin(), slice.end());
618 }
619
620 PfoList newSlicePfoList;
621 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->Recreate(selectedSlicePfos, newSlicePfoList));
622
623 return STATUS_CODE_SUCCESS;
624}
625
626//------------------------------------------------------------------------------------------------------------------------------------------
627
629{
630 for (const Pandora *const pCRWorker : m_crWorkerInstances)
631 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::Reset(*pCRWorker));
632
635
638
641
642 return STATUS_CODE_SUCCESS;
643}
644
645//------------------------------------------------------------------------------------------------------------------------------------------
646
647StatusCode MasterAlgorithm::Copy(const Pandora *const pPandora, const CaloHit *const pCaloHit) const
648{
649 const LArCaloHit *const pLArCaloHit{dynamic_cast<const LArCaloHit *>(pCaloHit)};
650 if (pLArCaloHit == nullptr)
651 {
652 std::cout << "MasterAlgorithm: Could not cast CaloHit to LArCaloHit" << std::endl;
653 return STATUS_CODE_INVALID_PARAMETER;
654 }
655 LArCaloHitParameters parameters;
656 pLArCaloHit->FillParameters(parameters);
657 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::CaloHit::Create(*pPandora, parameters, m_larCaloHitFactory));
658
660 {
661 MCParticleVector mcParticleVector;
662 for (const auto &weightMapEntry : pLArCaloHit->GetMCParticleWeightMap())
663 mcParticleVector.push_back(weightMapEntry.first);
664 std::sort(mcParticleVector.begin(), mcParticleVector.end(), LArMCParticleHelper::SortByMomentum);
665
666 for (const MCParticle *const pMCParticle : mcParticleVector)
667 {
668 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
669 PandoraApi::SetCaloHitToMCParticleRelationship(*pPandora, pLArCaloHit, pMCParticle, pLArCaloHit->GetMCParticleWeightMap().at(pMCParticle)));
670 }
671 }
672
673 return STATUS_CODE_SUCCESS;
674}
675
676//------------------------------------------------------------------------------------------------------------------------------------------
677
678StatusCode MasterAlgorithm::Copy(const Pandora *const pPandora, const MCParticle *const pMCParticle, const LArMCParticleFactory *const pMCParticleFactory) const
679{
680 const LArMCParticle *const pLArMCParticle = dynamic_cast<const LArMCParticle *>(pMCParticle);
681
682 if (!pLArMCParticle)
683 {
684 std::cout << "MasterAlgorithm::Copy - Expect to pass only LArMCParticles to Pandora worker instances." << std::endl;
685 return STATUS_CODE_INVALID_PARAMETER;
686 }
687
688 LArMCParticleParameters parameters;
689 pLArMCParticle->FillParameters(parameters);
690 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::MCParticle::Create(*pPandora, parameters, *pMCParticleFactory));
691
692 for (const MCParticle *const pDaughterMCParticle : pMCParticle->GetDaughterList())
693 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::SetMCParentDaughterRelationship(*pPandora, pMCParticle, pDaughterMCParticle));
694
695 for (const MCParticle *const pParentMCParticle : pMCParticle->GetParentList())
696 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::SetMCParentDaughterRelationship(*pPandora, pParentMCParticle, pMCParticle));
697
698 return STATUS_CODE_SUCCESS;
699}
700
701//------------------------------------------------------------------------------------------------------------------------------------------
702
703StatusCode MasterAlgorithm::Recreate(const PfoList &inputPfoList, PfoList &newPfoList) const
704{
705 if (inputPfoList.empty())
706 return STATUS_CODE_SUCCESS;
707
708 // TODO if no pfo in input list is primary - raise exception
709
710 std::string clusterListName;
711 const ClusterList *pClusterList(nullptr);
712 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pClusterList, clusterListName));
713
714 std::string vertexListName;
715 const VertexList *pVertexList(nullptr);
716 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, vertexListName));
717
718 std::string pfoListName;
719 const PfoList *pPfoList(nullptr);
720 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pPfoList, pfoListName));
721
722 for (const Pfo *const pPfo : inputPfoList)
723 {
724 if (pPfo->GetParentPfoList().empty())
725 this->Recreate(pPfo, nullptr, newPfoList);
726 }
727
728 if (!pClusterList->empty())
729 {
732 }
733
734 if (!pVertexList->empty())
735 {
738 }
739
740 if (!pPfoList->empty())
741 {
744 }
745
746 return STATUS_CODE_SUCCESS;
747}
748
749//------------------------------------------------------------------------------------------------------------------------------------------
750
751StatusCode MasterAlgorithm::Recreate(const ParticleFlowObject *const pInputPfo, const ParticleFlowObject *const pNewParentPfo, PfoList &newPfoList) const
752{
753 ClusterList inputClusterList2D, inputClusterList3D, newClusterList;
754 LArPfoHelper::GetTwoDClusterList(pInputPfo, inputClusterList2D);
755 LArPfoHelper::GetThreeDClusterList(pInputPfo, inputClusterList3D);
756
757 for (const Cluster *const pInputCluster : inputClusterList2D)
758 {
759 CaloHitList inputCaloHitList, newCaloHitList, newIsolatedCaloHitList;
760 pInputCluster->GetOrderedCaloHitList().FillCaloHitList(inputCaloHitList);
761
762 for (const CaloHit *const pInputCaloHit : inputCaloHitList)
763 newCaloHitList.push_back(static_cast<const CaloHit *>(pInputCaloHit->GetParentAddress()));
764
765 for (const CaloHit *const pInputCaloHit : pInputCluster->GetIsolatedCaloHitList())
766 newIsolatedCaloHitList.push_back(static_cast<const CaloHit *>(pInputCaloHit->GetParentAddress()));
767
768 if (!newCaloHitList.empty())
769 newClusterList.push_back(this->CreateCluster(pInputCluster, newCaloHitList, newIsolatedCaloHitList));
770 }
771
772 for (const Cluster *const pInputCluster : inputClusterList3D)
773 {
774 CaloHitList inputCaloHitList, newCaloHitList, newIsolatedCaloHitList;
775 pInputCluster->GetOrderedCaloHitList().FillCaloHitList(inputCaloHitList);
776
777 for (const CaloHit *const pInputCaloHit : inputCaloHitList)
778 {
779 const CaloHit *const pWorkerParentCaloHit(static_cast<const CaloHit *>(pInputCaloHit->GetParentAddress()));
780 const CaloHit *const pMasterParentCaloHit(static_cast<const CaloHit *>(pWorkerParentCaloHit->GetParentAddress()));
781 newCaloHitList.push_back(this->CreateCaloHit(pInputCaloHit, pMasterParentCaloHit));
782 }
783
784 for (const CaloHit *const pInputCaloHit : pInputCluster->GetIsolatedCaloHitList())
785 {
786 const CaloHit *const pWorkerParentCaloHit(static_cast<const CaloHit *>(pInputCaloHit->GetParentAddress()));
787 const CaloHit *const pMasterParentCaloHit(static_cast<const CaloHit *>(pWorkerParentCaloHit->GetParentAddress()));
788 newIsolatedCaloHitList.push_back(this->CreateCaloHit(pInputCaloHit, pMasterParentCaloHit));
789 }
790
791 if (!newCaloHitList.empty())
792 newClusterList.push_back(this->CreateCluster(pInputCluster, newCaloHitList, newIsolatedCaloHitList));
793 }
794
795 VertexList newVertexList;
796
797 for (const Vertex *const pInputVertex : pInputPfo->GetVertexList())
798 newVertexList.push_back(this->CreateVertex(pInputVertex));
799
800 const ParticleFlowObject *const pNewPfo(this->CreatePfo(pInputPfo, newClusterList, newVertexList));
801 newPfoList.push_back(pNewPfo);
802
803 if (pNewParentPfo)
804 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*this, pNewParentPfo, pNewPfo))
805
806 for (const ParticleFlowObject *const pInputDaughterPfo : pInputPfo->GetDaughterPfoList())
807 this->Recreate(pInputDaughterPfo, pNewPfo, newPfoList);
808
809 return STATUS_CODE_SUCCESS;
810}
811
812//------------------------------------------------------------------------------------------------------------------------------------------
813
814const CaloHit *MasterAlgorithm::CreateCaloHit(const CaloHit *const pInputCaloHit, const CaloHit *const pParentCaloHit) const
815{
816 PandoraContentApi::CaloHit::Parameters parameters;
817 parameters.m_positionVector = pInputCaloHit->GetPositionVector();
818 parameters.m_expectedDirection = pInputCaloHit->GetExpectedDirection();
819 parameters.m_cellNormalVector = pInputCaloHit->GetCellNormalVector();
820 parameters.m_cellGeometry = pInputCaloHit->GetCellGeometry();
821 parameters.m_cellSize0 = pInputCaloHit->GetCellSize0();
822 parameters.m_cellSize1 = pInputCaloHit->GetCellSize1();
823 parameters.m_cellThickness = pInputCaloHit->GetCellThickness();
824 parameters.m_nCellRadiationLengths = pInputCaloHit->GetNCellRadiationLengths();
825 parameters.m_nCellInteractionLengths = pInputCaloHit->GetNCellInteractionLengths();
826 parameters.m_time = pInputCaloHit->GetTime();
827 parameters.m_inputEnergy = pInputCaloHit->GetInputEnergy();
828 parameters.m_mipEquivalentEnergy = pInputCaloHit->GetMipEquivalentEnergy();
829 parameters.m_electromagneticEnergy = pInputCaloHit->GetElectromagneticEnergy();
830 parameters.m_hadronicEnergy = pInputCaloHit->GetHadronicEnergy();
831 parameters.m_isDigital = pInputCaloHit->IsDigital();
832 parameters.m_hitType = pInputCaloHit->GetHitType();
833 parameters.m_hitRegion = pInputCaloHit->GetHitRegion();
834 parameters.m_layer = pInputCaloHit->GetLayer();
835 parameters.m_isInOuterSamplingLayer = pInputCaloHit->IsInOuterSamplingLayer();
836 parameters.m_pParentAddress = static_cast<const void *>(pParentCaloHit);
837
838 const CaloHit *pNewCaloHit(nullptr);
839 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CaloHit::Create(*this, parameters, pNewCaloHit));
840
841 PandoraContentApi::CaloHit::Metadata metadata;
842 metadata.m_isIsolated = pInputCaloHit->IsIsolated();
843 metadata.m_isPossibleMip = pInputCaloHit->IsPossibleMip();
844 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CaloHit::AlterMetadata(*this, pNewCaloHit, metadata));
845
846 return pNewCaloHit;
847}
848
849//------------------------------------------------------------------------------------------------------------------------------------------
850
852 const Cluster *const pInputCluster, const CaloHitList &newCaloHitList, const CaloHitList &newIsolatedCaloHitList) const
853{
854 PandoraContentApi::Cluster::Parameters parameters;
855 parameters.m_caloHitList = newCaloHitList;
856 parameters.m_isolatedCaloHitList = newIsolatedCaloHitList;
857
858 const Cluster *pNewCluster(nullptr);
859 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, parameters, pNewCluster));
860
861 PandoraContentApi::Cluster::Metadata metadata;
862 metadata.m_particleId = pInputCluster->GetParticleId();
863 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::AlterMetadata(*this, pNewCluster, metadata));
864
865 return pNewCluster;
866}
867
868//------------------------------------------------------------------------------------------------------------------------------------------
869
870const Vertex *MasterAlgorithm::CreateVertex(const Vertex *const pInputVertex) const
871{
872 PandoraContentApi::Vertex::Parameters parameters;
873 parameters.m_position = pInputVertex->GetPosition();
874 parameters.m_vertexLabel = pInputVertex->GetVertexLabel();
875 parameters.m_vertexType = pInputVertex->GetVertexType();
876
877 const Vertex *pNewVertex(nullptr);
878 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pNewVertex));
879
880 return pNewVertex;
881}
882
883//------------------------------------------------------------------------------------------------------------------------------------------
884
886 const ParticleFlowObject *const pInputPfo, const ClusterList &newClusterList, const VertexList &newVertexList) const
887{
888 PandoraContentApi::ParticleFlowObject::Parameters parameters;
889 parameters.m_particleId = pInputPfo->GetParticleId();
890 parameters.m_charge = pInputPfo->GetCharge();
891 parameters.m_mass = pInputPfo->GetMass();
892 parameters.m_energy = pInputPfo->GetEnergy();
893 parameters.m_momentum = pInputPfo->GetMomentum();
894 parameters.m_clusterList = newClusterList;
895 parameters.m_trackList.clear();
896 parameters.m_vertexList = newVertexList;
897 parameters.m_propertiesToAdd = pInputPfo->GetPropertiesMap();
898
899 const ParticleFlowObject *pNewPfo(nullptr);
900 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::Create(*this, parameters, pNewPfo));
901
902 return pNewPfo;
903}
904
905//------------------------------------------------------------------------------------------------------------------------------------------
906
908 const LArTPC &larTPC, const DetectorGapList &gapList, const std::string &settingsFile, const std::string &name) const
909{
910 // The Pandora instance
911 const Pandora *const pPandora(new Pandora(name));
912 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, LArContent::RegisterAlgorithms(*pPandora));
913 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, LArContent::RegisterBasicPlugins(*pPandora));
917 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RegisterCustomContent(pPandora));
919
920 // The LArTPC
922 larTPCParameters.m_larTPCVolumeId = larTPC.GetLArTPCVolumeId();
923 larTPCParameters.m_centerX = larTPC.GetCenterX();
924 larTPCParameters.m_centerY = larTPC.GetCenterY();
925 larTPCParameters.m_centerZ = larTPC.GetCenterZ();
926 larTPCParameters.m_widthX = larTPC.GetWidthX();
927 larTPCParameters.m_widthY = larTPC.GetWidthY();
928 larTPCParameters.m_widthZ = larTPC.GetWidthZ();
929 larTPCParameters.m_wirePitchU = larTPC.GetWirePitchU();
930 larTPCParameters.m_wirePitchV = larTPC.GetWirePitchV();
931 larTPCParameters.m_wirePitchW = larTPC.GetWirePitchW();
932 larTPCParameters.m_wireAngleU = larTPC.GetWireAngleU();
933 larTPCParameters.m_wireAngleV = larTPC.GetWireAngleV();
934 larTPCParameters.m_wireAngleW = larTPC.GetWireAngleW();
935 larTPCParameters.m_sigmaUVW = larTPC.GetSigmaUVW();
936 larTPCParameters.m_isDriftInPositiveX = larTPC.IsDriftInPositiveX();
937 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::LArTPC::Create(*pPandora, larTPCParameters));
938
939 const float tpcMinX(larTPC.GetCenterX() - 0.5f * larTPC.GetWidthX()), tpcMaxX(larTPC.GetCenterX() + 0.5f * larTPC.GetWidthX());
940
941 // The Gaps
942 for (const DetectorGap *const pGap : gapList)
943 {
944 const LineGap *const pLineGap(dynamic_cast<const LineGap *>(pGap));
945
946 if (pLineGap && (((pLineGap->GetLineEndX() >= tpcMinX) && (pLineGap->GetLineEndX() <= tpcMaxX)) ||
947 ((pLineGap->GetLineStartX() >= tpcMinX) && (pLineGap->GetLineStartX() <= tpcMaxX))))
948 {
950 const LineGapType lineGapType(pLineGap->GetLineGapType());
951 lineGapParameters.m_lineGapType = lineGapType;
952 lineGapParameters.m_lineStartX = pLineGap->GetLineStartX();
953 lineGapParameters.m_lineEndX = pLineGap->GetLineEndX();
954
956 ((lineGapType == TPC_WIRE_GAP_VIEW_U) || (lineGapType == TPC_WIRE_GAP_VIEW_V) || (lineGapType == TPC_WIRE_GAP_VIEW_W)))
957 {
958 lineGapParameters.m_lineStartX = -std::numeric_limits<float>::max();
959 lineGapParameters.m_lineEndX = std::numeric_limits<float>::max();
960 }
961
962 lineGapParameters.m_lineStartZ = pLineGap->GetLineStartZ();
963 lineGapParameters.m_lineEndZ = pLineGap->GetLineEndZ();
964 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::LineGap::Create(*pPandora, lineGapParameters));
965 }
966 }
967
968 // Configuration
969 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::ReadSettings(*pPandora, settingsFile));
970 return pPandora;
971}
972
973//------------------------------------------------------------------------------------------------------------------------------------------
974
976 const LArTPCMap &larTPCMap, const DetectorGapList &gapList, const std::string &settingsFile, const std::string &name) const
977{
978 if (larTPCMap.empty())
979 {
980 std::cout << "MasterAlgorithm::CreateWorkerInstance - no LArTPC details provided" << std::endl;
981 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
982 }
983
984 // The Pandora instance
985 const Pandora *const pPandora(new Pandora(name));
986 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, LArContent::RegisterAlgorithms(*pPandora));
987 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, LArContent::RegisterBasicPlugins(*pPandora));
991 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, this->RegisterCustomContent(pPandora));
993
994 // The Parent LArTPC
995 const LArTPC *const pFirstLArTPC(larTPCMap.begin()->second);
996 float parentMinX(pFirstLArTPC->GetCenterX() - 0.5f * pFirstLArTPC->GetWidthX());
997 float parentMaxX(pFirstLArTPC->GetCenterX() + 0.5f * pFirstLArTPC->GetWidthX());
998 float parentMinY(pFirstLArTPC->GetCenterY() - 0.5f * pFirstLArTPC->GetWidthY());
999 float parentMaxY(pFirstLArTPC->GetCenterY() + 0.5f * pFirstLArTPC->GetWidthY());
1000 float parentMinZ(pFirstLArTPC->GetCenterZ() - 0.5f * pFirstLArTPC->GetWidthZ());
1001 float parentMaxZ(pFirstLArTPC->GetCenterZ() + 0.5f * pFirstLArTPC->GetWidthZ());
1002
1003 for (const LArTPCMap::value_type &mapEntry : larTPCMap)
1004 {
1005 const LArTPC *const pLArTPC(mapEntry.second);
1006 parentMinX = std::min(parentMinX, pLArTPC->GetCenterX() - 0.5f * pLArTPC->GetWidthX());
1007 parentMaxX = std::max(parentMaxX, pLArTPC->GetCenterX() + 0.5f * pLArTPC->GetWidthX());
1008 parentMinY = std::min(parentMinY, pLArTPC->GetCenterY() - 0.5f * pLArTPC->GetWidthY());
1009 parentMaxY = std::max(parentMaxY, pLArTPC->GetCenterY() + 0.5f * pLArTPC->GetWidthY());
1010 parentMinZ = std::min(parentMinZ, pLArTPC->GetCenterZ() - 0.5f * pLArTPC->GetWidthZ());
1011 parentMaxZ = std::max(parentMaxZ, pLArTPC->GetCenterZ() + 0.5f * pLArTPC->GetWidthZ());
1012 }
1013
1015 larTPCParameters.m_larTPCVolumeId = 0;
1016 larTPCParameters.m_centerX = 0.5f * (parentMaxX + parentMinX);
1017 larTPCParameters.m_centerY = 0.5f * (parentMaxY + parentMinY);
1018 larTPCParameters.m_centerZ = 0.5f * (parentMaxZ + parentMinZ);
1019 larTPCParameters.m_widthX = parentMaxX - parentMinX;
1020 larTPCParameters.m_widthY = parentMaxY - parentMinY;
1021 larTPCParameters.m_widthZ = parentMaxZ - parentMinZ;
1022 larTPCParameters.m_wirePitchU = std::max(pFirstLArTPC->GetWirePitchU(), pFirstLArTPC->GetWirePitchV());
1023 larTPCParameters.m_wirePitchV = std::max(pFirstLArTPC->GetWirePitchU(), pFirstLArTPC->GetWirePitchV());
1024 larTPCParameters.m_wirePitchW = pFirstLArTPC->GetWirePitchW();
1025 larTPCParameters.m_wireAngleU = pFirstLArTPC->GetWireAngleU();
1026 larTPCParameters.m_wireAngleV = pFirstLArTPC->GetWireAngleV();
1027 larTPCParameters.m_wireAngleW = pFirstLArTPC->GetWireAngleW();
1028 larTPCParameters.m_sigmaUVW = pFirstLArTPC->GetSigmaUVW();
1029 larTPCParameters.m_isDriftInPositiveX = pFirstLArTPC->IsDriftInPositiveX();
1030 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::LArTPC::Create(*pPandora, larTPCParameters));
1031
1032 // The Gaps
1033 for (const DetectorGap *const pGap : gapList)
1034 {
1035 const LineGap *const pLineGap(dynamic_cast<const LineGap *>(pGap));
1036
1037 if (pLineGap)
1038 {
1040 lineGapParameters.m_lineGapType = pLineGap->GetLineGapType();
1041 lineGapParameters.m_lineStartX = pLineGap->GetLineStartX();
1042 lineGapParameters.m_lineEndX = pLineGap->GetLineEndX();
1043 lineGapParameters.m_lineStartZ = pLineGap->GetLineStartZ();
1044 lineGapParameters.m_lineEndZ = pLineGap->GetLineEndZ();
1045 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::Geometry::LineGap::Create(*pPandora, lineGapParameters));
1046 }
1047 }
1048
1049 // Configuration
1050 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraApi::ReadSettings(*pPandora, settingsFile));
1051 return pPandora;
1052}
1053
1054//------------------------------------------------------------------------------------------------------------------------------------------
1055
1057{
1058 return STATUS_CODE_SUCCESS;
1059}
1060
1061//------------------------------------------------------------------------------------------------------------------------------------------
1062
1064{
1065 ExternalSteeringParameters *pExternalParameters(nullptr);
1066
1067 if (this->ExternalParametersPresent())
1068 {
1069 pExternalParameters = dynamic_cast<ExternalSteeringParameters *>(this->GetExternalParameters());
1070 if (!pExternalParameters)
1071 return STATUS_CODE_FAILURE;
1072 }
1073
1074 {
1075 AlgorithmToolVector algorithmToolVector;
1077 STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "SliceSelectionTools", algorithmToolVector));
1078
1079 for (AlgorithmTool *const pAlgorithmTool : algorithmToolVector)
1080 {
1081 SliceSelectionBaseTool *const pSliceSelectionTool(dynamic_cast<SliceSelectionBaseTool *>(pAlgorithmTool));
1082 if (!pSliceSelectionTool)
1083 return STATUS_CODE_INVALID_PARAMETER;
1084 m_sliceSelectionToolVector.push_back(pSliceSelectionTool);
1085 }
1086 }
1087
1088 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
1089 this->ReadExternalSettings(pExternalParameters, !pExternalParameters ? InputBool() : pExternalParameters->m_shouldRunAllHitsCosmicReco,
1090 xmlHandle, "ShouldRunAllHitsCosmicReco", m_shouldRunAllHitsCosmicReco));
1091
1092 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
1093 this->ReadExternalSettings(pExternalParameters, !pExternalParameters ? InputBool() : pExternalParameters->m_shouldRunStitching,
1094 xmlHandle, "ShouldRunStitching", m_shouldRunStitching));
1095
1097 {
1098 std::cout << "MasterAlgorithm::ReadSettings - ShouldRunStitching requires ShouldRunAllHitsCosmicReco to be true" << std::endl;
1099 return STATUS_CODE_INVALID_PARAMETER;
1100 }
1101
1103 {
1104 AlgorithmToolVector algorithmToolVector;
1105 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "StitchingTools", algorithmToolVector));
1106
1107 for (AlgorithmTool *const pAlgorithmTool : algorithmToolVector)
1108 {
1109 StitchingBaseTool *const pStitchingTool(dynamic_cast<StitchingBaseTool *>(pAlgorithmTool));
1110 if (!pStitchingTool)
1111 return STATUS_CODE_INVALID_PARAMETER;
1112 m_stitchingToolVector.push_back(pStitchingTool);
1113 }
1114 }
1115
1116 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
1117 this->ReadExternalSettings(pExternalParameters, !pExternalParameters ? InputBool() : pExternalParameters->m_shouldRunCosmicHitRemoval,
1118 xmlHandle, "ShouldRunCosmicHitRemoval", m_shouldRunCosmicHitRemoval));
1119
1121 {
1122 std::cout << "MasterAlgorithm::ReadSettings - ShouldRunCosmicHitRemoval requires ShouldRunAllHitsCosmicReco to be true" << std::endl;
1123 return STATUS_CODE_INVALID_PARAMETER;
1124 }
1125
1127 {
1128 AlgorithmToolVector algorithmToolVector;
1130 STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "CosmicRayTaggingTools", algorithmToolVector));
1131
1132 for (AlgorithmTool *const pAlgorithmTool : algorithmToolVector)
1133 {
1134 CosmicRayTaggingBaseTool *const pCosmicRayTaggingTool(dynamic_cast<CosmicRayTaggingBaseTool *>(pAlgorithmTool));
1135 if (!pCosmicRayTaggingTool)
1136 return STATUS_CODE_INVALID_PARAMETER;
1137 m_cosmicRayTaggingToolVector.push_back(pCosmicRayTaggingTool);
1138 }
1139 }
1140
1141 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
1142 this->ReadExternalSettings(pExternalParameters, !pExternalParameters ? InputBool() : pExternalParameters->m_shouldRunSlicing,
1143 xmlHandle, "ShouldRunSlicing", m_shouldRunSlicing));
1144
1145 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
1146 this->ReadExternalSettings(pExternalParameters, !pExternalParameters ? InputBool() : pExternalParameters->m_shouldRunNeutrinoRecoOption,
1147 xmlHandle, "ShouldRunNeutrinoRecoOption", m_shouldRunNeutrinoRecoOption));
1148
1149 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
1150 this->ReadExternalSettings(pExternalParameters, !pExternalParameters ? InputBool() : pExternalParameters->m_shouldRunCosmicRecoOption,
1151 xmlHandle, "ShouldRunCosmicRecoOption", m_shouldRunCosmicRecoOption));
1152
1153 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
1154 this->ReadExternalSettings(pExternalParameters, !pExternalParameters ? InputBool() : pExternalParameters->m_shouldPerformSliceId,
1155 xmlHandle, "ShouldPerformSliceId", m_shouldPerformSliceId));
1156
1158 {
1159 std::cout << "MasterAlgorithm::ReadSettings - ShouldPerformSliceId requires ShouldRunSlicing and both neutrino and cosmic reconstruction options"
1160 << std::endl;
1161 return STATUS_CODE_INVALID_PARAMETER;
1162 }
1163
1165 {
1166 AlgorithmToolVector algorithmToolVector;
1167 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "SliceIdTools", algorithmToolVector));
1168
1169 for (AlgorithmTool *const pAlgorithmTool : algorithmToolVector)
1170 {
1171 SliceIdBaseTool *const pSliceIdIdTool(dynamic_cast<SliceIdBaseTool *>(pAlgorithmTool));
1172 if (!pSliceIdIdTool)
1173 return STATUS_CODE_INVALID_PARAMETER;
1174 m_sliceIdToolVector.push_back(pSliceIdIdTool);
1175 }
1176 }
1177
1178 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=,
1179 this->ReadExternalSettings(pExternalParameters, !pExternalParameters ? InputBool() : pExternalParameters->m_printOverallRecoStatus,
1180 xmlHandle, "PrintOverallRecoStatus", m_printOverallRecoStatus));
1181
1182 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
1183 XmlHelper::ReadValue(xmlHandle, "VisualizeOverallRecoStatus", m_visualizeOverallRecoStatus));
1184
1186 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "LArCaloHitVersion", m_larCaloHitVersion));
1187
1188 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
1189 XmlHelper::ReadValue(xmlHandle, "ShouldRemoveOutOfTimeHits", m_shouldRemoveOutOfTimeHits));
1190
1191 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
1192 XmlHelper::ReadValue(xmlHandle, "FullWidthCRWorkerWireGaps", m_fullWidthCRWorkerWireGaps));
1193
1194 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
1195 XmlHelper::ReadValue(xmlHandle, "PassMCParticlesToWorkerInstances", m_passMCParticlesToWorkerInstances));
1196
1197 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
1198 XmlHelper::ReadValue(xmlHandle, "FilePathEnvironmentVariable", m_filePathEnvironmentVariable));
1199
1200 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "CRSettingsFile", m_crSettingsFile));
1201 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "NuSettingsFile", m_nuSettingsFile));
1202 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "SlicingSettingsFile", m_slicingSettingsFile));
1206
1208 {
1209 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "InputMCParticleListName", m_inputMCParticleListName));
1210 }
1211
1212 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "InputHitListName", m_inputHitListName));
1213 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RecreatedPfoListName", m_recreatedPfoListName));
1214 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RecreatedClusterListName", m_recreatedClusterListName));
1215 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "RecreatedVertexListName", m_recreatedVertexListName));
1216 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "InTimeMaxX0", m_inTimeMaxX0));
1217
1218 return STATUS_CODE_SUCCESS;
1219}
1220
1221//------------------------------------------------------------------------------------------------------------------------------------------
1222
1224 const TiXmlHandle xmlHandle, const std::string &xmlTag, bool &outputBool)
1225{
1226 if (pExternalParameters && inputBool.IsInitialized())
1227 {
1228 outputBool = inputBool.Get();
1229 }
1230 else
1231 {
1232 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, xmlTag, outputBool));
1233 }
1234
1235 return STATUS_CODE_SUCCESS;
1236}
1237
1238} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
#define PANDORA_MONITORING_API(command)
Header file for the lar calo hit class.
Header file for the cluster helper class.
Header file detailing content for use with particle flow reconstruction at liquid argon time projecti...
Header file for the file helper class.
Header file for the lar mc particle class.
Header file for the lar monte carlo particle helper helper class.
Header file for the pfo helper class.
Header file for the lar pseudo layer plugin class.
Header file for the rotational transformation plugin class.
Header file for the helper class for multiple drift volumes.
Header file for the master algorithm class.
std::vector< const pandora::Pandora * > PandoraInstanceList
Header file for the pandora api class.
Header file for the pfo mop up algorithm base 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 RegisterAlgorithms(const pandora::Pandora &pandora)
Register all the lar content algorithms and tools with pandora.
static pandora::StatusCode RegisterBasicPlugins(const pandora::Pandora &pandora)
Register the basic lar content plugins with pandora.
static void AddDaughterPandoraInstance(const pandora::Pandora *const pPrimaryPandora, const pandora::Pandora *const pDaughterPandora)
Add a pandora daughter instance, associated to a primary pandora instance.
static pandora::StatusCode ReadSettings(const pandora::Pandora &pandora, const std::string &xmlFileName)
Read pandora settings.
Definition PandoraApi.cc:21
static pandora::StatusCode ProcessEvent(const pandora::Pandora &pandora)
Process an event.
Definition PandoraApi.cc:14
static pandora::StatusCode Reset(const pandora::Pandora &pandora)
Reset pandora to process another event.
static pandora::StatusCode SetMCParentDaughterRelationship(const pandora::Pandora &pandora, const void *const pParentAddress, const void *const pDaughterAddress)
Set parent-daughter mc particle relationship.
Definition PandoraApi.cc:44
static pandora::StatusCode SetLArTransformationPlugin(const pandora::Pandora &pandora, pandora::LArTransformationPlugin *const pLArTransformationPlugin)
Set the lar transformation plugin used by pandora.
static pandora::StatusCode SetCaloHitToMCParticleRelationship(const pandora::Pandora &pandora, const void *const pCaloHitParentAddress, const void *const pMCParticleParentAddress, const float mcParticleWeight=1)
Set calo hit to mc particle relationship.
Definition PandoraApi.cc:68
static pandora::StatusCode SetPseudoLayerPlugin(const pandora::Pandora &pandora, pandora::PseudoLayerPlugin *const pPseudoLayerPlugin)
Set the pseudo layer plugin used by pandora.
static pandora::StatusCode GetCurrentPfoList(const pandora::Pandora &pandora, const pandora::PfoList *&pPfoList)
Get the current pfo list.
Definition PandoraApi.cc:84
static bool IsAvailable(const pandora::Algorithm &algorithm, const T *const pT)
Is object, or a list of objects, available as a building block.
static pandora::StatusCode ReplaceCurrentList(const pandora::Algorithm &algorithm, const std::string &newListName)
Replace the current list with a pre-saved list; use this new list as a permanent replacement for the ...
static pandora::StatusCode AddToPfo(const pandora::Algorithm &algorithm, const pandora::ParticleFlowObject *const pPfo, const T *const pT)
Add a cluster to a particle flow object.
static pandora::StatusCode CreateTemporaryListAndSetCurrent(const pandora::Algorithm &algorithm, const T *&pT, std::string &temporaryListName)
Create a temporary list and set it to be the current list, enabling object creation.
static pandora::StatusCode MergeAndDeleteClusters(const pandora::Algorithm &algorithm, const pandora::Cluster *const pClusterToEnlarge, const pandora::Cluster *const pClusterToDelete)
Merge two clusters in the current list, enlarging one cluster and deleting the second.
static pandora::StatusCode SetPfoParentDaughterRelationship(const pandora::Algorithm &algorithm, const pandora::ParticleFlowObject *const pParentPfo, const pandora::ParticleFlowObject *const pDaughterPfo)
Set parent-daughter particle flow object relationship.
static pandora::StatusCode Delete(const pandora::Algorithm &algorithm, const T *const pT)
Delete an object from the current list.
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
CosmicRayTaggingBaseTool class.
LAr calo hit class.
Definition LArCaloHit.h:40
unsigned int GetLArTPCVolumeId() const
Get the lar tpc volume id.
Definition LArCaloHit.h:167
LAr calo hit parameters.
Definition LArCaloHit.h:28
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
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...
LArMCParticleFactory responsible for object creation.
static bool SortByMomentum(const pandora::MCParticle *const pLhs, const pandora::MCParticle *const pRhs)
Sort mc particles by their momentum.
LAr mc particle class.
void FillParameters(LArMCParticleParameters &parameters) const
Fill the parameters associated with this MC particle.
LAr mc particle parameters.
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 GetThreeDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 3D clusters from an input pfo.
static void GetAllDownstreamPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively, of all daughters associated with those pfos in an input lis...
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
static void GetIsolatedCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of isolated calo hits of a particular hit type from a list of pfos.
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.
LarPandoraPseudoLayerPlugin class.
static bool HasPfoBeenStitched(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo has been stitched.
pandora::InputBool m_printOverallRecoStatus
Whether to print current operation status messages.
pandora::InputBool m_shouldRunStitching
Whether to stitch cosmic-ray muons crossing between volumes.
pandora::InputBool m_shouldPerformSliceId
Whether to identify slices and select most appropriate pfos.
pandora::InputBool m_shouldRunCosmicRecoOption
Whether to run cosmic-ray reconstruction for each slice.
pandora::InputBool m_shouldRunNeutrinoRecoOption
Whether to run neutrino reconstruction for each slice.
pandora::InputBool m_shouldRunCosmicHitRemoval
Whether to remove hits from tagged cosmic-rays.
pandora::InputBool m_shouldRunSlicing
Whether to slice events into separate regions for processing.
pandora::InputBool m_shouldRunAllHitsCosmicReco
Whether to run all hits cosmic-ray reconstruction.
const pandora::Pandora * m_pSliceNuWorkerInstance
The per-slice neutrino reconstruction worker instance.
bool m_printOverallRecoStatus
Whether to print current operation status messages.
std::string m_nuSettingsFile
The neutrino reconstruction settings file.
bool m_workerInstancesInitialized
Whether all worker instances have been initialized.
const pandora::Pandora * CreateWorkerInstance(const pandora::LArTPC &larTPC, const pandora::DetectorGapList &gapList, const std::string &settingsFile, const std::string &name) const
Create a pandora worker instance to handle a single LArTPC.
bool m_shouldRunAllHitsCosmicReco
Whether to run all hits cosmic-ray reconstruction.
pandora::StatusCode RunCosmicRayHitRemoval(const pandora::PfoList &ambiguousPfos) const
Run cosmic-ray hit removal, freeing hits in ambiguous pfos for further processing.
bool m_fullWidthCRWorkerWireGaps
Whether wire-type line gaps in cosmic-ray worker instances should cover all drift time.
const pandora::Pandora * m_pSlicingWorkerInstance
The slicing worker instance.
std::string m_crSettingsFile
The cosmic-ray reconstruction settings file.
void StitchPfos(const pandora::ParticleFlowObject *const pPfoToEnlarge, const pandora::ParticleFlowObject *const pPfoToDelete, PfoToLArTPCMap &pfoToLArTPCMap) const
Stitch together a pair of pfos.
std::string m_recreatedVertexListName
The output recreated vertex list name.
bool m_shouldRunCosmicHitRemoval
Whether to remove hits from tagged cosmic-rays.
bool m_shouldPerformSliceId
Whether to identify slices and select most appropriate pfos.
pandora::StatusCode Recreate(const pandora::PfoList &inputPfoList, pandora::PfoList &newPfoList) const
Recreate a specified list of pfos in the current pandora instance.
pandora::StatusCode StitchCosmicRayPfos(PfoToLArTPCMap &pfoToLArTPCMap, PfoToFloatMap &stitchedPfosToX0Map) const
Stitch together cosmic-ray pfos crossing between adjacent lar tpcs.
const pandora::Pandora * m_pSliceCRWorkerInstance
The per-slice cosmic-ray reconstruction worker instance.
pandora::StatusCode RecreateCosmicRayPfos(PfoToLArTPCMap &pfoToLArTPCMap) const
Recreate cosmic-ray pfos (created by worker instances) in the master instance.
std::string m_inputMCParticleListName
The input mc particle list name.
pandora::StatusCode SelectBestSliceHypotheses(const SliceHypotheses &nuSliceHypotheses, const SliceHypotheses &crSliceHypotheses) const
Examine slice hypotheses to identify the most appropriate to provide in final event output.
pandora::StatusCode ReadExternalSettings(const ExternalSteeringParameters *const pExternalParameters, const pandora::InputBool inputBool, const pandora::TiXmlHandle xmlHandle, const std::string &xmlTag, bool &outputBool)
Read settings from external steering parameters block, if present, otherwise from xml as standard.
const pandora::ParticleFlowObject * CreatePfo(const pandora::ParticleFlowObject *const pInputPfo, const pandora::ClusterList &newClusterList, const pandora::VertexList &newVertexList) const
Create a new pfo in the current pandora instance, based upon the provided input pfo.
bool m_passMCParticlesToWorkerInstances
Whether to pass mc particle details (and links to calo hits) to worker instances.
pandora::StatusCode Reset()
Reset all worker instances.
const pandora::Vertex * CreateVertex(const pandora::Vertex *const pInputVertex) const
Create a new vertex in the current pandora instance, based upon the provided input vertex.
bool m_shouldRunNeutrinoRecoOption
Whether to run neutrino reconstruction for each slice.
bool m_shouldRunCosmicRecoOption
Whether to run cosmic-ray reconstruction for each slice.
LArCaloHitFactory m_larCaloHitFactory
Factory for creating LArCaloHits during hit copying.
unsigned int m_larCaloHitVersion
The LArCaloHit version for LArCaloHitFactory.
virtual pandora::StatusCode RegisterCustomContent(const pandora::Pandora *const pPandora) const
Register custom content, such as algorithms or algorithm tools, with a specified pandora instance.
pandora::StatusCode Copy(const pandora::Pandora *const pPandora, const pandora::CaloHit *const pCaloHit) const
Copy a specified calo hit to the provided pandora instance.
std::string m_recreatedPfoListName
The output recreated pfo list name.
void ShiftPfoHierarchy(const pandora::ParticleFlowObject *const pParentPfo, const PfoToLArTPCMap &pfoToLArTPCMap, const float x0) const
Shift a Pfo hierarchy by a specified x0 value.
pandora::StatusCode CopyMCParticles() const
Copy mc particles in the named input list to all pandora worker instances.
std::string m_inputHitListName
The input hit list name.
bool m_shouldRemoveOutOfTimeHits
Whether to remove out of time hits.
pandora::StatusCode RunSlicing(const VolumeIdToHitListMap &volumeIdToHitListMap, SliceVector &sliceVector) const
Run the event slicing procedures, dividing available hits up into distinct 3D regions.
std::unordered_map< const pandora::ParticleFlowObject *, const pandora::LArTPC * > PfoToLArTPCMap
pandora::StatusCode Run()
Run the algorithm.
std::string m_filePathEnvironmentVariable
The environment variable providing a list of paths to xml files.
std::string m_slicingSettingsFile
The slicing settings file.
SliceSelectionToolVector m_sliceSelectionToolVector
The slice selection tool vector.
pandora::StatusCode RunSliceReconstruction(SliceVector &sliceVector, SliceHypotheses &nuSliceHypotheses, SliceHypotheses &crSliceHypotheses) const
Process each slice under different reconstruction hypotheses.
bool m_shouldRunSlicing
Whether to slice events into separate regions for processing.
bool m_visualizeOverallRecoStatus
Whether to display results of current operations.
pandora::StatusCode RunCosmicRayReconstruction(const VolumeIdToHitListMap &volumeIdToHitListMap) const
Run the cosmic-ray reconstruction worker instances.
PandoraInstanceList m_crWorkerInstances
The list of cosmic-ray reconstruction worker instances.
pandora::CaloHitList m_allHitList
The list of all hits originating from a given LArTPC.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
std::string m_recreatedClusterListName
The output recreated cluster list name.
CosmicRayTaggingToolVector m_cosmicRayTaggingToolVector
The cosmic-ray tagging tool vector.
const pandora::Cluster * CreateCluster(const pandora::Cluster *const pInputCluster, const pandora::CaloHitList &newCaloHitList, const pandora::CaloHitList &newIsolatedCaloHitList) const
Create a new cluster in the current pandora instance, based upon the provided input cluster.
std::map< unsigned int, LArTPCHitList > VolumeIdToHitListMap
pandora::StatusCode InitializeWorkerInstances()
Initialize pandora worker instances.
pandora::CaloHitList m_truncatedHitList
The list of hits confined within LArTPC boundaries for given beam t0 value.
float m_inTimeMaxX0
Cut on X0 to determine whether particle is clear cosmic ray.
SliceIdToolVector m_sliceIdToolVector
The slice id tool vector.
StitchingToolVector m_stitchingToolVector
The stitching tool vector.
bool m_shouldRunStitching
Whether to stitch cosmic-ray muons crossing between volumes.
pandora::StatusCode GetVolumeIdToHitListMap(VolumeIdToHitListMap &volumeIdToHitListMap) const
Get the mapping from lar tpc volume id to lists of all hits, and truncated hits.
pandora::StatusCode TagCosmicRayPfos(const PfoToFloatMap &stitchedPfosToX0Map, pandora::PfoList &clearCosmicRayPfos, pandora::PfoList &ambiguousPfos) const
Tag clear, unambiguous cosmic-ray pfos.
const pandora::CaloHit * CreateCaloHit(const pandora::CaloHit *const pInputCaloHit, const pandora::CaloHit *const pParentCaloHit) const
Create a new calo hit in the current pandora instance, based upon the provided input calo hit.
MasterAlgorithm()
Default constructor.
static const pandora::Cluster * GetParentCluster(const pandora::ClusterList &clusterList, const pandora::HitType hitType)
Select the parent cluster (same hit type and most hits) using a provided cluster list and hit type.
SliceIdBaseTool class.
SliceSelectionBaseTool class.
StitchingBaseTool class.
static pandora::StatusCode Create(const pandora::Pandora &pandora, const Parameters &parameters, const pandora::ObjectFactory< Parameters, Object > &factory=pandora::PandoraObjectFactory< Parameters, Object >())
Create a new object from a user factory.
AlgorithmTool class. Algorithm tools will tend to be tailored for specific parent algorithms,...
CaloHit class.
Definition CaloHit.h:26
float GetElectromagneticEnergy() const
Get the calibrated electromagnetic energy measure.
Definition CaloHit.h:483
HitType GetHitType() const
Get the calorimeter hit type.
Definition CaloHit.h:441
CellGeometry GetCellGeometry() const
Get the cell geometry.
Definition CaloHit.h:378
bool IsInOuterSamplingLayer() const
Whether cell is in one of the outermost detector sampling layers.
Definition CaloHit.h:469
HitRegion GetHitRegion() const
Get the region of the detector in which the calo hit is located.
Definition CaloHit.h:448
const CartesianVector & GetPositionVector() const
Get the position vector of center of calorimeter cell, units mm.
Definition CaloHit.h:350
bool IsIsolated() const
Whether the calo hit is flagged as isolated.
Definition CaloHit.h:518
CartesianVector m_positionVector
Position vector of center of calorimeter cell, units mm.
Definition CaloHit.h:312
unsigned int GetLayer() const
Get the subdetector readout layer number.
Definition CaloHit.h:455
float GetMipEquivalentEnergy() const
Get the calibrated mip equivalent energy.
Definition CaloHit.h:476
float GetNCellRadiationLengths() const
Get the absorber material in front of cell, units radiation lengths.
Definition CaloHit.h:406
float GetNCellInteractionLengths() const
Get the absorber material in front of cell, units interaction lengths.
Definition CaloHit.h:413
bool IsPossibleMip() const
Whether the calo hit is flagged as a possible mip hit.
Definition CaloHit.h:504
float GetCellThickness() const
Get the thickness of cell, units mm.
Definition CaloHit.h:399
float GetCellSize1() const
Get the cell size 1 [pointing: phi, rectangular: perpendicular to size 0 and thickness,...
Definition CaloHit.h:392
StatusCode AlterMetadata(const object_creation::CaloHit::Metadata &metadata)
Alter the metadata information stored in a calo hit.
Definition CaloHit.cc:127
bool IsDigital() const
Whether cell should be treated as digital.
Definition CaloHit.h:434
float GetCellSize0() const
Get the cell size 0 [pointing: eta, rectangular: up in ENDCAP, along beam in BARREL,...
Definition CaloHit.h:385
const CartesianVector & GetCellNormalVector() const
Get the unit vector normal to the sampling layer, pointing outwards from the origin.
Definition CaloHit.h:371
float GetHadronicEnergy() const
Get the calibrated hadronic energy measure.
Definition CaloHit.h:490
float GetInputEnergy() const
Get the corrected energy of the calorimeter cell, units GeV, as supplied by the user.
Definition CaloHit.h:420
float GetTime() const
Get the time of (earliest) energy deposition in this cell, units ns.
Definition CaloHit.h:427
const void * GetParentAddress() const
Get the address of the parent calo hit in the user framework.
Definition CaloHit.h:532
const CartesianVector & GetExpectedDirection() const
Get the unit vector in direction of expected hit propagation.
Definition CaloHit.h:364
Cluster class.
Definition Cluster.h:31
CaloHitList m_isolatedCaloHitList
The list of isolated hits, which contribute only towards cluster energy.
Definition Cluster.h:430
StatusCode AlterMetadata(const object_creation::Cluster::Metadata &metadata)
Alter the metadata information stored in a cluster.
Definition Cluster.cc:275
int GetParticleId() const
Get the particle id flag.
Definition Cluster.h:547
DetectorGap class.
Definition DetectorGap.h:25
bool ExternalParametersPresent() const
Whether external parameters are present.
ExternalParameters * GetExternalParameters() const
Get the external parameters associated with algorithm instances created by a given Pandora instance....
LArTPC class.
Definition LArTPC.h:26
float GetWireAngleV() const
Get the v wire angle to the vertical, units radians.
Definition LArTPC.h:245
float GetWirePitchU() const
Get the u wire pitch, units mm.
Definition LArTPC.h:217
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 GetWireAngleW() const
Get the w wire angle to the vertical, units radians.
Definition LArTPC.h:252
float GetCenterZ() const
Get center in z, units mm.
Definition LArTPC.h:189
bool IsDriftInPositiveX() const
Whether the electron drift is in the positive x direction.
Definition LArTPC.h:266
float GetCenterX() const
Get center in x, units mm.
Definition LArTPC.h:175
float GetWirePitchV() const
Get the v wire pitch, units mm.
Definition LArTPC.h:224
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
float GetWireAngleU() const
Get the u wire angle to the vertical, units radians.
Definition LArTPC.h:238
float GetWirePitchW() const
Get the w wire pitch, units mm.
Definition LArTPC.h:231
unsigned int GetLArTPCVolumeId() const
Get the lar volume id, uniquely specifying the lar tpc.
Definition LArTPC.h:168
float GetSigmaUVW() const
Get the u, v, w resolution, units mm.
Definition LArTPC.h:259
LineGap class, associated only with 2D TPC hit types and applied only to the z coordinate when sampli...
Definition DetectorGap.h:50
float GetLineEndZ() const
Get the line end z coordinate.
LineGapType GetLineGapType() const
Get the line gap type.
float GetLineStartX() const
Get the line start x coordinate.
float GetLineStartZ() const
Get the line start z coordinate.
float GetLineEndX() const
Get the line end x coordinate.
MCParticle class.
Definition MCParticle.h:26
const MCParticleList & GetDaughterList() const
Get list of daughters of mc particle.
Definition MCParticle.h:306
const MCParticleList & GetParentList() const
Get list of parents of mc particle.
Definition MCParticle.h:299
Pandora class.
Definition Pandora.h:40
bool IsInitialized() const
Whether the pandora type is initialized.
const T & Get() const
Get the value held by the pandora type.
ParticleFlowObject class.
float GetEnergy() const
Get the particle flow object energy.
const PropertiesMap & GetPropertiesMap() const
Get the map from registered property name to floating point property value.
const PfoList & GetDaughterPfoList() const
Get the daughter pfo list.
const ClusterList & GetClusterList() const
Get the cluster list.
const PfoList & GetParentPfoList() const
Get the parent pfo list.
const VertexList & GetVertexList() const
Get the vertex list.
StatusCode AlterMetadata(const object_creation::ParticleFlowObject::Metadata &metadata)
Alter particle flow object metadata parameters.
float GetMass() const
Get particle flow object mass.
int GetCharge() const
Get particle flow object charge.
int GetParticleId() const
Get the particle flow object id (PDG code)
int m_particleId
The particle flow object id (PDG code)
const CartesianVector & GetMomentum() const
Get particle flow object momentum vector.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
StatusCodeException class.
std::string ToString() const
Get status code as a string.
StatusCode GetStatusCode() const
Get status code.
Vertex class.
Definition Vertex.h:26
VertexType GetVertexType() const
Get the vertex type.
Definition Vertex.h:124
StatusCode AlterMetadata(const object_creation::Vertex::Metadata &metadata)
Alter the metadata information stored in a vertex.
Definition Vertex.cc:31
CartesianVector m_position
The vertex position.
Definition Vertex.h:90
const CartesianVector & GetPosition() const
Get the vertex position.
Definition Vertex.h:103
VertexLabel GetVertexLabel() const
Get the vertex label.
Definition Vertex.h:117
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
static StatusCode ProcessAlgorithmToolList(const Algorithm &algorithm, const TiXmlHandle &xmlHandle, const std::string &listName, AlgorithmToolVector &algorithmToolVector)
Process a list of algorithms tools in an xml file.
Definition XmlHelper.cc:101
std::unordered_map< const pandora::ParticleFlowObject *, float > PfoToFloatMap
std::vector< pandora::CaloHitList > SliceVector
std::vector< pandora::PfoList > SliceHypotheses
HitType
Calorimeter hit type enum.
MANAGED_CONTAINER< const MCParticle * > MCParticleList
std::vector< const Cluster * > ClusterVector
PandoraInputType< bool > InputBool
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< AlgorithmTool * > AlgorithmToolVector
std::map< unsigned int, const LArTPC * > LArTPCMap
MANAGED_CONTAINER< const DetectorGap * > DetectorGapList
MANAGED_CONTAINER< const CaloHit * > CaloHitList
std::vector< const MCParticle * > MCParticleVector
MANAGED_CONTAINER< const Vertex * > VertexList
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList
std::vector< const Vertex * > VertexVector
LineGapType
Line gap type.