LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
Track3DKalmanSPS_module.cc
Go to the documentation of this file.
1 //
3 // \file Track3DKalmanSPS.cxx
4 //
5 // \author echurch@fnal.gov
6 //
7 // This algorithm is designed to reconstruct 3D tracks through
8 // GENFIT's Kalman filter.
10 
11 // C++ includes
12 #include <algorithm> // std::sort()
13 #include <cmath>
14 #include <iterator> // std::distance()
15 #include <sstream>
16 #include <string>
17 #include <vector>
18 
19 // ROOT includes
20 #include "TDatabasePDG.h"
21 #include "TMath.h"
22 #include "TMatrixT.h"
23 #include "TPrincipal.h"
24 #include "TTree.h"
25 #include "TVector3.h"
26 
27 // Framework includes
28 #include "fhiclcpp/ParameterSet.h"
29 #include "fhiclcpp/exception.h"
31 
37 #include "art_root_io/TFileService.h"
41 
42 // GENFIT includes
47 #include "larreco/Genfit/GFTrack.h"
50 
51 // LArSoft includes
60 //\todo Reconstruction Producers should never include SimulationBase objects
63 
66 {
67  const double* xyz1 = h1->XYZ();
68  const double* xyz2 = h2->XYZ();
69  return xyz1[2] < xyz2[2];
70 }
73 {
74  const double* xyz1 = h1->XYZ();
75  const double* xyz2 = h2->XYZ();
76  return xyz1[1] < xyz2[1];
77 }
80 {
81  const double* xyz1 = h1->XYZ();
82  const double* xyz2 = h2->XYZ();
83  return xyz1[0] < xyz2[0];
84 }
85 
88 {
89  const unsigned int s1 = h1.size();
90  const unsigned int s2 = h2.size();
91  return s1 > s2;
92 }
93 
94 namespace trkf {
95 
97  public:
98  explicit Track3DKalmanSPS(fhicl::ParameterSet const& pset);
99 
100  private:
101  void produce(art::Event& evt);
102  void beginJob();
103  void endJob();
104  double energyLossBetheBloch(const double& mass, const double p);
105 
106  void rotationCov(TMatrixT<Double_t>& cov, const TVector3& u, const TVector3& v);
107  std::vector<double> dQdxCalc(const art::FindManyP<recob::Hit>& h,
109  const TVector3& p,
110  const TVector3& d);
111 
112  std::string fClusterModuleLabel; // label for input collection
113  std::string fSpptModuleLabel; // label for input collection
114  std::string fGenieGenModuleLabel; // label for input MC single particle generator
115  std::string fG4ModuleLabel; // label for input MC single particle generator
116  std::string fSortDim; // direction in which to sort spacepoints
117 
118  // TFile *fileGENFIT;
119  TTree* tree;
120 
121  TMatrixT<Double_t>* stMCT;
122  TMatrixT<Double_t>* covMCT;
123  TMatrixT<Double_t>* stREC;
124  TMatrixT<Double_t>* covREC;
125  Float_t chi2;
126  Float_t chi2ndf;
127  int fcont;
128 
129  Float_t* fpRECL;
130  Float_t* fpREC;
131  Float_t* fpMCMom;
132  Float_t* fpMCPos;
133  Float_t* fState0;
134  Float_t* fCov0;
135  int nfail;
136  int ndf;
138  int ispptvec;
139  int nspptvec;
140  unsigned int evtt;
141  unsigned int nTrks;
142  unsigned int fptsNo;
143  Float_t* fshx;
144  Float_t* fshy;
145  Float_t* fshz;
146  Float_t* feshx;
147  Float_t* feshy;
148  Float_t* feshz;
149  Float_t* feshyz;
150  Float_t* fupdate;
151  Float_t* fchi2hit;
152  Float_t* fth;
153  Float_t* feth;
154  Float_t* fedudw;
155  Float_t* fedvdw;
156  Float_t* feu;
157  Float_t* fev;
158  Float_t* fsep;
159  Float_t* fdQdx;
160  unsigned int fDimSize; // if necessary will get this from pset in constructor.
161  Float_t* fPCmeans;
162  Float_t* fPCevals;
163  Float_t* fPCsigmas;
164  Float_t* fPC1;
165  Float_t* fPC2;
166  Float_t* fPC3;
167 
168  std::vector<double> fPosErr;
169  std::vector<double> fMomErr;
170  std::vector<double> fMomStart;
171  double fPerpLim;
172  bool fDoFit;
173  int fNumIt;
174  uint16_t fMinNumSppts;
175  double fErrScaleS;
176  double fErrScaleM;
178  double fMaxUpdate;
180  double fDistanceU;
181  double fMaxUpdateU;
182  double fMomLow;
183  double fMomHigh;
184  int fPdg;
185  double fChi2Thresh;
186  int fMaxPass;
187 
190 
191  }; // class Track3DKalmanSPS
192 
193 }
194 
195 namespace trkf {
196 
197  //-------------------------------------------------
199  : EDProducer{pset}
200  , fDoFit(true)
201  , fNumIt(5)
202  , fMinNumSppts(5)
203  , fErrScaleS(1.0)
204  , fErrScaleM(1.0)
205  , fDecimate(1)
206  , fMaxUpdate(0.10)
207  , fDecimateU(1)
208  , fDistanceU(1.)
209  , fMaxUpdateU(0.10)
210  , fMomLow(0.001)
211  , fMomHigh(100.)
212  , fPdg(-13)
213  , fChi2Thresh(12.0E12)
214  , fMaxPass(1)
215  {
216  fClusterModuleLabel = pset.get<std::string>("ClusterModuleLabel");
217  fSpptModuleLabel = pset.get<std::string>("SpptModuleLabel");
218  fGenieGenModuleLabel = pset.get<std::string>("GenieGenModuleLabel");
219  fG4ModuleLabel = pset.get<std::string>("G4ModuleLabel");
220  fPosErr = pset.get<std::vector<double>>("PosErr3"); // resolution. cm
221  fMomErr = pset.get<std::vector<double>>("MomErr3"); // GeV
222  fMomStart = pset.get<std::vector<double>>("MomStart3"); //
223  fPerpLim = pset.get<double>("PerpLimit", 1.e6); // PCA cut.
224  fDoFit = pset.get<bool>("DoFit", true); // Der.
225  fNumIt = pset.get<int>("NumIt", 5); // Number x2 passes per fit.
226  fMinNumSppts =
227  pset.get<int>("MinNumSppts", 5); // Min number of sppts in vector to bother fitting
228  fErrScaleS = pset.get<double>("ErrScaleSim", 1.0); // error scale.
229  fErrScaleM = pset.get<double>("ErrScaleMeas", 1.0); // error scale.
230  fDecimate = pset.get<int>("DecimateC", 40); // Sparsify data.
231  fMaxUpdate = pset.get<double>("MaxUpdateC", 0.1); // 0-out.
232  fDecimateU = pset.get<int>("DecimateU", 100); // Sparsify data.
233  fDistanceU =
234  pset.get<double>("DistanceU", 10.0); // Require this separation on uncontained 2nd pass.
235  fMaxUpdateU = pset.get<double>("MaxUpdateU", 0.02); // 0-out.
236  fMomLow = pset.get<double>("MomLow", 0.01); // Fit Range.
237  fMomHigh = pset.get<double>("MomHigh", 20.); // Fit Range.
238  fPdg = pset.get<int>("PdgCode", -13); // mu+ Hypothesis.
239  fChi2Thresh = pset.get<double>("Chi2HitThresh", 12.0E12); //For Re-pass.
240  fSortDim = pset.get<std::string>("SortDirection", "z"); // case sensitive
241  fMaxPass = pset.get<int>("MaxPass", 2); // mu+ Hypothesis.
242  bool fGenfPRINT;
243  if (pset.get_if_present("GenfPRINT", fGenfPRINT)) {
244  MF_LOG_WARNING("Track3DKalmanSPS_GenFit")
245  << "Parameter 'GenfPRINT' has been deprecated.\n"
246  "Please use the standard message facility to enable GenFit debug output.";
247  // A way to enable debug output is all of the following:
248  // - compile in debug mode (no optimization, no profiling)
249  // - if that makes everything too noisy, add to have everything else quiet
250  // services.message.debugModules: [ "Track3DKalmanSPS" ]
251  // - to print all the GenFit debug messages, set
252  // services.message.destinations.LogDebugFile.categories.Track3DKalmanSPS_GenFit.limit: -1
253  // (assuming there is a LogDebugFile destination already; for example
254  // see the settings in uboonecode/uboone/Utilities/services_microboone.fcl )
255  }
256 
257  produces<std::vector<recob::Track>>();
258  produces<art::Assns<recob::Track, recob::Cluster>>();
259  produces<art::Assns<recob::Track, recob::SpacePoint>>();
260  produces<art::Assns<recob::Track, recob::Hit>>();
261  }
262 
263  //-------------------------------------------------
264  // stolen, mostly, from GFMaterialEffects.
265  double Track3DKalmanSPS::energyLossBetheBloch(const double& mass, const double p = 1.5)
266  {
267  const double charge(1.0);
268  const double mEE(188.); // eV
269  const double matZ(18.);
270  const double matA(40.);
271  const double matDensity(1.4);
272  const double me(0.000511);
273 
274  double beta = p / std::sqrt(mass * mass + p * p);
275  double gammaSquare = 1. / (1.0 - beta * beta);
276  // 4pi.r_e^2.N.me = 0.307075, I think.
277  double dedx = 0.307075 * matDensity * matZ / matA / (beta * beta) * charge * charge;
278  double massRatio = me / mass;
279  // me=0.000511 here is in GeV. So mEE comes in here in eV.
280  double argument = gammaSquare * beta * beta * me * 1.E3 * 2. /
281  ((1.E-6 * mEE) * std::sqrt(1 + 2 * std::sqrt(gammaSquare) * massRatio +
282  massRatio * massRatio));
283 
284  if (mass == 0.0) return (0.0);
285  if (argument <= exp(beta * beta)) { dedx = 0.; }
286  else {
287  dedx *= (log(argument) - beta * beta); // Bethe-Bloch [MeV/cm]
288  dedx *= 1.E-3; // in GeV/cm, hence 1.e-3
289  if (dedx < 0.) dedx = 0.;
290  }
291  return dedx;
292  }
293 
294  void Track3DKalmanSPS::rotationCov(TMatrixT<Double_t>& cov, const TVector3& u, const TVector3& v)
295  {
296  TVector3 xhat(1.0, 0.0, 0.0);
297  TVector3 yhat(0.0, 1.0, 0.0);
298  TVector3 zhat(0.0, 0.0, 1.0);
299  TVector3 w(u.Cross(v));
300  TVector3 uprime(u);
301  TVector3 vprime(w.Cross(xhat)); // vprime now lies in yz plane
302  Double_t angle(v.Angle(vprime)); /* This is the angle through which v
303  must rotate. */
304  uprime.Rotate(angle, w); // u now is rotated the same amount
305  if (uprime * xhat < 0) {
306  uprime.Rotate(TMath::Pi(), w);
307  vprime.Rotate(TMath::Pi(), w);
308  angle += TMath::Pi();
309  }
310  // Build the block-diagonal 5x5 matrix
311  double c = TMath::Cos(angle), s = TMath::Sin(angle);
312  TMatrixT<Double_t> rot(5, 5);
313  rot[0][0] = 1.0;
314  rot[1][1] = c;
315  rot[1][2] = s;
316  rot[2][1] = -s;
317  rot[2][2] = c;
318  rot[3][3] = c;
319  rot[3][4] = s;
320  rot[4][3] = -s;
321  rot[4][4] = c;
322 
323  cov = rot * cov;
324  }
325 
328  const TVector3& dir,
329  const TVector3& loc)
330  {
331  // For now just Collection plane.
332  // We should loop over all views, more generally.
334  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout>()->Get();
337  std::vector<double> v;
338 
339  double mindist(100.0); // cm
340  auto spptminIt(sppt);
341  while (sppt != s.end()) {
342  if (((**sppt).XYZ() - loc).Mag() < mindist) {
343  double dist = ((**sppt).XYZ() - loc).Mag();
344 
345  // Jump out if we're as close as 0.1 mm away.
346  if (dist < mindist) {
347  mindist = dist;
348  spptminIt = sppt;
349  if (mindist < 0.01) break;
350  }
351  }
352  sppt++;
353  }
354  sstart = spptminIt; // for next time.
355  unsigned int ind(std::distance(s.begin(), spptminIt));
356 
357  std::vector<art::Ptr<recob::Hit>> hitlist = h.at(ind);
358 
359  double wirePitch = 0.;
360  double angleToVert = 0;
361  double charge = 0.;
362 
363  // FIXME: Currently the last iteration sets the charge, wirePitch, and angleToVert variables.
364  // Is this expected?
365  for (std::vector<art::Ptr<recob::Hit>>::const_iterator ihit = hitlist.begin();
366  ihit != hitlist.end();
367  ++ihit) {
368  const recob::Hit& hit1 = **ihit;
369  if (hit1.SignalType() != sig) continue;
370  auto const& plane = wireReadoutGeom.Plane(hit1.WireID());
371  charge = hit1.Integral();
372  wirePitch = plane.WirePitch();
373  angleToVert = plane.Wire(0).ThetaZ(false) - 0.5 * TMath::Pi();
374  }
375 
376  double cosgamma =
377  TMath::Abs(TMath::Sin(angleToVert) * dir.Y() + TMath::Cos(angleToVert) * dir.Z());
378 
379  v.push_back(charge / wirePitch / cosgamma);
380 
381  return v;
382  }
383 
384  //-------------------------------------------------
386  {
387 
389 
390  stMCT = new TMatrixT<Double_t>(5, 1);
391  covMCT = new TMatrixT<Double_t>(5, 5);
392  stREC = new TMatrixT<Double_t>(5, 1);
393  covREC = new TMatrixT<Double_t>(5, 5);
394 
395  fpMCMom = new Float_t[4];
396  fpMCPos = new Float_t[4];
397  fpREC = new Float_t[4];
398  fpRECL = new Float_t[4];
399  fState0 = new Float_t[5];
400  fCov0 = new Float_t[25];
401  fDimSize = 20000; // if necessary will get this from pset in constructor.
402 
403  fshx = new Float_t[fDimSize];
404  fshy = new Float_t[fDimSize];
405  fshz = new Float_t[fDimSize];
406  feshx = new Float_t[fDimSize];
407  feshy = new Float_t[fDimSize];
408  feshz = new Float_t[fDimSize];
409  feshyz = new Float_t[fDimSize];
410  fupdate = new Float_t[fDimSize];
411  fchi2hit = new Float_t[fDimSize];
412  fth = new Float_t[fDimSize];
413  feth = new Float_t[fDimSize];
414  fedudw = new Float_t[fDimSize];
415  fedvdw = new Float_t[fDimSize];
416  feu = new Float_t[fDimSize];
417  fev = new Float_t[fDimSize];
418  fsep = new Float_t[fDimSize];
419  fdQdx = new Float_t[fDimSize];
420 
421  fPC1 = new Float_t[3];
422  fPC2 = new Float_t[3];
423  fPC3 = new Float_t[3];
424  fPCmeans = new Float_t[3];
425  fPCsigmas = new Float_t[3];
426  fPCevals = new Float_t[3];
427 
428  // //TFile fileGENFIT("GENFITout.root","RECREATE");
429 
430  tree = tfs->make<TTree>("GENFITttree", "GENFITttree");
431  //tree->Branch("stMCT",&stMCT,"stMCT[5]/F"); // "TMatrixT<Double_t>"
432 
433  //tree->Branch("stMCT","TMatrixD",&stMCT,64000,0);
434  //tree->Branch("covMCT",covMCT,"covMCT[25]/F");
435  tree->Branch("covMCT", "TMatrixD", &covMCT, 64000, 0);
436  tree->Branch("stREC", fState0, "stREC[5]/F");
437  //tree->Branch("stREC","TMatrixD",&stREC,64000,0);
438  tree->Branch("covREC", fCov0, "covREC[25]/F");
439  //tree->Branch("covREC","TMatrixD",&covREC,64000,0);
440 
441  tree->Branch("nchi2rePass", &nchi2rePass, "nchi2rePass/I");
442  tree->Branch("ispptvec", &ispptvec, "ispptvec/I");
443  tree->Branch("chi2", &chi2, "chi2/F");
444  tree->Branch("nfail", &nfail, "nfail/I");
445  tree->Branch("ndf", &ndf, "ndf/I");
446  tree->Branch("evtNo", &evtt, "evtNo/I");
447  tree->Branch("nspptvec", &nspptvec, "nspptvec/I");
448  tree->Branch("chi2ndf", &chi2ndf, "chi2ndf/F");
449 
450  tree->Branch("trkNo", &nTrks, "trkNo/I");
451  tree->Branch("ptsNo", &fptsNo, "ptsNo/I");
452  tree->Branch("cont", &fcont, "cont/I"); //O? Yes, O. Not 0, not L, ...
453  tree->Branch("shx", fshx, "shx[ptsNo]/F");
454  tree->Branch("shy", fshy, "shy[ptsNo]/F");
455  tree->Branch("shz", fshz, "shz[ptsNo]/F");
456  tree->Branch("sep", fsep, "sep[ptsNo]/F");
457  tree->Branch("dQdx", fdQdx, "dQdx[ptsNo]/F");
458  tree->Branch("eshx", feshx, "eshx[ptsNo]/F");
459  tree->Branch("eshy", feshy, "eshy[ptsNo]/F");
460  tree->Branch("eshz", feshz, "eshz[ptsNo]/F");
461  tree->Branch("eshyz", feshyz, "eshyz[ptsNo]/F");
462  tree->Branch("update", fupdate, "update[ptsNo]/F");
463  tree->Branch("chi2hit", fchi2hit, "chi2hit[ptsNo]/F");
464  tree->Branch("th", fth, "th[ptsNo]/F");
465  tree->Branch("eth", feth, "eth[ptsNo]/F");
466  tree->Branch("edudw", fedudw, "edudw[ptsNo]/F");
467  tree->Branch("edvdw", fedvdw, "edvdw[ptsNo]/F");
468  tree->Branch("eu", feu, "eu[ptsNo]/F");
469  tree->Branch("ev", fev, "ev[ptsNo]/F");
470 
471  tree->Branch("pcMeans", fPCmeans, "pcMeans[3]/F");
472  tree->Branch("pcSigmas", fPCsigmas, "pcSigmas[3]/F");
473  tree->Branch("pcEvals", fPCevals, "pcEvals[3]/F");
474  tree->Branch("pcEvec1", fPC1, "pcEvec1[3]/F");
475  tree->Branch("pcEvec2", fPC2, "pcEvec2[3]/F");
476  tree->Branch("pcEvec3", fPC3, "pcEvec3[3]/F");
477 
478  tree->Branch("pMCMom", fpMCMom, "pMCMom[4]/F");
479  tree->Branch("pMCPos", fpMCPos, "pMCPos[4]/F");
480  tree->Branch("pRECKalF", fpREC, "pRECKalF[4]/F");
481  tree->Branch("pRECKalL", fpRECL, "pRECKalL[4]/F");
482  }
483 
484  //-------------------------------------------------
486  {
487  if (!rep) delete rep;
488  if (!repMC) delete repMC;
489 
490  delete[] fpREC;
491  delete[] fpRECL;
492  delete[] fState0;
493  delete[] fCov0;
494 
495  delete[] fshx;
496  delete[] fshy;
497  delete[] fshz;
498  delete[] feshx;
499  delete[] feshy;
500  delete[] feshyz;
501  delete[] feshz;
502  delete[] fupdate;
503  delete[] fchi2hit;
504  delete[] fth;
505  delete[] feth;
506  delete[] fedudw;
507  delete[] fedvdw;
508  delete[] feu;
509  delete[] fev;
510  delete[] fsep;
511  delete[] fdQdx;
512 
513  delete[] fPCmeans;
514  delete[] fPCsigmas;
515  delete[] fPCevals;
516  delete[] fPC1;
517  delete[] fPC2;
518  delete[] fPC3;
519  }
520 
521  //------------------------------------------------------------------------------------//
523  {
524  rep = 0;
525  repMC = 0;
526  // get services
528 
530  // Make a std::unique_ptr<> for the thing you want to put into the event
531  // because that handles the memory management for you
533  std::unique_ptr<std::vector<recob::Track>> tcol(new std::vector<recob::Track>);
534  std::unique_ptr<art::Assns<recob::Track, recob::SpacePoint>> tspassn(
536  std::unique_ptr<art::Assns<recob::Track, recob::Hit>> thassn(
538 
539  unsigned int tcnt = 0;
540 
541  // get input Hit object(s).
542  art::Handle<std::vector<recob::Cluster>> clusterListHandle;
543  evt.getByLabel(fClusterModuleLabel, clusterListHandle);
544 
546  evt.getByLabel(fSpptModuleLabel, spptListHandle);
547 
549 
553  if (!evt.isRealData()) {
554 
555  art::Handle<std::vector<simb::MCTruth>> mctruthListHandle;
556  evt.getByLabel(fGenieGenModuleLabel, mctruthListHandle);
557 
558  for (unsigned int ii = 0; ii < mctruthListHandle->size(); ++ii) {
559  art::Ptr<simb::MCTruth> mctparticle(mctruthListHandle, ii);
560  mclist.push_back(mctparticle);
561  }
562  }
563 
564  std::vector<art::PtrVector<recob::SpacePoint>> spptIn(spptListHandle->begin(),
565  spptListHandle->end());
566  // Get the spptvectors that are largest to be first, and smallest last.
567  std::sort(spptIn.begin(), spptIn.end(), sp_sort_nsppts);
568 
569  std::vector<art::PtrVector<recob::SpacePoint>>::const_iterator sppt = spptIn.begin();
570  auto spptB = sppt;
571 
572  TVector3 MCOrigin;
573  TVector3 MCMomentum;
574  // TVector3 posErr(.05,.05,.05); // resolution. 0.5mm
575  // TVector3 momErr(.1,.1,0.2); // GeV
576  TVector3 posErr(fPosErr[0], fPosErr[1], fPosErr[2]); // resolution. 0.5mm
577  TVector3 momErr(fMomErr[0], fMomErr[1], fMomErr[2]); // GeV
578  TVector3 momErrFit(fMomErr[0], fMomErr[1], fMomErr[2]); // GeV
579 
580  // This is strictly for MC
584  if (!evt.isRealData()) {
585  // Below breaks are stupid, I realize. But rather than keep all the MC
586  // particles I just take the first primary, e.g., muon and only keep its
587  // info in the branches of the Ttree. I could generalize later, ...
588  for (unsigned int ii = 0; ii < mclist.size(); ++ii) {
589  art::Ptr<simb::MCTruth> mc(mclist[ii]);
590  for (int jj = 0; jj < mc->NParticles(); ++jj) {
592  MCOrigin.SetXYZ(part.Vx(), part.Vy(), part.Vz()); // V for Vertex
593  MCMomentum.SetXYZ(part.Px(), part.Py(), part.Pz());
594  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit")
595  << "FROM MC TRUTH, the particle's pdg code is: " << part.PdgCode()
596  << " with energy = " << part.E() << ", with energy = " << part.E()
597  << "\n vtx: " << genf::ROOTobjectToString(MCOrigin)
598  << "\n momentum: " << genf::ROOTobjectToString(MCMomentum)
599  << "\n (both in Global (not volTPC) coords)";
600 
601  repMC = new genf::RKTrackRep(MCOrigin, MCMomentum, posErr, momErr, part.PdgCode());
602  break;
603  }
604  break;
605  }
606  //for saving of MC truth
607  stMCT->ResizeTo(repMC->getState());
608  *stMCT = repMC->getState();
609  covMCT->ResizeTo(repMC->getCov());
610  *covMCT = repMC->getCov();
611  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit")
612  << " repMC, covMC are ... \n"
614 
615  } // !isRealData
616  nTrks = 0;
617  TParticlePDG* part = TDatabasePDG::Instance()->GetParticle(fPdg);
618  Double_t mass = part->Mass();
619 
620  auto const& tpc = geom->TPC({0, 0});
621  size_t cntp(0);
622  while (sppt != spptIn.end()) {
623 
624  const art::PtrVector<recob::SpacePoint>& spacepoints = *sppt;
625 
626  double fMaxUpdateHere(fMaxUpdateU);
627  int fDecimateHere(fDecimateU);
628  double fErrScaleSHere(fErrScaleS);
629  double fErrScaleMHere(fErrScaleM);
630  int rePass0(1);
631  unsigned int nTailPoints = 0; // 100;
632  if (spacepoints.size() < 5) {
633  sppt++;
634  rePass0 = 3;
635  continue;
636  } // for now...
637 
638  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit")
639  << "\n\t found " << spacepoints.size()
640  << " 3D spacepoint(s) for this element of std::vector<art:PtrVector> spacepoints. \n";
641 
642  // Let's find track's principle components.
643  // We will sort along that direction, rather than z.
644  // Further, we will skip outliers away from main axis.
645 
646  TPrincipal* principal = new TPrincipal(3, "ND");
647 
648  // I need to shuffle these around, so use copy constructor
649  // to make non-const version spacepointss.
650  art::PtrVector<recob::SpacePoint> spacepointss(spacepoints);
651 
652  // What I need is a nearest neighbor sorting.
653  if (fSortDim.compare("y") && fSortDim.compare("x"))
654  std::sort(spacepointss.begin(), spacepointss.end(), sp_sort_3dz);
655  if (!fSortDim.compare("y")) std::sort(spacepointss.begin(), spacepointss.end(), sp_sort_3dy);
656  if (!fSortDim.compare("x")) std::sort(spacepointss.begin(), spacepointss.end(), sp_sort_3dx);
657 
658  for (unsigned int point = 0; point < spacepointss.size(); ++point) {
659  if (point < (spacepointss.size() - nTailPoints)) {
660  principal->AddRow(spacepointss[point]->XYZ());
661  }
662  }
663  principal->MakePrincipals();
664 
665  const TVectorD* evals = principal->GetEigenValues();
666  const TMatrixD* evecs = principal->GetEigenVectors();
667  const TVectorD* means = principal->GetMeanValues();
668  const TVectorD* sigmas = principal->GetSigmas();
669 
670  Double_t tmp[3], tmp2[3];
671  principal->X2P((Double_t*)(means->GetMatrixArray()), tmp);
672  principal->X2P((Double_t*)(sigmas->GetMatrixArray()), tmp2);
673  for (unsigned int ii = 0; ii < 3; ++ii) {
674  fPCmeans[ii] = (Float_t)(tmp[ii]);
675  fPCsigmas[ii] = (Float_t)(tmp2[ii]);
676  fPCevals[ii] = (Float_t)(evals->GetMatrixArray())[ii];
677  // This method requires apparently pulling all 9
678  // elements. Maybe 3 works.
679  // Certainly, w can't be a scalar, I discovered.
680  double w[9];
681  evecs->ExtractRow(ii, 0, w);
682  fPC1[ii] = w[0];
683  fPC2[ii] = w[1];
684  fPC3[ii] = w[2];
685  }
686  Double_t tmp3[3], tmp4[3], tmp5[3];
687  principal->X2P((Double_t*)fPC1, tmp3);
688  principal->X2P((Double_t*)fPC2, tmp4);
689  principal->X2P((Double_t*)fPC3, tmp5);
690 
691  // Use a mip approximation assuming straight lines
692  // and a small angle wrt beam.
693  fMomStart[0] = spacepointss[spacepointss.size() - 1]->XYZ()[0] - spacepointss[0]->XYZ()[0];
694  fMomStart[1] = spacepointss[spacepointss.size() - 1]->XYZ()[1] - spacepointss[0]->XYZ()[1];
695  fMomStart[2] = spacepointss[spacepointss.size() - 1]->XYZ()[2] - spacepointss[0]->XYZ()[2];
696  // This presumes a 0.8 GeV/c particle
697  double dEdx = energyLossBetheBloch(mass, 1.0);
698  // mom is really KE.
699  TVector3 mom(dEdx * fMomStart[0], dEdx * fMomStart[1], dEdx * fMomStart[2]);
700  double pmag2 = pow(mom.Mag() + mass, 2. - mass * mass);
701  mom.SetMag(std::sqrt(pmag2));
702  // Over-estimate by just enough for contained particles (5%).
703  mom.SetMag(1.0 * mom.Mag());
704  // If 1st/last point is close to edge of TPC, this track is
705  // uncontained.Give higher momentum starting value in
706  // that case.
707  bool uncontained(false);
708  double close(5.); // cm.
709  double epsMag(0.001); // cm.
710  double epsX(250.0); // cm.
711  double epsZ(0.001); // cm.
712 
713  if (spacepointss[spacepointss.size() - 1]->XYZ()[0] > (2. * tpc.HalfWidth() - close) ||
714  spacepointss[spacepointss.size() - 1]->XYZ()[0] < close ||
715  spacepointss[0]->XYZ()[0] > (2. * tpc.HalfWidth() - close) ||
716  spacepointss[0]->XYZ()[0] < close ||
717  spacepointss[spacepointss.size() - 1]->XYZ()[1] > (1. * tpc.HalfHeight() - close) ||
718  (spacepointss[spacepointss.size() - 1]->XYZ()[1] < -1. * tpc.HalfHeight() + close) ||
719  spacepointss[0]->XYZ()[1] > (1. * tpc.HalfHeight() - close) ||
720  spacepointss[0]->XYZ()[1] < (-1. * tpc.HalfHeight() + close) ||
721  spacepointss[spacepointss.size() - 1]->XYZ()[2] > (tpc.Length() - close) ||
722  spacepointss[spacepointss.size() - 1]->XYZ()[2] < close ||
723  spacepointss[0]->XYZ()[2] > (tpc.Length() - close) || spacepointss[0]->XYZ()[2] < close)
724  uncontained = true;
725  fErrScaleSHere = fErrScaleS;
726  fErrScaleMHere = fErrScaleM;
727 
728  if (uncontained) {
729  // Big enough to not run out of gas right at end of
730  // track and give large angular deviations which
731  // will kill the fit.
732  mom.SetMag(2.0 * mom.Mag());
733  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit") << "Uncontained track ... ";
734  fDecimateHere = fDecimateU;
735  fMaxUpdateHere = fMaxUpdateU;
736  }
737  else {
738  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit")
739  << "Contained track ... Run " << evt.run() << " Event " << evt.id().event();
740  // Don't decimate contained tracks as drastically,
741  // and omit only very large corrections ...
742  // which hurt only high momentum tracks.
743  fDecimateHere = fDecimate;
744  fMaxUpdateHere = fMaxUpdate;
745  }
746  fcont = (int)(!uncontained);
747 
748  // This seems like best place to jump back to for a re-pass.
749  unsigned short rePass = rePass0; // 1 by default;
750  unsigned short maxPass(fMaxPass);
751  unsigned short tcnt1(0);
752  while (rePass <= maxPass) {
753 
754  TVector3 momM(mom);
755  TVector3 momErrFit(momM[0] / 3.0, momM[1] / 3.0,
756  momM[2] / 3.0); // GeV
757 
759  genf::GFDetPlane planeG((TVector3)(spacepointss[0]->XYZ()), momM);
760 
761  // Initialize with 1st spacepoint location and ...
762  rep = new genf::RKTrackRep((TVector3)(spacepointss[0]->XYZ()),
763  momM,
764  posErr,
765  momErrFit,
766  fPdg); // mu+ hypothesis
767 
768  genf::GFTrack fitTrack(rep); //initialized with smeared rep
769  fitTrack.setPDG(fPdg);
770  // Gonna sort in z cuz I want to essentially transform here to volTPC coords.
771  // volTPC coords, cuz that's what the Geant3/Geane stepper wants, as that's its understanding
772  // from the Geant4 geometry, which it'll use. EC, 7-Jan-2011.
773  int ihit = 0;
774  fptsNo = 0;
775  std::vector<unsigned int> spptSurvivedIndex;
776  std::vector<unsigned int> spptSkippedIndex;
777  unsigned int ppoint(0);
778  for (unsigned int point = 0; point < spacepointss.size(); ++point) {
779  double sep;
780  // Calculate the distance in 2nd and 3rd PCs and
781  // reject spt if it's too far out. Remember, the
782  // sigmas are std::sqrt(eigenvals).
783  double tmp[3];
784  principal->X2P((Double_t*)(spacepointss[point]->XYZ()), tmp);
785  sep = std::sqrt(tmp[1] * tmp[1] / fPCevals[1] + tmp[2] * tmp[2] / fPCevals[2]);
786  if ((std::abs(sep) > fPerpLim) && (point < (spacepointss.size() - nTailPoints)) &&
787  rePass <= 1) {
788  spptSkippedIndex.push_back(point);
789  continue;
790  }
791  // If point is too close in Mag or Z or too far in X from last kept point drop it.
792  // I think this is largely redundant with PCA cut.
793  TVector3 one(spacepointss[point]->XYZ());
794  TVector3 two(spacepointss[ppoint]->XYZ());
795  if (rePass == 2 && uncontained) {
796  epsMag = fDistanceU; // cm
797  fNumIt = 4;
798  fErrScaleMHere = 0.1;
799  // Above allows us to pretend as though measurements
800  // are perfect, which we can ostensibly do now with
801  // clean set of sppts. This creates larger gains, bigger
802  // updates: bigger sensitivity to multiple scattering.
803  }
804  else if (rePass == 2 && !uncontained) {}
805  if (point > 0 &&
806  ((one - two).Mag() < epsMag || // too close
807  ((one - two).Mag() > 8.0 && rePass == 1) || // too far
808  std::abs(spacepointss[point]->XYZ()[2] - spacepointss[ppoint]->XYZ()[2]) < epsZ ||
809  std::abs(spacepointss[point]->XYZ()[0] - spacepointss[ppoint]->XYZ()[0]) > epsX)) {
810  spptSkippedIndex.push_back(point);
811  continue;
812  }
813 
814  if (
815  point % fDecimateHere &&
816  rePass <=
817  1) // Jump out of loop except on every fDecimate^th pt. fDecimate==1 never sees continue.
818  {
819  /* Replace continue with a counter that will be used to index into vector of GFKalman fits. */
820  continue;
821  }
822 
823  ppoint = point;
824  TVector3 spt3 = (TVector3)(spacepointss[point]->XYZ());
825  std::vector<double> err3;
826  err3.push_back(spacepointss[point]->ErrXYZ()[0]);
827  err3.push_back(spacepointss[point]->ErrXYZ()[2]);
828  err3.push_back(spacepointss[point]->ErrXYZ()[4]);
829  err3.push_back(spacepointss[point]->ErrXYZ()[5]); // lower triangle diags.
830  if (fptsNo < fDimSize) {
831  fshx[fptsNo] = spt3[0];
832  fshy[fptsNo] = spt3[1];
833  fshz[fptsNo] = spt3[2];
834  feshx[fptsNo] = err3[0];
835  feshy[fptsNo] = err3[1];
836  feshz[fptsNo] = err3[3];
837  feshyz[fptsNo] = err3[2];
838  fsep[fptsNo] = sep;
839 
840  if (fptsNo > 1) {
841  TVector3 pointer(fshx[fptsNo] - fshx[fptsNo - 1],
842  fshy[fptsNo] - fshy[fptsNo - 1],
843  fshz[fptsNo] - fshz[fptsNo - 1]);
844  TVector3 pointerPrev(fshx[fptsNo - 1] - fshx[fptsNo - 2],
845  fshy[fptsNo - 1] - fshy[fptsNo - 2],
846  fshz[fptsNo - 1] - fshz[fptsNo - 2]);
847  fth[fptsNo] = (pointer.Unit()).Angle(pointerPrev.Unit());
848  }
849  feth[fptsNo] = 0.0;
850  fedudw[fptsNo] = 0.0;
851  fedvdw[fptsNo] = 0.0;
852  feu[fptsNo] = 0.0;
853  fev[fptsNo] = 0.0;
854  fupdate[fptsNo] = 0.0;
855  }
856 
857  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit")
858  << "ihit xyz..." << spt3[0] << "," << spt3[1] << "," << spt3[2];
859 
860  fitTrack.addHit(new genf::PointHit(spt3, err3),
861  1, //dummy detector id
862  ihit++);
863  spptSurvivedIndex.push_back(point);
864  fptsNo++;
865  } // end loop over spacepoints.
866 
867  if (fptsNo <=
868  fMinNumSppts) // Cuz 1st 2 in each direction don't count. Should have, say, 3 more.
869  {
870  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit")
871  << "Bailing cuz only " << fptsNo << " spacepoints.";
872  rePass++;
873  continue;
874  }
875  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit") << "Fitting on " << fptsNo << " spacepoints.";
876 
877  genf::GFKalman k;
878  k.setBlowUpFactor(5); // 500 out of box. EC, 6-Jan-2011.
879  k.setMomHigh(fMomHigh); // Don't fit above this many GeV.
880  k.setMomLow(fMomLow); // Don't fit below this many GeV.
881 
882  k.setInitialDirection(+1); // Instead of 1 out of box. EC, 6-Jan-2011.
884  k.setMaxUpdate(fMaxUpdateHere); // 0 out abs(update) bigger than this.
885  k.setErrorScaleSTh(fErrScaleSHere);
886  k.setErrorScaleMTh(fErrScaleMHere);
887 
888  bool skipFill = false;
889  std::vector<TMatrixT<double>> hitMeasCov;
890  std::vector<TMatrixT<double>> hitUpdate;
891  std::vector<TMatrixT<double>> hitCov;
892  std::vector<TMatrixT<double>> hitCov7x7;
893  std::vector<TMatrixT<double>> hitState;
894  std::vector<double> hitChi2;
895  std::vector<TVector3> hitPlaneXYZ;
896  std::vector<TVector3> hitPlaneUxUyUz;
897  std::vector<TVector3> hitPlaneU;
898  std::vector<TVector3> hitPlaneV;
899 
900  try {
901  if (fDoFit) k.processTrack(&fitTrack);
902  }
903  catch (cet::exception& e) {
904  MF_LOG_ERROR("Track3DKalmanSPS")
905  << "just caught a cet::exception: " << e.what()
906  << "\nExceptions won't be further handled; skip filling big chunks of the TTree.";
907  skipFill = true;
908  }
909 
910  if (rep->getStatusFlag() == 0) // 0 is successful completion
911  {
912  if (mf::isDebugEnabled()) {
913 
914  std::ostringstream dbgmsg;
915  dbgmsg << "Original plane:";
916  planeG.Print(dbgmsg);
917 
918  dbgmsg << "Current (fit) reference Plane:";
919  rep->getReferencePlane().Print(dbgmsg);
920 
921  dbgmsg << "Last reference Plane:";
922  rep->getLastPlane().Print(dbgmsg);
923 
924  if (planeG != rep->getReferencePlane())
925  dbgmsg << " => original hit plane (not surprisingly) not current reference Plane!";
926 
927  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit") << dbgmsg.str();
928  }
929  if (!skipFill) {
930  hitMeasCov = fitTrack.getHitMeasuredCov();
931  hitUpdate = fitTrack.getHitUpdate();
932  hitCov = fitTrack.getHitCov();
933  hitCov7x7 = fitTrack.getHitCov7x7();
934  hitState = fitTrack.getHitState();
935  hitChi2 = fitTrack.getHitChi2();
936  hitPlaneXYZ = fitTrack.getHitPlaneXYZ();
937  hitPlaneUxUyUz = fitTrack.getHitPlaneUxUyUz();
938  hitPlaneU = fitTrack.getHitPlaneU();
939  hitPlaneV = fitTrack.getHitPlaneV();
940  unsigned int totHits = hitState.size();
941 
942  // Pick up info from last fwd Kalman pass.
943  unsigned int jhit = 0;
944  for (unsigned int ihit = totHits - 2 * totHits / (2 * fNumIt);
945  ihit < (totHits - totHits / (2 * fNumIt));
946  ihit++) // was ihit<ihit<(totHits-fptsNo)<7
947  {
948  feth[jhit] = (Float_t)(hitMeasCov.at(ihit)[0][0]); // eth
949  fedudw[jhit] = (Float_t)(hitMeasCov.at(ihit)[1][1]);
950  fedvdw[jhit] = (Float_t)(hitMeasCov.at(ihit)[2][2]);
951  feu[jhit] = (Float_t)(hitMeasCov.at(ihit)[3][3]);
952  fev[jhit] = (Float_t)(hitMeasCov.at(ihit)[4][4]);
953  fupdate[jhit] = (Float_t)(hitUpdate.at(ihit)[0][0]);
954  fchi2hit[jhit] = (Float_t)(hitChi2.at(ihit));
955  jhit++;
956  }
957 
958  stREC->ResizeTo(rep->getState());
959  *stREC = rep->getState();
960  covREC->ResizeTo(rep->getCov());
961  *covREC = rep->getCov();
962  double dum[5];
963  double dum2[5];
964  for (unsigned int ii = 0; ii < 5; ii++) {
965  stREC->ExtractRow(ii, 0, dum);
966  fState0[ii] = dum[0];
967  covREC->ExtractRow(ii, 0, dum2);
968  for (unsigned int jj = 0; jj < 5; jj++) {
969  fCov0[ii * 5 + jj] = dum2[jj];
970  }
971  }
972  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit")
973  << " First State and Cov:" << genf::ROOTobjectToString(*stREC)
975  chi2 = (Float_t)(rep->getChiSqu());
976  ndf = rep->getNDF();
977  nfail = fitTrack.getFailedHits();
978  nchi2rePass = (int)rePass;
979  ispptvec = 1 + std::distance(spptB, sppt);
980  chi2ndf = (Float_t)(chi2 / ndf);
981 
982  nTrks++;
983  MF_LOG_DEBUG("Track3DKalmanSPS_GenFit")
984  << "Track3DKalmanSPS about to do tree->Fill(). Chi2/ndf is " << chi2 / ndf << ".";
985  fpMCMom[3] = MCMomentum.Mag();
986  for (int ii = 0; ii < 3; ++ii) {
987  fpMCMom[ii] = MCMomentum[ii];
988  fpMCPos[ii] = MCOrigin[ii];
989  fpREC[ii] = hitPlaneUxUyUz.at(totHits - 2 * totHits / (2 * fNumIt))[ii];
990  fpRECL[ii] = hitPlaneUxUyUz.at(totHits - totHits / (2 * fNumIt) - 1)[ii];
991  }
992 
993  evtt = (unsigned int)evt.id().event();
994  nspptvec = (unsigned int)spptListHandle->size();
995 
996  cntp++;
997  std::vector<std::vector<double>> dQdx;
998  // Calculate LastFwdPass quantities.
999  std::vector<TMatrixT<double>> hitCovLFP;
1000  std::vector<TVector3> hitPlaneXYZLFP;
1001  std::vector<TVector3> hitPlaneUxUyUzLFP;
1002  std::vector<TVector3> hitPlanePxPyPzLFP;
1003  std::vector<TVector3> hitPlaneULFP;
1004  std::vector<TVector3> hitPlaneVLFP;
1005  std::vector<double> pLFP;
1006  std::vector<TMatrixT<double>> c7x7LFP;
1007 
1008  art::FindManyP<recob::Hit> hitAssns(spacepointss, evt, fSpptModuleLabel);
1009  for (unsigned int ii = 0; ii < totHits / (2 * fNumIt); ii++) {
1010  pLFP.push_back(1. / hitState.at(totHits - 2 * totHits / (2 * fNumIt) + ii)[0][0]);
1011  // hitCov -> hitCov7x7 !! EC, 11-May-2012.
1012  c7x7LFP.push_back(hitCov7x7.at(totHits - 2 * totHits / (2 * fNumIt) + ii));
1013  hitCovLFP.push_back(hitCov.at(totHits - 2 * totHits / (2 * fNumIt) + ii));
1014  hitPlaneXYZLFP.push_back(hitPlaneXYZ.at(totHits - 2 * totHits / (2 * fNumIt) + ii));
1015  hitPlaneUxUyUzLFP.push_back(
1016  hitPlaneUxUyUz.at(totHits - 2 * totHits / (2 * fNumIt) + ii));
1017  hitPlanePxPyPzLFP.push_back(hitPlaneUxUyUzLFP.back() * pLFP.back());
1018  hitPlaneULFP.push_back(hitPlaneU.at(totHits - 2 * totHits / (2 * fNumIt) + ii));
1019  hitPlaneVLFP.push_back(hitPlaneV.at(totHits - 2 * totHits / (2 * fNumIt) + ii));
1020  // Transform cov appropriate for track rotated
1021  // about w, forcing
1022  // v to be in y-z plane and u pointing in
1023  // +-ive x direction, per TrackAna convention.
1024 
1025  rotationCov(hitCovLFP.back(), hitPlaneULFP.back(), hitPlaneVLFP.back());
1026  dQdx.push_back(
1027  dQdxCalc(hitAssns, spacepointss, hitPlaneUxUyUzLFP.back(), hitPlaneXYZLFP.back()));
1028  fdQdx[ii] = dQdx.back().back();
1029  }
1030  fpREC[3] = rep->getMom(rep->getReferencePlane()).Mag();
1031  fpRECL[3] = pLFP[1];
1032 
1033  tree->Fill();
1034 
1035  // Put newest track on stack for this set of sppts,
1036  // remove previous one.
1037  recob::tracking::SMatrixSym55 covVtx, covEnd;
1038  for (unsigned int i = 0; i < 5; i++) {
1039  for (unsigned int j = i; j < 5; j++) {
1040  covVtx(i, j) = hitCovLFP.front()(i, j);
1041  covEnd(i, j) = hitCovLFP.back()(i, j);
1042  }
1043  }
1044  recob::Track the3DTrack(
1046  recob::tracking::convertCollToVector(hitPlanePxPyPzLFP),
1047  recob::Track::Flags_t(hitPlaneXYZLFP.size()),
1048  true),
1049  0,
1050  -1.,
1051  0,
1052  covVtx,
1053  covEnd,
1054  tcnt++);
1055  if (rePass == 1) tcnt1++; // won't get here if Trackfit failed.
1056  if (rePass != 1 && tcnt1) tcol->pop_back();
1057  tcol->push_back(the3DTrack);
1058  util::CreateAssn(evt, *tcol, spacepointss, *tspassn);
1059  art::PtrVector<recob::Hit> hits; // = hitAssns;
1060  for (unsigned int ii = 0; ii < spacepointss.size(); ++ii) {
1061  hits.insert(hits.end(), hitAssns.at(ii).begin(), hitAssns.at(ii).end());
1062  }
1063  util::CreateAssn(evt, *tcol, hits, *thassn, tcol->size() - 1);
1064  } // end !skipFill
1065  } // getStatusFlag
1066 
1067  if (!rep) delete rep;
1068  rePass++;
1069  // need to first excise bad spacepoints.
1070  // Grab up large Chi2hits first.
1071  art::PtrVector<recob::SpacePoint> spacepointssExcise;
1072  for (unsigned int ind = 0; ind < spptSurvivedIndex.size(); ++ind) {
1073  // Stricter to chuck sppts from uncontained then contained trks.
1074  if ((uncontained && fchi2hit[ind] > fChi2Thresh) ||
1075  (!uncontained && fchi2hit[ind] > 1.e9) || fchi2hit[ind] < 0.0
1076  // =0 eliminates ruled-out large updates. Not obviously
1077  // helpful.
1078  // add a restriction on dQdx here ...
1079  ) {
1081  spacepointss.begin() + spptSurvivedIndex[ind];
1082  spacepointssExcise.push_back(*spptIt);
1083  }
1084  }
1085  // Now grab up those sppts which we skipped and don't want
1086  // to reconsider cuz they're too close to each other or
1087  // cuz they're too far in x, e.g.
1088  for (unsigned int ind = 0; ind < spptSkippedIndex.size(); ++ind) {
1090  spacepointss.begin() + spptSkippedIndex[ind];
1091  spacepointssExcise.push_back(*spptIt);
1092  }
1093  // Get rid of redundantly Excised sppts before proceeding.
1094  std::stable_sort(spacepointss.begin(), spacepointss.end());
1095  std::stable_sort(spacepointssExcise.begin(), spacepointssExcise.end());
1096  std::set_union(spacepointssExcise.begin(),
1097  spacepointssExcise.end(),
1098  spacepointssExcise.begin(),
1099  spacepointssExcise.end(),
1100  spacepointssExcise.begin());
1101  // Now excise. New spacepointss will be smaller for second pass.
1103  std::set_difference(spacepointss.begin(),
1104  spacepointss.end(),
1105  spacepointssExcise.begin(),
1106  spacepointssExcise.end(),
1107  spacepointss.begin());
1108  spacepointss.erase(diffSpptIt, spacepointss.end());
1109 
1110  // calculate new seed momentum, and errors as merited
1111  if (rePass == 2 /* && uncontained */) {
1112  if (fpREC[3] < fMomHigh && fpREC[3] > fMomLow) {
1113  double kick(0.9); //Try to get away with a smaller start
1114  // for contained tracks. While for uncontained tracks
1115  // let's start up at a higher momentum and come down.
1116  // Though, 2 (1) GeV/c tracks are too low (high), so
1117  // instead let's actually lower starting value on
1118  // this second pass. -- EC 7-Mar-2013
1119  if (uncontained) kick = 0.5;
1120  for (int ii = 0; ii < 3; ++ii) {
1121  mom[ii] = momM[ii] * kick;
1122  }
1123  }
1124  else if (uncontained) {
1125  double unstick(1.0);
1126  if (fpREC[3] >= fMomHigh) unstick = 0.3;
1127  for (int ii = 0; ii < 3; ++ii) {
1128  mom[ii] = momM[ii] * unstick;
1129  }
1130  }
1131  else
1132  for (int ii = 0; ii < 3; ++ii) {
1133  mom[ii] = 1.1 * momM[ii];
1134  }
1135  }
1136 
1137  } // end while rePass<=maxPass
1138 
1139  sppt++;
1140 
1141  } // end while on elements of std::vector of art::PtrVectors of SpPts.
1142 
1143  if (!repMC) delete repMC;
1144 
1145  evt.put(std::move(tcol));
1146  // and now the spacepoints
1147  evt.put(std::move(tspassn));
1148  // and the hits. Note that these are all the hits from all the spacepoints considered,
1149  // even though they're not all contributing to the tracks.
1150  evt.put(std::move(thassn));
1151  }
1152 
1154 
1155 } // end namespace
TMatrixT< Double_t > * stREC
unsigned int getNDF() const
std::vector< double > fMomErr
void setMomLow(Double_t f)
Definition: GFKalman.h:117
std::vector< TVector3 > getHitPlaneUxUyUz()
Definition: GFTrack.h:373
void setMaxUpdate(Double_t f)
Definition: GFKalman.h:119
geo::SigType_t SignalType() const
Signal type for the plane of the hit.
Definition: Hit.h:282
TMatrixT< Double_t > * stMCT
static bool sp_sort_3dz(const art::Ptr< recob::SpacePoint > &h1, const art::Ptr< recob::SpacePoint > &h2)
typename data_t::iterator iterator
Definition: PtrVector.h:54
const GFDetPlane & getReferencePlane() const
GFDetPlane getLastPlane() const
void rotationCov(TMatrixT< Double_t > &cov, const TVector3 &u, const TVector3 &v)
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
Definition: TrackingTypes.h:78
iterator begin()
Definition: PtrVector.h:217
Declaration of signal hit object.
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
void setMomHigh(Double_t f)
Definition: GFKalman.h:118
iterator erase(iterator position)
Definition: PtrVector.h:504
TrackTrajectory::Flags_t Flags_t
Definition: Track.h:67
std::vector< Double_t > getHitChi2()
Definition: GFTrack.h:368
constexpr auto abs(T v)
Returns the absolute value of the argument.
#define MF_LOG_ERROR(category)
std::vector< TMatrixT< Double_t > > getHitCov7x7()
Definition: GFTrack.h:371
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 >> SMatrixSym55
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:254
geo::WireID const & WireID() const
Initial tdc tick for hit.
Definition: Hit.h:290
Float_t tmp
Definition: plot.C:35
int NParticles() const
Definition: MCTruth.h:75
std::vector< double > fPosErr
void Print(std::ostream &out=std::cout) const
Definition: GFDetPlane.cxx:228
const TMatrixT< Double_t > & getState() const
bool isRealData() const
Definition: Event.cc:53
std::vector< TMatrixT< Double_t > > getHitState()
Definition: GFTrack.h:369
std::vector< TVector3 > getHitPlaneU()
Definition: GFTrack.h:374
static bool sp_sort_3dy(const art::Ptr< recob::SpacePoint > &h1, const art::Ptr< recob::SpacePoint > &h2)
void produce(art::Event &evt)
Base Class for genfit track representations. Defines interface for track parameterizations.
Definition: GFAbsTrackRep.h:81
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
TString part[npart]
Definition: Style.C:32
void hits()
Definition: readHits.C:15
typename data_t::const_iterator const_iterator
Definition: PtrVector.h:55
std::vector< double > fMomStart
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:435
virtual TVector3 getMom(const GFDetPlane &pl)=0
static bool sp_sort_3dx(const art::Ptr< recob::SpacePoint > &h1, const art::Ptr< recob::SpacePoint > &h2)
A trajectory in space reconstructed from hits.
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
void setBlowUpFactor(double f)
Set the blowup factor (see blowUpCovs() )
Definition: GFKalman.h:116
static bool sp_sort_nsppts(const art::PtrVector< recob::SpacePoint > &h1, const art::PtrVector< recob::SpacePoint > &h2)
iterator end()
Definition: PtrVector.h:231
double energyLossBetheBloch(const double &mass, const double p)
void setNumIterations(Int_t i)
Set number of iterations for Kalman Filter.
Definition: GFKalman.h:91
void setPDG(int pdgt)
Definition: GFTrack.h:365
Float_t d
Definition: plot.C:235
int getFailedHits(int repId=-1)
return the number of failed Hits in track fit repId == -1 will use cardinal rep
Definition: GFTrack.h:147
TMatrixT< Double_t > * covREC
void processTrack(GFTrack *)
Performs fit on a GFTrack.
Definition: GFKalman.cxx:57
static GFFieldManager * getInstance()
TMatrixT< Double_t > * covMCT
bool isDebugEnabled()
const Double32_t * XYZ() const
Definition: SpacePoint.h:78
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
Definition: TrackingTypes.h:68
Declaration of cluster object.
const TMatrixT< Double_t > & getCov() const
std::vector< TVector3 > getHitPlaneV()
Definition: GFTrack.h:375
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Definition: PFPUtils.cxx:2671
std::string ROOTobjectToString(const ROOTOBJ &obj)
Shortcut to write one ROOT object into a string.
Definition: GFException.h:114
size_type size() const
Definition: PtrVector.h:302
TH1F * h2
Definition: plot.C:44
Encapsulate the geometry of a wire .
const simb::MCParticle & GetParticle(int i) const
Definition: MCTruth.h:76
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
iterator insert(iterator position, Ptr< U > const &p)
std::vector< double > dQdxCalc(const art::FindManyP< recob::Hit > &h, const art::PtrVector< recob::SpacePoint > &s, const TVector3 &p, const TVector3 &d)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane .
double dist(const TReal *x, const TReal *y, const unsigned int dimension)
in close()
Provides recob::Track data product.
TDirectory * dir
Definition: macro.C:5
void setInitialDirection(int d)
Sets the inital direction of the track fit (1 for inner to outer, or -1 for outer to inner)...
Definition: GFKalman.h:112
#define MF_LOG_DEBUG(id)
void init(GFAbsBField *b)
set the magntic field here. Magnetic field classes must be derived from GFAbsBField ...
TH1F * h1
Definition: plot.C:41
EventNumber_t event() const
Definition: EventID.h:116
std::vector< TMatrixT< Double_t > > getHitUpdate()
Definition: GFTrack.h:367
void setErrorScaleSTh(Double_t f)
Definition: GFKalman.h:120
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
double getChiSqu() const
void addHit(GFAbsRecoHit *theHit)
deprecated!
Definition: GFTrack.h:301
TCEvent evt
Definition: DataStructs.cxx:8
std::vector< TMatrixT< Double_t > > getHitCov()
Definition: GFTrack.h:370
Track3DKalmanSPS(fhicl::ParameterSet const &pset)
#define MF_LOG_WARNING(category)
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:448
std::vector< TMatrixT< Double_t > > getHitMeasuredCov()
Definition: GFTrack.h:366
Float_t e
Definition: plot.C:35
RunNumber_t run() const
Definition: Event.cc:29
Float_t w
Definition: plot.C:20
EventID id() const
Definition: Event.cc:23
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:49
void setErrorScaleMTh(Double_t f)
Definition: GFKalman.h:121
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Signal from collection planes.
Definition: geo_types.h:148
std::vector< TVector3 > getHitPlaneXYZ()
Definition: GFTrack.h:372