LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
LArPandoraOutput.cxx
Go to the documentation of this file.
1 
9 #include "cetlib_except/exception.h"
11 
16 
22 
26 
27 #include "Api/PandoraApi.h"
28 
29 #include "Objects/CaloHit.h"
30 #include "Objects/Cluster.h"
31 #include "Objects/ParticleFlowObject.h"
32 #include "Objects/Vertex.h"
33 
36 
39 
40 #include <algorithm>
41 #include <iterator>
42 #include <iostream>
43 #include <limits>
44 
45 namespace lar_pandora
46 {
47 
48 void LArPandoraOutput::ProduceArtOutput(const Settings &settings, const IdToHitMap &idToHitMap, art::Event &evt)
49 {
50  mf::LogDebug("LArPandora") << " *** LArPandora::ProduceArtOutput() *** " << std::endl;
51 
52  if (!settings.m_pPrimaryPandora)
53  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- primary Pandora instance does not exist ";
54 
55  if (!settings.m_pProducer)
56  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- pointer to ART Producer module does not exist ";
57 
58  // Obtain a sorted vector of all output Pfos and their daughters
59  const pandora::PfoList *pPfoList(nullptr);
60  PANDORA_THROW_RESULT_IF(pandora::STATUS_CODE_SUCCESS, !=, PandoraApi::GetCurrentPfoList(*(settings.m_pPrimaryPandora), pPfoList));
61 
62  if (pPfoList->empty())
63  mf::LogDebug("LArPandora") << " Warning: No reconstructed particles for this event " << std::endl;
64 
65  pandora::PfoList connectedPfoList;
66  lar_content::LArPfoHelper::GetAllConnectedPfos(*pPfoList, connectedPfoList);
67 
68  pandora::PfoVector pfoVector(connectedPfoList.begin(), connectedPfoList.end());
69  std::sort(pfoVector.begin(), pfoVector.end(), lar_content::LArPfoHelper::SortByNHits);
70 
71  // Set up ART outputs from RecoBase, AnalysisBase and LArPandoraObjects
72  std::unique_ptr< std::vector<recob::PFParticle> > outputParticles( new std::vector<recob::PFParticle> );
73  std::unique_ptr< std::vector<recob::SpacePoint> > outputSpacePoints( new std::vector<recob::SpacePoint> );
74  std::unique_ptr< std::vector<recob::Cluster> > outputClusters( new std::vector<recob::Cluster> );
75  std::unique_ptr< std::vector<recob::Vertex> > outputVertices( new std::vector<recob::Vertex> );
76  std::unique_ptr< std::vector<anab::T0> > outputT0s( new std::vector<anab::T0> );
77  std::unique_ptr< std::vector<larpandoraobj::PFParticleMetadata> > outputParticleMetadata( new std::vector<larpandoraobj::PFParticleMetadata> );
78 
79  std::unique_ptr< art::Assns<recob::PFParticle, larpandoraobj::PFParticleMetadata> > outputParticlesToMetadata( new art::Assns<recob::PFParticle, larpandoraobj::PFParticleMetadata> );
80  std::unique_ptr< art::Assns<recob::PFParticle, recob::SpacePoint> > outputParticlesToSpacePoints( new art::Assns<recob::PFParticle, recob::SpacePoint> );
81  std::unique_ptr< art::Assns<recob::PFParticle, recob::Cluster> > outputParticlesToClusters( new art::Assns<recob::PFParticle, recob::Cluster> );
82  std::unique_ptr< art::Assns<recob::PFParticle, recob::Vertex> > outputParticlesToVertices( new art::Assns<recob::PFParticle, recob::Vertex> );
83  std::unique_ptr< art::Assns<recob::PFParticle, anab::T0> > outputParticlesToT0s( new art::Assns<recob::PFParticle, anab::T0> );
84  std::unique_ptr< art::Assns<recob::SpacePoint, recob::Hit> > outputSpacePointsToHits( new art::Assns<recob::SpacePoint, recob::Hit> );
85  std::unique_ptr< art::Assns<recob::Cluster, recob::Hit> > outputClustersToHits( new art::Assns<recob::Cluster, recob::Hit> );
86 
87  // prepare the algorithm to compute the cluster characteristics;
88  // we use the "standard" one here; configuration would happen here,
89  // but we are using the default configuration for that algorithm
90  cluster::StandardClusterParamsAlg ClusterParamAlgo;
91 
92  size_t particleCounter(0), vertexCounter(0), spacePointCounter(0), clusterCounter(0), t0Counter(0);
93 
94  // Build maps of pandora::Pfos and build recob::vertices
95  ThreeDParticleMap particleMap;
96  ThreeDVertexMap vertexMap;
97 
98  for (const pandora::ParticleFlowObject *const pPfo : pfoVector)
99  {
100  particleMap.insert( std::pair<const pandora::ParticleFlowObject*, size_t>(pPfo, particleCounter++) );
101 
102  if (!pPfo->GetVertexList().empty())
103  {
104  if(pPfo->GetVertexList().size() != 1)
105  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- this particle has multiple interaction vertices ";
106 
107  const pandora::Vertex *const pVertex(pPfo->GetVertexList().front());
108 
109  if (vertexMap.end() != vertexMap.find(pVertex))
110  continue;
111 
112  double pos[3] = {pVertex->GetPosition().GetX(), pVertex->GetPosition().GetY(), pVertex->GetPosition().GetZ()};
113  outputVertices->emplace_back(recob::Vertex(pos, vertexCounter++));
114  vertexMap.insert(std::pair<const pandora::Vertex*, unsigned int>(pVertex, vertexCounter - 1));
115  }
116  }
117 
118  // Loop over pandora::Pfos and build recob::PFParticles
119  for (const pandora::ParticleFlowObject *const pPfo : pfoVector)
120  {
121  // Get Pfo ID
122  ThreeDParticleMap::const_iterator iter = particleMap.find(pPfo);
123  if (particleMap.end() == iter)
124  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- found an unassociated particle";
125 
126  const size_t pfoIdCode(iter->second);
127 
128  // Get Pfo Parents
129  size_t parentIdCode(recob::PFParticle::kPFParticlePrimary);
130  const pandora::PfoList &parentList(pPfo->GetParentPfoList());
131 
132  if (!parentList.empty())
133  {
134  if (parentList.size() != 1)
135  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- this particle has multiple parent particles ";
136 
137  ThreeDParticleMap::const_iterator parentIdIter = particleMap.find(*parentList.begin());
138  if (particleMap.end() == parentIdIter)
139  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- found an unassociated particle ";
140 
141  parentIdCode = parentIdIter->second;
142  }
143 
144  // Get Pfo Daughters
145  std::vector<size_t> daughterIdCodes;
146  pandora::PfoVector daughterPfoVector(pPfo->GetDaughterPfoList().begin(), pPfo->GetDaughterPfoList().end());
147  std::sort(daughterPfoVector.begin(), daughterPfoVector.end(), lar_content::LArPfoHelper::SortByNHits);
148 
149  for (const pandora::ParticleFlowObject *const pDaughterPfo : daughterPfoVector)
150  {
151  ThreeDParticleMap::const_iterator daughterIdIter = particleMap.find(pDaughterPfo);
152  if (particleMap.end() == daughterIdIter)
153  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- found an unassociated particle ";
154 
155  const size_t daughterIdCode(daughterIdIter->second);
156  daughterIdCodes.push_back(daughterIdCode);
157  }
158 
159  // Build Particle
160  recob::PFParticle newParticle(pPfo->GetParticleId(), pfoIdCode, parentIdCode, daughterIdCodes);
161  outputParticles->push_back(newParticle);
162 
163  // Build default metadata
164  outputParticleMetadata->emplace_back(larpandoraobj::PFParticleMetadata(pPfo));
165 
166  // Associate metadata
167  util::CreateAssn(*(settings.m_pProducer), evt, *(outputParticles.get()), *(outputParticleMetadata.get()), *(outputParticlesToMetadata.get()), outputParticleMetadata->size()-1, outputParticleMetadata->size());
168 
169  // Associate Vertex
170  if (!pPfo->GetVertexList().empty())
171  {
172  if (pPfo->GetVertexList().size() != 1)
173  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- this particle has multiple interaction vertices ";
174 
175  const pandora::Vertex *const pVertex = *(pPfo->GetVertexList().begin());
176 
177  ThreeDVertexMap::const_iterator iter = vertexMap.find(pVertex);
178  if (vertexMap.end() == iter)
179  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- found an unassociated vertex ";
180 
181  const unsigned int vtxElement(iter->second);
182  util::CreateAssn(*(settings.m_pProducer), evt, *(outputParticles.get()), *(outputVertices.get()), *(outputParticlesToVertices.get()),
183  vtxElement, vtxElement + 1);
184  }
185 
186  // Build 2D Clusters
187  pandora::ClusterVector pandoraClusterVector(pPfo->GetClusterList().begin(), pPfo->GetClusterList().end());
188  std::sort(pandoraClusterVector.begin(), pandoraClusterVector.end(), lar_content::LArClusterHelper::SortByNHits);
189 
190  for (const pandora::Cluster *const pCluster : pandoraClusterVector)
191  {
192  if (pandora::TPC_3D == lar_content::LArClusterHelper::GetClusterHitType(pCluster))
193  continue;
194 
195  pandora::CaloHitList pandoraHitList2D;
196  pCluster->GetOrderedCaloHitList().FillCaloHitList(pandoraHitList2D);
197  pandoraHitList2D.insert(pandoraHitList2D.end(), pCluster->GetIsolatedCaloHitList().begin(), pCluster->GetIsolatedCaloHitList().end());
198 
199  pandora::CaloHitVector pandoraHitVector2D(pandoraHitList2D.begin(), pandoraHitList2D.end());
200  std::sort(pandoraHitVector2D.begin(), pandoraHitVector2D.end(), lar_content::LArClusterHelper::SortHitsByPosition);
201 
202  HitArray hitArray; // sort hits by drift volume
203  HitList isolatedHits; // select isolated hits
204 
205  for (const pandora::CaloHit *const pCaloHit2D : pandoraHitVector2D)
206  {
207  const art::Ptr<recob::Hit> hit = LArPandoraOutput::GetHit(idToHitMap, pCaloHit2D);
208 
209  const geo::WireID wireID(hit->WireID());
210  const unsigned int volID(100000 * wireID.Cryostat + wireID.TPC);
211  hitArray[volID].push_back(hit);
212 
213  if (pCaloHit2D->IsIsolated())
214  isolatedHits.insert(hit);
215  }
216 
217  if (hitArray.empty())
218  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- found a cluster with no hits ";
219 
220  for (const HitArray::value_type &hitArrayEntry : hitArray)
221  {
222  const HitVector &clusterHits(hitArrayEntry.second);
223  outputClusters->emplace_back(LArPandoraOutput::BuildCluster(clusterCounter++, clusterHits, isolatedHits, ClusterParamAlgo));
224 
225  util::CreateAssn(*(settings.m_pProducer), evt, *(outputClusters.get()), clusterHits, *(outputClustersToHits.get()));
226  util::CreateAssn(*(settings.m_pProducer), evt, *(outputParticles.get()), *(outputClusters.get()), *(outputParticlesToClusters.get()),
227  outputClusters->size() - 1, outputClusters->size());
228 
229  LOG_DEBUG("LArPandora") << "Stored cluster ID=" << outputClusters->back().ID() << " (#" << (outputClusters->size() - 1)
230  << ") with " << clusterHits.size() << " hits";
231  }
232  }
233 
234  // Build 3D SpacePoints and calculate T0 from shift in 2D hits
235  pandora::CaloHitList pandoraHitList3D;
236  lar_content::LArPfoHelper::GetCaloHits(pPfo, pandora::TPC_3D, pandoraHitList3D);
237 
238  pandora::CaloHitVector pandoraHitVector3D(pandoraHitList3D.begin(), pandoraHitList3D.end());
239  std::sort(pandoraHitVector3D.begin(), pandoraHitVector3D.end(), lar_content::LArClusterHelper::SortHitsByPosition);
240 
241  double sumT(0.), sumN(0.);
242 
243  for (const pandora::CaloHit *const pCaloHit3D : pandoraHitVector3D)
244  {
245  if (pandora::TPC_3D != pCaloHit3D->GetHitType())
246  throw cet::exception("LArPandora") << " LArPandoraOutput::ProduceArtOutput --- found a 2D hit in a 3D cluster";
247 
248  const pandora::CaloHit *const pCaloHit2D = static_cast<const pandora::CaloHit*>(pCaloHit3D->GetParentAddress());
249 
250  const art::Ptr<recob::Hit> hit = LArPandoraOutput::GetHit(idToHitMap, pCaloHit2D);
251 
252  HitVector spacePointHits;
253  spacePointHits.push_back(hit);
254 
255  // ATTN: We assume that the 2D Pandora hits have been shifted
256  sumT += LArPandoraOutput::CalculateT0(hit, pCaloHit2D);
257  sumN += 1.;
258 
259  outputSpacePoints->emplace_back(LArPandoraOutput::BuildSpacePoint(spacePointCounter++, pCaloHit3D));
260 
261  util::CreateAssn(*(settings.m_pProducer), evt, *(outputSpacePoints.get()), spacePointHits, *(outputSpacePointsToHits.get()));
262  util::CreateAssn(*(settings.m_pProducer), evt, *(outputParticles.get()), *(outputSpacePoints.get()), *(outputParticlesToSpacePoints.get()),
263  outputSpacePoints->size() - 1, outputSpacePoints->size());
264  }
265 
266  // Output T0 objects [arguments are: time (nanoseconds); trigger type (3 for TPC stitching!); pfparticle SelfID code; T0 ID code]
267  // ATTN: T0 values are currently calculated in nanoseconds relative to the trigger offset. Only non-zero values are outputted.
268  const double T0((sumN > 0. && std::fabs(sumT) > sumN) ? (sumT / sumN) : 0.);
269 
270  if (settings.m_shouldRunStitching && std::fabs(T0) > 0.)
271  {
272  outputT0s->emplace_back(anab::T0(T0, 3, outputParticles->back().Self(), t0Counter++));
273  util::CreateAssn(*(settings.m_pProducer), evt, *(outputParticles.get()), *(outputT0s.get()), *(outputParticlesToT0s.get()), outputT0s->size() - 1, outputT0s->size());
274  }
275  }
276 
277  mf::LogDebug("LArPandora") << " Number of new particles: " << outputParticles->size() << std::endl;
278  mf::LogDebug("LArPandora") << " Number of new clusters: " << outputClusters->size() << std::endl;
279  mf::LogDebug("LArPandora") << " Number of new space points: " << outputSpacePoints->size() << std::endl;
280  mf::LogDebug("LArPandora") << " Number of new vertices: " << outputVertices->size() << std::endl;
281 
282  if (settings.m_shouldRunStitching)
283  mf::LogDebug("LArPandora") << " Number of new T0s: " << outputT0s->size() << std::endl;
284 
285  evt.put(std::move(outputParticles));
286  evt.put(std::move(outputSpacePoints));
287  evt.put(std::move(outputClusters));
288  evt.put(std::move(outputVertices));
289  evt.put(std::move(outputParticleMetadata));
290 
291  evt.put(std::move(outputParticlesToMetadata));
292  evt.put(std::move(outputParticlesToSpacePoints));
293  evt.put(std::move(outputParticlesToClusters));
294  evt.put(std::move(outputParticlesToVertices));
295  evt.put(std::move(outputSpacePointsToHits));
296  evt.put(std::move(outputClustersToHits));
297 
298  if (settings.m_shouldRunStitching)
299  {
300  evt.put(std::move(outputT0s));
301  evt.put(std::move(outputParticlesToT0s));
302  }
303 
304  mf::LogDebug("LArPandora") << " *** LArPandora::ProduceArtOutput() [DONE!] *** " << std::endl;
305 }
306 
307 //------------------------------------------------------------------------------------------------------------------------------------------
308 
309 recob::Cluster LArPandoraOutput::BuildCluster(const int id, const HitVector &hitVector, const HitList &isolatedHits, cluster::ClusterParamsAlgBase &algo)
310 {
311  mf::LogDebug("LArPandora") << " Building Cluster [" << id << "], Number of hits = " << hitVector.size() << std::endl;
312 
313  if (hitVector.empty())
314  throw cet::exception("LArPandora") << " LArPandoraOutput::BuildCluster --- No input hits were provided ";
315 
316  // Fill list of cluster properties
318  geo::PlaneID planeID;
319 
320  double startWire(+std::numeric_limits<float>::max()), sigmaStartWire(0.0);
321  double startTime(+std::numeric_limits<float>::max()), sigmaStartTime(0.0);
322  double endWire(-std::numeric_limits<float>::max()), sigmaEndWire(0.0);
323  double endTime(-std::numeric_limits<float>::max()), sigmaEndTime(0.0);
324 
325  std::vector<recob::Hit const*> hits_for_params;
326  hits_for_params.reserve(hitVector.size());
327 
328  for (const art::Ptr<recob::Hit> &hit : hitVector)
329  {
330  const double thisWire(hit->WireID().Wire);
331  const double thisWireSigma(0.5);
332  const double thisTime(hit->PeakTime());
333  const double thisTimeSigma(double(2.*hit->RMS()));
334  const geo::View_t thisView(hit->View());
335  const geo::PlaneID thisPlaneID(hit->WireID().planeID());
336 
337  if (geo::kUnknown == view)
338  {
339  view = thisView;
340  planeID = thisPlaneID;
341  }
342 
343  if (!(thisView == view && thisPlaneID == planeID))
344  {
345  throw cet::exception("LArPandora") << " LArPandoraOutput::BuildCluster --- Input hits have inconsistent plane IDs ";
346  }
347 
348  hits_for_params.push_back(&*hit);
349 
350  if (isolatedHits.count(hit))
351  continue;
352 
353  if (thisWire < startWire || (thisWire == startWire && thisTime < startTime))
354  {
355  startWire = thisWire;
356  sigmaStartWire = thisWireSigma;
357  startTime = thisTime;
358  sigmaStartTime = thisTimeSigma;
359  }
360 
361  if (thisWire > endWire || (thisWire == endWire && thisTime > endTime))
362  {
363  endWire = thisWire;
364  sigmaEndWire = thisWireSigma;
365  endTime = thisTime;
366  sigmaEndTime = thisTimeSigma;
367  }
368 
369  }
370 
371  // feed the algorithm with all the cluster hits
372  algo.SetHits(hits_for_params);
373 
374  // create the recob::Cluster directly in the vector
376  algo, // algo
377  startWire, // start_wire
378  sigmaStartWire, // sigma_start_wire
379  startTime, // start_tick
380  sigmaStartTime, // sigma_start_tick
381  endWire, // end_wire
382  sigmaEndWire, // sigma_end_wire
383  endTime, // end_tick
384  sigmaEndTime, // sigma_end_tick
385  id, // ID
386  view, // view
387  planeID, // plane
388  recob::Cluster::Sentry // sentry
389  ).move();
390 }
391 
392 //------------------------------------------------------------------------------------------------------------------------------------------
393 
394 recob::SpacePoint LArPandoraOutput::BuildSpacePoint(const int id, const pandora::CaloHit *const pCaloHit)
395 {
396  if (pandora::TPC_3D != pCaloHit->GetHitType())
397  throw cet::exception("LArPandora") << " LArPandoraOutput::BuildSpacePoint --- trying to build a space point from a 2D hit";
398 
399  const pandora::CartesianVector point(pCaloHit->GetPositionVector());
400  double xyz[3] = { point.GetX(), point.GetY(), point.GetZ() };
401  double dxdydz[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // TODO: Fill in the error matrix
402  double chi2(0.0);
403 
404  return recob::SpacePoint(xyz, dxdydz, chi2, id);
405 }
406 
407 //------------------------------------------------------------------------------------------------------------------------------------------
408 
409 art::Ptr<recob::Hit> LArPandoraOutput::GetHit(const IdToHitMap &idToHitMap, const pandora::CaloHit *const pCaloHit)
410 {
411  const void *const pHitAddress(pCaloHit->GetParentAddress());
412  const intptr_t hitID_temp((intptr_t)(pHitAddress));
413  const int hitID((int)(hitID_temp));
414 
415  IdToHitMap::const_iterator artIter = idToHitMap.find(hitID);
416 
417  if (idToHitMap.end() == artIter)
418  throw cet::exception("LArPandora") << " LArPandoraOutput::GetHit --- found a Pandora hit without a parent ART hit ";
419 
420  return artIter->second;
421 }
422 
423 //------------------------------------------------------------------------------------------------------------------------------------------
424 
425 double LArPandoraOutput::CalculateT0(const art::Ptr<recob::Hit> hit, const pandora::CaloHit *const pCaloHit)
426 {
428  auto const* theDetector = lar::providerFrom<detinfo::DetectorPropertiesService>();
429 
430  const geo::WireID hit_WireID(hit->WireID());
431  const geo::TPCGeo &theTpc = theGeometry->Cryostat(hit_WireID.Cryostat).TPC(hit_WireID.TPC);
432 
433  // Calculate shift in x position between input and output hits
434  const double input_xpos_cm(theDetector->ConvertTicksToX(hit->PeakTime(), hit_WireID.Plane, hit_WireID.TPC, hit_WireID.Cryostat));
435  const double output_xpos_dm(pCaloHit->GetPositionVector().GetX());
436  const double x0_cm(output_xpos_dm - input_xpos_cm);
437 
438  // The ingredients for the T0 calculation all come from the detector properties service
439  const double dir((theTpc.DriftDirection() == geo::kNegX) ? 1.0 : -1.0);
440  const double cm_per_tick(theDetector->GetXTicksCoefficient());
441  const double ns_per_tick(theDetector->SamplingRate());
442 
443  // This calculation should give the T0 in nanoseconds relative to the initial 2D hit
444  return (- dir * x0_cm * ns_per_tick / cm_per_tick);
445 }
446 
447 //------------------------------------------------------------------------------------------------------------------------------------------
448 
450  m_pPrimaryPandora(nullptr),
451  m_pProducer(nullptr),
452  m_shouldRunStitching(false)
453 {
454 }
455 
456 } // namespace lar_pandora
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position, then pulse-height.
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
Header file for the pfo helper class.
Class managing the creation of a new recob::Cluster object.
const pandora::Pandora * m_pPrimaryPandora
static constexpr size_t kPFParticlePrimary
Define index to signify primary particle.
Definition: PFParticle.h:61
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Unknown view.
Definition: geo_types.h:83
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
Declaration of signal hit object.
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
Geometry information for a single TPC.
Definition: TPCGeo.h:37
Algorithm collection class computing cluster parameters.
Set of hits with a 2D structure.
Definition: Cluster.h:71
std::map< int, art::Ptr< recob::Hit > > IdToHitMap
Definition: ILArPandora.h:20
static double CalculateT0(const art::Ptr< recob::Hit > hit, const pandora::CaloHit *const pCaloHit)
Convert X0 correction into T0 correction.
static art::Ptr< recob::Hit > GetHit(const IdToHitMap &idToHitMap, const pandora::CaloHit *const pCaloHit)
Lookup ART hit from an input Pandora hit.
Helper functions for processing outputs from pandora.
Definition: T0.h:19
Drift towards negative X values.
Definition: geo_types.h:109
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
Metadata associated with a pandora produced PFParticle.
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
static recob::SpacePoint BuildSpacePoint(const int id, const pandora::CaloHit *const pCaloHit)
Build a recob::SpacePoint object.
std::map< const pandora::ParticleFlowObject *, size_t > ThreeDParticleMap
Algorithm collection class computing cluster parameters.
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
std::map< const pandora::Vertex *, unsigned int > ThreeDVertexMap
Int_t max
Definition: plot.C:27
intermediate_table::const_iterator const_iterator
Pandora PFParticleMetadata.
std::map< int, HitVector > HitArray
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
Header file for the cluster helper class.
Helper functions to create a cluster.
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
Wrapper for ClusterParamsAlgBase objects to accept arbitrary input.
static void ProduceArtOutput(const Settings &settings, const IdToHitMap &idToHitMap, art::Event &evt)
Convert the Pandora PFOs into ART clusters and write into ART event.
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
std::vector< art::Ptr< recob::Hit > > HitVector
Detector simulation of raw signals on wires.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:219
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
Utility object to perform functions of association.
TDirectory * dir
Definition: macro.C:5
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
#define LOG_DEBUG(id)
Interface to class computing cluster parameters.
virtual void SetHits(std::vector< recob::Hit const * > const &hits)=0
Sets the list of input hits.
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.
recob::Cluster && move()
Prepares the constructed hit to be moved away.
std::set< art::Ptr< recob::Hit > > HitList
static recob::Cluster BuildCluster(const int id, const HitVector &hitVector, const HitList &isolatedHits, cluster::ClusterParamsAlgBase &algo)
Build a recob::Cluster object from an input vector of recob::Hit objects.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33