dayoneconverter_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: dayoneconverter
3 // Plugin Type: producer (art v3_00_00)
4 // File: dayoneconverter_module.cc
5 //
6 // Generated at Tue Jun 23 12:28:55 2020 by Thomas Junk using cetskelgen
7 // from cetlib version v3_04_00.
8 ////////////////////////////////////////////////////////////////////////
9 
18 #include "fhiclcpp/ParameterSet.h"
22 
23 #include <memory>
24 
25 #include "TMath.h"
26 #include "TVector3.h"
27 #include "TF1.h"
28 
29 #include "Geant4/G4ThreeVector.hh"
30 #include "nug4/MagneticFieldServices/MagneticFieldService.h"
31 #include "nurandom/RandomUtils/NuRandomService.h"
32 #include "CLHEP/Random/RandGauss.h"
34 
35 // GArSoft Includes
36 
41 #include "Reco/TrackPar.h"
42 #include "Reco/tracker2algs.h"
44 
45 #include "Geometry/BitFieldCoder.h"
46 #include "CoreUtils/ServiceUtil.h"
47 #include "Geometry/GeometryCore.h"
48 #include "Geometry/GeometryGAr.h"
49 
50 
51 namespace gar {
52  namespace rec {
53 
55  public:
56  explicit dayoneconverter(fhicl::ParameterSet const& p);
57  // The compiler-generated destructor is fine for non-base
58  // classes without bare pointers or other resource use.
59 
60  // Plugins should not be copied or assigned.
61  dayoneconverter(dayoneconverter const&) = delete;
62  dayoneconverter(dayoneconverter&&) = delete;
63  dayoneconverter& operator=(dayoneconverter const&) = delete;
65 
66  // Required functions.
67  void produce(art::Event& e) override;
68 
69  private:
70 
71  // Declare member data here.
72 
73  std::string fInputEdepLabel; ///< Input label for edeps
74  std::string fInputEdepInstanceTPC; ///< Input instance for TPC edeps
75  std::string fInputEdepInstanceMuID; ///< Input instance for MuID edeps
76  bool fIncludeMuIDhits; ///< Include MuID hits as TPCClusters
77  float fSmearX; ///< amount by which to smear X, in cm
78  float fSmearY; ///< amount by which to smear Y, in cm
79  float fSmearT; ///< amount by which to smear T, in ns
80  float fPECm; ///< conversion factor from cm step length to pe
81  float fSmearLY; ///< amount by which to smear the LY
82  float fThrPE; ///< threshold cut in pe
83  float fZCut1; ///< Cut to ensure TPC Clusters are on different planes
84  float fZCut2; ///< Cut to ensure TPC clusters are on the same plane
85  float fRCut; ///< Road in the YZ plane to add hits on a circle
86  float fTimeBunch; ///< Time bunch spread, in ns
87 
88  bool fUseOnlyTrueMuonHits; ///< whether to cheat and use true muon hits
89  std::string fG4ModuleLabel; ///< Use this to get the MCParticles
90 
91  CLHEP::HepRandomEngine &fEngine; //< random engine
92 
93  const gar::geo::GeometryCore* fGeo; ///< geometry information
96  TF1* fMu2e;
97 
98  int makepatrectrack(std::vector<gar::rec::TPCCluster> &trackTPCClusters, gar::rec::TrackPar &trackpar);
99  void digitizeCaloHitsSimple(gar::sdp::CaloDeposit cd, float *fcpos, float &energy, float &time);
100  void digitizeCaloHitsMu2e(gar::sdp::CaloDeposit cd, float *fcpos, float &energy, float &time);
101  };
102 
104  : EDProducer{p}
106  // More initializers here.
107  {
108  // Call appropriate produces<>() functions here.
109  // Call appropriate consumes<>() for any products to be retrieved by this module.
110 
111  fInputEdepLabel = p.get<std::string>("InputLabel","edepconvert");
112  fInputEdepInstanceTPC = p.get<std::string>("InputInstanceTPC","TrackerSc");
113  fInputEdepInstanceMuID = p.get<std::string>("InputInstanceMuID","MuID");
114  fIncludeMuIDhits = p.get<bool>("IncludeMuIDhits", false);
115  fSmearX = p.get<float>("SmearX",0.3); // in cm
116  fSmearY = p.get<float>("SmearY",0.3); // in cm
117  fSmearT = p.get<float>("SmearT",1.0); // in ns
118  fPECm = p.get<float>("PeCm", 50.); // in pe/cm
119  fSmearLY = p.get<float>("SmearLY", 10.0); // in pe
120  fThrPE = p.get<float>("ThrPE", 5.0); // in pe
121  fZCut1 = p.get<float>("ZCut1",10.0); // in cm
122  fZCut2 = p.get<float>("ZCut2",0.5); // in cm
123  fRCut = p.get<float>("RCut" ,5.0); // in cm
124  fTimeBunch = p.get<float>("TimeBunch",150000); // in ns
125  fUseOnlyTrueMuonHits = p.get<bool>("UseOnlyTrueMuonHits",false); // whether to cheat or not
126  fG4ModuleLabel = p.get<std::string>("G4ModuleLabel","geant"); // for retrieving MCParticles
127 
128  art::InputTag tpcedeptag(fInputEdepLabel,fInputEdepInstanceTPC);
129  art::InputTag muidedeptag(fInputEdepLabel,fInputEdepInstanceMuID);
130  consumes<std::vector<gar::sdp::CaloDeposit> >(tpcedeptag);
131  consumes<std::vector<gar::sdp::CaloDeposit> >(muidedeptag);
132  if (fUseOnlyTrueMuonHits)
133  {
134  consumes<std::vector<simb::MCParticle> >(fG4ModuleLabel);
135  }
136  produces<std::vector<gar::rec::Track> >();
137  produces<std::vector<gar::rec::TPCCluster> >();
138  produces< art::Assns<gar::rec::TPCCluster, gar::rec::Track> >();
139 
140  fGeo = gar::providerFrom<gar::geo::GeometryGAr>();
141  std::string fEncoding = fGeo->GetMinervaCellIDEncoding();
142  fFieldDecoderTrk = new gar::geo::BitFieldCoder( fEncoding );
143  std::string fEncodingMuID = fGeo->GetMuIDCellIDEncoding();
144  fFieldDecoderMuID = new gar::geo::BitFieldCoder( fEncodingMuID );
145 
146  fMu2e = new TF1("mu2e_pe", "[0] + [1]*x", 0, 600);
147  fMu2e->SetParameter(0, 50.);//pe
148  fMu2e->SetParameter(1, -0.06);//pe/cm
149  }
150 
152  {
153  // Implementation of required member function here.
154  std::unique_ptr< std::vector<gar::rec::TPCCluster> > TPCClusterCol(new std::vector<gar::rec::TPCCluster>);
155  std::unique_ptr< std::vector<gar::rec::Track> > trkCol(new std::vector<gar::rec::Track>);
156  std::unique_ptr< art::Assns<gar::rec::TPCCluster,gar::rec::Track> > TPCClusterTrkAssns(new ::art::Assns<gar::rec::TPCCluster,gar::rec::Track>);
157 
159  auto tccdHandle = e.getValidHandle< std::vector<gar::sdp::CaloDeposit> >(tpcedeptag);
160  auto const& tccds = *tccdHandle;
161 
162  // put these back when we have tracks and can associate them
163  auto const trackPtrMaker = art::PtrMaker<gar::rec::Track>(e);
164  auto const tpcclusPtrMaker = art::PtrMaker<gar::rec::TPCCluster>(e);
165 
166  auto const *magFieldService = gar::providerFrom<mag::MagneticFieldService>();
167  G4ThreeVector zerovec(0,0,0);
168  G4ThreeVector magfield = magFieldService->FieldAtPoint(zerovec);
169 
171  std::unordered_map<int, const simb::MCParticle * > TrkIDMap;
173  {
174  mcphandle = e.getHandle<std::vector<simb::MCParticle> >(fG4ModuleLabel);
175  if (!mcphandle)
176  {
177  throw cet::exception("DayOneConverter::Produce")
178  << "Attempting to identify muon hits without MC particles";
179  }
180  for (auto const &mcp : *mcphandle)
181  {
182  TrkIDMap[mcp.TrackId()] = &mcp;
183  }
184  }
185 
186  // first stab, just make all the TPC clusters in the event, and then worry later
187  // about pattern recognition
188 
189  for (auto const& cd : tccds)
190  {
191  const int trackid = cd.TrackID();
193  {
194  auto mcpt = TrkIDMap.find(trackid);
195  if (mcpt == TrkIDMap.end()) continue;
196  if (std::abs(mcpt->second->PdgCode()) != 13) continue;
197  }
198 
199  float energy = 0.;
200  float time = 0.;
201  float fcpos[3] = {0., 0., 0.};
202 
203  // digitizeCaloHitsSimple(cd, fcpos, energy, time);
204  digitizeCaloHitsMu2e(cd, fcpos, energy, time);
205 
206  float covmat[6] = {0,0,0,0,0,0}; // TODO -- fill this in with something reasonble
207 
208  if(energy <= 0.) continue;
209 
210  TPCClusterCol->emplace_back(energy,
211  fcpos,
212  time, // time is in ns
213  time,
214  time,
215  fSmearX,
216  covmat);
217  }
218 
219  if(fIncludeMuIDhits)
220  {
222  auto muIDHandle = e.getValidHandle< std::vector<gar::sdp::CaloDeposit> >(muidedeptag);
223  auto const& muids = *muIDHandle;
224 
225  for (auto const& cd : muids)
226  {
227 
228  const int trackid = cd.TrackID();
230  {
231  auto mcpt = TrkIDMap.find(trackid);
232  if (mcpt == TrkIDMap.end()) continue;
233  if (std::abs(mcpt->second->PdgCode()) != 13) continue;
234  }
235 
236  float energy = 0.;
237  float time = 0.;
238  float fcpos[3] = {0., 0., 0.};
239 
240  // digitizeCaloHitsSimple(cd, fcpos, energy, time);
241  digitizeCaloHitsMu2e(cd, fcpos, energy, time);
242 
243  if(energy <= 0.) continue;
244 
245  float covmat[6] = {0,0,0,0,0,0}; // TODO -- fill this in with something reasonble
246 
247  TPCClusterCol->emplace_back(energy,
248  fcpos,
249  time, // time is in ns
250  time,
251  time,
252  fSmearX,
253  covmat);
254  }
255  }
256 
257  if (true)
258  {
259 
260  // sort the TPC Clusters based on time
261  bool debug=false;
262 
263  std::vector<std::vector<gar::rec::TPCCluster>> TPCClusterColTime;
264  std::vector<gar::rec::TPCCluster> TPCClusterColTimeBlock;
265  std::sort(TPCClusterCol->begin(),TPCClusterCol->end(),
266  [](const gar::rec::TPCCluster &a, const gar::rec::TPCCluster &b)->bool
267  { return a.Time() < b.Time(); } );
268  size_t ntpcclus = TPCClusterCol->size();
269 
270  if (ntpcclus!=0&&debug) std::cout<<"Time start and end: "<<TPCClusterCol->at(0).Time()<<" "<<TPCClusterCol->at(TPCClusterCol->size()-1).Time()<<std::endl;
271 
272  float startt= 0;
273  if (ntpcclus!=0)
274  {
275  startt=TPCClusterCol->at(0).Time();
276  for(size_t i=0; i<ntpcclus; i++)
277  {
278 
279  if(TPCClusterCol->at(i).Time()-startt<=fTimeBunch)
280  {
281  TPCClusterColTimeBlock.push_back(TPCClusterCol->at(i));
282  }
283  else
284  {
285  TPCClusterColTime.push_back(TPCClusterColTimeBlock);
286  startt=TPCClusterCol->at(i).Time();
287  TPCClusterColTimeBlock.clear();
288  TPCClusterColTimeBlock.push_back(TPCClusterCol->at(i));
289  }
290 
291  }
292 
293  if(TPCClusterColTimeBlock.size()!=0) TPCClusterColTime.push_back(TPCClusterColTimeBlock);
294  }
295 
296 
297  if(debug)
298  {
299  for(size_t c=0; c<TPCClusterColTime.size(); c++)
300  {
301 
302  std::cout << "l"<<c<<" = { ";
303  for (size_t d=0; d<TPCClusterColTime.at(c).size(); d++) {
304  std::cout << TPCClusterColTime.at(c).at(d).Time() << ", ";
305  }
306  std::cout << "};\n";
307 
308  }
309  }
310 
311  for(size_t t=0; t<TPCClusterColTime.size(); t++)
312  {
313 
314  ////Sort the clusters along Z
315  std::sort(TPCClusterColTime.at(t).begin(),TPCClusterColTime.at(t).end(),
316  [](const gar::rec::TPCCluster &a, const gar::rec::TPCCluster &b)->bool
317  { return a.Position()[2] < b.Position()[2]; } );
318 
319 
320  size_t ntpcclust = TPCClusterColTime.at(t).size();
321 
322 
323  // look for best-fit tracks in the list of TPC clusters
324  // find the best triplet of TPC Clusters with spacing at least fZCut that fit on a circle
325  // to think about -- time and energy cuts
326 
327  //create list of unused TPC clusters: a total one, and one for each plane
328 
329  std::list<size_t> unusedTPC;
330  std::list<size_t> TPCplane;
331  std::vector<std::list<size_t>> unusedTPCplanes;
332  float startz= 0;
333  float fZCut3= 4; //in cm thickness of the tracking plane
334 
335  if (ntpcclust!=0)
336  {
337  startz=TPCClusterColTime.at(t).at(0).Position()[2];
338  for(size_t i=0; i<ntpcclust; i++)
339  {
340  unusedTPC.push_back(i);
341 
342  if(TPCClusterColTime.at(t).at(i).Position()[2]-startz<=fZCut3)
343  {
344  TPCplane.push_back(i);
345  }
346  else
347  {
348  unusedTPCplanes.push_back(TPCplane);
349  startz=TPCClusterColTime.at(t).at(i).Position()[2];
350  TPCplane.clear();
351  TPCplane.push_back(i);
352  }
353 
354  }
355 
356  if(TPCplane.size()!=0) unusedTPCplanes.push_back(TPCplane);
357  }
358  else
359  {
360  for(size_t i=0; i<ntpcclust; i++)
361  {
362  unusedTPC.push_back(i);
363  }
364  }
365 
366  if(debug){
367  std::cout << "Plane division: p = { ";
368  for (size_t n : unusedTPC) {
369  std::cout << TPCClusterColTime.at(t).at(n).Time() << ", ";
370  }
371  std::cout << "};\n";
372 
373  for(size_t c=0; c<unusedTPCplanes.size(); c++)
374  {
375  std::cout << "p"<<c<<" = { ";
376  for (size_t n : unusedTPCplanes.at(c)) {
377  std::cout << TPCClusterColTime.at(t).at(n).Time() << ", ";
378  }
379  std::cout << "};\n";
380  }
381  }
382 
383  int done= 0;
384 
385  while (done==0)
386  {
387  size_t bestnpts = 0;
388  float bestsumr2 = 0;
389  std::vector<size_t> besttpcclusindex;
390 
391  for (size_t i=0; i<unusedTPCplanes.size(); ++i)
392  {
393  for (size_t it : unusedTPCplanes.at(i))
394  {
395  //const float *ipos = TPCClusterCol->at(it).Position();
396  for (size_t j=i+1; j<unusedTPCplanes.size(); ++j)
397  {
398  for (size_t jt : unusedTPCplanes.at(j))
399  {
400  //const float *jpos = TPCClusterCol->at(jt).Position();
401  //if (TMath::Abs( ipos[2] - jpos[2] ) < fZCut1) continue; Now superfluous using the lists
402  for (size_t k=j+1; k<unusedTPCplanes.size(); ++k)
403  {
404  for (size_t kt : unusedTPCplanes.at(k))
405  {
406  //const float *kpos = TPCClusterCol->at(kt).Position();
407  //if (TMath::Abs( ipos[2] - kpos[2] ) < fZCut1) continue; Now superfluous using the lists
408  std::vector<gar::rec::TPCCluster> triplet;
409  triplet.push_back(TPCClusterCol->at(it));
410  triplet.push_back(TPCClusterCol->at(jt));
411  triplet.push_back(TPCClusterCol->at(kt));
412  gar::rec::TrackPar triplettrack;
413  makepatrectrack(triplet,triplettrack);
414 
415  // pick the best TPC clusters at each Z position. Save their
416  // indices in tpcclusindex and sum the squares of distances in sum
417  std::vector<size_t> tpcclusindex;
418  float sumr2 = 0;
419 
420  float zcur = -2E9;
421  int tpcclusindexb = -1;
422  float dbest=1E9;
423  gar::rec::Track tpt;
424  gar::rec::TPCCluster tpcclusb;
425 
426  for (size_t kt2 : unusedTPC)
427  {
428  const float *k2pos = TPCClusterCol->at(kt2).Position();
429 
430  // clusters are sorted along Z. If we found a new Z, put the best point on the list
431 
432  if ((TMath::Abs(zcur - k2pos[2]) > fZCut2) &&
433  (tpcclusindexb > -1) &&
434  (dbest < fRCut) )
435  {
436  tpcclusindex.push_back(tpcclusindexb);
437  //TPCtrial.push_back(tpcclusb);
438  sumr2 += dbest*dbest;
439  dbest = 1E9;
440  tpcclusindexb = -1;
441  zcur = k2pos[2];
442  }
443 
444  float dist=0;
445  tpt = triplettrack.CreateTrack();
446  int retcode = util::TrackPropagator::DistXYZ(tpt.TrackParBeg(),tpt.Vertex(),k2pos,dist);
447  if (retcode != 0) continue;
448  if (dist > fRCut) continue;
449  if (dist<dbest)
450  {
451  dbest = dist;
452  tpcclusindexb = kt2;
453  }
454  // last point -- check to see if it gets added.
455  if (kt2 == *std::prev(unusedTPC.end(),1) && tpcclusindexb > -1)
456  {
457  tpcclusindex.push_back(tpcclusindexb);
458  sumr2 += dbest*dbest;
459  }
460  } // end loop over kt2 -- assigning clusters to this track
461 
462  if (tpcclusindex.size() > bestnpts ||
463  ((tpcclusindex.size() == bestnpts) &&
464  (sumr2 < bestsumr2)))
465  {
466  bestnpts = tpcclusindex.size();
467  bestsumr2 = sumr2;
468  besttpcclusindex = tpcclusindex;
469  }
470  } // end loop over k in triplet
471  }
472  } // end loop over j in triplet
473  }
474  } // end loop over i in triplet
475  }
476 
477  for(size_t i=0;i<bestnpts;i++)
478  {
479  unusedTPC.remove(besttpcclusindex.at(i));
480  for(size_t j=0;j<unusedTPCplanes.size();j++)
481  {
482  unusedTPCplanes.at(j).remove(besttpcclusindex.at(i));
483  }
484  }
485 
486  if (debug)
487  {
488  std::cout<<"bestnpts: "<<bestnpts<<std::endl;
489  for(size_t j=0;j<unusedTPCplanes.size();j++)
490  {
491  std::cout<<"unusedTPCplane"<<j<<" : "<<unusedTPCplanes.at(j).size()<<std::endl;
492  }
493  std::cout<<"unusedTPC: "<<unusedTPC.size()<<std::endl<<std::endl;
494  }
495 
496  if (bestnpts > 0)
497  {
498  // make track from all the TPC clusters
499  //trkCol->push_back(besttrack);
500  std::vector<gar::rec::TPCCluster> tcv;
501  for (size_t i=0;i<besttpcclusindex.size(); ++i)
502  {
503  tcv.push_back(TPCClusterCol->at(besttpcclusindex.at(i)));
504  }
505 
506  gar::rec::TrackPar btp;
507  makepatrectrack(tcv,btp);
508  gar::rec::Track btt = btp.CreateTrack();
509  trkCol->push_back(btt);
510 
511  auto const trackpointer = trackPtrMaker(trkCol->size()-1);
512  for (size_t i=0; i<besttpcclusindex.size(); ++i)
513  {
514  auto const tpccluspointer = tpcclusPtrMaker(besttpcclusindex.at(i));
515  TPCClusterTrkAssns->addSingle(tpccluspointer,trackpointer);
516  }
517  }
518  else
519  {
520  done= 1;
521  if (debug) std::cout<<"Not able to find a new track, stop cycle, done="<<done<<std::endl;
522  }
523 
524 
525  }
526 
527  }
528 
529  if(debug) std::cout<<"Found this many tracks: "<<trkCol->size()<<std::endl<<std::endl<<std::endl;
530  }
531 
532 
533  e.put(std::move(trkCol));
534  e.put(std::move(TPCClusterCol));
535  e.put(std::move(TPCClusterTrkAssns));
536 
537  }
538 
539  // digitize the plane hits based on minerva numbers
540 
542  {
543  //Need to check in which direction to smear (depends on the segmenetation)
544  //Can use the cellID decoder to know looking at cellX and cellY values
545  CLHEP::RandGauss GaussRand(fEngine);
546 
547  gar::raw::CellID_t cID = cd.CellID();
548  int cellX = fFieldDecoderTrk->get(cID, "cellX");
549  int cellY = fFieldDecoderTrk->get(cID, "cellY");
550 
551  fcpos[0] = cd.X(); // default values
552  fcpos[1] = cd.Y();
553  fcpos[2] = cd.Z();
554  energy = cd.Energy();
555  time = cd.Time();
556 
557  if(cellX == 0) {
558  //Segmented in Y
559  fcpos[0] += GaussRand.fire(0., fSmearX);
560  }
561 
562  if(cellY == 0) {
563  //Segmented in X
564  fcpos[1] += GaussRand.fire(0., fSmearY);
565  }
566 
567  time += GaussRand.fire(0., fSmearT);
568 
569  //convert energy to pe
570  energy = fPECm * cd.StepLength();
571  energy += GaussRand.fire(0., fSmearLY);
572 
573  if(energy < fThrPE) energy = 0.;
574 
575  return;
576  }
577 
578  //digitize based on Mu2e strip numbers
579 
581  {
582  //Need to check in which direction to smear (depends on the segmenetation)
583  //Can use the cellID decoder to know looking at cellX and cellY values
584  CLHEP::RandGauss GaussRand(fEngine);
585 
586  gar::raw::CellID_t cID = cd.CellID();
587  int cellX = fFieldDecoderTrk->get(cID, "cellX");
588  int cellY = fFieldDecoderTrk->get(cID, "cellY");
589 
590  fcpos[0] = cd.X(); // default values
591  fcpos[1] = cd.Y();
592  fcpos[2] = cd.Z();
593  energy = cd.Energy();
594  time = cd.Time();
595 
596  if(cellX == 0) {
597  //Segmented in Y
598  fcpos[0] += GaussRand.fire(0., fSmearX);
599  }
600 
601  if(cellY == 0) {
602  //Segmented in X
603  fcpos[1] += GaussRand.fire(0., fSmearY);
604  }
605 
606  time += GaussRand.fire(0., fSmearT);
607 
608  //convert energy to pe based on the distance in the strip
609  //Curve as "linear" with parameters a = 0.06 pe/cm, b = 50 pe (80*0.6 from Mu2e)
610  double local_distance = 0.;
611  std::array<double, 3> point = {cd.X(), cd.Y(), cd.Z()};
612  std::array<double, 3> pointLocal;
614  fGeo->WorldToLocal(point, pointLocal, trans);
615  TVector3 tpoint(point[0], point[1], point[2]);
616  std::string name = fGeo->VolumeName(tpoint);
617 
618  if(cellX == 0) {
619  //Segmented in Y -> get the x pos
620  local_distance = 300. - pointLocal[0];
621  }
622 
623  if(cellY == 0) {
624  //Segmented in X -> get the y pos
625  local_distance = 300. - pointLocal[1];
626  }
627 
628  energy = fMu2e->Eval(local_distance);
629  // std::cout << "Volume " << name << std::endl;
630  // std::cout << "CellX " << cellX << " CellY " << cellY << std::endl;
631  // std::cout << "Global Position " << cd.X() << ", " << cd.Y() << ", " << cd.Z() << std::endl;
632  // std::cout << "Local Position " << pointLocal[0] << ", " << pointLocal[1] << ", " << pointLocal[2] << std::endl;
633  // std::cout << "local distance in strip " << local_distance << " cm has " << energy << " pe detected" << std::endl;
634  energy += GaussRand.fire(0., fSmearLY);
635 
636  if(energy < fThrPE) energy = 0.;
637 
638  return;
639  }
640 
641 
642  // maybe refactor this so we don't have to duplicate it. But need to pass in all the config parameters.
643  // temporary: just hardcode the parameters to see if we can get something to work
644 
645  int dayoneconverter::makepatrectrack(std::vector<gar::rec::TPCCluster> &trackTPCClusters, gar::rec::TrackPar &trackpar)
646  {
647  // track parameters: x is the independent variable
648  // 0: y
649  // 1: z
650  // 2: curvature
651  // 3: phi
652  // 4: lambda = angle from the cathode plane
653  // 5: x /// added on to the end
654 
655  float fSortTransWeight = 1.0;
656  int fInitialTPNTPCClusters = 100;
657  float fSortDistBack = 2.0;
658  int fPrintLevel = 0;
659 
660  float lengthforwards = 0;
661  std::vector<int> hlf;
662  float lengthbackwards = 0;
663  std::vector<int> hlb;
664 
665  gar::rec::sort_TPCClusters_along_track(trackTPCClusters,hlf,hlb,fPrintLevel,lengthforwards,lengthbackwards,fSortTransWeight,fSortDistBack);
666 
667  std::vector<float> tparbeg(6,0);
668  float xother = 0;
669  if ( gar::rec::initial_trackpar_estimate(trackTPCClusters, hlf, tparbeg[2], tparbeg[4],
670  tparbeg[3], tparbeg[5], tparbeg[0], tparbeg[1], xother, fInitialTPNTPCClusters, fPrintLevel) != 0)
671  {
672  return 1;
673  }
674  float chisqforwards = 0;
675  float tvpos[3] = {tparbeg[5],tparbeg[0],tparbeg[1]};
676  for (size_t i=0; i<trackTPCClusters.size(); ++i)
677  {
678  float dist = 0;
679  const float *pos = trackTPCClusters.at(i).Position();
680  int retcode = util::TrackPropagator::DistXYZ(tparbeg.data(),tvpos,pos,dist);
681  if (retcode == 0)
682  {
683  chisqforwards += dist*dist/(fSmearX*fSmearX); // crude parameterization of errors
684  }
685  }
686 
687  std::vector<float> tparend(6,0);
688  if ( gar::rec::initial_trackpar_estimate(trackTPCClusters, hlb, tparend[2], tparend[4],
689  tparend[3], tparend[5], tparend[0], tparend[1], xother, fInitialTPNTPCClusters, fPrintLevel) != 0)
690  {
691  return 1;
692  }
693  float chisqbackwards = 0;
694  float tepos[3] = {tparend[5],tparend[0],tparend[1]};
695  for (size_t i=0; i<trackTPCClusters.size(); ++i)
696  {
697  float dist = 0;
698  const float *pos = trackTPCClusters.at(i).Position();
699  int retcode = util::TrackPropagator::DistXYZ(tparend.data(),tepos,pos,dist);
700  if (retcode == 0)
701  {
702  chisqbackwards += dist*dist/(fSmearX*fSmearX); // crude parameterization of errors
703  }
704  }
705 
706 
707  // no covariance matrix in patrec tracks
708  float covmatbeg[25];
709  float covmatend[25];
710  for (size_t i=0; i<25; ++i) // no covmat in patrec tracks
711  {
712  covmatend[i] = 0;
713  covmatbeg[i] = 0;
714  }
715 
716  trackpar.setNTPCClusters(trackTPCClusters.size());
717  trackpar.setTime(0);
718  trackpar.setChisqForwards(chisqforwards);
719  trackpar.setChisqBackwards(chisqbackwards);
720  trackpar.setLengthForwards(lengthforwards);
721  trackpar.setLengthBackwards(lengthbackwards);
722  trackpar.setCovMatBeg(covmatbeg);
723  trackpar.setCovMatEnd(covmatend);
724  trackpar.setTrackParametersBegin(tparbeg.data());
725  trackpar.setXBeg(tparbeg[5]);
726  trackpar.setTrackParametersEnd(tparend.data());
727  trackpar.setXEnd(tparend[5]);
728 
729  return 0;
730  }
731  }
732 }
733 
734 namespace gar {
735  namespace rec {
737  }
738 }
static QCString name
Definition: declinfo.cpp:673
void setNTPCClusters(const size_t nTPCClusters)
Definition: TrackPar.cxx:214
base_engine_t & createEngine(seed_t seed)
void setLengthForwards(const float lengthforwards)
Definition: TrackPar.cxx:251
float fZCut1
Cut to ensure TPC Clusters are on different planes.
rec
Definition: tracks.py:88
bool WorldToLocal(std::array< double, 3 > const &world, std::array< double, 3 > &local, gar::geo::LocalTransformation< TGeoHMatrix > &trans) const
float const & Time() const
Definition: CaloDeposit.h:71
CLHEP::HepRandomEngine & fEngine
const float * TrackParBeg() const
Definition: Track.h:151
void setCovMatBeg(const float *covmatbeg)
Definition: TrackPar.cxx:235
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
dayoneconverter(fhicl::ParameterSet const &p)
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
gar::geo::BitFieldCoder * fFieldDecoderTrk
static int DistXYZ(const float *trackpar, const float *Xpoint, const float *xyz, float &retDist)
double const & Z() const
Definition: CaloDeposit.h:75
Description of geometry of one entire detector.
Definition: GeometryCore.h:436
void setLengthBackwards(const float lengthbackwards)
Definition: TrackPar.cxx:256
bool fUseOnlyTrueMuonHits
whether to cheat and use true muon hits
Particle class.
float fRCut
Road in the YZ plane to add hits on a circle.
float fTimeBunch
Time bunch spread, in ns.
float fSmearY
amount by which to smear Y, in cm
std::string fInputEdepInstanceTPC
Input instance for TPC edeps.
Class to transform between world and local coordinates.
gar::geo::BitFieldCoder * fFieldDecoderMuID
float const & Energy() const
Definition: CaloDeposit.h:72
float fSmearLY
amount by which to smear the LY
void setTrackParametersBegin(const float *tparbeg)
Definition: TrackPar.cxx:219
T abs(T value)
std::string fInputEdepLabel
Input label for edeps.
float fThrPE
threshold cut in pe
const double e
const float * Vertex() const
Definition: Track.h:139
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
void digitizeCaloHitsSimple(gar::sdp::CaloDeposit cd, float *fcpos, float &energy, float &time)
void produce(art::Event &e) override
std::void_t< T > n
Helper class for decoding and encoding a bit field of 64bits for convenient declaration.
const double a
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
float fSmearT
amount by which to smear T, in ns
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
void setChisqBackwards(const float chisqbackwards)
Definition: TrackPar.cxx:266
double const & Y() const
Definition: CaloDeposit.h:74
std::string fG4ModuleLabel
Use this to get the MCParticles.
long long int CellID_t
Definition: CaloRawDigit.h:24
raw::CellID_t const & CellID() const
Definition: CaloDeposit.h:76
gar::rec::Track CreateTrack()
Definition: TrackPar.cxx:292
float fSmearX
amount by which to smear X, in cm
Interface to propagate a Track to the specific point.
bool fIncludeMuIDhits
Include MuID hits as TPCClusters.
General GArSoft Utilities.
double const & X() const
Definition: CaloDeposit.h:73
std::string fInputEdepInstanceMuID
Input instance for MuID edeps.
long64 get(long64 bitfield, size_t index) const
float fPECm
conversion factor from cm step length to pe
void setCovMatEnd(const float *covmatend)
Definition: TrackPar.cxx:243
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
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
dayoneconverter & operator=(dayoneconverter const &)=delete
static bool * b
Definition: config.cpp:1043
const std::string VolumeName(TVector3 const &point) const
Returns the name of the deepest volume containing specified point.
void setChisqForwards(const float chisqforwards)
Definition: TrackPar.cxx:261
const float * Position() const
Definition: TPCCluster.h:68
const gar::geo::GeometryCore * fGeo
geometry information
float Time() const
Definition: TPCCluster.h:73
void digitizeCaloHitsMu2e(gar::sdp::CaloDeposit cd, float *fcpos, float &energy, float &time)
int makepatrectrack(std::vector< gar::rec::TPCCluster > &trackTPCClusters, gar::rec::TrackPar &trackpar)
art framework interface to geometry description
void setTime(const double time)
Definition: TrackPar.cxx:281
float const & StepLength() const
Definition: CaloDeposit.h:78
float fZCut2
Cut to ensure TPC clusters are on the same plane.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
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