CaloClusterCheater_module.cc
Go to the documentation of this file.
1 #include <string>
2 #include <algorithm>
3 
11 
13 #include "fhiclcpp/ParameterSet.h"
15 
19 
20 #include "Geometry/GeometryGAr.h"
21 #include "MCCheater/BackTracker.h"
23 #include "nugen/EventGeneratorBase/GENIE/EVGBAssociationUtil.h"
24 
25 #include "RecoAlg/ClusterShapes.h"
26 #include "CLHEP/Vector/ThreeVector.h"
27 
28 namespace gar {
29  namespace rec {
30 
31  class eveLoc {
32  public:
33  eveLoc(int id)
34  : eveID(id)
35  {}
36 
37  ~eveLoc() {}
38 
39  friend bool operator < (eveLoc const& a, eveLoc const& b) {
40  return a.eveID < b.eveID;
41  }
42 
43  int GetEveID() const { return eveID; }
44 
45  private:
46  int eveID;
47  };
48 
50  public:
51  explicit CaloClusterCheater(fhicl::ParameterSet const& pset);
52 
53  // Plugins should not be copied or assigned.
54  CaloClusterCheater(CaloClusterCheater const &) = delete;
56  CaloClusterCheater & operator = (CaloClusterCheater const &) = delete;
57  CaloClusterCheater & operator = (CaloClusterCheater &&) = delete;
58 
59  // Required functions.
60  void produce(art::Event & e) override;
61 
62  private:
63 
64  std::string fCaloHitModuleLabel; ///< label for module creating rec::CaloHit objects
65  std::string fInstanceName; ///< product instance name
66 
67  unsigned int fMinHits; ///< minimum number of hits to make a cluster
68  bool fIgnoreNeutrons; ///< flag to ignore creating neutron clusters
69 
70  gar::geo::GeometryCore const* fGeo; ///< geometry information
71 
72  void CollectHits(const art::Event &evt, const std::string &label, const std::string &instance, std::vector< art::Ptr<gar::rec::CaloHit> > &hitVector);
73  gar::rec::Cluster CreateCluster(const simb::MCParticle *part, std::vector< art::Ptr<gar::rec::CaloHit> > hitVec);
74  };
75 
76  //-----------------------------------------------------------------------------------
77 
79  EDProducer{pset}
80  {
81  fCaloHitModuleLabel = pset.get< std::string >("CaloHitModuleLabel", "calohit" );
82  fInstanceName = pset.get<std::string >("InstanceLabelName", "");
83 
84  fMinHits = pset.get< unsigned int >("MinHits", 1 );
85  fIgnoreNeutrons = pset.get< bool >("IgnoreNeutrons", true );
86 
87  fGeo = gar::providerFrom<geo::GeometryGAr>();
88 
89  art::InputTag tag(fCaloHitModuleLabel, fInstanceName);
90  consumes< std::vector<gar::rec::CaloHit> >(tag);
91  produces< std::vector<gar::rec::Cluster> >(fInstanceName);
92  produces< art::Assns<gar::rec::Cluster, gar::rec::CaloHit> >(fInstanceName);
93  }
94 
95  //-----------------------------------------------------------------------------------
97  {
98  cheat::BackTrackerCore const* bt = gar::providerFrom<cheat::BackTracker>();
99 
100  //Collect the hits to be passed to the algo
101  std::vector< art::Ptr<gar::rec::CaloHit> > artHits;
102  this->CollectHits(e, fCaloHitModuleLabel, fInstanceName, artHits);
103 
104  std::map< eveLoc, std::vector< art::Ptr<gar::rec::CaloHit> > > eveCaloHitMap;
105 
106  // loop over all hits and fill in the map
107  for( auto const& itr : artHits ) {
108 
109  std::vector<gar::cheat::CalIDE> eveides = bt->CaloHitToCalIDEs(itr);
110  // loop over all eveides for this hit
111  for(size_t ieve = 0; ieve < eveides.size(); ieve++) {
112  // don't worry about eve particles that contribute less than 10% of the
113  // energy in the current hit
114  if( eveides[ieve].energyFrac < 0.1) continue;
115 
116  eveLoc el(eveides[ieve].trackID);
117  eveCaloHitMap[el].push_back(itr);
118 
119  } // end loop over eve IDs for this hit
120  }// end loop over hits
121 
122  // loop over the map and make clusters
123  std::unique_ptr< std::vector<gar::rec::Cluster> > clustercol(new std::vector<gar::rec::Cluster>);
124  std::unique_ptr< art::Assns<gar::rec::Cluster, gar::rec::CaloHit> > assn(new art::Assns<gar::rec::Cluster, gar::rec::CaloHit>);
125 
126  for(auto hitMapItr : eveCaloHitMap) {
127 
128  MF_LOG_DEBUG("CaloClusterCheater")
129  << "Found cluster of " << hitMapItr.second.size() << " hits"
130  << " with eveid " << hitMapItr.first.GetEveID();
131 
132  if(hitMapItr.second.size() < fMinHits) continue;
133 
134  const simb::MCParticle *part = bt->TrackIDToParticle(hitMapItr.first.GetEveID());
135  if(!part) {
136  MF_LOG_WARNING("CaloClusterCheater")
137  << "Cannot find MCParticle for eveid: " << hitMapItr.first.GetEveID();
138  continue;
139  }
140 
141  if(fIgnoreNeutrons && part->PdgCode() == 2112) continue;
142 
143  gar::rec::Cluster cluster = this->CreateCluster(part, hitMapItr.second);
144 
145  clustercol->emplace_back(cluster);
146  // association the hits to this cluster
147  evgb::util::CreateAssn(*this, e, *clustercol, hitMapItr.second, *assn, clustercol->size() - 1);
148  MF_LOG_DEBUG("CaloClusterCheater") << "adding cluster: \n" << clustercol->back() << "\nto collection.";
149 
150  } // end loop over the map
151 
152  e.put(std::move(clustercol), fInstanceName);
153  e.put(std::move(assn), fInstanceName);
154  }
155 
156  //-----------------------------------------------------------------------------------
158  {
159  art::InputTag itag(label,instance);
160  auto theHits = evt.getHandle< std::vector<gar::rec::CaloHit> >(itag);
161  if (!theHits) return;
162 
163  for (unsigned int i = 0; i < theHits->size(); ++i)
164  {
165  const art::Ptr<gar::rec::CaloHit> hit(theHits, i);
166  hitVector.push_back(hit);
167  }
168  }
169 
170  //-----------------------------------------------------------------------------------
172  {
173  gar::rec::Cluster clu;
174 
175  unsigned n = hitVec.size() ;
176  unsigned i = 0 ;
177  float rmin = 9999.;
178  float rmax = 0.;
179  std::vector<float> tmin;
180  std::vector<float> tmax;
181 
182  std::vector<float> a, t, x, y, z;
183  a.resize(n);
184  t.resize(n);
185  x.resize(n);
186  y.resize(n);
187  z.resize(n);
188 
189  for( auto const &it : hitVec ) {
190  a[i] = it->Energy() ;
191  t[i] = it->Time().first ;
192  x[i] = it->Position()[0] ;
193  y[i] = it->Position()[1] ;
194  z[i] = it->Position()[2] ;
195 
196  // clu.addHit( it , a[i] ) ;
197 
198  //get time of first layer and last layer to compute the difference
199  float r = std::sqrt(y[i]*y[i] + z[i]*z[i]);
200  if( std::fabs(x[i]) < fGeo->GetECALEndcapStartX() ){
201  //case in barrel
202  if(rmin >= r)
203  {
204  rmin = r;
205  tmin.push_back(t[i]);
206  }
207  if(rmax <= r)
208  {
209  rmax = r;
210  tmax.push_back(t[i]);
211  }
212  }
213  else{
214  //case endcap
215  if( rmin >= std::fabs(x[i]) )
216  {
217  rmin = std::fabs(x[i]);
218  tmin.push_back(t[i]);
219  }
220  if( rmax <= std::fabs(x[i]) )
221  {
222  rmax = std::fabs(x[i]);
223  tmax.push_back(t[i]);
224  }
225  }
226 
227  ++i ;
228  }
229 
230  //get minimum time of the first layer
231  auto time_first = std::min_element( tmin.begin(), tmin.end() );
232  assert(time_first != tmin.end());
233  //get minimum time of the last layer
234  auto time_last = std::min_element( tmax.begin(), tmax.end() );
235  assert(time_last != tmax.end());
236 
237  util::ClusterShapes cs(n, a, t, x, y, z) ;
238 
239  clu.setEnergy( cs.getTotalAmplitude() ) ;
240  clu.setTime( cs.getAverageTime(), *time_first - *time_last ) ;
241  clu.setPosition( cs.getCenterOfGravity() ) ;
242 
243  // direction of cluster's PCA
244  float* d = cs.getEigenVecInertia() ;
245  clu.setEigenVectors( d );
246 
247  //Main eigenvector
248  CLHEP::Hep3Vector v( d[0], d[1], d[2] ) ;
249 
250  clu.setITheta( v.theta() ) ;
251  clu.setIPhi( v.phi() ) ;
252 
253  float param[6] ;
254 
255  // param[0] = cs.getElipsoid_r1() ;
256  param[0] = cs.getElipsoid_r_forw();
257  param[1] = cs.getElipsoid_r_back();
258  param[2] = cs.getElipsoid_r2() ;
259  param[3] = cs.getElipsoid_r3() ;
260  param[4] = cs.getElipsoid_vol() ;
261  param[5] = cs.getWidth() ;
262 
263  clu.setShape( param ) ;
264 
265  clu.setParticleID( part->PdgCode() );
266 
267  return clu;
268  }
269 
270  } //namespace rec
271  } //namespace gar
272 
273  namespace gar {
274  namespace rec {
276  }
277  }
std::vector< CalIDE > CaloHitToCalIDEs(art::Ptr< rec::CaloHit > const &hit) const
int PdgCode() const
Definition: MCParticle.h:212
rec
Definition: tracks.py:88
bool fIgnoreNeutrons
flag to ignore creating neutron clusters
void setParticleID(int pid)
Definition: Cluster.cxx:59
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
void setShape(const float *shape)
Definition: Cluster.cxx:54
struct vector vector
gar::rec::Cluster CreateCluster(const simb::MCParticle *part, std::vector< art::Ptr< gar::rec::CaloHit > > hitVec)
const std::string instance
Description of geometry of one entire detector.
Definition: GeometryCore.h:436
Cluster finding and building.
friend bool operator<(eveLoc const &a, eveLoc const &b)
void setEigenVectors(const float *eigenvectors)
Definition: Cluster.cxx:49
void CollectHits(const art::Event &evt, const std::string &label, const std::string &instance, std::vector< art::Ptr< gar::rec::CaloHit > > &hitVector)
const double e
void setEnergy(float energy)
Definition: Cluster.cxx:18
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
bt
Definition: tracks.py:83
std::void_t< T > n
std::string fCaloHitModuleLabel
label for module creating rec::CaloHit objects
void setPosition(const float *position)
Definition: Cluster.cxx:34
const double a
def move(depos, offset)
Definition: depos.py:107
simb::MCParticle * TrackIDToParticle(int const &id) const
gar::geo::GeometryCore const * fGeo
geometry information
CaloClusterCheater(fhicl::ParameterSet const &pset)
std::string fInstanceName
product instance name
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
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.
float GetECALEndcapStartX() const
Definition: GeometryCore.h:975
unsigned int fMinHits
minimum number of hits to make a cluster
General GArSoft Utilities.
void setIPhi(float phi)
Definition: Cluster.cxx:44
void setITheta(float theta)
Definition: Cluster.cxx:39
#define MF_LOG_DEBUG(id)
static bool * b
Definition: config.cpp:1043
void produce(art::Event &e) override
list x
Definition: train.py:276
TCEvent evt
Definition: DataStructs.cxx:7
const char * cs
#define MF_LOG_WARNING(category)
art framework interface to geometry description
void setTime(float time, float time_diff)
Definition: Cluster.cxx:28