tpcpatreccheat_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: tpcpatreccheat
3 // Plugin Type: producer (art v3_00_00)
4 // File: tpcpatreccheat_module.cc
5 //
6 // copied from tpcpatrec2 and modified to just use the backtracker to cheat. No vector hits are required
7 // from cetlib version v3_04_00.
8 ////////////////////////////////////////////////////////////////////////
9 
17 #include "fhiclcpp/ParameterSet.h"
20 #include "canvas/Persistency/Common/FindManyP.h"
21 
22 #include <memory>
23 #include <set>
24 
25 #include "TMath.h"
26 #include "TVector3.h"
27 
28 #include "Geant4/G4ThreeVector.hh"
29 
30 // GArSoft Includes
34 #include "Reco/TrackPar.h"
35 #include "Reco/tracker2algs.h"
36 #include "MCCheater/BackTracker.h"
37 #include "Geometry/GeometryGAr.h"
38 
39 namespace gar {
40  namespace rec {
41 
43  public:
44  explicit tpcpatreccheat(fhicl::ParameterSet const& p);
45  // The compiler-generated destructor is fine for non-base
46  // classes without bare pointers or other resource use.
47 
48  // Plugins should not be copied or assigned.
49  tpcpatreccheat(tpcpatreccheat const&) = delete;
50  tpcpatreccheat(tpcpatreccheat&&) = delete;
51  tpcpatreccheat& operator=(tpcpatreccheat const&) = delete;
53 
54  // Required functions.
55  void produce(art::Event& e) override;
56 
57  private:
58 
59  // Declare member data here.
60 
61  std::string fHitLabel; ///< label of module making hits
62  std::string fTPCClusterLabel; /// label of module for input TPC clusters
63  int fPrintLevel; ///< debug printout: 0: none, 1: selected, 2: all
64  size_t fMinNumTPCClusters; ///< minimum number of hits for a patrec track
65 
66  float fSortTransWeight; ///< for use in the hit sorting algorithm -- transverse distance weight factor
67  float fSortDistBack; ///< for use in the hit sorting algorithm -- how far to go back before raising the distance figure of merit
68  float fTPCClusterRCut; ///< maximum radius from center of TPC in YZ to take a cluster
69  float fTPCClusterGapCut; ///< in cm -- skip TPC clusters within this distance of a gap
70 
71  unsigned int fInitialTPNTPCClusters; ///< number of hits to use for initial trackpar estimate, if present
72 
73  // rough estimate of track parameters
74  int makepatrectrack(std::vector<gar::rec::TPCCluster> &hits, gar::rec::TrackPar &trackpar);
75 
76  };
77 
78 
80  {
81  fHitLabel = p.get<std::string>("HitLabel","hit");
82  fTPCClusterLabel = p.get<std::string>("TPCClusterLabel","tpccluster");
83  fPrintLevel = p.get<int>("PrintLevel",0);
84  fMinNumTPCClusters = p.get<size_t>("MinNumTPCClusters",20);
85  fInitialTPNTPCClusters = p.get<unsigned int>("InitialTPNTPCClusters",100);
86  fTPCClusterRCut = p.get<float>("TPCClusterRCut",280.0);
87  fTPCClusterGapCut = p.get<float>("TPCClusterGapCut",5.0);
88  fSortTransWeight = p.get<float>("SortTransWeight",0.1);
89  fSortDistBack = p.get<float>("SortDistBack",2.0);
90 
91  art::InputTag hitTag(fHitLabel);
92  art::InputTag TPCClusterTag(fTPCClusterLabel);
93 
94  consumes< std::vector<gar::rec::Hit> >(hitTag);
95  consumes< std::vector<gar::rec::TPCCluster> >(TPCClusterTag);
96  consumes< art::Assns<gar::rec::TPCCluster, gar::rec::Hit> >(TPCClusterTag);
97 
98  produces< std::vector<gar::rec::Track> >();
99  produces< art::Assns<gar::rec::TPCCluster, gar::rec::Track> >();
100  produces< art::Assns<gar::rec::VecHit, gar::rec::Track> >();
101  }
102 
104  {
105 
106  if( e.isRealData() ){
107  throw cet::exception("tpcpatreccheat")
108  << "Attempting to cheat the track pattern recognition for real data. "
109  << "That will not work";
110  }
111 
112  auto TPCClusterHandle = e.getValidHandle< std::vector<gar::rec::TPCCluster> >(fTPCClusterLabel);
113  auto const& TPCClusters = *TPCClusterHandle;
114 
115  std::unique_ptr< std::vector<gar::rec::Track> > trkCol(new std::vector<gar::rec::Track>);
116  std::unique_ptr< art::Assns<gar::rec::VecHit,gar::rec::Track> > vhTrkAssns(new ::art::Assns<gar::rec::VecHit,gar::rec::Track>);
117  std::unique_ptr< art::Assns<gar::rec::TPCCluster,gar::rec::Track> > TPCClusterTrkAssns(new ::art::Assns<gar::rec::TPCCluster,gar::rec::Track>);
118 
119  auto const trackPtrMaker = art::PtrMaker<gar::rec::Track>(e);
120  auto const TPCClusterPtrMaker = art::PtrMaker<gar::rec::TPCCluster>(e, TPCClusterHandle.id());
121  const art::FindManyP<gar::rec::Hit> HitsFromTPCClusters(TPCClusterHandle,e,fTPCClusterLabel);
122 
123  auto bt = gar::providerFrom<cheat::BackTracker>();
124  auto geo = gar::providerFrom<geo::GeometryGAr>();
125  TVector3 xhat(1,0,0);
126  TVector3 tpccent(geo->TPCXCent(),geo->TPCYCent(),geo->TPCZCent());
127 
128 
129  // Do everything separately for the two sides -- do not make a single track out of pieces on either side of the cathode
130 
131  for (int iside=-1; iside <= 1; iside += 2)
132  {
133  std::map<int, std::set<size_t> > trackIDclusmap;
134  for (size_t iclus = 0; iclus<TPCClusters.size(); ++iclus)
135  {
136  TVector3 cluspos(TPCClusters.at(iclus).Position());
137  TVector3 cprel = cluspos - tpccent;
138  float rclus = (cprel.Cross(xhat)).Mag();
139  if ( rclus > fTPCClusterRCut ) continue;
140 
141  // logic to see if a hit is close to a gap and skip if it is
142  if ( rclus > geo->GetIROCInnerRadius())
143  {
144  float phi = TMath::ATan2(cprel.Z(),cprel.Y());
145  if (phi<0) phi += 2.0*TMath::Pi();
146  float phisc = phi/( TMath::Pi()/9.0 );
147  UInt_t isector = TMath::Floor(phisc); // assumes the sector boundary is at phi=0 // goes from 0 to 17
148  // rotate this back down to a single sector
149  float rotang = ( isector*TMath::Pi()/9.0 );
150  float crot = TMath::Cos(rotang);
151  float srot = TMath::Sin(rotang);
152  //float zrot = cprel.Z()*crot + cprel.Y()*srot;
153  float yrot = - cprel.Z()*srot + cprel.Y()*crot;
154  if (TMath::Abs(yrot) < fTPCClusterGapCut) continue;
155  }
156 
157  float totcharge = 0;
158  std::map<int, float> chargemap; // trackID to charge map -- charge is in electrons
159  auto hits = HitsFromTPCClusters.at(iclus);
160  for (size_t ihit=0; ihit< hits.size(); ++ihit)
161  {
162  unsigned int channel = hits.at(ihit)->Channel();
163  float chanpos[3];
164  geo->ChannelToPosition(channel,chanpos);
165  int hitside = 1;
166  if (chanpos[0] < tpccent.X())
167  {
168  hitside = -1;
169  }
170  if (hitside != iside) continue;
171  auto hitides = bt->HitToHitIDEs(hits.at(ihit));
172  //std::cout << "number of hitides: " << hitides.size() << std::endl;
173  for (size_t i=0; i<hitides.size(); ++i)
174  {
175  float charge = hitides.at(i).energyTot;
176  totcharge += charge;
177  int trackid = TMath::Abs(hitides.at(i).trackID);
178  auto cmf = chargemap.find(trackid);
179  if (cmf == chargemap.end())
180  {
181  chargemap[trackid]=charge;
182  }
183  else
184  {
185  cmf->second += charge;
186  }
187  }
188  }
189  if (totcharge > 0)
190  {
191  float maxcharge = 0;
192  int ibesttrackid = 0;
193  for (auto const& cm : chargemap)
194  {
195  if (cm.second > maxcharge)
196  {
197  maxcharge = cm.second;
198  ibesttrackid = cm.first;
199  }
200  }
201  trackIDclusmap[ibesttrackid].emplace(iclus);
202  }
203  } // end loop over TPC Clusters for grouping them by trackID
204 
205  // loop over the map associating trackIDs to TPC clusters and for each entry
206  // make a local list of TPCClusters for each track and find initial track parameters
207 
208  for (auto const& tic : trackIDclusmap)
209  {
210  std::vector<gar::rec::TPCCluster> TPCClusters_thistrack;
211  std::vector<art::Ptr<gar::rec::TPCCluster> > TPCClusterptrs;
212  for (auto const& iclus : tic.second)
213  {
214  TPCClusters_thistrack.push_back(TPCClusters.at(iclus));
215  TPCClusterptrs.push_back(TPCClusterPtrMaker(iclus));
216  }
217 
218 
219  if (TPCClusters_thistrack.size() >= fMinNumTPCClusters)
220  {
221  gar::rec::TrackPar trackpar;
222  if ( makepatrectrack(TPCClusters_thistrack,trackpar) == 0 )
223  {
224  trkCol->push_back(trackpar.CreateTrack());
225  auto const trackpointer = trackPtrMaker(trkCol->size()-1);
226  for (size_t iTPCCluster=0; iTPCCluster<TPCClusters_thistrack.size(); ++iTPCCluster)
227  {
228  TPCClusterTrkAssns->addSingle(TPCClusterptrs.at(iTPCCluster),trackpointer);
229  }
230  }
231  }
232  }
233  }
234  e.put(std::move(trkCol));
235  e.put(std::move(vhTrkAssns));
236  e.put(std::move(TPCClusterTrkAssns));
237  }
238 
239 
240  // rough estimate of track parameters -- both ends
241 
242  int tpcpatreccheat::makepatrectrack(std::vector<gar::rec::TPCCluster> &trackTPCClusters, gar::rec::TrackPar &trackpar)
243  {
244  // track parameters: x is the independent variable
245  // 0: y
246  // 1: z
247  // 2: curvature
248  // 3: phi
249  // 4: lambda = angle from the cathode plane
250  // 5: x /// added on to the end
251 
252 
253  float lengthforwards = 0;
254  std::vector<int> hlf;
255  float lengthbackwards = 0;
256  std::vector<int> hlb;
257 
258  gar::rec::sort_TPCClusters_along_track(trackTPCClusters,hlf,hlb,fPrintLevel,lengthforwards,lengthbackwards,fSortTransWeight,fSortDistBack);
259 
260  std::vector<float> tparbeg(6,0);
261  float xother = 0;
262  if ( gar::rec::initial_trackpar_estimate(trackTPCClusters, hlf, tparbeg[2], tparbeg[4],
263  tparbeg[3], tparbeg[5], tparbeg[0], tparbeg[1], xother, fInitialTPNTPCClusters, fPrintLevel) != 0)
264  {
265  return 1;
266  }
267 
268  std::vector<float> tparend(6,0);
269  if ( gar::rec::initial_trackpar_estimate(trackTPCClusters, hlb, tparend[2], tparend[4],
270  tparend[3], tparend[5], tparend[0], tparend[1], xother, fInitialTPNTPCClusters, fPrintLevel) != 0)
271  {
272  return 1;
273  }
274 
275  // no chisquare or covariance in patrec tracks
276  float covmatbeg[25];
277  float covmatend[25];
278  for (size_t i=0; i<25; ++i) // no covmat in patrec tracks
279  {
280  covmatend[i] = 0;
281  covmatbeg[i] = 0;
282  }
283 
284  trackpar.setNTPCClusters(trackTPCClusters.size());
285  trackpar.setTime(0);
286  trackpar.setChisqForwards(0);
287  trackpar.setChisqBackwards(0);
288  trackpar.setLengthForwards(lengthforwards);
289  trackpar.setLengthBackwards(lengthbackwards);
290  trackpar.setCovMatBeg(covmatbeg);
291  trackpar.setCovMatEnd(covmatend);
292  trackpar.setTrackParametersBegin(tparbeg.data());
293  trackpar.setXBeg(tparbeg[5]);
294  trackpar.setTrackParametersEnd(tparend.data());
295  trackpar.setXEnd(tparend[5]);
296 
297  return 0;
298  }
299 
300 
302 
303 
304  } // namespace rec
305 } // namespace gar
static constexpr double cm
Definition: Units.h:68
void setNTPCClusters(const size_t nTPCClusters)
Definition: TrackPar.cxx:214
tpcpatreccheat(fhicl::ParameterSet const &p)
void produce(art::Event &e) override
void setLengthForwards(const float lengthforwards)
Definition: TrackPar.cxx:251
rec
Definition: tracks.py:88
int makepatrectrack(std::vector< gar::rec::TPCCluster > &hits, gar::rec::TrackPar &trackpar)
void setCovMatBeg(const float *covmatbeg)
Definition: TrackPar.cxx:235
std::string string
Definition: nybbler.cc:12
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
float fTPCClusterGapCut
in cm – skip TPC clusters within this distance of a gap
uint8_t channel
Definition: CRTFragment.hh:201
void setLengthBackwards(const float lengthbackwards)
Definition: TrackPar.cxx:256
std::string fHitLabel
label of module making hits
bool isRealData() const
void setTrackParametersBegin(const float *tparbeg)
Definition: TrackPar.cxx:219
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
bt
Definition: tracks.py:83
int fPrintLevel
label of module for input TPC clusters
def move(depos, offset)
Definition: depos.py:107
void setXEnd(const float xend)
Definition: TrackPar.cxx:276
void setTrackParametersEnd(const float *tparend)
Definition: TrackPar.cxx:227
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
void setChisqBackwards(const float chisqbackwards)
Definition: TrackPar.cxx:266
gar::rec::Track CreateTrack()
Definition: TrackPar.cxx:292
General GArSoft Utilities.
unsigned int fInitialTPNTPCClusters
number of hits to use for initial trackpar estimate, if present
void setCovMatEnd(const float *covmatend)
Definition: TrackPar.cxx:243
float fTPCClusterRCut
maximum radius from center of TPC in YZ to take a cluster
float fSortTransWeight
for use in the hit sorting algorithm – transverse distance weight factor
void sort_TPCClusters_along_track(const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &hlf, std::vector< int > &hlb, int printlevel, float &lengthforwards, float &lengthbackwards, float sorttransweight, float sortdistback)
void setXBeg(const float xbeg)
Definition: TrackPar.cxx:271
float fSortDistBack
for use in the hit sorting algorithm – how far to go back before raising the distance figure of meri...
size_t fMinNumTPCClusters
minimum number of hits for a patrec track
tpcpatreccheat & operator=(tpcpatreccheat const &)=delete
void setChisqForwards(const float chisqforwards)
Definition: TrackPar.cxx:261
LArSoft geometry interface.
Definition: ChannelGeo.h:16
art framework interface to geometry description
void setTime(const double time)
Definition: TrackPar.cxx:281
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
int initial_trackpar_estimate(const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &TPCClusterlist, float &curvature_init, float &lambda_init, float &phi_init, float &xpos, float &ypos, float &zpos, float &x_other_end, unsigned int initialtpnTPCClusters, int printlevel)
Definition: tracker2algs.cxx:8