Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
gar::rec::tracker1 Class Reference
Inheritance diagram for gar::rec::tracker1:
art::EDProducer art::detail::Producer art::detail::LegacyModule art::Modifier art::ModuleBase art::ProductRegistryHelper

Classes

struct  vechit_t
 

Public Member Functions

 tracker1 (fhicl::ParameterSet const &p)
 
 tracker1 (tracker1 const &)=delete
 
 tracker1 (tracker1 &&)=delete
 
tracker1operator= (tracker1 const &)=delete
 
tracker1operator= (tracker1 &&)=delete
 
void produce (art::Event &e) override
 
- Public Member Functions inherited from art::EDProducer
 EDProducer (fhicl::ParameterSet const &pset)
 
template<typename Config >
 EDProducer (Table< Config > const &config)
 
std::string workerType () const
 
- Public Member Functions inherited from art::detail::Producer
virtual ~Producer () noexcept
 
 Producer (fhicl::ParameterSet const &)
 
 Producer (Producer const &)=delete
 
 Producer (Producer &&)=delete
 
Produceroperator= (Producer const &)=delete
 
Produceroperator= (Producer &&)=delete
 
void doBeginJob (SharedResources const &resources)
 
void doEndJob ()
 
void doRespondToOpenInputFile (FileBlock const &fb)
 
void doRespondToCloseInputFile (FileBlock const &fb)
 
void doRespondToOpenOutputFiles (FileBlock const &fb)
 
void doRespondToCloseOutputFiles (FileBlock const &fb)
 
bool doBeginRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doEndRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doBeginSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEndSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEvent (EventPrincipal &ep, ModuleContext const &mc, std::atomic< std::size_t > &counts_run, std::atomic< std::size_t > &counts_passed, std::atomic< std::size_t > &counts_failed)
 
- Public Member Functions inherited from art::Modifier
 ~Modifier () noexcept
 
 Modifier ()
 
 Modifier (Modifier const &)=delete
 
 Modifier (Modifier &&)=delete
 
Modifieroperator= (Modifier const &)=delete
 
Modifieroperator= (Modifier &&)=delete
 
- Public Member Functions inherited from art::ModuleBase
virtual ~ModuleBase () noexcept
 
 ModuleBase ()
 
ModuleDescription const & moduleDescription () const
 
void setModuleDescription (ModuleDescription const &)
 
std::array< std::vector< ProductInfo >, NumBranchTypes > const & getConsumables () const
 
void sortConsumables (std::string const &current_process_name)
 
template<typename T , BranchType BT>
ViewToken< T > consumesView (InputTag const &tag)
 
template<typename T , BranchType BT>
ViewToken< T > mayConsumeView (InputTag const &tag)
 

Private Member Functions

int initial_trackpar_estimate (art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, float &curvature_init, float &lambda_init, float &phi_init, float &xpos, float &ypos, float &zpos, float &x_other_end)
 
int KalmanFit (art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, std::vector< float > &trackparatend, float &chisquared, float &length, float *covmat, std::set< int > &unused_hits)
 
int KalmanFitBothWays (art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, std::set< int > &unused_hits, TrackPar &trackpar)
 
int FitHelix (art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, std::set< int > &unused_hits, TrackPar &trackpar)
 
size_t ifob (size_t ihit, size_t nhits, bool isForwards)
 
float capprox (float x1, float y1, float x2, float y2, float x3, float y3, float &xc, float &yc)
 initial guess of curvature calculator – from ALICE. Also returns circle center More...
 
float capprox2 (float y0, float z0, float y1, float z1, float y2, float z2)
 
bool vh_hitmatch (TVector3 &hpvec, int ihit, vechit_t &vechit, const std::vector< gar::rec::Hit > &hits, std::vector< int > &hsi)
 
void fitlinesdir (std::vector< TVector3 > &hlist, TVector3 &pos, TVector3 &dir)
 
void fitline (std::vector< double > &x, std::vector< double > &y, double &lambda, double &intercept)
 
bool vhclusmatch (std::vector< vechit_t > &cluster, vechit_t &vh)
 

Private Attributes

float fHitRCut
 only take hits within rcut of the center of the detector More...
 
size_t fPatRecAlg
 1: x-sorted patrec. 2: vector-hit patrec More...
 
size_t fPatRecLookBack1
 n hits to look backwards to make a linear extrapolation More...
 
size_t fPatRecLookBack2
 extrapolate from lookback1 to lookback2 and see how close the new hit is to the line More...
 
float fHitResolYZ
 resolution in cm of a hit in YZ (pad size) More...
 
float fHitResolX
 resolution in cm of a hit in X (drift direction) More...
 
float fSigmaRoad
 how many sigma away from a track a hit can be and still add it during patrec More...
 
float fMaxVecHitLen
 maximum vector hit length in patrec alg 2, in cm More...
 
float fVecHitRoad
 max dist from a vector hit to a hit to assign it. for patrec alg 2. in cm. More...
 
float fVecHitMatchCos
 matching condition for pairs of vector hits cos angle between directions More...
 
float fVecHitMatchPos
 matching condition for pairs of vector hits – 3D distance (cm) More...
 
float fVecHitMatchPEX
 matching condition for pairs of vector hits – miss distance (cm) More...
 
float fVecHitMatchEta
 matching condition for pairs of vector hits – eta match (cm) More...
 
float fVecHitMatchLambda
 matching condition for pairs of vector hits – dLambda (radians) More...
 
unsigned int fVecHitMinHits
 minimum number of hits on a vector hit for it to be considered More...
 
float fKalCurvStepUncSq
 constant uncertainty term on each step of the Kalman fit – squared, for curvature More...
 
float fKalPhiStepUncSq
 constant uncertainty term on each step of the Kalman fit – squared, for phi More...
 
float fKalLambdaStepUncSq
 constant uncertainty term on each step of the Kalman fit – squared, for lambda More...
 
unsigned int fMinNumHits
 minimum number of hits to define a track More...
 
unsigned int fInitialTPNHits
 number of hits to use for initial trackpar estimate, if present More...
 
std::string fHitLabel
 label of module creating hits More...
 
int fPrintLevel
 debug printout: 0: none, 1: just track parameters and residuals, 2: all More...
 
int fTrackPass
 which pass of the tracking to save as the tracks in the event More...
 
int fDumpTracks
 0: do not print out tracks, 1: print out tracks More...
 
std::string fSortOrder
 switch to tell what way to sort hits before presenting them to the fitter More...
 
float fHitResolYZinFit
 Hit resolution parameter to use in fit. More...
 
float fRoadYZinFit
 cut in cm for dropping hits from tracks in fit More...
 
std::string fFirstPassFitType
 helix or Kalman – which fitter to call for first-pass tracks More...
 
std::string fSecondPassFitType
 helix or Kalman – which fitter to call for second-pass tracks More...
 

Additional Inherited Members

- Public Types inherited from art::EDProducer
using ModuleType = EDProducer
 
using WorkerType = WorkerT< EDProducer >
 
- Public Types inherited from art::detail::Producer
template<typename UserConfig , typename KeysToIgnore = void>
using Table = Modifier::Table< UserConfig, KeysToIgnore >
 
- Public Types inherited from art::Modifier
template<typename UserConfig , typename UserKeysToIgnore = void>
using Table = ProducerTable< UserConfig, detail::ModuleConfig, UserKeysToIgnore >
 
- Static Public Member Functions inherited from art::EDProducer
static void commitEvent (EventPrincipal &ep, Event &e)
 
