dayonetrackfit_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: dayonetrackfit
3 // Plugin Type: producer (art v3_00_00)
4 // File: dayonetrackfit_module.cc
5 //
6 // copied from tpctrackfit2_module.cc and modified for the day one tracker
7 // need to step in Z and not X and compute track parameters nonlinearly
8 // second try, non-kalman: starting with the patrec track parameters
9 // and minimize chisquared swimming the particle from one station to the next
10 ////////////////////////////////////////////////////////////////////////
11 
19 #include "fhiclcpp/ParameterSet.h"
22 #include "canvas/Persistency/Common/FindManyP.h"
23 
24 #include <memory>
25 #include <set>
26 
27 // ROOT includes
28 
29 #include "TVectorF.h"
30 #include "TMatrix.h"
31 #include "TMath.h"
32 #include "TVector3.h"
33 
34 // GArSoft Includes
41 #include "Reco/TrackPar.h"
42 #include "Reco/tracker2algs.h"
43 #include "Geometry/GeometryGAr.h"
44 #include "CoreUtils/ServiceUtil.h"
46 
47 #include "Geant4/G4ThreeVector.hh"
48 
49 #include "nug4/MagneticFieldServices/MagneticFieldService.h"
50 
51 namespace gar {
52  namespace rec {
53 
54  class dayonetrackfit : public art::EDProducer {
55  public:
56  explicit dayonetrackfit(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  dayonetrackfit(dayonetrackfit const&) = delete;
62  dayonetrackfit(dayonetrackfit&&) = delete;
63  dayonetrackfit& operator=(dayonetrackfit 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 fPatRecLabel; ///< input patrec tracks and associations
74  int fPrintLevel; ///< debug printout: 0: none, 1: just track parameters and residuals, 2: all
75  float fTPCClusterResolXY; ///< pad size in cm in YZ to determine step size
76  float fTPCClusterResolZ; ///< drift direction contribution to determine step size (resolution of a TPCCluster)
77  int fDumpTracks; ///< 0: do not print out tracks, 1: print out tracks
78  // float fRoadYZinFit; ///< cut in cm for dropping TPCClusters from tracks in fit
79  // float fMinIonizGapCut; ///< Don't compute dEdx for this dx or larger
80 
81  int DayOneFitBothWays(const gar::rec::Track &patrectrack, std::vector<gar::rec::TPCCluster> &TPCClusters,
82  TrackPar &trackpar, TrackIoniz &trackions, TrackTrajectory &tracktraj);
83 
84  int DayOneFit( std::vector<TPCCluster> &TPCClusters,
85  std::vector<int> &TPCClusterlist, // sort ordered list
86  std::vector<float> &trackparbeg,
87  float &chisquared,
88  float &length,
89  float *covmat, // 5x5 covariance matrix
90  std::vector<std::pair<float,float>>& dSigdXs,
91  std::vector<TVector3>& trajpts);
92 
93  void updatepar(TVectorF &parvec, float zcur, float xh, float yh, float zh, TVectorF &predstep, float &dlength);
94 
95  };
96 
97 
99  {
100  // Call appropriate produces<>() functions here.
101  // Call appropriate consumes<>() for any products to be retrieved by this module.
102 
103  fPatRecLabel = p.get<std::string>("PatRecLabel","patrec");
104  fPrintLevel = p.get<int>("PrintLevel",0);
105  fDumpTracks = p.get<int>("DumpTracks",0);
106  fTPCClusterResolXY = p.get<float>("TPCClusterResolXY",0.3); // TODO -- think about what this value is
107  fTPCClusterResolZ = p.get<float>("TPCClusterResolZ",0.3); // this is probably much better
108 
109  art::InputTag patrecTag(fPatRecLabel);
110  consumes< std::vector<gar::rec::Track> >(patrecTag);
111  consumes< art::Assns<gar::rec::TPCCluster, gar::rec::Track> >(patrecTag);
112 
113  produces< std::vector<gar::rec::Track> >();
114  produces< art::Assns<gar::rec::TPCCluster, gar::rec::Track> >();
115  produces<std::vector<gar::rec::TrackIoniz>>();
116  produces<art::Assns<rec::TrackIoniz, rec::Track>>();
117  produces<std::vector<gar::rec::TrackTrajectory>>();
118  produces<art::Assns<rec::TrackTrajectory, rec::Track>>();
119  }
120 
121 
122 
124  {
125  // output collections
126 
127  std::unique_ptr< std::vector<gar::rec::Track> > trkCol(new std::vector<gar::rec::Track>);
128  std::unique_ptr< art::Assns<gar::rec::TPCCluster,gar::rec::Track> > TPCClusterTrkAssns(new ::art::Assns<gar::rec::TPCCluster,gar::rec::Track>);
129  std::unique_ptr< std::vector<rec::TrackIoniz> > ionCol(new std::vector<rec::TrackIoniz>);
130  std::unique_ptr< art::Assns<rec::TrackIoniz,rec::Track> > ionTrkAssns(new ::art::Assns<rec::TrackIoniz,rec::Track>);
131  std::unique_ptr< std::vector<rec::TrackTrajectory> > trajCol(new std::vector<rec::TrackTrajectory>);
132  std::unique_ptr< art::Assns<rec::TrackTrajectory,rec::Track> > trajTrkAssns(new ::art::Assns<rec::TrackTrajectory,rec::Track>);
133 
134  // inputs
135 
136  auto patrecTrackHandle = e.getValidHandle< std::vector<gar::rec::Track> >(fPatRecLabel);
137  auto const& patrecTracks = *patrecTrackHandle;
138 
139  auto const trackPtrMaker = art::PtrMaker<gar::rec::Track>(e);
140  auto const ionizPtrMaker = art::PtrMaker<rec::TrackIoniz>(e);
141  auto const trajPtrMaker = art::PtrMaker<rec::TrackTrajectory>(e);
142  //auto const TPCClusterPtrMaker = art::PtrMaker<gar::rec::TPCCluster>(e, TPCClusterHandle.id());
143 
144  auto const *magFieldService = gar::providerFrom<mag::MagneticFieldService>();
145  G4ThreeVector zerovec(0,0,0);
146  G4ThreeVector magfield = magFieldService->FieldAtPoint(zerovec);
147 
149  //double xtpccent = geo->GetOriginX();
150  //double ytpccent = geo->GetOriginY();
151  //double ztpccent = geo->GetOriginZ();
152  //TVector3 tpccent(xtpccent,ytpccent,ztpccent);
153  TVector3 xhat(1,0,0);
154 
155  const art::FindManyP<gar::rec::TPCCluster> TPCClustersFromPatRecTracks(patrecTrackHandle,e,fPatRecLabel);
156 
157  for (size_t itrack = 0; itrack < patrecTracks.size(); ++itrack)
158  {
159  std::vector<gar::rec::TPCCluster> TPCClusters;
160  for (size_t iTPCCluster=0; iTPCCluster < TPCClustersFromPatRecTracks.at(itrack).size(); ++iTPCCluster)
161  {
162  TPCClusters.push_back(*TPCClustersFromPatRecTracks.at(itrack).at(iTPCCluster)); // make our own local copy of TPCClusters. Maybe we can skip this?
163  }
164  TrackPar trackparams;
165  TrackIoniz trackions;
166  TrackTrajectory tracktraj;
167  if (DayOneFitBothWays(patrecTracks.at(itrack),TPCClusters,trackparams,trackions,tracktraj) == 0)
168  {
169  trkCol->push_back(trackparams.CreateTrack());
170  ionCol->push_back(trackions);
171  trajCol->push_back(tracktraj);
172  auto const trackpointer = trackPtrMaker(trkCol->size()-1);
173  auto const ionizpointer = ionizPtrMaker(ionCol->size()-1);
174  auto const trajpointer = trajPtrMaker(trajCol->size()-1);
175  for (size_t iTPCCluster=0; iTPCCluster<TPCClusters.size(); ++iTPCCluster)
176  {
177  TPCClusterTrkAssns->addSingle(TPCClustersFromPatRecTracks.at(itrack).at(iTPCCluster),trackpointer);
178  }
179  ionTrkAssns->addSingle(ionizpointer, trackpointer);
180  trajTrkAssns->addSingle(trajpointer, trackpointer);
181  }
182  }
183 
184  e.put(std::move(trkCol));
185  e.put(std::move(TPCClusterTrkAssns));
186  e.put(std::move(ionCol));
187  e.put(std::move(ionTrkAssns));
188  e.put(std::move(trajCol));
189  e.put(std::move(trajTrkAssns));
190  }
191 
193  std::vector<gar::rec::TPCCluster> &TPCClusters,
194  TrackPar &trackpar,
195  TrackIoniz &trackions,
196  TrackTrajectory &tracktraj)
197 
198  {
199  // track parameters: x is the independent variable in TPC track fits, but just report it here.
200  // 0: y
201  // 1: z
202  // 2: curvature
203  // 3: phi
204  // 4: lambda = angle from the cathode plane
205  // 5: x /// added on to the end
206 
207  size_t nclus = TPCClusters.size();
208  std::vector<float> TPCClusterz;
209  for (size_t i=0; i<nclus; ++i)
210  {
211  TPCClusterz.push_back(TPCClusters[i].Position()[2]);
212  }
213  std::vector<int> hsi(nclus); // "hit sort index" -- really TPC clusters
214  TMath::Sort((int) nclus,TPCClusterz.data(),hsi.data());
215  std::vector<int> hsib(nclus);
216  for (size_t i=0; i<nclus; ++i)
217  {
218  hsib[nclus-i-1] = hsi[i];
219  }
220 
221  std::vector<float> tparbeg(6); // fill with initial track parameters from patrec track
222  for (size_t i=0; i<5; ++i)
223  {
224  tparbeg[i] = patrectrack.TrackParBeg()[i];
225  }
226  tparbeg[5] = patrectrack.Vertex()[0];
227  float covmatbeg[25];
228  patrectrack.CovMatBegSymmetric(covmatbeg);
229  float chisqforwards = 0;
230  float lengthforwards = 0;
231  std::vector<std::pair<float,float>> dSigdXs_FWD;
232  std::vector<TVector3> trajpts_FWD;
233 
234  int retcode = DayOneFit(TPCClusters,hsi,tparbeg,chisqforwards,lengthforwards,covmatbeg,dSigdXs_FWD,trajpts_FWD);
235  if (retcode != 0) return 1;
236 
237 
238  std::vector<float> tparend(6); // fill with end track parameters from patrec track
239  for (size_t i=0; i<5; ++i)
240  {
241  tparend[i] = patrectrack.TrackParEnd()[i];
242  }
243  tparend[5] = patrectrack.End()[0];
244  float covmatend[25];
245  patrectrack.CovMatEndSymmetric(covmatend);
246  float chisqbackwards = 0;
247  float lengthbackwards = 0;
248  std::vector<std::pair<float,float>> dSigdXs_BAK;
249  std::vector<TVector3> trajpts_BAK;
250 
251  retcode = DayOneFit(TPCClusters,hsib,tparend,chisqbackwards,lengthbackwards,covmatend,dSigdXs_BAK,trajpts_BAK);
252  if (retcode != 0) return 1;
253 
254  size_t nTPCClusters=TPCClusters.size();
255  trackpar.setNTPCClusters(nTPCClusters);
256  trackpar.setTime(0);
257  trackpar.setChisqForwards(chisqforwards);
258  trackpar.setChisqBackwards(chisqbackwards);
259  trackpar.setLengthForwards(lengthforwards);
260  trackpar.setLengthBackwards(lengthbackwards);
261  trackpar.setCovMatBeg(covmatbeg);
262  trackpar.setCovMatEnd(covmatend);
263  trackpar.setTrackParametersBegin(tparbeg.data());
264  trackpar.setXBeg(tparbeg[5]);
265  trackpar.setTrackParametersEnd(tparend.data());
266  trackpar.setXEnd(tparend[5]);
267 
268  trackions.setData(dSigdXs_FWD,dSigdXs_BAK);
269  tracktraj.setData(trajpts_FWD,trajpts_BAK);
270 
271  return 0;
272  }
273 
274  //--------------------------------------------------------------------------------------------------------------
275 
276  // track parameters visible to caller
277 
278  // 0: y
279  // 1: z
280  // 2: curvature
281  // 3: phi
282  // 4: lambda
283  // 5: x
284 
285  int dayonetrackfit::DayOneFit( std::vector<TPCCluster> &TPCClusters,
286  std::vector<int> &TPCClusterlist, // sort ordered list
287  std::vector<float> &trackparbeg,
288  float &chisquared,
289  float &length,
290  float * /* covmat */, // 5x5 covariance matrix
291  std::vector<std::pair<float,float>>& /* dSigdXs */,
292  std::vector<TVector3>& trajpts)
293  {
294 
295  // set some default values in case we return early
296 
297  size_t nclus = TPCClusterlist.size();
298  chisquared = 0;
299  length = 0;
300 
301  // first try, do nothing, but we should calculate a chisquared
302 
303  for (size_t i=0;i<nclus; ++i)
304  {
305  const float *pos = TPCClusters.at(TPCClusterlist.at(i)).Position();
306  TVector3 tvec(pos[0],pos[1],pos[2]);
307  trajpts.push_back(tvec);
308  float dist = 0;
309  float tvpos[3] = {trackparbeg[5],trackparbeg[0],trackparbeg[1]};
310  int retcode = util::TrackPropagator::DistXYZ(trackparbeg.data(),tvpos,pos,dist);
311  if (retcode == 0)
312  {
313  chisquared += TMath::Sq(dist/fTPCClusterResolXY); // todo -- break this up into X,Y vs. Z pieces.
314  }
315  }
316 
317  return 0;
318  }
319 
320  //--------------------------------------------------------------------------------------------------------------
321 
322  // extrapolate a helix using the current helix parameters at parvec to a new hit position, given by z.
323  // ouptut is predstep
324 
325  // 0: y
326  // 1: x
327  // 2: curvature
328  // 3: phi
329  // 4: lambda
330 
331  void dayonetrackfit::updatepar(TVectorF &parvec, float zcur, float xh, float /* yh */, float zh, TVectorF &predstep, float &dlength)
332  {
333 
334  predstep = parvec;
335 
336  // radius and center of the circle
337 
338  float r = 1E4;
339  if (parvec[2] != 0)
340  {
341  r = 1/parvec[2];
342  }
343  float yc = parvec[0] + r*TMath::Cos(parvec[3]);
344  float zc = zcur - r*TMath::Sin(parvec[3]);
345 
346  // two solutions of arcsin, plus any number of 2pi. We could be on
347  // the boundary of a wraparound.
348 
349  float phip1 = TMath::ASin((zh-zc)/r);
350  float phip2 = TMath::Pi() - phip1;
351 
352  // find the solution that's closest to the one suggested by x
353 
354  float tanlambda = TMath::Tan(parvec[4]);
355  if (tanlambda == 0) tanlambda = 1E-4;
356  float phip3 = parvec[3] + (xh-parvec[1])/(r*tanlambda);
357 
358  float dphip1n = (phip1-phip3)/TMath::TwoPi();
359  float niphi1 = nearbyint(dphip1n);
360  float dphip1a = TMath::Abs(dphip1n - niphi1);
361 
362  float dphip2n = (phip2-phip3)/TMath::TwoPi();
363  float niphi2 = nearbyint(dphip2n);
364  float dphip2a = TMath::Abs(dphip2n - niphi2);
365 
366  float phiex=phip1 + niphi1*TMath::TwoPi();
367  if (dphip1a > dphip2a)
368  {
369  phiex = phip2 + niphi2*TMath::TwoPi();
370  }
371 
372  // update predstep to values at this z. Leave curvature and lambda
373  // unchanged
374 
375  predstep[0] = yc - r*TMath::Cos(phiex); // y
376  predstep[1] = parvec[1] + r*tanlambda*(phiex-parvec[3]); // x
377  predstep[3] = phiex;
378 
379  dlength = TMath::Abs( r * (phiex - parvec[3]) / TMath::Cos(parvec[4]) );
380  }
381 
382 
384 
385  } // namespace rec
386 } // namespace gar
void setNTPCClusters(const size_t nTPCClusters)
Definition: TrackPar.cxx:214
void setLengthForwards(const float lengthforwards)
Definition: TrackPar.cxx:251
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
void updatepar(TVectorF &parvec, float zcur, float xh, float yh, float zh, TVectorF &predstep, float &dlength)
rec
Definition: tracks.py:88
dayonetrackfit(fhicl::ParameterSet const &p)
const float * TrackParBeg() const
Definition: Track.h:151
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
struct vector vector
static int DistXYZ(const float *trackpar, const float *Xpoint, const float *xyz, float &retDist)
int DayOneFit(std::vector< TPCCluster > &TPCClusters, std::vector< int > &TPCClusterlist, std::vector< float > &trackparbeg, float &chisquared, float &length, float *covmat, std::vector< std::pair< float, float >> &dSigdXs, std::vector< TVector3 > &trajpts)
void setLengthBackwards(const float lengthbackwards)
Definition: TrackPar.cxx:256
void setTrackParametersBegin(const float *tparbeg)
Definition: TrackPar.cxx:219
const double e
const float * Vertex() const
Definition: Track.h:139
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
std::string fPatRecLabel
input patrec tracks and associations
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
const float * TrackParEnd() const
Definition: Track.h:152
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
void setChisqBackwards(const float chisqbackwards)
Definition: TrackPar.cxx:266
void setData(std::vector< TVector3 > ForwardTrajectory, std::vector< TVector3 > BackwardTrajectory)
const float * End() const
Definition: Track.h:140
Interface to propagate a Track to the specific point.
void produce(art::Event &e) override
General GArSoft Utilities.
float fTPCClusterResolXY
pad size in cm in YZ to determine step size
void setCovMatEnd(const float *covmatend)
Definition: TrackPar.cxx:243
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
int DayOneFitBothWays(const gar::rec::Track &patrectrack, std::vector< gar::rec::TPCCluster > &TPCClusters, TrackPar &trackpar, TrackIoniz &trackions, TrackTrajectory &tracktraj)
void setXBeg(const float xbeg)
Definition: TrackPar.cxx:271
void setData(std::vector< std::pair< float, float >> dSigdX_FWD, std::vector< std::pair< float, float >> dSigdX_BAK)
Definition: TrackIoniz.cxx:20
float fTPCClusterResolZ
drift direction contribution to determine step size (resolution of a TPCCluster)
int fDumpTracks
0: do not print out tracks, 1: print out tracks
void setChisqForwards(const float chisqforwards)
Definition: TrackPar.cxx:261
void CovMatBegSymmetric(float *cmb) const
Definition: Track.cxx:246
LArSoft geometry interface.
Definition: ChannelGeo.h:16
art framework interface to geometry description
void CovMatEndSymmetric(float *cme) const
Definition: Track.cxx:257
void setTime(const double time)
Definition: TrackPar.cxx:281
dayonetrackfit & operator=(dayonetrackfit const &)=delete