All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Attributes | List of all members
sbn::PCAnglePlaneMaker Class Reference
Inheritance diagram for sbn::PCAnglePlaneMaker:

Public Member Functions

 PCAnglePlaneMaker (fhicl::ParameterSet const &p)
 
 PCAnglePlaneMaker (PCAnglePlaneMaker const &)=delete
 
 PCAnglePlaneMaker (PCAnglePlaneMaker &&)=delete
 
PCAnglePlaneMakeroperator= (PCAnglePlaneMaker const &)=delete
 
PCAnglePlaneMakeroperator= (PCAnglePlaneMaker &&)=delete
 
void produce (art::Event &e) override
 

Private Attributes

art::InputTag fPFParticleLabel
 
bool fFollowDaughters
 
float fHitGroupDistance
 
bool fOnlyPrimary
 

Detailed Description

Definition at line 51 of file PCAnglePlaneMaker_module.cc.

Constructor & Destructor Documentation

sbn::PCAnglePlaneMaker::PCAnglePlaneMaker ( fhicl::ParameterSet const &  p)
explicit

Definition at line 177 of file PCAnglePlaneMaker_module.cc.

178  : EDProducer{p},
179  fPFParticleLabel(p.get<std::string>("PFParticleLabel", "pandora")),
180  fFollowDaughters(p.get<bool>("FollowDaughters", true)),
181  fHitGroupDistance(p.get<float>("HitGroupDistance")),
182  fOnlyPrimary(p.get<bool>("OnlyPrimary", true))
183 {
184  produces<std::vector<sbn::PCAnglePlane>>();
185  produces<art::Assns<recob::PFParticle, sbn::PCAnglePlane>>();
186 }
pdgs p
Definition: selectors.fcl:22
sbn::PCAnglePlaneMaker::PCAnglePlaneMaker ( PCAnglePlaneMaker const &  )
delete
sbn::PCAnglePlaneMaker::PCAnglePlaneMaker ( PCAnglePlaneMaker &&  )
delete

Member Function Documentation

PCAnglePlaneMaker& sbn::PCAnglePlaneMaker::operator= ( PCAnglePlaneMaker const &  )
delete
PCAnglePlaneMaker& sbn::PCAnglePlaneMaker::operator= ( PCAnglePlaneMaker &&  )
delete
void sbn::PCAnglePlaneMaker::produce ( art::Event &  e)
override

Definition at line 188 of file PCAnglePlaneMaker_module.cc.