- Protected Member Functions inherited from art::ModuleBase
ConsumesCollectorconsumesCollector ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > consumes (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > consumesView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void consumesMany ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > mayConsume (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > mayConsumeView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void mayConsumeMany ()
 

Detailed Description

Definition at line 47 of file tracker1_module.cc.

Constructor & Destructor Documentation

gar::rec::tracker1::tracker1 ( fhicl::ParameterSet const &  p)
explicit

Definition at line 166 of file tracker1_module.cc.

167  {
168 
169  fHitRCut = p.get<float>("HitRCut",240);
170  fPatRecAlg = p.get<size_t>("PatRecAlg",2);
171  fPatRecLookBack1 = p.get<size_t>("PatRecLookBack1",5);
172  fPatRecLookBack2 = p.get<size_t>("PatRecLookBack2",10);
173  if (fPatRecLookBack1 == fPatRecLookBack2)
174  {
175  throw cet::exception("tracker1_module: PatRecLookBack1 and PatRecLookBack2 are the same");
176  }
177  fHitResolYZ = p.get<float>("HitResolYZ",1.0); // TODO -- think about what this value is
178  fHitResolX = p.get<float>("HitResolX",0.5); // this is probably much better
179  fSigmaRoad = p.get<float>("SigmaRoad",5.0);
180  fMinNumHits = p.get<unsigned int>("MinNumHits",20);
181  fHitLabel = p.get<std::string>("HitLabel","hit");
182  fPrintLevel = p.get<int>("PrintLevel",0);
183  fTrackPass = p.get<int>("TrackPass",2);
184  fDumpTracks = p.get<int>("DumpTracks",2);
185  fHitResolYZinFit = p.get<float>("HitResolYZinFit",4.0);
186  fRoadYZinFit = p.get<float>("RoadYZinFit",1.0);
187  fFirstPassFitType = p.get<std::string>("FirstPassFitType","helix");
188  fSecondPassFitType = p.get<std::string>("SecondPassFitType","Kalman");
189  fMaxVecHitLen = p.get<float>("MaxVecHitLen",10.0);
190  fVecHitRoad = p.get<float>("VecHitRoad",5.0);
191  fVecHitMatchCos = p.get<float>("VecHitMatchCos",0.9);
192  fVecHitMatchPos = p.get<float>("VecHitMatchPos",20.0);
193  fVecHitMatchPEX = p.get<float>("VecHitMatchPEX",5.0);
194  fVecHitMatchEta = p.get<float>("VecHitMatchEta",1.0);
195  fVecHitMatchLambda = p.get<float>("VecHitMatchLambda",0.1);
196  fVecHitMinHits = p.get<unsigned int>("VecHitMinHits",3);
197 
198  fSortOrder = p.get<std::string>("SortOrder","AlongLength");
199  fInitialTPNHits = p.get<int>("InitialTPNHits",100);
200 
201  fKalCurvStepUncSq = p.get<float>("KalCurvStepUncSq",1.0E-9);
202  fKalPhiStepUncSq = p.get<float>("KalPhiStepUncSq",1.0E-9);
203  fKalLambdaStepUncSq = p.get<float>("KalLambdaStepUncSq",1.0E-9);
204 
205  art::InputTag itag(fHitLabel);
206  consumes< std::vector<gar::rec::Hit> >(itag);
207  produces< std::vector<gar::rec::Track> >();
208  produces< art::Assns<gar::rec::Hit, gar::rec::Track> >();
209  }
float fKalLambdaStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for lambda
size_t fPatRecLookBack1
n hits to look backwards to make a linear extrapolation
float fVecHitMatchPos
matching condition for pairs of vector hits – 3D distance (cm)
std::string string
Definition: nybbler.cc:12
std::string fSecondPassFitType
helix or Kalman – which fitter to call for second-pass tracks
float fKalCurvStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for curvature ...
float fVecHitMatchPEX
matching condition for pairs of vector hits – miss distance (cm)
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
unsigned int fMinNumHits
minimum number of hits to define a track
std::string fFirstPassFitType
helix or Kalman – which fitter to call for first-pass tracks
float fHitRCut
only take hits within rcut of the center of the detector
std::string fSortOrder
switch to tell what way to sort hits before presenting them to the fitter
int fTrackPass
which pass of the tracking to save as the tracks in the event
p
Definition: test.py:223
unsigned int fVecHitMinHits
minimum number of hits on a vector hit for it to be considered
float fVecHitRoad
max dist from a vector hit to a hit to assign it. for patrec alg 2. in cm.
float fVecHitMatchCos
matching condition for pairs of vector hits cos angle between directions
float fRoadYZinFit
cut in cm for dropping hits from tracks in fit
float fHitResolX
resolution in cm of a hit in X (drift direction)
float fVecHitMatchLambda
matching condition for pairs of vector hits – dLambda (radians)
int fDumpTracks
0: do not print out tracks, 1: print out tracks
float fSigmaRoad
how many sigma away from a track a hit can be and still add it during patrec
unsigned int fInitialTPNHits
number of hits to use for initial trackpar estimate, if present
float fMaxVecHitLen
maximum vector hit length in patrec alg 2, in cm
float fHitResolYZinFit
Hit resolution parameter to use in fit.
size_t fPatRecAlg
1: x-sorted patrec. 2: vector-hit patrec
float fVecHitMatchEta
matching condition for pairs of vector hits – eta match (cm)
float fHitResolYZ
resolution in cm of a hit in YZ (pad size)
std::string fHitLabel
label of module creating hits
size_t fPatRecLookBack2
extrapolate from lookback1 to lookback2 and see how close the new hit is to the line ...
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
float fKalPhiStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for phi
gar::rec::tracker1::tracker1 ( tracker1 const &  )
delete
gar::rec::tracker1::tracker1 ( tracker1 &&  )
delete

Member Function Documentation

float gar::rec::tracker1::capprox ( float  x1,
float  y1,
float  x2,
float  y2,
float  x3,
float  y3,
float &  xc,
float &  yc 
)
private

initial guess of curvature calculator – from ALICE. Also returns circle center

Definition at line 666 of file tracker1_module.cc.

670  {
671  //-----------------------------------------------------------------
672  // Initial approximation of the track curvature -- copied from ALICE
673  // here x is y and y is z for us
674  //-----------------------------------------------------------------
675  x3 -=x1;
676  x2 -=x1;
677  y3 -=y1;
678  y2 -=y1;
679  //
680  float det = x3*y2-x2*y3;
681  if (TMath::Abs(det)<1e-10){
682  return 100;
683  }
684  //
685  float u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
686  float x0 = x3*0.5-y3*u;
687  float y0 = y3*0.5+x3*u;
688  float c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
689  xc = x0 + x1;
690  yc = y0 + y1;
691  if (det<0) c2*=-1;
692  return c2;
693  }
const double e
float gar::rec::tracker1::capprox2 ( float  y0,
float  z0,
float  y1,
float  z1,
float  y2,
float  z2 
)
private

Definition at line 698 of file tracker1_module.cc.

699  {
700  float A = y1*(z2 - z0) - z1*(y2 - y0) + (y2*z0 - z2*y0);
701 
702  float B = -( (y1*y1 + z1*z1)*(z2 - z0)
703  -z1*( (y2*y2 + z2*z2) - (y0*y0 + z0*z0) )
704  + ( (y2*y2 + z2*z2)*z0 - z2*(y0*y0 + z0*z0) ) );
705 
706  float C = (y1*y1 + z1*z1)*(y2 - y0)
707  -y1*( (y2*y2 + z2*z2) - (y0*y0 + z0*z0))
708  + ( (y2*y2 + z2*z2)*y0 - y2*(y0*y0 + z0*z0) );
709 
710  float D = - ( (y1*y1 + z1*z1)*(y2*z0 - z2*y0)
711  - y1*( (y2*y2 + z2*z2)*z0 - z2*(y0*y0 + z0*z0) )
712  + z1*( (y2*y2 + z2*z2)*y0 - y2*(y0*y0 + z0*z0) ));
713 
714  if (TMath::Abs(A) < 1E-10)
715  { return 0;}
716 
717  float yc = -B/(2.0*A);
718  float zc = -C/(2.0*A);
719  float rs = yc*yc + zc*zc -D/A;
720 
721  if (fPrintLevel > 1)
722  {
723  std::cout << " In capprox2, A, B, C, D, rs: " << A << " " << B << " " << C << " " << D << " " << rs << std::endl;
724  }
725  if (rs <= 0)
726  { throw cet::exception("tracker1capprox2: negative input to sqrt"); }
727  float curv = 1.0/TMath::Sqrt(rs);
728  return curv;
729  }
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
#define A
Definition: memgrp.cpp:38
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
int gar::rec::tracker1::FitHelix ( art::ValidHandle< std::vector< Hit > > &  hitHandle,
std::vector< std::vector< int > > &  hitlist,
std::vector< int > &  hsi,
int  itrack,
bool  isForwards,
std::set< int > &  unused_hits,
TrackPar trackpar 
)
private

Definition at line 1434 of file tracker1_module.cc.

1442  {
1443  auto const& hits = *hitHandle;
1444  size_t nhits = hitlist[itrack].size();
1445  if (nhits < fMinNumHits) return 1;
1446 
1447  // estimate curvature, lambda, phi, xpos from the initial track parameters
1448  float curvature_init=0.1;
1449  float phi_init = 0;
1450  float lambda_init = 0;
1451  float xpos_init=0;
1452  float ypos_init=0;
1453  float zpos_init=0;
1454  float x_other_end=0;
1455  if ( initial_trackpar_estimate(hitHandle,
1456  hitlist,
1457  hsi,
1458  itrack,
1459  isForwards,
1460  curvature_init,
1461  lambda_init,
1462  phi_init,
1463  xpos_init,
1464  ypos_init,
1465  zpos_init,
1466  x_other_end) != 0)
1467  {
1468  return 1;
1469  }
1470 
1471  float tpi[5] = {ypos_init, zpos_init, curvature_init, phi_init, lambda_init};
1472  float covmat[25] = {0};
1473 
1474  // syntax from $ROOTSYS/tutorials/fit/fitCircle.C
1475 
1476  auto chi2Function = [&](const Double_t *par) {
1477  //minimisation function computing the sum of squares of residuals
1478  // looping at the graph points
1479 
1480  float tpl[5] = { (float) par[0], (float) par[1], (float) par[2], (float) par[3], (float) par[4] };
1481 
1482  // only need this to compute chisquared, so set the track parameters the same at the beginning and end,
1483  // and no covmat is needed (defined outside to be zero)
1484 
1485  TrackPar tpar(0,0,nhits,xpos_init,tpl,covmat,0,xpos_init,tpl,covmat,0,0);
1486 
1487  float c2sum = 0;
1488  for (size_t ihit=0; ihit<nhits; ++ihit)
1489  {
1490  TVector3 hitpos(hits[hsi[hitlist[itrack][ihit]]].Position()[0],
1491  hits[hsi[hitlist[itrack][ihit]]].Position()[1],
1492  hits[hsi[hitlist[itrack][ihit]]].Position()[2]);
1493  TVector3 helixpos = tpar.getPosAtX(hitpos.X(),isForwards);
1494  //std::cout << hitpos.X() << " " << hitpos.Y() << " " << hitpos.Z() << " " << helixpos.X() << " " << helixpos.Y() << " " << helixpos.Z() << std::endl;
1495  c2sum += (hitpos-helixpos).Mag2();
1496  }
1497  double dc2sum = c2sum;
1498  return dc2sum;
1499  };
1500 
1501  // wrap chi2 funciton in a function object for the fit
1502  // 5 is the number of fit parameters (size of array par)
1503  ROOT::Math::Functor fcn(chi2Function,5);
1504  ROOT::Fit::Fitter fitter;
1505 
1506  double pStart[5];
1507  for (size_t i=0; i<5; ++i) pStart[i] = tpi[i];
1508  fitter.SetFCN(fcn, pStart);
1509  fitter.Config().ParSettings(0).SetName("y0");
1510  fitter.Config().ParSettings(1).SetName("z0");
1511  fitter.Config().ParSettings(2).SetName("curvature");
1512  fitter.Config().ParSettings(3).SetName("phi0");
1513  fitter.Config().ParSettings(4).SetName("lambda");
1514 
1515  // do the fit
1516  bool ok = fitter.FitFCN();
1517  if (!ok) {
1518  LOG_WARNING("gar::rec::tracker1") << "Helix Fit failed";
1519  return(1);
1520  }
1521 
1522  const ROOT::Fit::FitResult & result = fitter.Result();
1523  //result.Print(std::cout);
1524  float fity0 = result.Value(0);
1525  float fitz0 = result.Value(1);
1526  float fitcurvature = result.Value(2);
1527  float fitphi0 = result.Value(3);
1528  float fitlambda = result.Value(4);
1529  float tpfit[5] = {fity0,fitz0,fitcurvature,fitphi0,fitlambda};
1530  float chisqmin = result.MinFcnValue();
1531 
1532  float stmp = TMath::Tan(fitlambda);
1533  //float stmp = TMath::Tan(fTrackParametersBegin[4]);
1534  if (stmp != 0)
1535  {
1536  stmp = 1.0/stmp;
1537  }
1538  else
1539  {
1540  stmp = 1E9;
1541  }
1542 
1543  float tracklength = TMath::Abs(xpos_init - x_other_end) * TMath::Sqrt( 1.0 + stmp*stmp );
1544  float covmatfit[25];
1545  for (size_t i=0; i<5; ++i)
1546  {
1547  for (size_t j=0; j<5; ++j)
1548  {
1549  covmatfit[5*i + j] = result.CovMatrix(i,j);
1550  }
1551  }
1552 
1553  trackpar.setNHits(nhits);
1554  trackpar.setTime(0);
1555  trackpar.setChisqForwards(chisqmin);
1556  trackpar.setChisqBackwards(chisqmin);
1557  trackpar.setLengthForwards(tracklength);
1558  trackpar.setLengthBackwards(tracklength);
1559  trackpar.setCovMatBeg(covmatfit); // todo -- put in covariance matrices at both ends properly.
1560  trackpar.setCovMatEnd(covmatfit);
1561  if (isForwards)
1562  {
1563  trackpar.setTrackParametersBegin(tpfit);
1564  trackpar.setXBeg(xpos_init);
1565  trackpar.setXEnd(x_other_end);
1566  TVector3 xyzend = trackpar.getPosAtX(x_other_end,true);
1567  float yend = xyzend[1];
1568  float zend = xyzend[2];
1569  float tp_other_end[5] = {yend,zend,fitcurvature,fitphi0,fitlambda};
1570  trackpar.setTrackParametersEnd(tp_other_end);
1571  }
1572  else
1573  {
1574  trackpar.setTrackParametersEnd(tpfit);
1575  trackpar.setXEnd(xpos_init);
1576  trackpar.setXBeg(x_other_end);
1577  TVector3 xyzend = trackpar.getPosAtX(x_other_end,true);
1578  float yend = xyzend[1];
1579  float zend = xyzend[2];
1580  float tp_other_end[5] = {yend,zend,fitcurvature,fitphi0,fitlambda};
1581  trackpar.setTrackParametersBegin(tp_other_end);
1582  }
1583 
1584  return 0;
1585  }
static QCString result
unsigned int fMinNumHits
minimum number of hits to define a track
int initial_trackpar_estimate(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, float &curvature_init, float &lambda_init, float &phi_init, float &xpos, float &ypos, float &zpos, float &x_other_end)
for(std::string line;std::getline(inFile, line);)
Definition: regex_t.cc:37
void gar::rec::tracker1::fitline ( std::vector< double > &  x,
std::vector< double > &  y,
double &  lambda,
double &  intercept 
)
private

Definition at line 1710 of file tracker1_module.cc.

1711  {
1712  size_t n = x.size();
1713  if (n < 2)
1714  {
1715  throw cet::exception("tracker1: too few hits to fit a line in linefit");
1716  }
1717  double sumx = 0;
1718  double sumy = 0;
1719  double sumxx = 0;
1720  double sumxy = 0;
1721 
1722  for (size_t i=0; i<n; ++i)
1723  {
1724  sumx += x[i];
1725  sumy += y[i];
1726  sumxx += TMath::Sq(x[i]);
1727  sumxy += x[i]*y[i];
1728  }
1729  double denom = (n*sumxx) - TMath::Sq(sumx);
1730  if (denom == 0)
1731  {
1732  slope = 1E6; // is this right?
1733  intercept = 0;
1734  }
1735  else
1736  {
1737  slope = (n*sumxy - sumx*sumy)/denom;
1738  intercept = (sumxx*sumy - sumx*sumxy)/denom;
1739  }
1740  }
std::void_t< T > n
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void gar::rec::tracker1::fitlinesdir ( std::vector< TVector3 > &  hlist,
TVector3 &  pos,
TVector3 &  dir 
)
private

Definition at line 1628 of file tracker1_module.cc.

1629  {
1630  std::vector<double> x;
1631  std::vector<double> y;
1632  std::vector<double> z;
1633  for (size_t i=0; i<hlist.size();++i)
1634  {
1635  x.push_back(hlist[i].X());
1636  y.push_back(hlist[i].Y());
1637  z.push_back(hlist[i].Z());
1638  }
1639  double slope_yx=0;
1640  double slope_zx=0;
1641  double intercept_yx=0;
1642  double intercept_zx=0;
1643 
1644  double slope_yz=0;
1645  double slope_xz=0;
1646  double intercept_yz=0;
1647  double intercept_xz=0;
1648 
1649  double slope_xy=0;
1650  double slope_zy=0;
1651  double intercept_xy=0;
1652  double intercept_zy=0;
1653 
1654  fitline(x,y,slope_xy,intercept_xy);
1655  fitline(x,z,slope_xz,intercept_xz);
1656 
1657  fitline(y,z,slope_yz,intercept_yz);
1658  fitline(y,x,slope_yx,intercept_yx);
1659 
1660  fitline(z,y,slope_zy,intercept_zy);
1661  fitline(z,x,slope_zx,intercept_zx);
1662 
1663  // pick the direction with the smallest sum of the absolute values of slopes to use to determine the line direction
1664  // in three-dimensional space
1665 
1666  double slopesumx = TMath::Abs(slope_xy) + TMath::Abs(slope_xz);
1667  double slopesumy = TMath::Abs(slope_yz) + TMath::Abs(slope_yx);
1668  double slopesumz = TMath::Abs(slope_zx) + TMath::Abs(slope_zy);
1669 
1670  if (slopesumx < slopesumy && slopesumx < slopesumz)
1671  {
1672  dir.SetXYZ(1.0,slope_xy,slope_xz);
1673  double avgx = 0;
1674  for (size_t i=0; i<x.size(); ++i)
1675  {
1676  avgx += x[i];
1677  }
1678  avgx /= x.size();
1679  pos.SetXYZ(avgx, avgx*slope_xy + intercept_xy, avgx*slope_xz + intercept_xz);
1680  }
1681  else if (slopesumy < slopesumx && slopesumy < slopesumz)
1682  {
1683  dir.SetXYZ(slope_yx,1.0,slope_yz);
1684  double avgy = 0;
1685  for (size_t i=0; i<y.size(); ++i)
1686  {
1687  avgy += y[i];
1688  }
1689  avgy /= y.size();
1690  pos.SetXYZ(avgy*slope_yx + intercept_yx, avgy, avgy*slope_yz + intercept_yz);
1691  }
1692  else
1693  {
1694  dir.SetXYZ(slope_zx,slope_zy,1.0);
1695  double avgz = 0;
1696  for (size_t i=0; i<z.size(); ++i)
1697  {
1698  avgz += z[i];
1699  }
1700  avgz /= z.size();
1701  pos.SetXYZ(avgz*slope_zx + intercept_zx, avgz*slope_zy + intercept_zy, avgz);
1702  }
1703  dir *= 1.0/dir.Mag();
1704 
1705  // put in fit values for y and z
1706  }
string dir
list x
Definition: train.py:276
void fitline(std::vector< double > &x, std::vector< double > &y, double &lambda, double &intercept)
size_t gar::rec::tracker1::ifob ( size_t  ihit,
size_t  nhits,
bool  isForwards 
)
private

Definition at line 1303 of file tracker1_module.cc.

1304  {
1305 
1306  return ihit; // disable ifob -- hit list now encodes track direction
1307 
1308  //if (ihit >= nhits)
1309  // {
1310  // throw cet::exception("Tracker1") << "Invalid hit index in ifob: " << ihit << " nhits: " << nhits;
1311  // }
1312  //if (isForwards)
1313  //{
1314  // return ihit;
1315  //}
1316  //else
1317  //{
1318  // return (nhits - ihit - 1);
1319  // }
1320  }
int gar::rec::tracker1::initial_trackpar_estimate ( art::ValidHandle< std::vector< Hit > > &  hitHandle,
std::vector< std::vector< int > > &  hitlist,
std::vector< int > &  hsi,
int  itrack,
bool  isForwards,
float &  curvature_init,
float &  lambda_init,
float &  phi_init,
float &  xpos,
float &  ypos,
float &  zpos,
float &  x_other_end 
)
private

Definition at line 1325 of file tracker1_module.cc.

1337  {
1338  // form a rough guess of track parameters
1339 
1340  auto const& hits = *hitHandle;
1341  size_t nhits = hitlist[itrack].size();
1342 
1343  size_t farhit_index = TMath::Min(nhits-1, (size_t) fInitialTPNHits);
1344  size_t inthit_index = farhit_index/2;
1345 
1346  size_t firsthit = ifob(0,nhits,isForwards);
1347  //size_t inthit = ifob(fMinNumHits/2,nhits,isForwards);
1348  //size_t farhit = ifob(fMinNumHits-1,nhits,isForwards);
1349  size_t inthit = ifob(inthit_index,nhits,isForwards);
1350  size_t farhit = ifob(farhit_index,nhits,isForwards);
1351  size_t lasthit = ifob(nhits-1,nhits,isForwards);
1352 
1353  float trackbeg[3] = {hits[hsi[hitlist[itrack][firsthit]]].Position()[0],
1354  hits[hsi[hitlist[itrack][firsthit]]].Position()[1],
1355  hits[hsi[hitlist[itrack][firsthit]]].Position()[2]};
1356 
1357  float tp1[3] = {hits[hsi[hitlist[itrack][inthit]]].Position()[0],
1358  hits[hsi[hitlist[itrack][inthit]]].Position()[1],
1359  hits[hsi[hitlist[itrack][inthit]]].Position()[2]};
1360 
1361  float tp2[3] = {hits[hsi[hitlist[itrack][farhit]]].Position()[0],
1362  hits[hsi[hitlist[itrack][farhit]]].Position()[1],
1363  hits[hsi[hitlist[itrack][farhit]]].Position()[2]};
1364 
1365  if (fPrintLevel>1)
1366  {
1367  std::cout << "Hit Dump in initial_trackpar_estimate: " << std::endl;
1368  for (size_t i=0;i<nhits;++i)
1369  {
1370  size_t ihf = ifob(i,nhits,isForwards);
1371  std::cout << i << " : " <<
1372  hits[hsi[hitlist[itrack][ihf]]].Position()[0] << " " <<
1373  hits[hsi[hitlist[itrack][ihf]]].Position()[1] << " " <<
1374  hits[hsi[hitlist[itrack][ihf]]].Position()[2] << std::endl;
1375  }
1376  }
1377  if (fPrintLevel>0)
1378  {
1379  std::cout << "isForwards: " << isForwards << std::endl;
1380  std::cout << "first hit: " << firsthit << ", inter hit: " << inthit << " " << " far hit: " << farhit << std::endl;
1381  std::cout << "in the hit list: " << hsi[hitlist[itrack][firsthit]] << " " << hsi[hitlist[itrack][inthit]] << " " << hsi[hitlist[itrack][farhit]] << std::endl;
1382  std::cout << "First hit x, y, z: " << trackbeg[0] << " " << trackbeg[1] << " " << trackbeg[2] << std::endl;
1383  std::cout << "Inter hit x, y, z: " << tp1[0] << " " << tp1[1] << " " << tp1[2] << std::endl;
1384  std::cout << "Far hit x, y, z: " << tp2[0] << " " << tp2[1] << " " << tp2[2] << std::endl;
1385  }
1386 
1387  xpos = trackbeg[0];
1388  ypos = trackbeg[1];
1389  zpos = trackbeg[2];
1390  x_other_end = hits[hsi[hitlist[itrack][lasthit]]].Position()[0];
1391 
1392 
1393  float ycc=0;
1394  float zcc=0;
1395  curvature_init = capprox(trackbeg[1],trackbeg[2],tp1[1],tp1[2],tp2[1],tp2[2],ycc,zcc);
1396  //std::cout << " inputs to trackpar circ fit (y,z): " << trackbeg[1] << " " << trackbeg[2] << " : "
1397  // << tp1[1] << " " << tp1[2] << " : " << tp2[1] << " " << tp2[2] << std::endl;
1398  //std::cout << "curvature output: " << curvature_init << std::endl;
1399 
1400  phi_init = TMath::ATan2( trackbeg[2] - zcc, ycc - trackbeg[1] );
1401  float phi2 = phi_init;
1402  if (curvature_init<0) phi_init += TMath::Pi();
1403  float radius_init = 10000;
1404  if (curvature_init != 0) radius_init = 1.0/curvature_init;
1405 
1406  float dx1 = tp2[0] - xpos;
1407  if (dx1 != 0)
1408  {
1409  float dphi2 = TMath::ATan2(tp2[2]-zcc,ycc-tp2[1])-phi2;
1410  if (dphi2 > TMath::Pi()) dphi2 -= 2.0*TMath::Pi();
1411  if (dphi2 < -TMath::Pi()) dphi2 += 2.0*TMath::Pi();
1412  lambda_init = TMath::ATan(1.0/((radius_init/dx1)*dphi2));
1413  }
1414  else
1415  {
1416  //std::cout << "initial track par estimate failure" << std::endl;
1417  lambda_init = 0;
1418  return 1;
1419  } // got fMinNumHits all at exactly the same value of x (they were sorted). Reject track.
1420 
1421  if (fPrintLevel>0)
1422  {
1423  std::cout << "phi calc: dz, dy " << tp2[2]-trackbeg[2] << " " << tp2[1]-trackbeg[1] << std::endl;
1424  std::cout << "initial curvature, phi, lambda: " << curvature_init << " " << phi_init << " " << lambda_init << std::endl;
1425  }
1426  return 0;
1427  }
TH3F * xpos
Definition: doAna.cpp:29
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
TH3F * ypos
Definition: doAna.cpp:30
TH3F * zpos
Definition: doAna.cpp:31
float capprox(float x1, float y1, float x2, float y2, float x3, float y3, float &xc, float &yc)
initial guess of curvature calculator – from ALICE. Also returns circle center
unsigned int fInitialTPNHits
number of hits to use for initial trackpar estimate, if present
QTextStream & endl(QTextStream &s)
size_t ifob(size_t ihit, size_t nhits, bool isForwards)
int gar::rec::tracker1::KalmanFit ( art::ValidHandle< std::vector< Hit > > &  hitHandle,
std::vector< std::vector< int > > &  hitlist,
std::vector< int > &  hsi,
int  itrack,
bool  isForwards,
std::vector< float > &  trackparatend,
float &  chisquared,
float &  length,
float *  covmat,
std::set< int > &  unused_hits 
)
private

Definition at line 998 of file tracker1_module.cc.

1008  {
1009 
1010  // set some default values in case we return early
1011 
1012  auto const& hits = *hitHandle;
1013  size_t nhits = hitlist[itrack].size();
1014  chisquared = 0;
1015  length = 0;
1016  for (size_t i=0; i<5; ++i) trackparatend[i] = 0;
1017  for (size_t i=0; i<25; ++i) covmat[i] = 0;
1018 
1019  float roadsq = fRoadYZinFit*fRoadYZinFit;
1020 
1021  // estimate curvature, lambda, phi, xpos from the initial track parameters
1022  float curvature_init=0.1;
1023  float phi_init = 0;
1024  float lambda_init = 0;
1025  float xpos_init=0;
1026  float ypos_init=0;
1027  float zpos_init=0;
1028  float x_other_end = 0;
1029  if ( initial_trackpar_estimate(hitHandle,
1030  hitlist,
1031  hsi,
1032  itrack,
1033  isForwards,
1034  curvature_init,
1035  lambda_init,
1036  phi_init,
1037  xpos_init,
1038  ypos_init,
1039  zpos_init,
1040  x_other_end) != 0)
1041  {
1042  //std::cout << "kalman fit failed on initial trackpar estimate" << std::endl;
1043  return 1;
1044  }
1045 
1046  // Kalman fitter variables
1047 
1048  float xpos = xpos_init;
1049 
1050  TMatrixF P(5,5); // covariance matrix of parameters
1051  // fill in initial guesses -- generous uncertainties on first value.
1052  P.Zero();
1053  P[0][0] = TMath::Sq(1); // initial position uncertainties -- y
1054  P[1][1] = TMath::Sq(1); // and z
1055  P[2][2] = TMath::Sq(.5); // curvature of zero gets us to infinite momentum, and curvature of 2 is curled up tighter than the pads
1056  P[3][3] = TMath::Sq(.5); // phi uncertainty
1057  P[4][4] = TMath::Sq(.5); // lambda uncertainty
1058 
1059  TMatrixF PPred(5,5);
1060 
1061  // per-step additions to the covariance matrix
1062  TMatrixF Q(5,5);
1063  Q.Zero();
1064  Q[2][2] = fKalCurvStepUncSq; // allow for some curvature uncertainty between points
1065  Q[3][3] = fKalPhiStepUncSq; // phi
1066  Q[4][4] = fKalLambdaStepUncSq; // lambda
1067 
1068  // uncertainties on the measured points (big for now)
1069  TMatrixF R(2,2);
1070  R.Zero();
1071  R[0][0] = TMath::Sq(fHitResolYZinFit); // in cm^2
1072  R[1][1] = TMath::Sq(fHitResolYZinFit); // in cm^2
1073 
1074  // add the hits and update the track parameters and uncertainties. Put in additional terms to keep uncertainties from shrinking when
1075  // scattering and energy loss can change the track parameters along the way.
1076 
1077  // F = partial(updatefunc)/partial(parvec). Update functions are in the comments below.
1078  TMatrixF F(5,5);
1079  TMatrixF FT(5,5);
1080  TVectorF parvec(5);
1081  parvec[0] = ypos_init;
1082  parvec[1] = zpos_init;
1083  parvec[2] = curvature_init;
1084  parvec[3] = phi_init;
1085  parvec[4] = lambda_init;
1086  TVectorF predstep(5);
1087 
1088  TMatrixF H(2,5); // partial(obs)/partial(params)
1089  H.Zero();
1090  H[0][0] = 1; // y
1091  H[1][1] = 1; // z
1092  TMatrixF HT(5,2);
1093 
1094  TVectorF z(2);
1095  TVectorF ytilde(2);
1096  TVectorF hx(2);
1097  TMatrixF S(2,2);
1098  TMatrixF K(5,2);
1099 
1100  TMatrixF I(5,5);
1101  I.Zero();
1102  for (int i=0;i<5;++i) I[i][i] = 1;
1103 
1104  for (size_t ihit=1; ihit<nhits; ++ihit)
1105  {
1106 
1107  size_t ihf = ifob(ihit,nhits,isForwards);
1108  float xh = hits[hsi[hitlist[itrack][ihf]]].Position()[0];
1109  float yh = hits[hsi[hitlist[itrack][ihf]]].Position()[1];
1110  float zh = hits[hsi[hitlist[itrack][ihf]]].Position()[2];
1111 
1112  if (fPrintLevel > 0)
1113  {
1114  std::cout << std::endl;
1115  std::cout << "Adding a new hit: " << xh << " " << yh << " " << zh << std::endl;
1116  }
1117 
1118  // for readability
1119 
1120  float curvature = parvec[2];
1121  float phi = parvec[3];
1122  float lambda = parvec[4];
1123 
1124  // update prediction to the plane containing x. Maybe we need to find the closest point on the helix to the hit we are adding,
1125  // and not necessarily force it to be at this x
1126 
1127  F.Zero();
1128 
1129  // y = yold + slope*dx*Sin(phi). F[0][i] = dy/dtrackpar[i], where f is the update function slope*dx*Sin(phi)
1130 
1131  float slope = TMath::Tan(lambda);
1132  if (slope != 0)
1133  {
1134  slope = 1.0/slope;
1135  }
1136  else
1137  {
1138  slope = 1E9;
1139  }
1140 
1141  // relocate dx to be the location along the helix of the closest point. Linearize for now near xpos.
1142  // old calc
1143 
1144  float dx = xh - xpos;
1145 
1146  float dxdenom = slope*slope/(fHitResolYZ*fHitResolYZ) + 1.0/(fHitResolX*fHitResolX);
1147  float dxnum = (slope/(fHitResolYZ*fHitResolYZ))*( (yh - parvec[0])*TMath::Sin(phi) + (zh - parvec[1])*TMath::Cos(phi) )
1148  + (xh - xpos)/(fHitResolX*fHitResolX);
1149  dx = dxnum/dxdenom;
1150  if (dx == 0) dx = 1E-3;
1151  //std::cout << "dxdenom, dxnum: " << dxdenom << " " << dxnum << std::endl;
1152  //std::cout << "Track pos: " << xpos << " " << parvec[0] << " " << parvec[1] << " " << " Hit pos: " << xh << " " << yh << " " << zh << std::endl;
1153  //std::cout << "dx old and new: " << xh - xpos << " " << dx << std::endl;
1154 
1155 
1156  //TODO check this -- are these the derivatives?
1157 
1158  // y = yold + dx*slope*TMath::Sin(phi)
1159  // slope = cot(lambda), so dslope/dlambda = -csc^2(lambda) = -1 - slope^2
1160  F[0][0] = 1.;
1161  F[0][3] = dx*slope*TMath::Cos(phi);
1162  F[0][4] = dx*TMath::Sin(phi)*(-1.0-slope*slope);
1163 
1164  // z = zold + slope*dx*Cos(phi)
1165  F[1][1] = 1.;
1166  F[1][3] = -dx*slope*TMath::Sin(phi);
1167  F[1][4] = dx*TMath::Cos(phi)*(-1.0-slope*slope);
1168 
1169  // curvature = old curvature -- doesn't change but put in an uncertainty
1170  F[2][2] = 1.;
1171 
1172  // phi = old phi + curvature*slope*dx
1173  // need to take the derivative of a product here
1174  F[3][2] = dx*slope;
1175  F[3][3] = 1.;
1176  F[3][4] = dx*curvature*(-1.0-slope*slope);
1177 
1178  // lambda -- same -- but put in an uncertainty in case it changes
1179  F[4][4] = 1.;
1180 
1181  // predicted step
1182 
1183  if (fPrintLevel > 1)
1184  {
1185  std::cout << "F Matrix: " << std::endl;
1186  F.Print();
1187  std::cout << "P Matrix: " << std::endl;
1188  P.Print();
1189  }
1190  if (fPrintLevel > 0)
1191  {
1192  std::cout << "x: " << xpos << " dx: " << dx << std::endl;
1193  std::cout << " Parvec: y " << parvec[0] << " z " << parvec[1] << " c " << parvec[2] << " phi " << parvec[3] << " lambda " << parvec[4] << std::endl;
1194  }
1195 
1196  predstep = parvec;
1197  predstep[0] += slope*dx*TMath::Sin(phi); // update y
1198  predstep[1] += slope*dx*TMath::Cos(phi); // update z
1199  predstep[3] += slope*dx*curvature; // update phi
1200 
1201  if (fPrintLevel > 1)
1202  {
1203  std::cout << " Predstep: y " << predstep[0] << " z " << predstep[1] << " c " << predstep[2] << " phi " << predstep[3] << " lambda " << predstep[4] << std::endl;
1204  }
1205  // equations from the extended Kalman filter
1206  FT.Transpose(F);
1207  PPred = F*P*FT + Q;
1208  if (fPrintLevel > 1)
1209  {
1210  std::cout << "PPred Matrix: " << std::endl;
1211  PPred.Print();
1212  }
1213 
1214  ytilde[0] = yh - predstep[0];
1215  ytilde[1] = zh - predstep[1];
1216  float ydistsq = ytilde.Norm2Sqr();
1217  if (ydistsq > roadsq)
1218  {
1219  unused_hits.insert(ihf);
1220  continue;
1221  }
1222  chisquared += ytilde.Norm2Sqr()/TMath::Sq(fHitResolYZ);
1223  if (fPrintLevel > 0)
1224  {
1225  std::cout << "ytilde (residuals): " << std::endl;
1226  ytilde.Print();
1227  }
1228  if (fPrintLevel > 1)
1229  {
1230  std::cout << "H Matrix: " << std::endl;
1231  H.Print();
1232  }
1233 
1234  HT.Transpose(H);
1235  S = H*PPred*HT + R;
1236  if (fPrintLevel > 1)
1237  {
1238  std::cout << "S Matrix: " << std::endl;
1239  S.Print();
1240  }
1241 
1242  S.Invert();
1243  if (fPrintLevel > 1)
1244  {
1245  std::cout << "Inverted S Matrix: " << std::endl;
1246  S.Print();
1247  }
1248 
1249  K = PPred*HT*S;
1250  if (fPrintLevel > 1)
1251  {
1252  std::cout << "K Matrix: " << std::endl;
1253  K.Print();
1254  }
1255 
1256  float yprev = parvec[0];
1257  float zprev = parvec[1];
1258  parvec = predstep + K*ytilde;
1259  P = (I-K*H)*PPred;
1260  xpos = xpos + dx;
1261  //std::cout << " Updated xpos: " << xpos << " " << dx << std::endl;
1262 
1263  length += TMath::Sqrt( dx*dx + TMath::Sq(parvec[0]-yprev) + TMath::Sq(parvec[1]-zprev) );
1264  }
1265 
1266  for (size_t i=0; i<5; ++i)
1267  {
1268  trackparatend[i] = parvec[i];
1269  }
1270  trackparatend[5] = xpos; // tack this on so we can specify where the track endpoint is
1271  if (fPrintLevel > 1)
1272  {
1273  std::cout << "Track params at end (y, z, curv, phi, lambda) " << trackparatend[0] << " " << trackparatend[1] << " " <<
1274  trackparatend[2] << " " << trackparatend[3] <<" " << trackparatend[4] << std::endl;
1275  S.Print();
1276  }
1277 
1278  // just for visualization of the initial track parameter guesses. Comment out when fitting tracks
1279 
1280  //trackparatend[0] = ypos_init;
1281  //trackparatend[1] = zpos_init;
1282  //trackparatend[2] = curvature_init;
1283  //trackparatend[3] = phi_init;
1284  //trackparatend[4] = lambda_init;
1285  //trackparatend[5] = xpos_init;
1286 
1287 
1288  size_t icov=0;
1289  for (size_t i=0; i<5; ++i)
1290  {
1291  for (size_t j=0; j<5; ++j)
1292  {
1293  covmat[icov] = P[i][j];
1294  }
1295  }
1296 
1297  return 0;
1298  }
float fKalLambdaStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for lambda
TH3F * xpos
Definition: doAna.cpp:29
float fKalCurvStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for curvature ...
Definition: 044_section.h:5
std::pair< float, std::string > P
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
float fRoadYZinFit
cut in cm for dropping hits from tracks in fit
float fHitResolX
resolution in cm of a hit in X (drift direction)
int initial_trackpar_estimate(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, float &curvature_init, float &lambda_init, float &phi_init, float &xpos, float &ypos, float &zpos, float &x_other_end)
float fHitResolYZinFit
Hit resolution parameter to use in fit.
float fHitResolYZ
resolution in cm of a hit in YZ (pad size)
QTextStream & endl(QTextStream &s)
size_t ifob(size_t ihit, size_t nhits, bool isForwards)
float fKalPhiStepUncSq
constant uncertainty term on each step of the Kalman fit – squared, for phi
int gar::rec::tracker1::KalmanFitBothWays ( art::ValidHandle< std::vector< Hit > > &  hitHandle,
std::vector< std::vector< int > > &  hitlist,
std::vector< int > &  hsi,
int  itrack,
std::set< int > &  unused_hits,
TrackPar trackpar 
)
private

Definition at line 732 of file tracker1_module.cc.

740  {
741  // variables: x is the independent variable
742  // 0: y
743  // 1: z
744  // 2: curvature
745  // 3: phi
746  // 4: lambda = angle from the cathode plane
747  // 5: x /// added on to the end
748 
749  // the "forward" fit is just in increasing x. Track parameters are at the end of the fit
750 
751 
752  // re-sort hits before giving them to the fitter. Sorting in X may scramble the hit order if the track is in the Y,Z plane
753  // start calling them tracks here.
754 
755  std::vector<std::vector<int> > hlf;
756  std::vector<std::vector<int> > hlb;
757 
758  if (fSortOrder == "AlongLength")
759  {
760 
761  hlf = hitlist; // only sort the track we're working on but pass the whole hitlist to the Kalman filter for historical reasons
762  hlb = hitlist;
763 
764  auto const& hits = *hitHandle;
765 
766  float cmin[3]; // min x, y, and z coordinates over all hits
767  float cmax[3]; // max x, y, and z coordinates over all hits
768  size_t ihex[6]; // index of hit which gave the min or max ("extreme") 0-2: (min xyz) 3-5 (max xyz)
769 
770  for (size_t ihit=0; ihit<hitlist[itrack].size(); ++ihit)
771  {
772  for (int i=0; i<3; ++i)
773  {
774  float c = hits[hsi[hitlist[itrack][ihit]]].Position()[i];
775  if (ihit==0)
776  {
777  cmin[i] = c;
778  cmax[i] = c;
779  ihex[i] = 0;
780  ihex[i+3] = 0;
781  }
782  else
783  {
784  if (c<cmin[i])
785  {
786  cmin[i] = c;
787  ihex[i] = ihit;
788  }
789  if (c>cmax[i])
790  {
791  cmax[i] = c;
792  ihex[i+3] = ihit;
793  }
794  }
795  }
796  }
797  // now we have six hits that have the min and max x, y, and z values. Find out which of these six
798  // hits has the biggest sum of distances to all the other hits (the most extreme)
799  float sumdmax = 0;
800  size_t imax = 0;
801  for (size_t i=0; i<6; ++i)
802  {
803  float sumd = 0;
804  TVector3 poshc(hits[hsi[hitlist[itrack][ihex[i]]]].Position());
805  for (size_t ihit=0; ihit<hitlist[itrack].size(); ++ihit)
806  {
807  TVector3 hp(hits[hsi[hitlist[itrack][ihit]]].Position());
808  sumd += (poshc - hp).Mag();
809  }
810  if (sumd > sumdmax)
811  {
812  sumdmax = sumd;
813  imax = i;
814  }
815  }
816 
817  // Use this hit as a starting point -- find the closest hit to the last
818  // and add it to the newly sorted list hls. Change -- sort hits in order of how
819  // far they are from the first hit. Prevents oscillations in position on sort order.
820  // This can be optimized to just sort an arry of distances using TMath::Sort.
821 
822  std::vector<int> hls;
823  hls.push_back(hitlist[itrack][ihex[imax]]);
824  TVector3 lpos(hits[hsi[hls[0]]].Position());
825  for (size_t inh=1;inh<hitlist[itrack].size();++inh)
826  {
827  float dmin=0;
828  float jmin=-1;
829  for (size_t jh=0;jh<hitlist[itrack].size();++jh)
830  {
831  bool found = false;
832  for (size_t kh=0;kh<hls.size();++kh)
833  {
834  if (hls[kh] == hitlist[itrack][jh])
835  {
836  found = true;
837  break;
838  }
839  }
840  if (found) continue; // skip if we've already assigned this hit on this track
841  TVector3 hpos(hits[hsi[hitlist[itrack][jh]]].Position());
842  float d=(hpos-lpos).Mag();
843  if (jmin == -1)
844  {
845  jmin = jh;
846  dmin = d;
847  }
848  else
849  {
850  if (d<dmin)
851  {
852  jmin = jh;
853  dmin = d;
854  }
855  }
856  }
857  // std::cout << "dmin: " << dmin << std::endl;
858  hls.push_back(hitlist[itrack][jmin]);
859  }
860  // replace our hit list with our newly sorted hit list.
861 
862  if (fPrintLevel>2)
863  {
864  std::cout << "Itrack: " << itrack << std::endl;
865  for (size_t ihit=0; ihit<hitlist[itrack].size(); ++ihit)
866  {
867  printf("Sort compare: %5d %10.3f %10.3f %10.3f %5d %10.3f %10.3f %10.3f\n",
868  hitlist[itrack][ihit],
869  hits[hsi[hitlist[itrack][ihit]]].Position()[0],
870  hits[hsi[hitlist[itrack][ihit]]].Position()[1],
871  hits[hsi[hitlist[itrack][ihit]]].Position()[2],
872  hls[ihit],
873  hits[hsi[hls[ihit]]].Position()[0],
874  hits[hsi[hls[ihit]]].Position()[1],
875  hits[hsi[hls[ihit]]].Position()[2]);
876  }
877  }
878  hlf[itrack] = hls;
879 
880  // now go backwards -- start at the end hit and use that as a starting point
881 
882  hls.clear();
883  hls.push_back(hlf[itrack].back());
884  TVector3 lpos2(hits[hsi[hls[0]]].Position());
885  for (size_t inh=1;inh<hitlist[itrack].size();++inh)
886  {
887  float dmin=0;
888  float jmin=-1;
889  for (size_t jh=0;jh<hitlist[itrack].size();++jh)
890  {
891  bool found = false;
892  for (size_t kh=0;kh<hls.size();++kh)
893  {
894  if (hls[kh] == hitlist[itrack][jh])
895  {
896  found = true;
897  break;
898  }
899  }
900  if (found) continue; // skip if we've already assigned this hit on this track
901  TVector3 hpos(hits[hsi[hitlist[itrack][jh]]].Position());
902  float d=(hpos-lpos2).Mag();
903  if (jmin == -1)
904  {
905  jmin = jh;
906  dmin = d;
907  }
908  else
909  {
910  if (d<dmin)
911  {
912  jmin = jh;
913  dmin = d;
914  }
915  }
916  }
917  // std::cout << "dmin: " << dmin << std::endl;
918  hls.push_back(hitlist[itrack][jmin]);
919  }
920  // replace our hit list with our newly sorted hit list.
921 
922  if (fPrintLevel>2)
923  {
924  std::cout << "Itrack: " << itrack << std::endl;
925  for (size_t ihit=0; ihit<hitlist[itrack].size(); ++ihit)
926  {
927  printf("Sort compare: %5d %10.3f %10.3f %10.3f %5d %10.3f %10.3f %10.3f\n",
928  hitlist[itrack][ihit],
929  hits[hsi[hitlist[itrack][ihit]]].Position()[0],
930  hits[hsi[hitlist[itrack][ihit]]].Position()[1],
931  hits[hsi[hitlist[itrack][ihit]]].Position()[2],
932  hls[ihit],
933  hits[hsi[hls[ihit]]].Position()[0],
934  hits[hsi[hls[ihit]]].Position()[1],
935  hits[hsi[hls[ihit]]].Position()[2]);
936  }
937  }
938  hlb[itrack] = hls;
939 
940  }
941  else if (fSortOrder == "X")
942  {
943  hlf = hitlist;
944  std::sort(hlf[itrack].begin(), hlf[itrack].end(),
945  [&hsi](int a, int b ) { return (hsi[a] > hsi[b]);});
946  hlb = hitlist;
947  std::sort(hlb[itrack].begin(), hlb[itrack].end(),
948  [&hsi](int a, int b ) { return (hsi[a] < hsi[b]);});
949  }
950 
951  std::vector<float> tparend(6);
952  float covmatend[25];
953  float chisqforwards = 0;
954  float lengthforwards = 0;
955  int retcode = KalmanFit(hitHandle,hlf,hsi,itrack,true,tparend,chisqforwards,lengthforwards,covmatend,unused_hits);
956  if (retcode != 0) return 1;
957 
958  // the "backwards" fit is in decreasing x. Track paramters are at the end of the fit, the other end of the track
959 
960  std::vector<float> tparbeg(6);
961  float covmatbeg[25];
962  float chisqbackwards = 0;
963  float lengthbackwards = 0;
964 
965  retcode = KalmanFit(hitHandle,hlb,hsi,itrack,false,tparbeg,chisqbackwards,lengthbackwards,covmatbeg,unused_hits);
966  if (retcode != 0) return 1;
967 
968  size_t nhits=0;
969  if (hitlist[itrack].size()>unused_hits.size())
970  { nhits = hitlist[itrack].size()-unused_hits.size(); }
971  trackpar.setNHits(nhits);
972  trackpar.setTime(0);
973  trackpar.setChisqForwards(chisqforwards);
974  trackpar.setChisqBackwards(chisqbackwards);
975  trackpar.setLengthForwards(lengthforwards);
976  trackpar.setLengthBackwards(lengthbackwards);
977  trackpar.setCovMatBeg(covmatbeg);
978  trackpar.setCovMatEnd(covmatend);
979  trackpar.setTrackParametersBegin(tparbeg.data());
980  trackpar.setXBeg(tparbeg[5]);
981  trackpar.setTrackParametersEnd(tparend.data());
982  trackpar.setXEnd(tparend[5]);
983 
984  return 0;
985  }
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
std::string fSortOrder
switch to tell what way to sort hits before presenting them to the fitter
const double a
int KalmanFit(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, std::vector< float > &trackparatend, float &chisquared, float &length, float *covmat, std::set< int > &unused_hits)
int imax
Definition: tracks.py:195
static bool * b
Definition: config.cpp:1043
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
QTextStream & endl(QTextStream &s)
tracker1& gar::rec::tracker1::operator= ( tracker1 const &  )
delete
tracker1& gar::rec::tracker1::operator= ( tracker1 &&  )
delete
void gar::rec::tracker1::produce ( art::Event e)
overridevirtual

Implements art::EDProducer.

Definition at line 211 of file tracker1_module.cc.

212  {
213  std::unique_ptr< std::vector<gar::rec::Track> > trkCol(new std::vector<gar::rec::Track>);
214  std::unique_ptr< art::Assns<gar::rec::Hit,gar::rec::Track> > hitTrkAssns(new ::art::Assns<gar::rec::Hit,gar::rec::Track>);
215 
216  auto hitHandle = e.getValidHandle< std::vector<Hit> >(fHitLabel);
217  auto const& hits = *hitHandle;
218 
219  auto const trackPtrMaker = art::PtrMaker<gar::rec::Track>(e);
220  auto const hitPtrMaker = art::PtrMaker<gar::rec::Hit>(e, hitHandle.id());
221 
223  G4ThreeVector zerovec(0,0,0);
224  G4ThreeVector magfield = magFieldService->FieldAtPoint(zerovec);
225 
227  double xtpccent = geo->TPCXCent();
228  double ytpccent = geo->TPCYCent();
229  double ztpccent = geo->TPCZCent();
230  TVector3 tpccent(xtpccent,ytpccent,ztpccent);
231  TVector3 xhat(1,0,0);
232 
233  // make an array of hit indices sorted by hit X position
234  std::vector<float> hitx;
235  for (size_t i=0; i<hits.size(); ++i)
236  {
237  hitx.push_back(hits[i].Position()[0]);
238  }
239  std::vector<int> hsi(hitx.size());
240  TMath::Sort((int) hitx.size(),hitx.data(),hsi.data());
241 
242  float roadsq = fSigmaRoad*fSigmaRoad;
243 
244  // record which hits we have assigned to which tracks. Make a forwards and a backwards hit list
245  // as the sorting is different
246 
247  std::vector< std::vector<int> > hitlist;
248 
249  float resolSq = fHitResolYZ*fHitResolYZ;
250 
251  // initial patrec algorithm -- sort hits in x and look for clusters in y and z
252 
253  if (fPatRecAlg == 1)
254  {
255 
256  // do this twice, once going forwards through the hits, once backwards, and then collect hits
257  // in groups and split them when either the forwards or the backwards list says to split them.
258 
259  std::vector< std::vector<int> > hitlistf;
260  std::vector<int> trackf(hits.size());
261  for (size_t ihit=0; ihit<hits.size(); ++ihit)
262  {
263  const float *hpos = hits[hsi[ihit]].Position();
264  TVector3 hpvec(hpos);
265  if ( ((hpos - tpccent).Cross(xhat)).Mag() > fHitRCut ) continue; // skip hits if they are too far away from center as the
266  // last few pad rows may have distorted hits
267 
268  float bestsignifs = -1;
269  int ibest = -1;
270  for (size_t itcand = 0; itcand < hitlistf.size(); ++itcand)
271  {
272  float signifs = 1E9;
273  size_t hlsiz = hitlistf[itcand].size();
274  if (hlsiz > fPatRecLookBack1 && hlsiz > fPatRecLookBack2)
275  {
276  TVector3 pt1( hits[hsi[hitlistf[itcand][hlsiz-fPatRecLookBack1]]].Position() );
277  TVector3 pt2( hits[hsi[hitlistf[itcand][hlsiz-fPatRecLookBack2]]].Position() );
278  TVector3 uv = pt1-pt2;
279  uv *= 1.0/uv.Mag();
280  signifs = ((hpvec-pt1).Cross(uv)).Mag2()/resolSq;
281  }
282  else // not enough hits, just look how close we are to the last one
283  {
284  const float *cpos = hits[hsi[hitlistf[itcand].back()]].Position();
285  signifs = (TMath::Sq( (hpos[1]-cpos[1]) ) +
286  TMath::Sq( (hpos[2]-cpos[2]) ))/resolSq;
287  }
288  if (bestsignifs < 0 || signifs < bestsignifs)
289  {
290  bestsignifs = signifs;
291  ibest = itcand;
292  }
293  }
294  if (ibest == -1 || bestsignifs > roadsq) // start a new track if we're not on the road, or if we had no tracks to begin with
295  {
296  ibest = hitlistf.size();
297  std::vector<int> vtmp;
298  hitlistf.push_back(vtmp);
299  }
300  hitlistf[ibest].push_back(ihit);
301  trackf[ihit] = ibest;
302  }
303 
304  std::vector< std::vector<int> > hitlistb;
305  std::vector<int> trackb(hits.size());
306  for (int ihit=hits.size()-1; ihit >= 0; --ihit)
307  {
308  const float *hpos = hits[hsi[ihit]].Position();
309  TVector3 hpvec(hpos);
310  if ( ((hpos - tpccent).Cross(xhat)).Mag() > fHitRCut ) continue; // skip hits if they are too far away from center as the
311  // last few pad rows may have distorted hits
312 
313  float bestsignifs = -1;
314  int ibest = -1;
315  for (size_t itcand = 0; itcand < hitlistb.size(); ++itcand)
316  {
317  float signifs = 1E9;
318  size_t hlsiz = hitlistb[itcand].size();
319  if (hlsiz > fPatRecLookBack1 && hlsiz > fPatRecLookBack2)
320  {
321  TVector3 pt1( hits[hsi[hitlistb[itcand][hlsiz-fPatRecLookBack1]]].Position() );
322  TVector3 pt2( hits[hsi[hitlistb[itcand][hlsiz-fPatRecLookBack2]]].Position() );
323  TVector3 uv = pt1-pt2;
324  uv *= 1.0/uv.Mag();
325  signifs = ((hpvec-pt1).Cross(uv)).Mag2()/resolSq;
326  }
327  else // not enough hits, just look how close we are to the last one
328  {
329  const float *cpos = hits[hsi[hitlistb[itcand].back()]].Position();
330  signifs = (TMath::Sq( (hpos[1]-cpos[1]) ) +
331  TMath::Sq( (hpos[2]-cpos[2]) ))/resolSq;
332  }
333 
334  if (bestsignifs < 0 || signifs < bestsignifs)
335  {
336  bestsignifs = signifs;
337  ibest = itcand;
338  }
339  }
340  if (ibest == -1 || bestsignifs > roadsq) // start a new track if we're not on the road, or if we had no tracks to begin with
341  {
342  ibest = hitlistb.size();
343  std::vector<int> vtmp;
344  hitlistb.push_back(vtmp);
345  }
346  hitlistb[ibest].push_back(ihit);
347  trackb[ihit] = ibest;
348  }
349 
350  // make a list of tracks that is the set of disjoint subsets
351 
352  for (size_t itrack=0; itrack<hitlistf.size(); ++itrack)
353  {
354  int itrackl = 0;
355  for (size_t ihit=0; ihit<hitlistf[itrack].size(); ++ihit)
356  {
357  int ihif = hitlistf[itrack][ihit];
358  if (ihit == 0 || (trackb[ihif] != itrackl))
359  {
360  std::vector<int> vtmp;
361  hitlist.push_back(vtmp);
362  itrackl = trackb[ihif];
363  }
364  hitlist.back().push_back(ihif);
365  }
366  }
367 
368  }
369 
370  // second try at a patrec algorithm -- find "vector hits"
371  // start with hits sorted in x. At least that limits how far through the list we must search
372  // make a vector of vector hits, and then piece them together to form track candidates.
373 
374  else if (fPatRecAlg == 2)
375  {
376  std::vector<vechit_t> vechits;
377  std::vector<vechit_t> vhtmp;
378 
379  for (size_t ihit=0; ihit<hits.size(); ++ihit)
380  {
381  const float *hpos = hits[hsi[ihit]].Position();
382  TVector3 hpvec(hpos);
383  if ( ((hpos - tpccent).Cross(xhat)).Mag() > fHitRCut ) continue; // skip hits if they are too far away from center as the
384  // last few pad rows may have distorted hits
385 
386  bool matched=false;
387  for (size_t ivh=0; ivh<vhtmp.size(); ++ivh)
388  {
389  //std::cout << "testing hit: " << ihit << " with vector hit " << ivh << std::endl;
390  if (vh_hitmatch(hpvec, ihit, vhtmp[ivh], hits, hsi )) // updates vechit with this hit if matched
391  {
392  matched = true;
393  break;
394  }
395  }
396  if (!matched) // make a new vechit if we haven't found one yet
397  {
398  vechit_t vh;
399  vh.pos.SetXYZ(hpos[0],hpos[1],hpos[2]);
400  vh.dir.SetXYZ(0,0,0); // new vechit with just one hit; don't know the direction yet
401  vh.hitindex.push_back(ihit);
402  vhtmp.push_back(vh);
403  //std::cout << "Created a new vector hit with one hit: " << hpos[0] << " " << hpos[1] << " " << hpos[2] << std::endl;
404  }
405  }
406 
407  // trim the list of vechits down to only those with more than two hits
408 
409  for (size_t ivh=0; ivh<vhtmp.size(); ++ivh)
410  {
411  if (vhtmp[ivh].hitindex.size() >= (size_t)fVecHitMinHits)
412  {
413  vechits.push_back(vhtmp[ivh]);
414  }
415  }
416 
417  // stitch together vector hits into tracks
418  // question -- do we need to iterate this, first looking for small-angle matches, and then
419  // loosening up? Also need to address tracks that get stitched across the primary vertex -- may need to split
420  // these after other tracks have been found.
421 
422  std::vector< std::vector< vechit_t > > vhclusters;
423 
424  for (size_t ivh = 0; ivh< vechits.size(); ++ ivh)
425  {
426  //std::cout << " vhprint " << vechits[ivh].pos.X() << " " << vechits[ivh].pos.Y() << " " << vechits[ivh].pos.Z() << " " <<
427  //vechits[ivh].dir.X() << " " << vechits[ivh].dir.Y() << " " << vechits[ivh].dir.Z() << " " << vechits[ivh].hitindex.size() << std::endl;
428 
429  std::vector<size_t> clusmatchlist;
430  for (size_t iclus=0; iclus<vhclusters.size(); ++iclus)
431  {
432  if (vhclusmatch(vhclusters[iclus],vechits[ivh]))
433  {
434  clusmatchlist.push_back(iclus);
435  }
436  }
437  if (clusmatchlist.size() == 0)
438  {
439  std::vector<vechit_t> newclus;
440  newclus.push_back(vechits[ivh]);
441  vhclusters.push_back(newclus);
442  }
443  else if (clusmatchlist.size() == 1)
444  {
445  vhclusters[clusmatchlist[0]].push_back(vechits[ivh]);
446  }
447  else // multiple matches -- merge clusters togetehr
448  {
449  for (size_t icm=1; icm<clusmatchlist.size(); ++icm)
450  {
451  for (size_t ivh=0; ivh<vhclusters[clusmatchlist[icm]].size(); ++ivh)
452  {
453  vhclusters[clusmatchlist[0]].push_back(vhclusters[clusmatchlist[icm]][ivh]);
454  }
455  }
456  // remove the merged vh clusters, using the new indexes after removing earlier ones
457  for (size_t icm=1; icm<clusmatchlist.size(); ++icm)
458  {
459  vhclusters.erase(vhclusters.begin() + (clusmatchlist[icm]-icm+1));
460  }
461  }
462  }
463 
464 
465  // populate the hit list with hits from the vector hits in clusters.
466 
467  for (size_t iclus=0; iclus < vhclusters.size(); ++iclus)
468  {
469  std::vector<int> vtmp;
470  hitlist.push_back(vtmp);
471  for (size_t ivh=0; ivh < vhclusters[iclus].size(); ++ ivh)
472  {
473  for (size_t ihit=0; ihit < vhclusters[iclus][ivh].hitindex.size(); ++ihit)
474  {
475  hitlist.back().push_back(vhclusters[iclus][ivh].hitindex[ihit]);
476  //std::cout << "Added a hit " << hitlist.back().size() << " to track: " << iclus << std::endl;
477  }
478  }
479  // re-sort the hitlist in x
480 
481  std::sort(hitlist[iclus].begin(), hitlist[iclus].end(),
482  [&hsi](int a, int b ) { return (hsi[a] > hsi[b]);});
483  }
484  }
485 
486  else
487  {
488  throw cet::exception("tracker1_module.cc: ununderstood PatRecAlg: ") << fPatRecAlg;
489  }
490 
491  size_t ntracks = hitlist.size();
492 
493  // do a first pass of fitting the tracks
494 
495  std::vector<TrackPar> firstpass_tracks;
496  std::vector<int> firstpass_tid;
497  std::vector<TrackPar> secondpass_tracks;
498  std::vector<int> secondpass_tid;
499 
500  if (fDumpTracks > 0)
501  {
502  int ntracktmp = 0;
503  for (size_t itrack=0;itrack<ntracks;++itrack)
504  {
505  if (hitlist[itrack].size() >= fMinNumHits) ntracktmp++;
506  }
507  std::cout << "Trkdump: " << ntracktmp << std::endl;
508  }
509 
510  std::vector<int> whichtrack(hits.size(),-1);
511 
512  for (size_t itrack=0; itrack<ntracks; ++itrack)
513  {
514  size_t nhits = hitlist[itrack].size();
515  if ( nhits >= fMinNumHits)
516  {
517  for (size_t ihit=0; ihit<nhits; ++ihit)
518  {
519  whichtrack[hitlist[itrack][ihit]] = itrack; // fill this here so we only get the ones passing the nhits cut
520  }
521 
522  if (fPrintLevel)
523  {
524  std::cout << "Starting a new Pass1 track: " << itrack << " Number of hits: " << nhits << std::endl;
525  }
526 
527  TrackPar trackparams;
528  std::set<int> unused_hits;
529 
530  int retcode=0;
531  if (fFirstPassFitType == "helix")
532  {
533  retcode = FitHelix(hitHandle,hitlist,hsi,itrack,true,unused_hits,trackparams);
534  }
535  else if (fFirstPassFitType == "Kalman")
536  {
537  retcode = KalmanFitBothWays(hitHandle,hitlist,hsi,itrack,unused_hits,trackparams);
538  }
539  else
540  {
541  throw cet::exception("Tracker1") << "Invalid first-pass fit type: " << fFirstPassFitType;
542  }
543  if (retcode != 0) continue;
544 
545  firstpass_tracks.push_back(trackparams);
546  firstpass_tid.push_back(itrack);
547 
548  if (fDumpTracks > 0)
549  {
550  std::cout << "Trkdump: " << itrack << std::endl;
551  std::cout << "Trkdump: " << trackparams.getTrackParametersBegin()[5] << std::endl;
552  for (int i=0; i<5;++i) std::cout << "Trkdump: " << trackparams.getTrackParametersBegin()[i] << std::endl;
553  std::cout << "Trkdump: " << trackparams.getTrackParametersEnd()[5] << std::endl;
554  for (int i=0; i<5;++i) std::cout << "Trkdump: " << trackparams.getTrackParametersEnd()[i] << std::endl;
555  std::cout << "Trkdump: " << nhits << std::endl;
556  for (size_t ihit=0;ihit<nhits;++ihit)
557  {
558  std::cout << "Trkdump: " << hits[hsi[hitlist[itrack][ihit]]].Position()[0] << std::endl;
559  std::cout << "Trkdump: " << hits[hsi[hitlist[itrack][ihit]]].Position()[1] << std::endl;
560  std::cout << "Trkdump: " << hits[hsi[hitlist[itrack][ihit]]].Position()[2] << std::endl;
561  }
562  }
563  }
564  }
565 
566  // Rearrange the hit lists -- ask ourselves which track each hit is best assigned to. Make a new hit list, hitlist2
567  // start only with hits that were assigned to tracks in pass1 (i.e. don't try to add new hits that made short, faraway tracks)
568  // todo -- change this last requirement to an absolute distance cut. Debug the track parameter extrapolation first.
569 
570  std::vector< std::vector<int> > hitlist2(firstpass_tracks.size());
571  if (firstpass_tracks.size() > 0 && fTrackPass > 1)
572  {
573  for (size_t ihit=0; ihit< hits.size(); ++ihit)
574  {
575  if (whichtrack[ihit] < 0) continue;
576  const float *hpos = hits[hsi[ihit]].Position();
577  float mindist = 0;
578  size_t ibest = 0;
579  for (size_t itrack=0; itrack<firstpass_tracks.size(); ++itrack)
580  {
581  float dist = firstpass_tracks[itrack].DistXYZ(hpos);
582  if (itrack == 0 || dist < mindist)
583  {
584  mindist = dist;
585  ibest = itrack;
586  }
587  }
588  hitlist2[ibest].push_back(ihit);
589  }
590 
591  size_t ntracks2 = hitlist2.size();
592  for (size_t itrack=0; itrack<ntracks2; ++itrack)
593  {
594  size_t nhits = hitlist2[itrack].size();
595  if ( nhits >= fMinNumHits)
596  {
597  if (fPrintLevel)
598  {
599  std::cout << "Starting a new Pass2 track: " << itrack << " Number of hits: " << nhits << std::endl;
600  }
601 
602  TrackPar trackparams;
603  std::set<int> unused_hits;
604 
605  int retcode=0;
606  if (fFirstPassFitType == "helix")
607  {
608  retcode = FitHelix(hitHandle,hitlist2,hsi,itrack,true,unused_hits,trackparams);
609  }
610  else if (fFirstPassFitType == "Kalman")
611  {
612  retcode = KalmanFitBothWays(hitHandle,hitlist2,hsi,itrack,unused_hits,trackparams);
613  }
614  else
615  {
616  throw cet::exception("Tracker1") << "Invalid first-pass fit type: " << fFirstPassFitType;
617  }
618  if (retcode != 0) continue;
619 
620  secondpass_tracks.push_back(trackparams);
621  secondpass_tid.push_back(itrack);
622  }
623  }
624  }
625  // Remove stray hits. Dig through unassociated hits and try to make extra tracks out of them.
626  // May need to wait until vertex finding is done so we know where to concentrate the effort
627 
628  // currently -- put second-pass tracks and associations with hits in the event
629 
630  if (fTrackPass == 1)
631  {
632  for (size_t itrack=0; itrack<firstpass_tracks.size(); ++itrack)
633  {
634  trkCol->push_back(firstpass_tracks[itrack].CreateTrack());
635  auto const trackpointer = trackPtrMaker(itrack);
636  for (size_t ihit=0; ihit<hitlist[firstpass_tid[itrack]].size(); ++ ihit)
637  {
638  auto const hitpointer = hitPtrMaker(hsi[hitlist[firstpass_tid[itrack]][ihit]]);
639  hitTrkAssns->addSingle(hitpointer,trackpointer);
640  }
641  }
642  }
643  else if (fTrackPass == 2)
644  {
645  for (size_t itrack=0; itrack<secondpass_tracks.size(); ++itrack)
646  {
647  trkCol->push_back(secondpass_tracks[itrack].CreateTrack());
648  auto const trackpointer = trackPtrMaker(itrack);
649  for (size_t ihit=0; ihit<hitlist2[secondpass_tid[itrack]].size(); ++ ihit)
650  {
651  auto const hitpointer = hitPtrMaker(hsi[hitlist2[secondpass_tid[itrack]][ihit]]);
652  hitTrkAssns->addSingle(hitpointer,trackpointer);
653  }
654  }
655  }
656  else
657  {
658  throw cet::exception("Tracker1") << "Invalid track pass number requested: " << fTrackPass;
659  }
660 
661  e.put(std::move(trkCol));
662  e.put(std::move(hitTrkAssns));
663  }
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
size_t fPatRecLookBack1
n hits to look backwards to make a linear extrapolation
int ntracks
Definition: tracks.py:246
bool vh_hitmatch(TVector3 &hpvec, int ihit, vechit_t &vechit, const std::vector< gar::rec::Hit > &hits, std::vector< int > &hsi)
int fPrintLevel
debug printout: 0: none, 1: just track parameters and residuals, 2: all
unsigned int fMinNumHits
minimum number of hits to define a track
std::string fFirstPassFitType
helix or Kalman – which fitter to call for first-pass tracks
float fHitRCut
only take hits within rcut of the center of the detector
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
int fTrackPass
which pass of the tracking to save as the tracks in the event
const double e
const double a
def move(depos, offset)
Definition: depos.py:107
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
bool vhclusmatch(std::vector< vechit_t > &cluster, vechit_t &vh)
unsigned int fVecHitMinHits
minimum number of hits on a vector hit for it to be considered
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
int fDumpTracks
0: do not print out tracks, 1: print out tracks
float fSigmaRoad
how many sigma away from a track a hit can be and still add it during patrec
static bool * b
Definition: config.cpp:1043
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
int FitHelix(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, bool isForwards, std::set< int > &unused_hits, TrackPar &trackpar)
int KalmanFitBothWays(art::ValidHandle< std::vector< Hit > > &hitHandle, std::vector< std::vector< int > > &hitlist, std::vector< int > &hsi, int itrack, std::set< int > &unused_hits, TrackPar &trackpar)
size_t fPatRecAlg
1: x-sorted patrec. 2: vector-hit patrec
LArSoft geometry interface.
Definition: ChannelGeo.h:16
float fHitResolYZ
resolution in cm of a hit in YZ (pad size)
std::string fHitLabel
label of module creating hits
size_t fPatRecLookBack2
extrapolate from lookback1 to lookback2 and see how close the new hit is to the line ...
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
bool gar::rec::tracker1::vh_hitmatch ( TVector3 &  hpvec,
int  ihit,
tracker1::vechit_t vechit,
const std::vector< gar::rec::Hit > &  hits,
std::vector< int > &  hsi 
)
private

Definition at line 1590 of file tracker1_module.cc.

1591  {
1592  bool retval = false;
1593 
1594  float dist = 1E6;
1595  for (size_t iht=0; iht<vechit.hitindex.size(); ++iht)
1596  {
1597  TVector3 ht(hits[hsi[vechit.hitindex[iht]]].Position());
1598  float d = (hpvec - ht).Mag();
1599  if (d>fMaxVecHitLen) return retval;
1600  dist = TMath::Min(dist,d);
1601  }
1602 
1603  if (vechit.hitindex.size() > 1)
1604  {
1605  dist = ((hpvec - vechit.pos).Cross(vechit.dir)).Mag();
1606  //std::cout << " Distance cross comparison: " << dist << std::endl;
1607  }
1608 
1609  if (dist < fVecHitRoad) // add hit to vector hit if we have a match
1610  {
1611  //std::cout << "matched a hit to a vh" << std::endl;
1612  std::vector<TVector3> hplist;
1613  for (size_t i=0; i< vechit.hitindex.size(); ++i)
1614  {
1615  hplist.emplace_back(hits[hsi[vechit.hitindex[i]]].Position());
1616  }
1617  hplist.push_back(hpvec);
1618  fitlinesdir(hplist,vechit.pos,vechit.dir);
1619  vechit.hitindex.push_back(ihit);
1620  //std::cout << "vechit now has " << hplist.size() << " hits" << std::endl;
1621  //std::cout << vechit.pos.X() << " " << vechit.pos.Y() << " " << vechit.pos.Z() << std::endl;
1622  //std::cout << vechit.dir.X() << " " << vechit.dir.Y() << " " << vechit.dir.Z() << std::endl;
1623  retval = true;
1624  }
1625  return retval;
1626  }
void fitlinesdir(std::vector< TVector3 > &hlist, TVector3 &pos, TVector3 &dir)
float fVecHitRoad
max dist from a vector hit to a hit to assign it. for patrec alg 2. in cm.
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
float fMaxVecHitLen
maximum vector hit length in patrec alg 2, in cm
bool gar::rec::tracker1::vhclusmatch ( std::vector< vechit_t > &  cluster,
vechit_t vh 
)
private

Definition at line 1742 of file tracker1_module.cc.

1743  {
1744  for (size_t ivh=0; ivh<cluster.size(); ++ivh)
1745  {
1746  //std::cout << "Testing vh " << ivh << " in a cluster of size: " << cluster.size() << std::endl;
1747 
1748  // require the two VH's directions to point along each other -- use dot product
1749 
1750  if (TMath::Abs((vh.dir).Dot(cluster[ivh].dir)) < fVecHitMatchCos)
1751  {
1752  // std::cout << " Dot failure: " << TMath::Abs((vh.dir).Dot(cluster[ivh].dir)) << std::endl;
1753  continue;
1754  }
1755 
1756  // require the positions to be within fVecHitMatchPos of each other
1757 
1758  if ((vh.pos-cluster[ivh].pos).Mag() > fVecHitMatchPos)
1759  {
1760  //std::cout << " Pos failure: " << (vh.pos-cluster[ivh].pos).Mag() << std::endl;
1761  continue;
1762  }
1763 
1764  // require the extrapolation of one VH's line to another VH's center to match up. Do for
1765  // both VH's.
1766 
1767  if ( ((vh.pos-cluster[ivh].pos).Cross(vh.dir)).Mag() > fVecHitMatchPEX )
1768  {
1769  //std::cout << "PEX failure: " << ((vh.pos-cluster[ivh].pos).Cross(vh.dir)).Mag() << std::endl;
1770  continue;
1771  }
1772  if ( ((vh.pos-cluster[ivh].pos).Cross(cluster[ivh].dir)).Mag() > fVecHitMatchPEX )
1773  {
1774  //std::cout << "PEX failure: " << ((vh.pos-cluster[ivh].pos).Cross(cluster[ivh].dir)).Mag() << std::endl;
1775  continue;
1776  }
1777 
1778  //--------------------------
1779  // compute a 2D eta
1780 
1781  // normalized direction vector for the VH under test, just the components
1782  // perpendicular to X
1783 
1784  TVector3 vhdp(vh.dir);
1785  vhdp.SetX(0);
1786  float norm = vhdp.Mag();
1787  if (norm > 0) vhdp *= (1.0/norm);
1788 
1789  // same for the VH in the cluster under test
1790 
1791  TVector3 vhcp(cluster[ivh].dir);
1792  vhcp.SetX(0);
1793  norm = vhcp.Mag();
1794  if (norm > 0) vhcp *= (1.0/norm);
1795 
1796  float relsign = 1.0;
1797  if (vhdp.Dot(vhcp) < 0) relsign = -1;
1798 
1799  TVector3 dcent = vh.pos-cluster[ivh].pos;
1800  dcent.SetX(0);
1801 
1802  TVector3 avgdir1 = 0.5*(vhdp + relsign*vhcp);
1803  float amag = avgdir1.Mag();
1804  if (amag != 0) avgdir1 *= 1.0/amag;
1805  float eta = (dcent.Cross(avgdir1)).Mag();
1806 
1807  if ( eta > fVecHitMatchEta )
1808  {
1809  //std::cout << "Eta failure: " << eta1 << " " << eta2 << std::endl;
1810  continue;
1811  }
1812 
1813  //----------------
1814  // lambda requirement
1815 
1816  float vhpd = TMath::Sqrt( TMath::Sq(vh.dir.Y()) + TMath::Sq(vh.dir.Z()) );
1817  float vhxd = TMath::Abs( vh.dir.X() );
1818  float vhlambda = TMath::Pi()/2.0;
1819  if (vhpd >0) vhlambda = TMath::ATan(vhxd/vhpd);
1820 
1821  float cvhpd = TMath::Sqrt( TMath::Sq(cluster[ivh].dir.Y()) + TMath::Sq(cluster[ivh].dir.Z()) );
1822  float cvhxd = TMath::Abs( cluster[ivh].dir.X() );
1823  float cvhlambda = TMath::Pi()/2.0;
1824  if (cvhpd >0) cvhlambda = TMath::ATan(cvhxd/cvhpd);
1825 
1826  if ( TMath::Abs(vhlambda - cvhlambda) > fVecHitMatchLambda )
1827  {
1828  //std::cout << "dlambda failure: " << vhlambda << " " << cvhlambda << std::endl;
1829  continue;
1830  }
1831 
1832  if ( vh.dir.Dot(cluster[ivh].dir) * vh.dir.X() * cluster[ivh].dir.X() < 0 &&
1833  TMath::Abs(vh.dir.X()) > 0.01 && TMath::Abs(cluster[ivh].dir.X()) > 0.01)
1834  {
1835  //std::cout << "lambda sign failure" << std::endl;
1836  continue;
1837  }
1838 
1839  //std::cout << " vh cluster match " << std::endl;
1840  return true;
1841  }
1842  return false;
1843  }
float fVecHitMatchPos
matching condition for pairs of vector hits – 3D distance (cm)
float fVecHitMatchPEX
matching condition for pairs of vector hits – miss distance (cm)
string dir
float fVecHitMatchCos
matching condition for pairs of vector hits cos angle between directions
auto norm(Vector const &v)
Return norm of the specified vector.
float fVecHitMatchLambda
matching condition for pairs of vector hits – dLambda (radians)
float fVecHitMatchEta
matching condition for pairs of vector hits – eta match (cm)

Member Data Documentation

int gar::rec::tracker1::fDumpTracks
private

0: do not print out tracks, 1: print out tracks

Definition at line 91 of file tracker1_module.cc.

std::string gar::rec::tracker1::fFirstPassFitType
private

helix or Kalman – which fitter to call for first-pass tracks

Definition at line 98 of file tracker1_module.cc.

std::string gar::rec::tracker1::fHitLabel
private

label of module creating hits

Definition at line 88 of file tracker1_module.cc.

float gar::rec::tracker1::fHitRCut
private

only take hits within rcut of the center of the detector

Definition at line 64 of file tracker1_module.cc.

float gar::rec::tracker1::fHitResolX
private

resolution in cm of a hit in X (drift direction)

Definition at line 69 of file tracker1_module.cc.

float gar::rec::tracker1::fHitResolYZ
private

resolution in cm of a hit in YZ (pad size)

Definition at line 68 of file tracker1_module.cc.

float gar::rec::tracker1::fHitResolYZinFit
private

Hit resolution parameter to use in fit.

Definition at line 95 of file tracker1_module.cc.

unsigned int gar::rec::tracker1::fInitialTPNHits
private

number of hits to use for initial trackpar estimate, if present

Definition at line 87 of file tracker1_module.cc.

float gar::rec::tracker1::fKalCurvStepUncSq
private

constant uncertainty term on each step of the Kalman fit – squared, for curvature

Definition at line 81 of file tracker1_module.cc.

float gar::rec::tracker1::fKalLambdaStepUncSq
private

constant uncertainty term on each step of the Kalman fit – squared, for lambda

Definition at line 83 of file tracker1_module.cc.

float gar::rec::tracker1::fKalPhiStepUncSq
private

constant uncertainty term on each step of the Kalman fit – squared, for phi

Definition at line 82 of file tracker1_module.cc.

float gar::rec::tracker1::fMaxVecHitLen
private

maximum vector hit length in patrec alg 2, in cm

Definition at line 72 of file tracker1_module.cc.

unsigned int gar::rec::tracker1::fMinNumHits
private

minimum number of hits to define a track

Definition at line 86 of file tracker1_module.cc.

size_t gar::rec::tracker1::fPatRecAlg
private

1: x-sorted patrec. 2: vector-hit patrec

Definition at line 65 of file tracker1_module.cc.

size_t gar::rec::tracker1::fPatRecLookBack1
private

n hits to look backwards to make a linear extrapolation

Definition at line 66 of file tracker1_module.cc.

size_t gar::rec::tracker1::fPatRecLookBack2
private

extrapolate from lookback1 to lookback2 and see how close the new hit is to the line

Definition at line 67 of file tracker1_module.cc.

int gar::rec::tracker1::fPrintLevel
private

debug printout: 0: none, 1: just track parameters and residuals, 2: all

Definition at line 89 of file tracker1_module.cc.

float gar::rec::tracker1::fRoadYZinFit
private

cut in cm for dropping hits from tracks in fit

Definition at line 96 of file tracker1_module.cc.

std::string gar::rec::tracker1::fSecondPassFitType
private

helix or Kalman – which fitter to call for second-pass tracks

Definition at line 99 of file tracker1_module.cc.

float gar::rec::tracker1::fSigmaRoad
private

how many sigma away from a track a hit can be and still add it during patrec

Definition at line 70 of file tracker1_module.cc.

std::string gar::rec::tracker1::fSortOrder
private

switch to tell what way to sort hits before presenting them to the fitter

Definition at line 93 of file tracker1_module.cc.

int gar::rec::tracker1::fTrackPass
private

which pass of the tracking to save as the tracks in the event

Definition at line 90 of file tracker1_module.cc.

float gar::rec::tracker1::fVecHitMatchCos
private

matching condition for pairs of vector hits cos angle between directions

Definition at line 74 of file tracker1_module.cc.

float gar::rec::tracker1::fVecHitMatchEta
private

matching condition for pairs of vector hits – eta match (cm)

Definition at line 77 of file tracker1_module.cc.

float gar::rec::tracker1::fVecHitMatchLambda
private

matching condition for pairs of vector hits – dLambda (radians)

Definition at line 78 of file tracker1_module.cc.

float gar::rec::tracker1::fVecHitMatchPEX
private

matching condition for pairs of vector hits – miss distance (cm)

Definition at line 76 of file tracker1_module.cc.

float gar::rec::tracker1::fVecHitMatchPos
private

matching condition for pairs of vector hits – 3D distance (cm)

Definition at line 75 of file tracker1_module.cc.

unsigned int gar::rec::tracker1::fVecHitMinHits
private

minimum number of hits on a vector hit for it to be considered

Definition at line 79 of file tracker1_module.cc.

float gar::rec::tracker1::fVecHitRoad
private

max dist from a vector hit to a hit to assign it. for patrec alg 2. in cm.

Definition at line 73 of file tracker1_module.cc.


The documentation for this class was generated from the following file: