LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
TrackCheater_module.cc
Go to the documentation of this file.
1 //
3 // TrackCheater module
4 //
5 // brebel@fnal.gov
6 //
8 // Framework includes
10 
11 #ifndef TRKF_TRACKCHEATER_H
12 #define TRKF_TRACKCHEATER_H
13 #include <string>
14 
15 #include <vector>
16 
17 // ROOT includes
18 #include "TVector3.h"
19 
20 // LArSoft includes
31 
32 // Framework includes
36 #include "fhiclcpp/ParameterSet.h"
43 
44 
45 namespace trkf {
46  class TrackCheater : public art::EDProducer {
47  public:
48  explicit TrackCheater(fhicl::ParameterSet const& pset);
49  virtual ~TrackCheater();
50 
51  void produce(art::Event& evt);
52 
53  void reconfigure(fhicl::ParameterSet const& pset);
54 
55  private:
56 
57  std::string fCheatedClusterLabel;
58  std::string fG4ModuleLabel;
59 
60  };
61 }
62 
63 namespace trkf{
64 
65  //--------------------------------------------------------------------
67  {
68  this->reconfigure(pset);
69 
70  produces< std::vector<recob::Track> >();
71  produces< std::vector<recob::SpacePoint> >();
72  produces< art::Assns<recob::Track, recob::Cluster> >();
73  produces< art::Assns<recob::Track, recob::SpacePoint> >();
74  produces< art::Assns<recob::Track, recob::Hit> >();
75  }
76 
77  //--------------------------------------------------------------------
79  {
80  }
81 
82  //--------------------------------------------------------------------
84  {
85  fCheatedClusterLabel = pset.get< std::string >("CheatedClusterLabel", "cluster" );
86  fG4ModuleLabel = pset.get< std::string >("G4ModuleLabel", "largeant");
87 
88  return;
89  }
90 
91  //--------------------------------------------------------------------
93  {
97 
98  // grab the clusters that have been reconstructed
100  evt.getByLabel(fCheatedClusterLabel, clustercol);
101 
102  art::FindManyP<recob::Hit> fmh(clustercol, evt, fCheatedClusterLabel);
103 
104  // make a vector of them - we aren't writing anything out to a file
105  // so no need for a art::PtrVector here
106  std::vector< art::Ptr<recob::Cluster> > clusters;
107  art::fill_ptr_vector(clusters, clustercol);
108 
109  // loop over the clusters and figure out which particle contributed to each one
110  std::vector< art::Ptr<recob::Cluster> >::iterator itr = clusters.begin();
111 
112  // make a map of vectors of art::Ptrs keyed by eveID values
113  std::map< int, std::vector< std::pair<size_t, art::Ptr<recob::Cluster> > > > eveClusterMap;
114 
115  // loop over all clusters and fill in the map
116  for(size_t c = 0; c < clusters.size(); ++c){
117 
118  std::pair<size_t, art::Ptr<recob::Cluster> > idxPtr(c, clusters[c]);
119 
120  // in the ClusterCheater module we set the cluster ID to be
121  // the eve particle track ID*1000 + plane*100 + tpc*10 + cryostat number. The
122  // floor function on the cluster ID / 1000 will give us
123  // the eve track ID
124  int eveID = floor((*itr)->ID()/1000.);
125 
126  eveClusterMap[eveID].push_back(idxPtr);
127  ++itr;
128  }// end loop over clusters
129 
130  // loop over the map and make prongs
131  std::unique_ptr< std::vector<recob::Track> > trackcol(new std::vector<recob::Track>);
132  std::unique_ptr< std::vector<recob::SpacePoint> > spcol (new std::vector<recob::SpacePoint>);
133  std::unique_ptr< art::Assns<recob::Track, recob::SpacePoint> > tspassn(new art::Assns<recob::Track, recob::SpacePoint>);
134  std::unique_ptr< art::Assns<recob::Track, recob::Cluster> > tcassn (new art::Assns<recob::Track, recob::Cluster>);
135  std::unique_ptr< art::Assns<recob::Track, recob::Hit> > thassn (new art::Assns<recob::Track, recob::Hit>);
136 
137  for(auto const& clusterMapItr : eveClusterMap){
138 
139  // separate out the hits for each particle into the different views
140  std::vector< std::pair<size_t, art::Ptr<recob::Cluster> > > const& eveClusters = clusterMapItr.second;
141 
142  simb::MCParticle *part = pi_serv->ParticleList()[clusterMapItr.first];
143 
144  // is this prong electro-magnetic in nature or
145  // hadronic/muonic? EM --> shower, everything else is a track
146  if( abs(part->PdgCode()) != 11 &&
147  abs(part->PdgCode()) != 22 &&
148  abs(part->PdgCode()) != 111 ){
149 
150  // vectors to hold the positions and directions of the track
151  std::vector<TVector3> points;
152  std::vector<TVector3> dirs;
153 
154  size_t nviews = geo->Nviews();
155  std::vector< std::vector<double> > dQdx(nviews);
156 
157  mf::LogInfo("TrackCheater") << "G4 id " << clusterMapItr.first
158  << " is a track with pdg code "
159  << part->PdgCode();
160 
162  std::vector<size_t> idxs;
163  for(auto const& idxPtr : eveClusters){
164  ptrvs.push_back(idxPtr.second);
165  idxs.push_back(idxPtr.first);
166  }
167 
168  // grab the hits associated with the collection plane
169  std::vector< art::Ptr<recob::Hit> > hits;
170  for(size_t p = 0; p < ptrvs.size(); ++p){
171  std::vector< art::Ptr<recob::Hit> > chits = fmh.at(idxs[p]);
172  if (!chits.size()) continue;
173  if (chits[0]->SignalType() != geo::kCollection) continue;
174  hits.insert(hits.end(), chits.begin(), chits.end());
175  }
176 
177  // need at least 2 hits to make a track
178  if(hits.size() < 2) continue;
179 
180  // loop over the hits to get the positions and directions
181  size_t spStart = spcol->size();
182  for(size_t t = 0; t < hits.size(); ++t){
183  std::vector<double> xyz = bt_serv->HitToXYZ(hits[t]);
184  points.push_back(TVector3(xyz[0], xyz[1], xyz[2]));
185 
186  std::vector<double> xyz1;
187  double charge = hits[t]->Integral();
188  double dx = 0.;
189  double sign = 1.;
190 
191  if(t < hits.size()-1){
192  xyz1 = bt_serv->HitToXYZ(hits[t+1]);
193  }
194  else{
195  xyz1 = bt_serv->HitToXYZ(hits[t-1]);
196  sign = -1.;
197  }
198 
199  // dx is always positive
200  dx = std::sqrt(std::pow(xyz1[0] - xyz[0], 2) +
201  std::pow(xyz1[1] - xyz[1], 2) +
202  std::pow(xyz1[2] - xyz[2], 2));
203 
204  // direction is always from the previous point along track to
205  // the next point, that is why sign is there
206  dirs.push_back(TVector3(sign*(xyz1[0] - xyz[0])/dx,
207  sign*(xyz1[1] - xyz[1])/dx,
208  sign*(xyz1[2] - xyz[2])/dx));
209 
210  dQdx[0].push_back(charge/dx);
211  dQdx[1].push_back(charge/dx);
212  dQdx[2].push_back(charge/dx);
213 
214  // make the space point and set its ID and XYZ
215  double xyzerr[6] = {1.e-3};
216  double chisqr = 0.9;
217  recob::SpacePoint sp(&xyz[0], xyzerr, chisqr, clusterMapItr.first*10000 + t);
218  spcol->push_back(sp);
219  }
220 
221  size_t spEnd = spcol->size();
222 
223  // add a track to the collection. Make the track
224  // ID be the same as the track ID for the eve particle
225  std::vector<double> momentum(2);
226  momentum[0] = part->P();
227  momentum[1] = part->P(part->NumberTrajectoryPoints()-1);
228  trackcol->push_back(recob::Track(points, dirs, dQdx, momentum, clusterMapItr.first));
229 
230  // associate the track with its clusters
231  util::CreateAssn(*this, evt, *trackcol, ptrvs, *tcassn);
232 
233  // assume the input tracks were previously associated with hits
234  hits.clear();
235  for(size_t p = 0; p < ptrvs.size(); ++p){
236  hits = fmh.at(idxs[p]);
237  util::CreateAssn(*this, evt, *trackcol, hits, *thassn);
238  }
239 
240  // associate the track to the space points
241  util::CreateAssn(*this, evt, *trackcol, *spcol, *tspassn, spStart, spEnd);
242 
243  mf::LogInfo("TrackCheater") << "adding track: \n"
244  << trackcol->back()
245  << "\nto collection.";
246 
247  }//end if this is a track
248 
249  } // end loop over the map
250 
251  evt.put(std::move(trackcol));
252  evt.put(std::move(spcol));
253  evt.put(std::move(tcassn));
254  evt.put(std::move(thassn));
255  evt.put(std::move(tspassn));
256 
257  return;
258 
259  } // end produce
260 
261 } // end namespace
262 
263 namespace trkf{
264 
266 
267 }
268 
269 #endif
void produce(art::Event &evt)
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:222
int PdgCode() const
Definition: MCParticle.h:216
std::string fG4ModuleLabel
label for module running G4 and making particles, etc
const std::vector< double > HitToXYZ(const recob::Hit &hit)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Declaration of signal hit object.
TrackCheater(fhicl::ParameterSet const &pset)
std::string fCheatedClusterLabel
label for module creating recob::Cluster objects
Particle class.
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
void hits()
Definition: readHits.C:15
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:441
double P(const int i=0) const
Definition: MCParticle.h:238
T get(std::string const &key) const
Definition: ParameterSet.h:231
TString part[npart]
Definition: Style.C:32
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.
Declaration of cluster object.
Provides recob::Track data product.
size_type size() const
Definition: PtrVector.h:308
int sign(double val)
Definition: UtilFunc.cxx:106
Utility object to perform functions of association.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
void reconfigure(fhicl::ParameterSet const &pset)
unsigned int Nviews() const
Returns the number of views (different wire orientations)
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:464
Namespace collecting geometry-related classes utilities.
art framework interface to geometry description
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:51
Signal from collection planes.
Definition: geo_types.h:93