189 {
190  // output stuff
191  std::unique_ptr<std::vector<sbn::PCAnglePlane>> outAngles(new std::vector<sbn::PCAnglePlane>);
192  std::unique_ptr<art::Assns<recob::PFParticle, sbn::PCAnglePlane>> assn(new art::Assns<recob::PFParticle, sbn::PCAnglePlane>);
193 
194  art::PtrMaker<sbn::PCAnglePlane> anglePtrMaker {evt};
195 
196  // collect services
197  const geo::GeometryCore *geo = lar::providerFrom<geo::Geometry>();
198  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
199  auto const dprop =
200  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clock_data);
201 
202 
203  // get the PFParticle's and the associated data
204  art::Handle<std::vector<recob::PFParticle>> pfparticle_handle;
205  evt.getByLabel(fPFParticleLabel, pfparticle_handle);
206 
207  std::vector<art::Ptr<recob::PFParticle>> pfparticles;
208  art::fill_ptr_vector(pfparticles, pfparticle_handle);
209 
210  // organize the PFPlist into a map
211  std::map<unsigned, art::Ptr<recob::PFParticle>> id_to_pfp;
212  for (unsigned i = 0; i < pfparticles.size(); i++) {
213  id_to_pfp[pfparticles[i]->Self()] = pfparticles[i];
214  }
215 
216  art::FindManyP<recob::Cluster> pfparticleClusters(pfparticles, evt, fPFParticleLabel);
217  art::FindManyP<recob::Vertex> pfparticleVertices(pfparticles, evt, fPFParticleLabel);
218 
219  // iterate over each particle
220  for (unsigned i_part = 0; i_part < pfparticles.size(); i_part++) {
221  std::cout << "New particle! " << i_part << std::endl;
222  art::Ptr<recob::PFParticle> thisPFP = pfparticles[i_part];
223 
224  std::cout << "Child of: " << thisPFP->Parent() << std::endl;
225 
226  // ignore non-primary or child of primary
227  if (fOnlyPrimary &&
228  thisPFP->Parent() != recob::PFParticle::kPFParticlePrimary &&
229  id_to_pfp.at(thisPFP->Parent())->Parent() != recob::PFParticle::kPFParticlePrimary) {
230  continue;
231  }
232 
233  // keep track of the map between this PFParticle and all the hits
234  std::map<unsigned, std::array<std::vector<unsigned>, 3>> pfpToHits;
235  std::map<unsigned, std::array<std::vector<art::Ptr<recob::Hit>>,3>> allHits;
236 
237  const std::vector<art::Ptr<recob::Cluster>> &thisCluster = pfparticleClusters.at(i_part);
238  art::FindManyP<recob::Hit> clusterHits(thisCluster, evt, fPFParticleLabel);
239 
240  // ignore PFP's w/out hits
241  if (!thisCluster.size()) {
242  std::cout << "No clusters :/\n";
243  continue;
244  }
245 
246  const std::vector<art::Ptr<recob::Vertex>> &pfpVerts = pfparticleVertices.at(i_part);
247 
248  // ignore PFP's w/out vertex
249  if (!pfpVerts.size()) {
250  std::cout << "No vertex :/\n";
251  continue;
252  }
253 
254  // grab the vertex
255  const recob::Vertex &pfpVert = *pfpVerts.at(0);
256 
257  std::cout << "Valid!\n";
258 
259  for (unsigned i_clus = 0; i_clus < thisCluster.size(); i_clus++) {
260  allHits[thisPFP->Self()][thisCluster[i_clus]->Plane().Plane].insert(allHits[thisPFP->Self()][thisCluster[i_clus]->Plane().Plane].begin(),
261  clusterHits.at(i_clus).begin(), clusterHits.at(i_clus).end());
262  SaveHits(pfpToHits, clusterHits.at(i_clus), thisCluster[i_clus]->Plane().Plane, thisPFP);
263  }
264 
265  // also get the hits from each daughter PFP (and so on) if configured
266  if (fFollowDaughters) {
267  // define the data we keep in the stack
268  struct daughter_stack_info {
269  unsigned daughter_id;
270  long unsigned hit_key;
271  };
272 
273  std::stack<daughter_stack_info> d_pfps;
274  for (unsigned d: thisPFP->Daughters()) {
275  daughter_stack_info dsi {d, thisPFP->Self()};
276  d_pfps.push(dsi);
277  }
278 
279  // DFS
280  while (!d_pfps.empty()) {
281  daughter_stack_info daughter_info = d_pfps.top();
282  unsigned daughter = daughter_info.daughter_id;
283  unsigned hit_key = daughter_info.hit_key;
284  d_pfps.pop();
285 
286  // get the PFP
287  const art::Ptr<recob::PFParticle> &d_pfp = id_to_pfp.at(daughter);
288 
289  // determine whether to branch
290  if (DoBranch(d_pfp, id_to_pfp)) {
291  // branching -- make a new entry in the allHits-map with this particle
292  //
293  // First clone the hits we already have
294  allHits[d_pfp->Self()][0] = allHits[hit_key][0];
295  allHits[d_pfp->Self()][1] = allHits[hit_key][1];
296  allHits[d_pfp->Self()][2] = allHits[hit_key][2];
297 
298  // and re-direct this hits to the new location
299  hit_key = d_pfp->Self();
300  }
301 
302  // add the daughter-daughters
303  for (unsigned d: d_pfp->Daughters()) {
304  daughter_stack_info dsi {d, hit_key};
305  d_pfps.push(dsi);
306  }
307 
308  // add the hits
309  const std::vector<art::Ptr<recob::Cluster>> &d_cluster = pfparticleClusters.at(d_pfp.key());
310 
311  // ignore PFP's w/out hits
312  if (!d_cluster.size()) continue;
313 
314  art::FindManyP<recob::Hit> d_cluster_hits(d_cluster, evt, fPFParticleLabel);
315  for (unsigned i_clus = 0; i_clus < d_cluster.size(); i_clus++) {
316  allHits[hit_key][d_cluster[i_clus]->Plane().Plane].insert(allHits[hit_key][d_cluster[i_clus]->Plane().Plane].begin(),
317  d_cluster_hits.at(i_clus).begin(), d_cluster_hits.at(i_clus).end());
318  SaveHits(pfpToHits, d_cluster_hits.at(i_clus), d_cluster[i_clus]->Plane().Plane, d_pfp);
319  }
320  }
321  }
322 
323 
324  std::array<std::vector<sbn::PCAngleInfo>, 3> planeAngles;
325  // Now we have all the hits we need!
326  //
327  // iterate through each branch
328  for (auto const &pair: allHits) {
329  unsigned branch_id = pair.first;
330  const std::array<std::vector<art::Ptr<recob::Hit>>, 3> &branchHits = pair.second;
331 
332  // Now, for each hit, we'll consider the PCA angle and the vec angle
333  //
334  // First, order this hits
335  std::array<std::vector<art::Ptr<recob::Hit>>, 3> sortedHits = SortHits(branchHits, pfpVert, geo, dprop);
336 
337  // iterate through all the Hits
338  for (unsigned i_plane = 0; i_plane < 3; i_plane++) {
339  for (unsigned i_hit = 0; i_hit < sortedHits[i_plane].size(); i_hit++) {
340  // get nearby hits
341  auto [hitslo, hitshi, complete] = sbnpca::GetNearestHits(sortedHits[i_plane], i_hit, fHitGroupDistance, geo, dprop);
342 
343  //std::cout << "Plane: " << i_plane << " Branch: " << branch_id << " hit: " << i_hit << " " << sortedHits[i_plane][i_hit].key();
344  //if (hitslo.size()) std::cout << " lo: " << hitslo.back().key();
345  //else std::cout << " lo: none";
346  //if (hitshi.size()) std::cout << " hi: " << hitshi.back().key();
347  //else std::cout << " hi: none";
348  //std::cout << std::endl;
349 
350  // invalid -- continue
351  // if (hithi.size() < 2 || hitslo.size() < 2) continue;
352 
353  // Get the PCA dirs
354  std::array<float, 2> pca_vec_lo = sbnpca::HitPCAVec(hitslo, *sortedHits[i_plane][i_hit], geo, dprop);
355  std::array<float, 2> pca_vec_hi = sbnpca::HitPCAVec(hitshi, *sortedHits[i_plane][i_hit], geo, dprop);
356  float angle = -100.;
357  // check if valid vecs
358  if (pca_vec_lo[0] > -99. && pca_vec_lo[1] > -99. && pca_vec_hi[0] > -99. && pca_vec_hi[1] > -99.) {
359  // get angle between the two vecs and flip
360  angle = M_PI - sbnpca::VecAngle(pca_vec_lo, pca_vec_hi);
361  }
362 
363  std::array<float, 2> hv = sbnpca::HitVector(*sortedHits[i_plane][i_hit], geo, dprop);
364 
365  // and save
366  sbn::PCAngleInfo thisAngle;
367  thisAngle.angle.wire = sortedHits[i_plane][i_hit]->WireID();
368  thisAngle.angle.angle = angle;
369  thisAngle.angle.lo_vector = pca_vec_lo;
370  thisAngle.angle.hi_vector = pca_vec_hi;
371  thisAngle.angle.hit_wire_cm = hv[0];
372  thisAngle.angle.hit_time_cm = hv[1];
373  thisAngle.angle.complete = complete;
374  thisAngle.angle.hitID = sortedHits[i_plane][i_hit].key();
375 
376  if (hitshi.size()) thisAngle.angle.dist_to_hi = sbnpca::HitDistance(*hitshi.back(), *sortedHits[i_plane][i_hit], geo, dprop);
377  else thisAngle.angle.dist_to_hi = -100.;
378  if (hitslo.size()) thisAngle.angle.dist_to_lo = sbnpca::HitDistance(*hitslo.back(), *sortedHits[i_plane][i_hit], geo, dprop);
379  else thisAngle.angle.dist_to_lo = -100.;
380 
381  if (hitshi.size()) thisAngle.angle.hitIDHi = hitshi.back().key();
382  else thisAngle.angle.hitIDHi = -1;
383  if (hitslo.size()) thisAngle.angle.hitIDLo = hitslo.back().key();
384  else thisAngle.angle.hitIDLo = -1;
385 
386  thisAngle.branch = branch_id;
387  thisAngle.hit_ind = i_hit;
388 
389  // get the generation
390  thisAngle.generation = 0;
391  art::Ptr<recob::PFParticle> check = id_to_pfp.at(branch_id);
392  while (check->Self() != thisPFP->Self()) {
393  thisAngle.generation ++;
394  check = id_to_pfp.at(check->Parent());
395  }
396 
397  planeAngles[i_plane].push_back(thisAngle);
398  }
399  }
400  }
401 
402  // Save the angles on each plane
403  for (unsigned i_plane = 0; i_plane < 3; i_plane++) {
404  std::map<unsigned, std::vector<sbn::PCAngleInfo>> selected = RemoveDupes(planeAngles[i_plane]);
405 
406  sbn::PCAnglePlane thisPlane;
407  geo::PlaneID planeID(0, 0, i_plane); // TPC and cryo are arbitrary
408  thisPlane.plane = planeID;
409  for (auto const &pair: selected) {
410  thisPlane.branchIDs.push_back(pair.first);
411 
412  // look up the hierarchy
413  thisPlane.branchHierarchy.emplace_back();
414  art::Ptr<recob::PFParticle> check = id_to_pfp.at(pair.first);
415  thisPlane.branchHierarchy.back().push_back(check->Self());
416  while (check->Self() != thisPFP->Self()) {
417  check = id_to_pfp.at(check->Parent());
418  thisPlane.branchHierarchy.back().push_back(check->Self());
419  }
420 
421  if (pair.second.size()) thisPlane.generations.push_back(pair.second.front().generation);
422  else thisPlane.generations.push_back(-1);
423 
424  if (pair.second.size()) thisPlane.plane = pair.second.front().angle.wire;
425 
426  thisPlane.angles.emplace_back();
427  for (const sbn::PCAngleInfo &a: pair.second) thisPlane.angles.back().push_back(a.angle);
428  }
429  thisPlane.nBranches = thisPlane.angles.size();
430  outAngles->push_back(thisPlane);
431  art::Ptr<sbn::PCAnglePlane> thisAnglePtr = anglePtrMaker(outAngles->size()-1);
432  assn->addSingle(thisPFP, thisAnglePtr);
433  }
434 
435  }
436 
437  evt.put(std::move(outAngles));
438  evt.put(std::move(assn));
439 
440 }
void SaveHits(std::map< unsigned, std::array< std::vector< unsigned >, 3 >> &pfpToHits, const std::vector< art::Ptr< recob::Hit >> &hits, unsigned plane, const art::Ptr< recob::PFParticle > &pfp)
BEGIN_PROLOG true icarus_rawdigitfilter FilterTools FilterPlane1 Plane
std::array< float, 2 > HitPCAVec(const std::vector< art::Ptr< recob::Hit >> &hits, const recob::Hit &center, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
Definition: PCA.cc:69
static constexpr size_t kPFParticlePrimary
Define index to signify primary particle.
Definition: PFParticle.h:61
std::map< unsigned, std::vector< sbn::PCAngleInfo > > RemoveDupes(std::vector< sbn::PCAngleInfo > &angles)
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
process_name gaushit a
std::tuple< std::vector< art::Ptr< recob::Hit > >, std::vector< art::Ptr< recob::Hit > >, bool > GetNearestHits(const std::vector< art::Ptr< recob::Hit >> &hits, int ihit, float distance, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
Definition: PCA.cc:39
process_name tightIsolTest check
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > SortHits(const std::array< std::vector< art::Ptr< recob::Hit >>, 3 > &hits, const recob::Vertex &start, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
float VecAngle(std::array< float, 2 > A, std::array< float, 2 > B)
Definition: PCA.cc:5
float HitDistance(const recob::Hit &A, const recob::Hit &B, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
Definition: PCA.cc:34
Description of geometry of one entire detector.
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
finds tracks best matching by angle
TCEvent evt
Definition: DataStructs.cxx:8
bool DoBranch(art::Ptr< recob::PFParticle > particle, const std::map< unsigned, art::Ptr< recob::PFParticle >> &pfpMap)
BEGIN_PROLOG could also be cout
std::array< float, 2 > HitVector(const recob::Hit &A, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
Definition: PCA.cc:12

Member Data Documentation

bool sbn::PCAnglePlaneMaker::fFollowDaughters
private

Definition at line 70 of file PCAnglePlaneMaker_module.cc.

float sbn::PCAnglePlaneMaker::fHitGroupDistance
private

Definition at line 71 of file PCAnglePlaneMaker_module.cc.

bool sbn::PCAnglePlaneMaker::fOnlyPrimary
private

Definition at line 72 of file PCAnglePlaneMaker_module.cc.

art::InputTag sbn::PCAnglePlaneMaker::fPFParticleLabel
private

Definition at line 69 of file PCAnglePlaneMaker_module.cc.


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