LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
trkf::CCTrackMaker Class Reference
Inheritance diagram for trkf::CCTrackMaker:
art::EDProducer art::ProducerBase art::Consumer art::EngineCreator art::ProductRegistryHelper

Classes

struct  clPar
 
struct  ClsChainPar
 
struct  MatchPars
 
struct  TrkPar
 
struct  vtxPar
 

Public Types

using ModuleType = EDProducer
 
using WorkerType = WorkerT< EDProducer >
 
template<typename UserConfig , typename KeysToIgnore = void>
using Table = ProducerBase::Table< UserConfig, KeysToIgnore >
 

Public Member Functions

 CCTrackMaker (fhicl::ParameterSet const &pset)
 
virtual ~CCTrackMaker ()
 
void reconfigure (fhicl::ParameterSet const &p)
 
void produce (art::Event &evt)
 
void beginJob ()
 
template<typename PROD , BranchType B = InEvent>
ProductID getProductID (std::string const &instanceName={}) const
 
template<typename PROD , BranchType B>
ProductID getProductID (ModuleDescription const &moduleDescription, std::string const &instanceName) const
 
bool modifiesEvent () const
 
template<typename T , BranchType = InEvent>
ProductToken< T > consumes (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ProductToken< T > consumes (InputTag const &it)
 
template<typename T , BranchType = InEvent>
void consumesMany ()
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > consumesView (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ViewToken< T > consumesView (InputTag const &it)
 
template<typename T , BranchType = InEvent>
ProductToken< T > mayConsume (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ProductToken< T > mayConsume (InputTag const &it)
 
template<typename T , BranchType = InEvent>
void mayConsumeMany ()
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > mayConsumeView (InputTag const &)
 
template<typename T , art::BranchType BT>
art::ViewToken< T > mayConsumeView (InputTag const &it)
 
base_engine_tcreateEngine (seed_t seed)
 
base_engine_tcreateEngine (seed_t seed, std::string const &kind_of_engine_to_make)
 
base_engine_tcreateEngine (seed_t seed, std::string const &kind_of_engine_to_make, label_t const &engine_label)
 
seed_t get_seed_value (fhicl::ParameterSet const &pset, char const key[]="seed", seed_t const implicit_seed=-1)
 

Static Public Member Functions

static cet::exempt_ptr< Consumernon_module_context ()
 

Protected Member Functions

CurrentProcessingContext const * currentContext () const
 
void validateConsumedProduct (BranchType const bt, ProductInfo const &pi)
 
void prepareForJob (fhicl::ParameterSet const &pset)
 
void showMissingConsumes () const
 

Private Member Functions

void PrintClusters () const
 
void PrintTracks () const
 
void MakeClusterChains (art::FindManyP< recob::Hit > const &fmCluHits)
 
float dXClTraj (art::FindManyP< recob::Hit > const &fmCluHits, unsigned short ipl, unsigned short icl1, unsigned short end1, unsigned short icl2)
 
void FillChgNear ()
 
void FillWireHitRange ()
 
void FindMaybeVertices ()
 
void VtxMatch (art::FindManyP< recob::Hit > const &fmCluHits)
 
void PlnMatch (art::FindManyP< recob::Hit > const &fmCluHits)
 
void AngMatch (art::FindManyP< recob::Hit > const &fmCluHits)
 
void MakeFamily ()
 
void TagCosmics ()
 
void FitVertices ()
 
void FillEndMatch (MatchPars &match)
 
void FillEndMatch2 (MatchPars &match)
 
float ChargeAsym (std::array< float, 3 > &mChg)
 
void FindMidPointMatch (art::FindManyP< recob::Hit > const &fmCluHits, MatchPars &match, unsigned short kkpl, unsigned short kkcl, unsigned short kkend, float &kkWir, float &kkX)
 
bool FindMissingCluster (unsigned short kpl, short &kcl, unsigned short &kend, float kWir, float kX, float okWir, float okX)
 
bool DupMatch (MatchPars &match)
 
void SortMatches (art::FindManyP< recob::Hit > const &fmCluHits, unsigned short procCode)
 
void FillTrkHits (art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat)
 
void StoreTrack (art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat, unsigned short procCode)
 
float ChargeNear (unsigned short ipl, unsigned short wire1, float time1, unsigned short wire2, float time2)
 
float AngleFactor (float slope)
 

Private Attributes

std::string fHitModuleLabel
 
std::string fClusterModuleLabel
 
std::string fVertexModuleLabel
 
art::ServiceHandle< geo::Geometrygeom
 
const detinfo::DetectorPropertiesdetprop
 
TrackTrajectoryAlg fTrackTrajectoryAlg
 
VertexFitAlg fVertexFitAlg
 
unsigned short algIndex
 
std::vector< short > fMatchAlgs
 
std::vector< float > fXMatchErr
 
std::vector< float > fAngleMatchErr
 
std::vector< float > fChgAsymFactor
 
std::vector< float > fMatchMinLen
 
std::vector< bool > fMakeAlgTracks
 
float fMaxDAng
 
float fChainMaxdX
 
float fChainVtxAng
 
float fMergeChgAsym
 
float fMaxMergeError
 
float fMergeErrorCut
 
float fChgWindow
 
float fWirePitch
 
float fFiducialCut
 
float fDeltaRayCut
 
bool fMakePFPs
 
unsigned short fNVtxTrkHitsFit
 
float fHitFitErrFac
 
bool fuBCode
 
short fDebugAlg
 
short fDebugPlane
 
short fDebugCluster
 
bool fPrintAllClusters
 
bool prt
 
unsigned short nplanes
 
unsigned int cstat
 
unsigned int tpc
 
std::array< unsigned int, 3 > firstWire
 
std::array< unsigned int, 3 > lastWire
 
std::array< unsigned int, 3 > firstHit
 
std::array< unsigned int, 3 > lastHit
 
std::array< std::vector< std::pair< int, int > >, 3 > WireHitRange
 
std::vector< art::Ptr< recob::Hit > > allhits
 
std::array< std::vector< clPar >, 3 > cls
 
std::array< std::vector< ClsChainPar >, 3 > clsChain
 
std::vector< vtxParvtx
 
std::array< std::vector< unsigned short >, 3 > vxCls
 
std::vector< TrkPartrk
 
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > trkHits
 
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > seedHits
 
std::array< float, 3 > ChgNorm
 
std::vector< unsigned short > pfpToTrkID
 
std::vector< MatchParsmatcomb
 

Detailed Description

Definition at line 62 of file CCTrackMaker_module.cc.

Member Typedef Documentation

using art::EDProducer::ModuleType = EDProducer
inherited

Definition at line 34 of file EDProducer.h.

template<typename UserConfig , typename KeysToIgnore = void>
using art::EDProducer::Table = ProducerBase::Table<UserConfig, KeysToIgnore>
inherited

Definition at line 43 of file EDProducer.h.

using art::EDProducer::WorkerType = WorkerT<EDProducer>
inherited

Definition at line 35 of file EDProducer.h.

Constructor & Destructor Documentation

trkf::CCTrackMaker::CCTrackMaker ( fhicl::ParameterSet const &  pset)
explicit

Definition at line 305 of file CCTrackMaker_module.cc.

306  {
307  this->reconfigure(pset);
308  produces< std::vector<recob::PFParticle> >();
309  produces< art::Assns<recob::PFParticle, recob::Track> >();
310  produces< art::Assns<recob::PFParticle, recob::Cluster> >();
311  produces< art::Assns<recob::PFParticle, recob::Seed> >();
312  produces< art::Assns<recob::PFParticle, recob::Vertex> >();
313  produces< std::vector<recob::Vertex> >();
314  produces< std::vector<recob::Track> >();
315  produces< art::Assns<recob::Track, recob::Hit> >();
316  produces<std::vector<recob::Seed> >();
317  //produces< art::Assns<recob::Seed, recob::Hit> >();
318  }
void reconfigure(fhicl::ParameterSet const &p)
trkf::CCTrackMaker::~CCTrackMaker ( )
virtual

Definition at line 372 of file CCTrackMaker_module.cc.

373  {
374  }

Member Function Documentation

float trkf::CCTrackMaker::AngleFactor ( float  slope)
private

Definition at line 3326 of file CCTrackMaker_module.cc.

3327  {
3328  float slp = fabs(slope);
3329  if(slp > 10.) slp = 30.;
3330  // return a value between 1 and 46
3331  return 1 + 0.05 * slp * slp;
3332  } // AngleFactor
void trkf::CCTrackMaker::AngMatch ( art::FindManyP< recob::Hit > const &  fmCluHits)
private
void trkf::CCTrackMaker::beginJob ( )
virtual

Reimplemented from art::EDProducer.

Definition at line 377 of file CCTrackMaker_module.cc.

378  {
379  }
float trkf::CCTrackMaker::ChargeAsym ( std::array< float, 3 > &  mChg)
private

Definition at line 3092 of file CCTrackMaker_module.cc.

3093  {
3094  // find charge asymmetry between the cluster with the highest (lowest)
3095  // charge
3096  float big = 0, small = 1.E9;
3097  for(unsigned short ii = 0; ii < 3; ++ii) {
3098  if(mChg[ii] < small) small = mChg[ii];
3099  if(mChg[ii] > big) big = mChg[ii];
3100  }
3101  // chgAsym varies between 0 (perfect charge match) and 1 (dreadfull)
3102  return (big - small) / (big + small);
3103  } // CalculateChargeAsym
float trkf::CCTrackMaker::ChargeNear ( unsigned short  ipl,
unsigned short  wire1,
float  time1,
unsigned short  wire2,
float  time2 
)
private

Definition at line 3335 of file CCTrackMaker_module.cc.

References t1, and t2.

3336  {
3337  // returns the hit charge along a line between (wire1, time1) and
3338  // (wire2, time2)
3339 
3340  // put in increasing wire order (wire2 > wire1)
3341  unsigned short w1 = wire1;
3342  unsigned short w2 = wire2;
3343  double t1 = time1;
3344  double t2 = time2;
3345  double slp, prtime;
3346  if(w1 == w2) {
3347  slp = 0;
3348  } else {
3349  if(w1 > w2) {
3350  w1 = wire2;
3351  w2 = wire1;
3352  t1 = time2;
3353  t2 = time1;
3354  }
3355  slp = (t2 - t1) / (w2 - w1);
3356  }
3357 
3358  unsigned short wire;
3359 
3360  float chg = 0;
3361  for(unsigned short hit = 0; hit < allhits.size(); ++hit) {
3362  if(allhits[hit]->WireID().Cryostat != cstat) continue;
3363  if(allhits[hit]->WireID().TPC != tpc) continue;
3364  if(allhits[hit]->WireID().Plane != ipl) continue;
3365  wire = allhits[hit]->WireID().Wire;
3366  if(wire < w1) continue;
3367  if(wire > w2) continue;
3368  prtime = t1 + (wire - w1) * slp;
3369  // std::cout<<"prtime "<<wire<<":"<<(int)prtime<<" hit "<<allhits[hit]->PeakTimeMinusRMS(3)<<" "<<allhits[hit]->PeakTimePlusRMS(3)<<"\n";
3370  if(prtime > allhits[hit]->PeakTimePlusRMS(3)) continue;
3371  if(prtime < allhits[hit]->PeakTimeMinusRMS(3)) continue;
3372  chg += ChgNorm[ipl] * allhits[hit]->Integral();
3373  } // hit
3374  return chg;
3375  } // ChargeNear
TTree * t1
Definition: plottest35.C:26
std::vector< art::Ptr< recob::Hit > > allhits
std::array< float, 3 > ChgNorm
Detector simulation of raw signals on wires.
TTree * t2
Definition: plottest35.C:36
template<typename T , BranchType = InEvent>
ProductToken<T> art::Consumer::consumes ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ProductToken<T> art::Consumer::consumes ( InputTag const &  it)
inherited

Definition at line 147 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

148 {
149  if (!moduleContext_)
150  return ProductToken<T>::invalid();
151 
152  consumables_[BT].emplace_back(ConsumableType::Product,
153  TypeID{typeid(T)},
154  it.label(),
155  it.instance(),
156  it.process());
157  return ProductToken<T>{it};
158 }
static ProductToken< T > invalid()
Definition: ProductToken.h:47
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename T , art::BranchType BT>
void art::Consumer::consumesMany ( )
inherited

Definition at line 162 of file Consumer.h.

163 {
164  if (!moduleContext_)
165  return;
166 
167  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
168 }
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename Element , BranchType = InEvent>
ViewToken<Element> art::Consumer::consumesView ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ViewToken<T> art::Consumer::consumesView ( InputTag const &  it)
inherited

Definition at line 172 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

173 {
174  if (!moduleContext_)
175  return ViewToken<T>::invalid();
176 
177  consumables_[BT].emplace_back(ConsumableType::ViewElement,
178  TypeID{typeid(T)},
179  it.label(),
180  it.instance(),
181  it.process());
182  return ViewToken<T>{it};
183 }
static ViewToken< Element > invalid()
Definition: ProductToken.h:75
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
EngineCreator::base_engine_t & EngineCreator::createEngine ( seed_t  seed,
std::string const &  kind_of_engine_to_make 
)
inherited

Definition at line 32 of file EngineCreator.cc.

References art::EngineCreator::rng().

34 {
35  return rng()->createEngine(
36  placeholder_schedule_id(), seed, kind_of_engine_to_make);
37 }
long seed
Definition: chem4.cc:68
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
EngineCreator::base_engine_t & EngineCreator::createEngine ( seed_t  seed,
std::string const &  kind_of_engine_to_make,
label_t const &  engine_label 
)
inherited

Definition at line 40 of file EngineCreator.cc.

References art::EngineCreator::rng().

43 {
44  return rng()->createEngine(
45  placeholder_schedule_id(), seed, kind_of_engine_to_make, engine_label);
46 }
long seed
Definition: chem4.cc:68
static art::ServiceHandle< art::RandomNumberGenerator > & rng()
CurrentProcessingContext const * art::EDProducer::currentContext ( ) const
protectedinherited

Definition at line 120 of file EDProducer.cc.

References art::EDProducer::current_context_.

121  {
122  return current_context_.get();
123  }
CPC_exempt_ptr current_context_
Definition: EDProducer.h:116
bool trkf::CCTrackMaker::DupMatch ( MatchPars match)
private

Definition at line 2328 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::MatchPars::Cls, trkf::CCTrackMaker::MatchPars::dAng, trkf::CCTrackMaker::MatchPars::dWir, trkf::CCTrackMaker::MatchPars::dX, trkf::CCTrackMaker::MatchPars::End, trkf::CCTrackMaker::MatchPars::Err, trkf::CCTrackMaker::MatchPars::odAng, trkf::CCTrackMaker::MatchPars::odWir, trkf::CCTrackMaker::MatchPars::odX, trkf::CCTrackMaker::MatchPars::oErr, trkf::CCTrackMaker::MatchPars::oVtx, and trkf::CCTrackMaker::MatchPars::Vtx.

2329  {
2330 
2331  unsigned short nMatCl, nMiss;
2332  float toterr = match.Err + match.oErr;
2333  for(unsigned int imat = 0; imat < matcomb.size(); ++imat) {
2334  // check for exact matches
2335  if(match.Cls[0] == matcomb[imat].Cls[0] &&
2336  match.Cls[1] == matcomb[imat].Cls[1] &&
2337  match.Cls[2] == matcomb[imat].Cls[2]) {
2338 
2339  // compare the error
2340  if(toterr < matcomb[imat].Err + matcomb[imat].oErr) {
2341  // keep the better one
2342  matcomb[imat].End[0] = match.End[0];
2343  matcomb[imat].End[1] = match.End[1];
2344  matcomb[imat].End[2] = match.End[2];
2345  matcomb[imat].Vtx = match.Vtx;
2346  matcomb[imat].dWir = match.dWir;
2347  matcomb[imat].dAng = match.dAng;
2348  matcomb[imat].dX = match.dX;
2349  matcomb[imat].Err = match.Err;
2350  matcomb[imat].oVtx = match.oVtx;
2351  matcomb[imat].odWir = match.odWir;
2352  matcomb[imat].odAng = match.odAng;
2353  matcomb[imat].odX = match.odX;
2354  matcomb[imat].oErr = match.oErr;
2355  }
2356  return true;
2357  } // test
2358  // check for a 3-plane match vs 2-plane match
2359  nMatCl = 0;
2360  nMiss = 0;
2361  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
2362  if(match.Cls[ipl] >= 0) {
2363  if(match.Cls[ipl] == matcomb[imat].Cls[ipl] && (match.End[0] == matcomb[imat].End[0] || match.End[1] == matcomb[imat].End[1])) ++nMatCl;
2364  } else {
2365  ++nMiss;
2366  }
2367  } // ipl
2368  if(nMatCl == 2 && nMiss == 1) return true;
2369  } // imat
2370  return false;
2371  } // DupMatch
std::vector< MatchPars > matcomb
float trkf::CCTrackMaker::dXClTraj ( art::FindManyP< recob::Hit > const &  fmCluHits,
unsigned short  ipl,
unsigned short  icl1,
unsigned short  end1,
unsigned short  icl2 
)
private

Definition at line 1861 of file CCTrackMaker_module.cc.

1862  {
1863  // project cluster icl1 at end1 to find the best intersection with icl2
1864  float dw, dx, best = 999;
1865  std::vector<art::Ptr<recob::Hit>> clusterhits = fmCluHits.at(cls[ipl][icl1].EvtIndex);
1866  for(unsigned short hit = 0; hit < clusterhits.size(); ++hit) {
1867  dw = clusterhits[hit]->WireID().Wire - cls[ipl][icl1].Wire[end1];
1868  dx = fabs(cls[ipl][icl1].Time[end1] + dw * fWirePitch * cls[ipl][icl1].Slope[end1] - clusterhits[hit]->PeakTime());
1869  if(dx < best) best = dx;
1870  if(dx < 0.01) break;
1871  } // hit
1872  return best;
1873  } // dXClTraj
std::array< std::vector< clPar >, 3 > cls
Detector simulation of raw signals on wires.
void trkf::CCTrackMaker::FillChgNear ( )
private

Definition at line 951 of file CCTrackMaker_module.cc.

References dir, evd::details::end(), and w.

952  {
953  // fills the CHgNear array
954 
955  unsigned short wire, nwires, indx;
956  float dir, ctime, cx, chgWinLo, chgWinHi;
957  float cnear;
958 
959  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
960  for(unsigned short icl = 0; icl < cls[ipl].size(); ++icl) {
961  // find the nearby charge at the US and DS ends
962  nwires = cls[ipl][icl].Length / 2;
963  if(nwires < 2) continue;
964  // maximum of 30 wires for long clusters
965  if(nwires > 30) nwires = 30;
966  for(unsigned short end = 0; end < 2; ++end) {
967  cnear = 0;
968  // direction for adding/subtracting wire numbers
969  dir = 1 - 2 * end;
970  for(unsigned short w = 0; w < nwires; ++w) {
971  wire = cls[ipl][icl].Wire[end] + dir * w;
972  cx = cls[ipl][icl].X[end] + dir * w * cls[ipl][icl].Slope[end] * fWirePitch;
973  ctime = detprop->ConvertXToTicks(cx, ipl, tpc, cstat);
974  chgWinLo = ctime - fChgWindow;
975  chgWinHi = ctime + fChgWindow;
976  indx = wire - firstWire[ipl];
977  if(WireHitRange[ipl][indx].first < 0) continue;
978  unsigned int firhit = WireHitRange[ipl][indx].first;
979  unsigned int lashit = WireHitRange[ipl][indx].second;
980  for(unsigned int hit = firhit; hit < lashit; ++hit) {
981  if(hit > allhits.size() - 1) {
982  mf::LogError("CCTM")<<"FillChgNear bad lashit "<<lashit<<" size "<<allhits.size()<<"\n";
983  continue;
984  }
985  if(allhits[hit]->PeakTime() < chgWinLo) continue;
986  if(allhits[hit]->PeakTime() > chgWinHi) continue;
987  cnear += allhits[hit]->Integral();
988  } // hit
989  } // w
990  cnear /= (float)(nwires-1);
991  if(cnear > cls[ipl][icl].Charge[end]) {
992  cls[ipl][icl].ChgNear[end] = ChgNorm[ipl] * cnear / cls[ipl][icl].Charge[end];
993  } else {
994  cls[ipl][icl].ChgNear[end] = 0;
995  }
996  } // end
997  } // icl
998  } //ipl
999 
1000  } // FillChgNear
std::array< unsigned int, 3 > firstWire
std::vector< art::Ptr< recob::Hit > > allhits
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::array< float, 3 > ChgNorm
std::array< std::vector< clPar >, 3 > cls
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
std::array< std::vector< std::pair< int, int > >, 3 > WireHitRange
Detector simulation of raw signals on wires.
TDirectory * dir
Definition: macro.C:5
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
Float_t w
Definition: plot.C:23
const detinfo::DetectorProperties * detprop
void trkf::CCTrackMaker::FillEndMatch ( MatchPars match)
private

Definition at line 2641 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::MatchPars::Chg, trkf::CCTrackMaker::MatchPars::Cls, trkf::CCTrackMaker::MatchPars::dAng, trkf::CCTrackMaker::MatchPars::dWir, trkf::CCTrackMaker::MatchPars::dX, trkf::CCTrackMaker::MatchPars::End, trkf::CCTrackMaker::MatchPars::Err, geo::kX, max, trkf::CCTrackMaker::MatchPars::odAng, trkf::CCTrackMaker::MatchPars::odWir, trkf::CCTrackMaker::MatchPars::odX, trkf::CCTrackMaker::MatchPars::oErr, trkf::CCTrackMaker::MatchPars::oVtx, trkf::CCTrackMaker::MatchPars::Vtx, and X.

2642  {
2643  // fill the matching parameters for this cluster match. The calling routine
2644  // should set the match end vertex ID (if applicable) as well as the
2645  // cluster IDs and matching ends in each plane. Note that the matching variables
2646  // Note that dWir, dAng and dTim are not filled if there is a vertex (match.Vtx >= 0).
2647  // Likewise, odWir, odAng and odX are not filled if there is a vertex match
2648  // at the other end
2649 
2650  if(nplanes == 2) {
2651  FillEndMatch2(match);
2652  return;
2653  }
2654 
2655  std::array<short, 3> mVtx;
2656  std::array<short, 3> oVtx;
2657  std::array<float, 3> oWir;
2658  std::array<float, 3> oSlp;
2659  std::array<float, 3> oAng;
2660  std::array<float, 3> oX;
2661 
2662  std::array<float, 3> mChg;
2663 
2664  unsigned short ii, ipl, iend, jpl, jend, kpl, kend, oend;
2665  short icl, jcl, kcl;
2666 
2667  for(ipl = 0; ipl < 3; ++ipl) {
2668  mVtx[ipl] = -1; oVtx[ipl] = -1;
2669  oWir[ipl] = -66; oSlp[ipl] = -66; oAng[ipl] = -66; oX[ipl] = -66;
2670  mChg[ipl] = -1;
2671  } // ipl
2672 
2673  // initialize parameters that shouldn't have been set by the calling routine
2674  match.dWir = 0; match.dAng = 0; match.dX = 0; match.Err = 100;
2675  match.odWir = 0; match.odAng = 0; match.odX = 0; match.oErr = 100;
2676  match.oVtx = -1;
2677 
2678  if(prt) {
2679  mf::LogVerbatim myprt("CCTM");
2680  myprt<<"FEM ";
2681  for(ipl = 0; ipl < nplanes; ++ipl) {
2682  myprt<<" "<<ipl<<":"<<match.Cls[ipl]<<":"<<match.End[ipl];
2683  }
2684  }
2685 
2686  short missingPlane = -1;
2687  unsigned short nClInPln = 0;
2688  // number of vertex matches at each end
2689  short aVtx = -1;
2690  unsigned short novxmat = 0;
2691  short aoVtx = -1;
2692  unsigned short nvxmat = 0;
2693  unsigned short nShortCl = 0;
2694  // fill the other end parameters in each plane
2695  for(ipl = 0; ipl < nplanes; ++ipl) {
2696  if(match.Cls[ipl] < 0) {
2697  missingPlane = ipl;
2698  continue;
2699  }
2700  ++nClInPln;
2701  icl = match.Cls[ipl];
2702  match.Chg[ipl] = clsChain[ipl][icl].TotChg;
2703  mChg[ipl] = clsChain[ipl][icl].TotChg;
2704  iend = match.End[ipl];
2705  mVtx[ipl] = clsChain[ipl][icl].VtxIndex[iend];
2706  if(clsChain[ipl][icl].Length < 6) ++nShortCl;
2707  if(mVtx[ipl] >= 0) {
2708  if(aVtx < 0) aVtx = mVtx[ipl];
2709  if(mVtx[ipl] == aVtx) ++nvxmat;
2710  }
2711  if(prt ) mf::LogVerbatim("CCTM")<<"FEM: m "<<ipl<<":"<<icl<<":"<<iend<<" Vtx "<<mVtx[ipl]<<" Wir "<<clsChain[ipl][icl].Wire[iend]<<std::fixed<<std::setprecision(3)<<" Slp "<<clsChain[ipl][icl].Slope[iend]<<std::fixed<<std::setprecision(1)<<" X "<<clsChain[ipl][icl].X[iend];
2712 
2713  oend = 1 - iend;
2714  oWir[ipl] = clsChain[ipl][icl].Wire[oend];
2715  oAng[ipl] = clsChain[ipl][icl].Angle[oend];
2716  oSlp[ipl] = clsChain[ipl][icl].Slope[oend];
2717  oX[ipl] = clsChain[ipl][icl].X[oend];
2718  oVtx[ipl] = clsChain[ipl][icl].VtxIndex[oend];
2719  if(oVtx[ipl] >= 0) {
2720  if(aoVtx < 0) aoVtx = oVtx[ipl];
2721  if(oVtx[ipl] == aoVtx) ++novxmat;
2722  }
2723 
2724  if(prt) mf::LogVerbatim("CCTM")<<" o "<<ipl<<":"<<icl<<":"<<oend<<" oVtx "<<oVtx[ipl]<<" oWir "<<oWir[ipl]<<std::fixed<<std::setprecision(3)<<" oSlp "<<oSlp[ipl]<<std::fixed<<std::setprecision(1)<<" oX "<<oX[ipl]<<" Chg "<<(int)mChg[ipl];
2725 
2726  } // ipl
2727 
2728  bool isShort = (nShortCl > 1);
2729 
2730  if(nClInPln < 2) {
2731  mf::LogWarning("CCTM")<<"Not enough matched planes supplied";
2732  return;
2733  }
2734 
2735  if(prt) mf::LogVerbatim("CCTM")<<"FEM: Vtx m "<<aVtx<<" count "<<nvxmat
2736  <<" o "<<aoVtx<<" count "<<novxmat
2737  <<" missingPlane "<<missingPlane
2738  <<" nClInPln "<<nClInPln;
2739 
2740  // perfect match
2741  if(nvxmat == 3 && novxmat == 3) {
2742  match.Vtx = aVtx; match.Err = 0;
2743  match.oVtx = aoVtx; match.oErr = 0;
2744  return;
2745  }
2746 
2747  // 2-plane vertex match?
2748  // factors applied to error = 1 (no vtx), 0.5 (2 pln vtx), 0.33 (3 pln vtx)
2749  float vxFactor = 1;
2750  float ovxFactor = 1;
2751  if(nClInPln == 3) {
2752  // a cluster in all 3 planes
2753  if(nvxmat == 3) {
2754  // and all vertex assignments agree at the match end
2755  match.Vtx = aVtx; vxFactor = 0.33;
2756  }
2757  if(novxmat == 3) {
2758  // and all vertex assignments agree at the other end
2759  match.oVtx = aoVtx; ovxFactor = 0.33;
2760  }
2761  } else {
2762  // a cluster in 2 planes
2763  if(nvxmat == 2) {
2764  match.Vtx = aVtx; vxFactor = 0.5;
2765  }
2766  if(novxmat == 2) {
2767  match.oVtx = aoVtx; ovxFactor = 0.5;
2768  }
2769  } // nClInPln
2770 
2771  // find wire, X and Time at both ends
2772 
2773  // Find the "other end" matching parameters with
2774  // two cases: a 3-plane match or a 2-plane match
2775  // and with/without an other end vertex
2776 
2777  double ypos, zpos;
2778  float kWir, okWir;
2779  float kSlp, okSlp, kAng, okAng, okX, kX, kTim, okTim;
2780 
2781  if(nClInPln == 3) {
2782  ipl = 0; jpl = 1; kpl = 2;
2783  } else {
2784  // 2-plane match
2785  kpl = missingPlane;
2786  if(kpl == 0) {
2787  ipl = 1; jpl = 2;
2788  } else if(kpl == 1) {
2789  ipl = 2; jpl = 0;
2790  } else {
2791  ipl = 0; jpl = 1;
2792  } // kpl test
2793  } // missing plane
2794  iend = match.End[ipl]; jend = match.End[jpl];
2795  icl = match.Cls[ipl]; jcl = match.Cls[jpl];
2796  if(nplanes > 2) {
2797  kcl = match.Cls[kpl];
2798  kend = match.End[kpl];
2799  }
2800 
2802  okSlp = geom->ThirdPlaneSlope(ipl, oSlp[ipl], jpl, oSlp[jpl], tpc, cstat);
2803  okAng = atan(okSlp);
2804  // handle the case near pi/2, where the errors on large slopes could result in
2805  // a wrong-sign kAng
2806  bool ignoreSign = (fabs(okSlp) > 10);
2807  if(ignoreSign) okAng = fabs(okAng);
2808  if(match.oVtx >= 0) {
2809  // a vertex exists at the other end
2810  okWir = geom->WireCoordinate(vtx[match.oVtx].Y, vtx[match.oVtx].Z, kpl, tpc, cstat);
2811  okX = vtx[match.oVtx].X;
2812  } else {
2813  // no vertex at the other end
2814  geom->IntersectionPoint(oWir[ipl], oWir[jpl],ipl, jpl, cstat, tpc, ypos, zpos);
2815  okWir = (0.5 + geom->WireCoordinate(ypos, zpos, kpl, tpc, cstat));
2816  okX = 0.5 * (oX[ipl] + oX[jpl]);
2817  }
2818  okTim = detprop->ConvertXToTicks(okX, kpl, tpc, cstat);
2819  if(prt) mf::LogVerbatim("CCTM")<<"FEM: oEnd"<<" kpl "<<kpl<<" okSlp "<<okSlp<<" okAng "
2820  <<okAng<<" okWir "<<(int)okWir<<" okX "<<okX;
2821 
2822 
2824 
2825  kSlp = geom->ThirdPlaneSlope(ipl, clsChain[ipl][icl].Slope[iend], jpl, clsChain[jpl][jcl].Slope[jend], tpc, cstat);
2826  kAng = atan(kSlp);
2827  if(ignoreSign) kAng = fabs(kAng);
2828  if(match.Vtx >= 0) {
2829  if(vtx.size() == 0 || (unsigned int)match.Vtx > vtx.size() - 1) {
2830  mf::LogError("CCTM")<<"FEM: Bad match.Vtx "<<match.Vtx<<" vtx size "<<vtx.size();
2831  return;
2832  }
2833  // a vertex exists at the match end
2834  kWir = geom->WireCoordinate(vtx[match.Vtx].Y, vtx[match.Vtx].Z, kpl, tpc, cstat);
2835  kX = vtx[match.Vtx].X;
2836  } else {
2837  // no vertex at the match end
2838  geom->IntersectionPoint(clsChain[ipl][icl].Wire[iend], clsChain[jpl][jcl].Wire[jend], ipl, jpl, cstat, tpc, ypos, zpos);
2839  kWir = (0.5 + geom->WireCoordinate(ypos, zpos, kpl, tpc, cstat));
2840  kX = 0.5 * (clsChain[ipl][icl].X[iend] + clsChain[jpl][jcl].X[jend]);
2841  }
2842  kTim = detprop->ConvertXToTicks(kX, kpl, tpc, cstat);
2843  if(prt) mf::LogVerbatim("CCTM")<<"FEM: mEnd"<<" kpl "<<kpl<<" kSlp "<<kSlp<<" kAng "<<kAng<<" kX "<<kX;
2844 
2845  // try to find a 3-plane match using this information
2846  if(nClInPln < 3 && FindMissingCluster(kpl, kcl, kend, kWir, kX, okWir, okX)) {
2847  nClInPln = 3;
2848  // update local variables
2849  match.Cls[kpl] = kcl;
2850  match.End[kpl] = kend;
2851  match.Chg[kpl] = clsChain[kpl][kcl].TotChg;
2852  mChg[kpl] = clsChain[kpl][kcl].TotChg;
2853  oend = 1 - kend;
2854  oWir[kpl] = clsChain[kpl][kcl].Wire[oend];
2855  oX[kpl] = clsChain[kpl][kcl].X[oend];
2856  oAng[kpl] = clsChain[kpl][kcl].Angle[oend];
2857  oSlp[kpl] = clsChain[kpl][kcl].Slope[oend];
2858  } // FindMissingCluster
2859 
2860  // decide whether to continue with a 2-plane match. The distance between match and other end should
2861  // be large enough to create a cluster
2862  if(nClInPln == 2 && fabs(okWir - kWir) > 3) return;
2863 
2864  // Calculate the cluster charge asymmetry. This factor will be applied
2865  // to the error of the end matches
2866  float chgAsym = 1;
2867  // Get the charge in the plane without a matching cluster
2868  if(nClInPln < 3 && mChg[missingPlane] <= 0) {
2869  if(missingPlane != kpl) mf::LogError("CCTM")<<"FEM bad missingPlane "<<missingPlane<<" "<<kpl<<"\n";
2870  mChg[kpl] = ChargeNear(kpl, (unsigned short)kWir, kTim, (unsigned short)okWir, okTim);
2871  match.Chg[kpl] = mChg[kpl];
2872  if(prt) mf::LogVerbatim("CCTM")<<"FEM: Missing cluster in "<<kpl<<" ChargeNear "<<(int)kWir<<":"<<(int)kTim
2873  <<" "<<(int)okWir<<":"<<(int)okTim<<" chg "<<mChg[kpl];
2874  if(mChg[kpl] <= 0) return;
2875  }
2876 
2877  if(fChgAsymFactor[algIndex] > 0) {
2878  chgAsym = ChargeAsym(mChg);
2879  if(chgAsym > 0.5) return;
2880  chgAsym = 1 + fChgAsymFactor[algIndex] * chgAsym;
2881  }
2882 
2883  if(prt) mf::LogVerbatim("CCTM")<<"FEM: charge asymmetry factor "<<chgAsym;
2884  float sigmaX, sigmaA;
2885  float da, dx, dw;
2886 
2888  // check for vertex consistency at the match end
2889  aVtx = -1;
2890  bool allPlnVtxMatch = false;
2891  if(nClInPln == 3) {
2892  unsigned short nmvtx = 0;
2893  for(ii = 0; ii < nplanes; ++ii) {
2894  if(mVtx[ii] >= 0) {
2895  if(aVtx < 0) aVtx = mVtx[ii];
2896  ++nmvtx;
2897  }
2898  } // ii
2899  // same vertex in all planes
2900  if(nmvtx ) allPlnVtxMatch = true;
2901  } // nClInPln
2902 
2903  // inflate the X match error to allow for missing one wire on the end of a cluster
2904  sigmaX = fXMatchErr[algIndex] + std::max(kSlp, (float)20);
2905  sigmaA = fAngleMatchErr[algIndex] * AngleFactor(kSlp);
2906  if(prt) mf::LogVerbatim("CCTM")<<"bb "<<algIndex<<" "<<fXMatchErr[algIndex]<<" "<<fAngleMatchErr[algIndex]<<" kslp "<<kSlp;
2907 
2908  if(nClInPln == 3) {
2909  kcl = match.Cls[kpl];
2910  kend = match.End[kpl];
2911  dw = kWir - clsChain[kpl][kcl].Wire[kend];
2912  match.dWir = dw;
2913  if(fabs(match.dWir) > 100) return;
2914  if(match.Vtx >= 0) {
2915  match.dX = kX - clsChain[kpl][kcl].X[kend];
2916  } else {
2917  match.dX = std::abs(clsChain[ipl][icl].X[iend] - clsChain[jpl][jcl].X[jend]) +
2918  std::abs(clsChain[ipl][icl].X[iend] - clsChain[kpl][kcl].X[kend]);
2919  }
2920  if(prt) mf::LogVerbatim("CCTM")<<" dw "<<dw<<" dx "<<match.dX;
2921  // TODO: Angle matching has problems with short clusters
2922  if(!isShort) {
2923  if(ignoreSign) {
2924  match.dAng = kAng - fabs(clsChain[kpl][kcl].Angle[kend]);
2925  } else {
2926  match.dAng = kAng - clsChain[kpl][kcl].Angle[kend];
2927  }
2928  } // !isShort
2929  da = fabs(match.dAng) / sigmaA;
2930  dx = fabs(match.dX) / sigmaX;
2931  if(allPlnVtxMatch) {
2932  // matched vertex. Use angle for match error
2933  match.Err = vxFactor * chgAsym * da / 3;
2934  if(prt) mf::LogVerbatim("CCTM")<<" 3-pln w Vtx match.Err "<<match.Err;
2935  } else {
2936  dw /= 2;
2937  // divide by 9
2938  match.Err = vxFactor * chgAsym * sqrt(dx*dx + da*da + dw*dw) / 9;
2939  if(prt) mf::LogVerbatim("CCTM")<<" 3-pln match.Err "<<match.Err;
2940  }
2941  } else {
2942  // 2-plane match
2943  match.dWir = -1;
2944  match.dAng = -1;
2945  match.dX = clsChain[ipl][icl].X[iend] - clsChain[jpl][jcl].X[jend];
2946  // degrade error by 3 for 2-plane matches
2947  match.Err = 3 + vxFactor * chgAsym * fabs(match.dX) / sigmaX;
2948  if(prt) mf::LogVerbatim("CCTM")<<" 2-pln Err "<<match.Err;
2949  } // !(nClInPln == 3)
2950 
2952  if(nClInPln == 3) {
2953  // A cluster in all 3 planes
2954  dw = okWir - oWir[kpl];
2955  match.odWir = dw;
2956  if(match.oVtx >= 0) {
2957  match.odX = okX - oX[kpl];
2958  } else {
2959  match.odX = std::abs(oX[ipl] - oX[jpl]) + std::abs(oX[ipl] - oX[kpl]);
2960  }
2961  if(prt) mf::LogVerbatim("CCTM")<<" odw "<<match.odWir<<" odx "<<match.odX<<" sigmaX "<<sigmaX;
2962  // TODO: CHECK FOR SHOWER-LIKE CLUSTER OTHER END MATCH
2963  if(!isShort) {
2964  if(ignoreSign) {
2965  match.odAng = okAng - fabs(oAng[kpl]);
2966  } else {
2967  match.odAng = okAng - oAng[kpl];
2968  }
2969  } // !isShort
2970  da = match.odAng / sigmaA;
2971  dx = fabs(match.odX) / sigmaX;
2972  // error for wire number match
2973  dw /= 2;
2974  // divide by number of planes with clusters * 3 for dx, da and dw
2975  match.oErr = ovxFactor * chgAsym * sqrt(dx*dx + da*da + dw*dw) / 9;
2976  if(prt) mf::LogVerbatim("CCTM")<<" 3-pln match.oErr "<<match.oErr;
2977  } else {
2978  // Only 2 clusters in 3 planes
2979  match.odX = (oX[ipl] - oX[jpl]) / sigmaX;
2980  match.oErr = 3 + ovxFactor * chgAsym * fabs(match.odX);
2981  if(prt) mf::LogVerbatim("CCTM")<<" 2-pln match.oErr "<<match.oErr;
2982  }
2983  // std::cout<<"FEM done\n";
2984 
2985  /*
2986  if(nClInPln == 3 && fabs(match.dAng) < 20) {
2987  if(fabs(match.dX) > 0.5) mf::LogVerbatim("CCTM")<<"Bad dX "<<match.dX<<" "<<dx<<" clusters "<<ipl<<":"<<icl<<" "<<jpl<<":"<<jcl<<" "<<kpl<<":"<<kcl<<"\n";
2988  // temp code to grep for ntuple elements in the output
2989  mf::LogVerbatim("CCTM")<<"ntup "<<kSlp<<" "<<match.dX<<" "<<chgAsym<<" "<<match.dAng<<" "<<match.dX<<" "<<match.dWir<<" "<<match.Err<<" "<<match.odAng<<" "<<match.odX<<" "<<match.odWir<<" "<<match.oErr;
2990  if(chgAsym > 1.5) mf::LogVerbatim("CCTM")<<"BadAsym "<<"0:"<<match.Cls[0]<<":"<<match.End[0]<<" 1:"<<match.Cls[1]<<":"<<match.End[1]<<" 2:"<<match.Cls[2]<<":"<<match.End[2];
2991  }
2992  */
2993  } // FillEndMatch
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
float ChargeNear(unsigned short ipl, unsigned short wire1, float time1, unsigned short wire2, float time2)
std::vector< float > fChgAsymFactor
Planes which measure X direction.
Definition: geo_types.h:81
double ThirdPlaneSlope(geo::PlaneID const &pid1, double slope1, geo::PlaneID const &pid2, double slope2, geo::PlaneID const &output_plane) const
Returns the slope on the third plane, given it in the other two.
bool FindMissingCluster(unsigned short kpl, short &kcl, unsigned short &kend, float kWir, float kX, float okWir, float okX)
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::vector< float > fAngleMatchErr
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
std::array< std::vector< ClsChainPar >, 3 > clsChain
Int_t max
Definition: plot.C:27
if(nlines<=0)
float AngleFactor(float slope)
std::vector< vtxPar > vtx
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
void FillEndMatch2(MatchPars &match)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
art::ServiceHandle< geo::Geometry > geom
std::vector< float > fXMatchErr
float ChargeAsym(std::array< float, 3 > &mChg)
Float_t X
Definition: plot.C:39
const detinfo::DetectorProperties * detprop
void trkf::CCTrackMaker::FillEndMatch2 ( MatchPars match)
private

Definition at line 2557 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::MatchPars::Chg, trkf::CCTrackMaker::MatchPars::Cls, trkf::CCTrackMaker::MatchPars::dAng, trkf::CCTrackMaker::MatchPars::dWir, trkf::CCTrackMaker::MatchPars::dX, trkf::CCTrackMaker::MatchPars::End, trkf::CCTrackMaker::MatchPars::Err, max, trkf::CCTrackMaker::MatchPars::odAng, trkf::CCTrackMaker::MatchPars::odWir, trkf::CCTrackMaker::MatchPars::odX, trkf::CCTrackMaker::MatchPars::oErr, trkf::CCTrackMaker::MatchPars::oVtx, and trkf::CCTrackMaker::MatchPars::Vtx.

2558  {
2559  // 2D version of FillEndMatch
2560 
2561  match.Err = 100;
2562  match.oErr = 100;
2563  match.Chg[2] = 0;
2564  match.dWir = 0; match.dAng = 0;
2565  match.odWir = 0; match.odAng = 0;
2566 
2567  unsigned short ipl = 0;
2568  unsigned short jpl = 1;
2569 // mf::LogVerbatim("CCTM")<<"chk "<<ipl<<":"<<match.Cls[ipl]<<":"<<match.End[ipl]<<" and "<<jpl<<":"<<match.Cls[jpl]<<":"<<match.End[jpl];
2570 
2571  if(match.Cls[0] < 0 || match.Cls[1] < 0) return;
2572 
2573  unsigned short icl = match.Cls[ipl];
2574  unsigned short iend = match.End[ipl];
2575  match.Chg[ipl] = clsChain[ipl][icl].TotChg;
2576  // cluster i match end
2577  float miX = clsChain[ipl][icl].X[iend];
2578  // cluster i other end
2579  unsigned short oiend = 1 - iend;
2580  float oiX = clsChain[ipl][icl].X[oiend];
2581 
2582  unsigned short jcl = match.Cls[jpl];
2583  unsigned short jend = match.End[jpl];
2584  match.Chg[jpl] = clsChain[jpl][jcl].TotChg;
2585  // cluster j match end
2586  float mjX = clsChain[jpl][jcl].X[jend];
2587  // cluster j other end
2588  unsigned short ojend = 1 - jend;
2589  float ojX = clsChain[jpl][jcl].X[ojend];
2590 
2591  // look for a match end vertex match
2592  match.Vtx = -1;
2593  if(clsChain[ipl][icl].VtxIndex[iend] >= 0 &&
2594  clsChain[ipl][icl].VtxIndex[iend] == clsChain[jpl][jcl].VtxIndex[jend]) {
2595  match.Vtx = clsChain[ipl][icl].VtxIndex[iend];
2596  miX = vtx[match.Vtx].X;
2597  mjX = vtx[match.Vtx].X;
2598  }
2599 
2600  // look for an other end vertex match
2601  match.oVtx = -1;
2602  if(clsChain[ipl][icl].VtxIndex[oiend] >= 0 &&
2603  clsChain[ipl][icl].VtxIndex[oiend] == clsChain[jpl][jcl].VtxIndex[ojend]) {
2604  match.oVtx = clsChain[ipl][icl].VtxIndex[oiend];
2605  oiX = vtx[match.oVtx].X;
2606  ojX = vtx[match.oVtx].X;
2607  }
2608 
2609  // find the charge asymmetry
2610  float chgAsym = 1;
2611  if(fChgAsymFactor[algIndex] > 0) {
2612  chgAsym = fabs(match.Chg[ipl] - match.Chg[jpl]) / (match.Chg[ipl] + match.Chg[jpl]);
2613  if(chgAsym > 0.5) return;
2614  chgAsym = 1 + fChgAsymFactor[algIndex] * chgAsym;
2615  }
2616 
2617  // find the error at the match end
2618  float maxSlp = fabs(clsChain[ipl][icl].Slope[iend]);
2619  if(fabs(clsChain[jpl][jcl].Slope[jend]) > maxSlp) maxSlp = fabs(clsChain[jpl][jcl].Slope[jend]);
2620  float sigmaX = fXMatchErr[algIndex] + std::max(maxSlp, (float)20);
2621  match.dX = fabs(miX - mjX);
2622  match.Err = chgAsym * match.dX / sigmaX;
2623 
2624 
2625  // find the error at the other end
2626  maxSlp = fabs(clsChain[ipl][icl].Slope[oiend]);
2627  if(fabs(clsChain[jpl][jcl].Slope[ojend]) > maxSlp) maxSlp = fabs(clsChain[jpl][jcl].Slope[ojend]);
2628  sigmaX = fXMatchErr[algIndex] + std::max(maxSlp, (float)20);
2629  match.odX = fabs(oiX - ojX);
2630  match.oErr = chgAsym * match.odX / sigmaX;
2631 
2632  if(prt) mf::LogVerbatim("CCTM")<<"FEM2: m "<<ipl<<":"<<icl<<":"<<iend<<" miX "<<miX
2633  <<" - "<<jpl<<":"<<jcl<<":"<<jend<<" mjX "<<mjX<<" match.dX "<<match.dX
2634  <<" match.Err "<<match.Err<<" chgAsym "<<chgAsym<<" o "<<" oiX "<<oiX
2635  <<" ojX "<<ojX<<" match.odX "<<match.odX<<" match.oErr "<<match.oErr<<"\n";
2636 
2637 
2638 } // FillEndMatch2
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< float > fChgAsymFactor
std::array< std::vector< ClsChainPar >, 3 > clsChain
Int_t max
Definition: plot.C:27
std::vector< vtxPar > vtx
std::vector< float > fXMatchErr
void trkf::CCTrackMaker::FillTrkHits ( art::FindManyP< recob::Hit > const &  fmCluHits,
unsigned short  imat 
)
private

Definition at line 3107 of file CCTrackMaker_module.cc.

References clear().

3108  {
3109  // Fills the trkHits vector using cluster hits associated with the match combo imat
3110 
3111  unsigned short ipl;
3112 
3113  for(ipl = 0; ipl < 3; ++ipl) trkHits[ipl].clear();
3114 
3115  if(imat > matcomb.size()) return;
3116 
3117  unsigned short indx;
3118  std::vector<art::Ptr<recob::Hit>> clusterhits;
3119  unsigned short icc, ccl, icl, ecl, iht, ii;
3120  short endOrder, fillOrder;
3121 
3122  if(prt) mf::LogVerbatim("CCTM")<<"In FillTrkHits: matcomb "<<imat<<" cluster chains "<<matcomb[imat].Cls[0]<<" "<<matcomb[imat].Cls[1]<<" "<<matcomb[imat].Cls[2];
3123 
3124  for(ipl = 0; ipl < nplanes; ++ipl) {
3125  if(matcomb[imat].Cls[ipl] < 0) continue;
3126  // ccl is the cluster chain index
3127  ccl = matcomb[imat].Cls[ipl];
3128  // endOrder = 1 for normal order (hits added from US to DS), and -1 for reverse order
3129  endOrder = 1 - 2 * matcomb[imat].End[ipl];
3130  // re-order the sequence of cluster indices for reverse order
3131  if(endOrder < 0) {
3132  std::reverse(clsChain[ipl][ccl].ClsIndex.begin(), clsChain[ipl][ccl].ClsIndex.end());
3133  std::reverse(clsChain[ipl][ccl].Order.begin(), clsChain[ipl][ccl].Order.end());
3134  for(ii = 0; ii < clsChain[ipl][ccl].Order.size(); ++ii) clsChain[ipl][ccl].Order[ii] = 1 - clsChain[ipl][ccl].Order[ii];
3135  }
3136  if(ccl > clsChain[ipl].size() - 1) {
3137  mf::LogError("CCTM")<<"Bad cluster chain index "<<ccl<<" in plane "<<ipl;
3138  continue;
3139  }
3140  // loop over all the clusters in the chain
3141  for(icc = 0; icc < clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
3142  icl = clsChain[ipl][ccl].ClsIndex[icc];
3143  if(icl > fmCluHits.size() - 1) {
3144  std::cout<<"oops in FTH "<<icl<<" clsChain size "<<clsChain[ipl].size()<<"\n";
3145  exit(1);
3146  }
3147  ecl = cls[ipl][icl].EvtIndex;
3148  if(ecl > fmCluHits.size() - 1) {
3149  std::cout<<"FTH bad EvtIndex "<<ecl<<" fmCluHits size "<<fmCluHits.size()<<"\n";
3150  continue;
3151  }
3152  clusterhits = fmCluHits.at(ecl);
3153  if(clusterhits.size() == 0) {
3154  std::cout<<"FTH no cluster hits for EvtIndex "<<cls[ipl][icl].EvtIndex<<"\n";
3155  continue;
3156  }
3157  indx = trkHits[ipl].size();
3158  trkHits[ipl].resize(indx + clusterhits.size());
3159  // ensure the hit fill ordering is consistent
3160  fillOrder = 1 - 2 * clsChain[ipl][ccl].Order[icc];
3161 // mf::LogVerbatim("CCTM")<<"FillOrder ipl "<<ipl<<" ccl "<<ccl<<" icl "<<icl<<" endOrder "<<endOrder<<" fillOrder "<<fillOrder;
3162  if(fillOrder == 1) {
3163 // mf::LogVerbatim("CCTM")<<" first hit "<<clusterhits[0]->WireID().Wire<<":"<<(int)clusterhits[0]->PeakTime();
3164  for(iht = 0; iht < clusterhits.size(); ++iht) {
3165  if(indx + iht > trkHits[ipl].size() - 1) std::cout<<"FTH oops3\n";
3166  trkHits[ipl][indx + iht] = clusterhits[iht];
3167  }
3168  } else {
3169 // iht = clusterhits.size() - 1;
3170 // mf::LogVerbatim("CCTM")<<" first hit "<<clusterhits[iht]->WireID().Wire<<":"<<(int)clusterhits[iht]->PeakTime();
3171  for(ii = 0; ii < clusterhits.size(); ++ii) {
3172  iht = clusterhits.size() - 1 - ii;
3173  if(indx + ii > trkHits[ipl].size() - 1) std::cout<<"FTH oops4\n";
3174  trkHits[ipl][indx + ii] = clusterhits[iht];
3175  } // ii
3176  }
3177  } // icc
3178  ii = trkHits[ipl].size() - 1;
3179  if(prt) mf::LogVerbatim("CCTM")<<"plane "<<ipl<<" first p "<<trkHits[ipl][0]->WireID().Plane<<" w "<<trkHits[ipl][0]->WireID().Wire<<":"<<(int)trkHits[ipl][0]->PeakTime()<<" last p "<<trkHits[ipl][ii]->WireID().Plane<<" w "<<trkHits[ipl][ii]->WireID().Wire<<":"<<(int)trkHits[ipl][ii]->PeakTime();
3180 // for(ii = 0; ii < trkHits[ipl].size(); ++ii) mf::LogVerbatim("CCTM")<<ii<<" p "<<trkHits[ipl][ii]->WireID().Plane<<" w "<<trkHits[ipl][ii]->WireID().Wire<<" t "<<(int)trkHits[ipl][ii]->PeakTime();
3181  } // ipl
3182 
3183  // TODO Check the ends of trkHits to see if there are missing hits that should have been included
3184  // in a cluster
3185 
3186  } // FillTrkHits
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< MatchPars > matcomb
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::array< std::vector< clPar >, 3 > cls
std::array< std::vector< ClsChainPar >, 3 > clsChain
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > trkHits
vec_iX clear()
void trkf::CCTrackMaker::FillWireHitRange ( )
private

Definition at line 3378 of file CCTrackMaker_module.cc.

References DEFINE_ART_MODULE, and w.

3379  {
3380  // fills the WireHitRange vector. Slightly modified version of the one in ClusterCrawlerAlg
3381 
3382  unsigned short ipl;
3383 
3384  // initialize everything
3385  for(ipl = 0; ipl < 3; ++ipl) {
3386  firstWire[ipl] = INT_MAX;
3387  lastWire[ipl] = 0;
3388  firstHit[ipl] = INT_MAX;
3389  lastHit[ipl] = 0;
3390  WireHitRange[ipl].clear();
3391  ChgNorm[ipl] = 0;
3392  }
3393 
3394  // find the first and last wire with a hit
3395  unsigned short oldipl = 0;
3396  for(unsigned int hit = 0; hit < allhits.size(); ++hit) {
3397  if(allhits[hit]->WireID().Cryostat != cstat) continue;
3398  if(allhits[hit]->WireID().TPC != tpc) continue;
3399  ipl = allhits[hit]->WireID().Plane;
3400  if(allhits[hit]->WireID().Wire > geom->Nwires(ipl, tpc, cstat)) {
3401  if(lastWire[ipl] < firstWire[ipl]) {
3402  mf::LogError("CCTM")<<"Invalid WireID().Wire "<<allhits[hit]->WireID().Wire;
3403  return;
3404  }
3405  }
3406 // ChgNorm[ipl] += allhits[hit]->Integral();
3407  if(ipl < oldipl) {
3408  mf::LogError("CCTM")<<"Hits are not in increasing-plane order\n";
3409  return;
3410  }
3411  oldipl = ipl;
3412  if(firstHit[ipl] == INT_MAX) {
3413  firstHit[ipl] = hit;
3414  firstWire[ipl] = allhits[hit]->WireID().Wire;
3415  }
3416  lastHit[ipl] = hit;
3417  lastWire[ipl] = allhits[hit]->WireID().Wire;
3418  } // hit
3419 
3420  // xxx
3421  for(ipl = 0; ipl < nplanes; ++ipl) {
3422  if(lastWire[ipl] < firstWire[ipl]) {
3423  mf::LogError("CCTM")<<"Invalid first/last wire in plane "<<ipl;
3424  return;
3425  }
3426  } // ipl
3427 
3428  // normalize charge in induction planes to the collection plane
3429 // for(ipl = 0; ipl < nplanes; ++ipl) ChgNorm[ipl] = ChgNorm[nplanes - 1] / ChgNorm[ipl];
3430  for(ipl = 0; ipl < nplanes; ++ipl) ChgNorm[ipl] = 1;
3431 
3432  // get the service to learn about channel status
3433  //lariov::ChannelStatusProvider const& channelStatus
3434  // = art::ServiceHandle<lariov::ChannelStatusService>()->GetProvider();
3435 
3436  // now we can define the WireHitRange vector.
3437  int sflag, nwires, wire;
3438  unsigned int indx, thisWire, thisHit, lastFirstHit;
3439  //uint32_t chan;
3440  for(ipl = 0; ipl < nplanes; ++ipl) {
3441  nwires = lastWire[ipl] - firstWire[ipl] + 1;
3442  WireHitRange[ipl].resize(nwires);
3443  // start by defining the "no hits on wire" condition
3444  sflag = -2;
3445  for(wire = 0; wire < nwires; ++wire) WireHitRange[ipl][wire] = std::make_pair(sflag, sflag);
3446  // overwrite with the "dead wires" condition
3447  sflag = -1;
3448  for(wire = 0; wire < nwires; ++wire) {
3449  //chan = geom->PlaneWireToChannel(ipl, wire, tpc, cstat);
3450  //if(channelStatus.IsBad(chan)) {
3451  // indx = wire - firstWire[ipl];
3452  // WireHitRange[ipl][indx] = std::make_pair(sflag, sflag);
3453  //}
3454  } // wire
3455  // next overwrite with the index of the first/last hit on each wire
3456  lastWire[ipl] = firstWire[ipl];
3457  thisHit = firstHit[ipl];
3458  lastFirstHit = firstHit[ipl];
3459  for(unsigned int hit = firstHit[ipl]; hit <= lastHit[ipl]; ++hit) {
3460  thisWire = allhits[hit]->WireID().Wire;
3461  if(thisWire > lastWire[ipl]) {
3462  indx = lastWire[ipl] - firstWire[ipl];
3463  int tmp1 = lastFirstHit;
3464  int tmp2 = thisHit;
3465  WireHitRange[ipl][indx] = std::make_pair(tmp1, tmp2);
3466  lastWire[ipl] = thisWire;
3467  lastFirstHit = thisHit;
3468  } else if(thisWire < lastWire[ipl]) {
3469  mf::LogError("CCTM")<<"Hit not in proper order in plane "<<ipl;
3470  exit(1);
3471  }
3472  ++thisHit;
3473  } // hit
3474  // define the last wire
3475  indx = lastWire[ipl] - firstWire[ipl];
3476  int tmp1 = lastFirstHit;
3477  ++lastHit[ipl];
3478  int tmp2 = lastHit[ipl];
3479  WireHitRange[ipl][indx] = std::make_pair(tmp1, tmp2);
3480  // add one to lastWire and lastHit for more standard indexing
3481  ++lastWire[ipl];
3482  } // ipl
3483 
3484  // error checking
3485  for(ipl = 0; ipl < nplanes; ++ipl) {
3486  if(firstWire[ipl] < INT_MAX) continue;
3487  if(lastWire[ipl] > 0) continue;
3488  if(firstHit[ipl] < INT_MAX) continue;
3489  if(lastHit[ipl] > 0) continue;
3490  std::cout<<"FWHR problem\n";
3491  exit(1);
3492  } // ipl
3493 
3494  unsigned int nht = 0;
3495  std::vector<bool> hchk(allhits.size());
3496  for(unsigned int ii = 0; ii < hchk.size(); ++ii) hchk[ii] = false;
3497  for(ipl = 0; ipl < nplanes; ++ipl) {
3498  for(unsigned int w = firstWire[ipl]; w < lastWire[ipl]; ++w) {
3499  indx = w - firstWire[ipl];
3500  if(indx > lastWire[ipl]) {
3501  std::cout<<"FWHR bad index "<<indx<<"\n";
3502  exit(1);
3503  }
3504  // no hit on this wire
3505  if(WireHitRange[ipl][indx].first < 0) continue;
3506  unsigned int firhit = WireHitRange[ipl][indx].first;
3507  unsigned int lashit = WireHitRange[ipl][indx].second;
3508  for(unsigned int hit = firhit; hit < lashit; ++hit) {
3509  ++nht;
3510  if(hit > allhits.size() -1) {
3511  std::cout<<"FWHR: Bad hchk "<<hit<<" size "<<allhits.size()<<"\n";
3512  continue;
3513  }
3514  hchk[hit] = true;
3515  if(allhits[hit]->WireID().Plane != ipl || allhits[hit]->WireID().Wire != w) {
3516  std::cout<<"FWHR bad plane "<<allhits[hit]->WireID().Plane<<" "<<ipl<<" or wire "<<allhits[hit]->WireID().Wire<<" "<<w<<"\n";
3517  exit(1);
3518  }
3519  } // hit
3520  } // w
3521  } // ipl
3522 
3523  if(nht != allhits.size()) {
3524  std::cout<<"FWHR hit count problem "<<nht<<" "<<allhits.size()<<"\n";
3525  for(unsigned int ii = 0; ii < hchk.size(); ++ii) if(!hchk[ii]) std::cout<<" "<<ii<<" "<<allhits[ii]->WireID().Plane<<" "<<allhits[ii]->WireID().Wire<<" "<<(int)allhits[ii]->PeakTime()<<"\n";
3526  exit(1);
3527  }
3528 
3529  } // FillWireHitRange
std::array< unsigned int, 3 > firstWire
std::vector< art::Ptr< recob::Hit > > allhits
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::array< float, 3 > ChgNorm
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
std::array< std::vector< std::pair< int, int > >, 3 > WireHitRange
std::array< unsigned int, 3 > firstHit
Detector simulation of raw signals on wires.
std::array< unsigned int, 3 > lastWire
std::array< unsigned int, 3 > lastHit
art::ServiceHandle< geo::Geometry > geom
recob::tracking::Plane Plane
Definition: TrackState.h:17
Float_t w
Definition: plot.C:23
void trkf::CCTrackMaker::FindMaybeVertices ( )
private

Definition at line 1437 of file CCTrackMaker_module.cc.

References evd::details::end(), X, Y, and Z.

1438  {
1439  // Project clusters to vertices and fill mVtxIndex. No requirement is
1440  // made that charge exists on the line between the Begin (End) of the
1441  // cluster and the vertex
1442  unsigned short ipl, icl, end, ivx, oend;
1443  float best, dWire, dX;
1444  short ibstvx;
1445 
1446  if(vtx.size() == 0) return;
1447 
1448  for(ipl = 0; ipl < nplanes; ++ipl) {
1449  for(icl = 0; icl < cls[ipl].size(); ++icl) {
1450  for(end = 0; end < 2; ++end) {
1451  // ignore already attached clusters
1452  if(cls[ipl][icl].VtxIndex[end] >= 0) continue;
1453  ibstvx = -1;
1454  best = 1.;
1455  // index of the other end
1456  oend = 1 - end;
1457  for(ivx = 0; ivx < vtx.size(); ++ ivx) {
1458  // ignore if the other end is attached to this vertex (which can happen with short clusters)
1459  if(cls[ipl][icl].VtxIndex[oend] == ivx) continue;
1460  dWire = geom->WireCoordinate(vtx[ivx].Y, vtx[ivx].Z, ipl, tpc, cstat) - cls[ipl][icl].Wire[end];
1461  /*
1462  if(prt) std::cout<<"FMV: ipl "<<ipl<<" icl "<<icl<<" end "<<end
1463  <<" vtx wire "<<geom->WireCoordinate(vtx[ivx].Y, vtx[ivx].Z, ipl, tpc, cstat)
1464  <<" cls wire "<<cls[ipl][icl].Wire[end]
1465  <<" dWire "<<dWire<<"\n";
1466  */
1467  if(end == 0) {
1468  if(dWire > 30 || dWire < -2) continue;
1469  } else {
1470  if(dWire < -30 || dWire > 2) continue;
1471  }
1472  // project the cluster to the vertex wire
1473  dX = fabs(cls[ipl][icl].X[end] + cls[ipl][icl].Slope[end] * fWirePitch * dWire - vtx[ivx].X);
1474  // if(prt) std::cout<<"dX "<<dX<<"\n";
1475  if(dX < best) {
1476  best = dX;
1477  ibstvx = ivx;
1478  }
1479  } // ivx
1480  if(ibstvx >= 0) {
1481  // attach
1482  cls[ipl][icl].VtxIndex[end] = ibstvx;
1483  cls[ipl][icl].mVtxIndex[end] = ibstvx;
1484  }
1485  } // end
1486  } // icl
1487  } // ipl
1488 
1489  } // FindMaybeVertices
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
Float_t Y
Definition: plot.C:39
std::array< std::vector< clPar >, 3 > cls
Float_t Z
Definition: plot.C:39
std::vector< vtxPar > vtx
art::ServiceHandle< geo::Geometry > geom
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
Float_t X
Definition: plot.C:39
void trkf::CCTrackMaker::FindMidPointMatch ( art::FindManyP< recob::Hit > const &  fmCluHits,
MatchPars match,
unsigned short  kkpl,
unsigned short  kkcl,
unsigned short  kkend,
float &  kkWir,
float &  kkX 
)
private

Definition at line 2997 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::MatchPars::Cls, Y, and Z.

2998  {
2999  // Cluster chain kkcl is broken due to a failure in MakeClusterChains. Find the intersection of
3000  // the other two clusters in match at the appropriate end of cluster kkcl
3001 
3002  kkWir = -1;
3003  // find the match point at the other end of the original match point
3004  kkend = 1 - kkend;
3005  // mf::LogVerbatim("CCTM")<<"FMPM "<<kkpl<<":"<<kkcl<<":"<<kkend;
3006  kkX = clsChain[kkpl][kkcl].X[kkend];
3007  float matchTime = detprop->ConvertXToTicks(kkX, kkpl, tpc, cstat);
3008 
3009  // vector of wire numbers that have the most similar time
3010  std::vector<unsigned int> wirs;
3011  std::vector<unsigned int> plns;
3012  std::vector<art::Ptr<recob::Hit>> clusterhits;
3013  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3014  if(ipl == kkpl) continue;
3015  // this shouldn't happen but check anyway
3016  if(match.Cls[ipl] < 0) continue;
3017  float dTime, best = 99999;
3018  unsigned short wire = 0;
3019  unsigned short icl, ccl = match.Cls[ipl];
3020  // loop over all clusters in the chain
3021  for(unsigned short ii = 0; ii < clsChain[kkpl][ccl].ClsIndex.size(); ++ii) {
3022  icl = clsChain[kkpl][ccl].ClsIndex[ii];
3023  if(cls[ipl][icl].EvtIndex > fmCluHits.size() -1) {
3024  std::cout<<"Bad ClsIndex in FMPM\n";
3025  exit(1);
3026  }
3027  clusterhits = fmCluHits.at(cls[ipl][icl].EvtIndex);
3028  // loop over all the hits in each cluster
3029  for(unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
3030  dTime = fabs(clusterhits[iht]->PeakTime() - matchTime);
3031  if(dTime < best) {
3032  best = dTime;
3033  wire = clusterhits[iht]->WireID().Wire;
3034  }
3035  } // iht
3036  } // ii
3037  wirs.push_back(wire);
3038  plns.push_back(ipl);
3039  // mf::LogVerbatim("CCTM")<<" ipl "<<ipl<<" wire "<<wire;
3040  } // ipl
3041  if(wirs.size() != 2) return;
3042  double Y, Z;
3043  geom->IntersectionPoint(wirs[0], wirs[1], plns[0], plns[1], cstat, tpc, Y, Z);
3044  kkWir = geom->WireCoordinate(Y, Z, kkpl, tpc, cstat);
3045 
3046  } // FindMidPointMatch
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
Float_t Y
Definition: plot.C:39
std::array< std::vector< clPar >, 3 > cls
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
Float_t Z
Definition: plot.C:39
std::array< std::vector< ClsChainPar >, 3 > clsChain
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
art::ServiceHandle< geo::Geometry > geom
const detinfo::DetectorProperties * detprop
bool trkf::CCTrackMaker::FindMissingCluster ( unsigned short  kpl,
short &  kcl,
unsigned short &  kend,
float  kWir,
float  kX,
float  okWir,
float  okX 
)
private

Definition at line 3049 of file CCTrackMaker_module.cc.

References evd::details::end(), and X.

3050  {
3051  // try to attach a missing cluster to the cluster chain kcl. kend is the "match end"
3052 
3053  unsigned short okend;
3054  float dxcut;
3055 
3056  if(kcl >= 0) return false;
3057 
3058  // Look for a missing cluster with loose cuts
3059  float kslp = fabs((okX - kX) / (okWir - kWir));
3060  if(kslp > 20) kslp = 20;
3061  // expand dX cut assuming there is a missing hit on the end of a cluster => 1 wire
3062  dxcut = 3 * fXMatchErr[algIndex] + kslp;
3063  unsigned short nfound = 0;
3064  unsigned short foundCl = 0, foundEnd = 0;
3065  for(unsigned short ccl = 0; ccl < clsChain[kpl].size(); ++ccl) {
3066  if(clsChain[kpl][ccl].InTrack >= 0) continue;
3067  // require a match at both ends
3068  for(unsigned short end = 0; end < 2; ++end) {
3069  okend = 1 - end;
3070  if(fabs(clsChain[kpl][ccl].Wire[end] - kWir) > 4) continue;
3071  if(fabs(clsChain[kpl][ccl].Wire[okend] - okWir) > 4) continue;
3072  // mf::LogVerbatim("CCTM")<<"FMC chk "<<kpl<<":"<<ccl<<":"<<end<<" dW "<<clsChain[kpl][ccl].Wire[end] - kWir<<" odW "<<clsChain[kpl][ccl].Wire[okend] - okWir<<" ccl X "<<clsChain[kpl][ccl].X[end]<<" kX "<<kX<<" ccl oX "<<clsChain[kpl][ccl].X[okend]<<" okX "<<okX<<" dxcut "<<dxcut;
3073  // require at least one end to match
3074  if(fabs(clsChain[kpl][ccl].X[end] - kX) > dxcut && fabs(clsChain[kpl][ccl].X[okend] - okX) > dxcut) continue;
3075  ++nfound;
3076  foundCl = ccl;
3077  foundEnd = end;
3078  } // end
3079  } // ccl
3080  if(nfound == 0) return false;
3081  if(nfound > 1) {
3082  mf::LogVerbatim("CCTM")<<"FindMissingCluster: Found too many matches. Write some code "<<nfound;
3083  return false;
3084  }
3085  kcl = foundCl;
3086  kend = foundEnd;
3087  return true;
3088 
3089  } // FindMissingCluster
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
Planes which measure X direction.
Definition: geo_types.h:81
std::array< std::vector< ClsChainPar >, 3 > clsChain
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
std::vector< float > fXMatchErr
Float_t X
Definition: plot.C:39
void trkf::CCTrackMaker::FitVertices ( )
private

Definition at line 851 of file CCTrackMaker_module.cc.

References evd::details::end().

852  {
853 
854  std::vector<std::vector<geo::WireID>> hitWID;
855  std::vector<std::vector<double>> hitX;
856  std::vector<std::vector<double>> hitXErr;
857  TVector3 pos, posErr;
858  std::vector<TVector3> trkDir;
859  std::vector<TVector3> trkDirErr;
860  float ChiDOF;
861 
862  if(fNVtxTrkHitsFit == 0) return;
863 
864  unsigned short indx, indx2, iht, nHitsFit;
865 
866 // mf::LogVerbatim("CCTM")<<"Inside FitVertices "<<vtx.size()<<" trks "<<trk.size()<<"\n";
867 
868  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
869  if(!vtx[ivx].Neutrino) continue;
870  hitWID.clear();
871  hitX.clear();
872  hitXErr.clear();
873  trkDir.clear();
874  // find the tracks associated with this vertex
875  unsigned int thePln, theTPC, theCst;
876  for(unsigned short itk = 0; itk < trk.size(); ++itk) {
877  for(unsigned short end = 0; end < 2; ++end) {
878  if(trk[itk].VtxIndex[end] != ivx) continue;
879  unsigned short itj = 0;
880  if(end == 1) itj = trk[itk].TrjPos.size() - 1;
881 // mf::LogVerbatim("CCTM")<<"ivx "<<ivx<<" trk "<<itk<<" end "<<end<<" TrjPos "<<trk[itk].TrjPos[itj](0)<<" "<<trk[itk].TrjPos[itj](1)<<" "
882 // <<trk[itk].TrjPos[itj](2)<<" TrjDir "<<trk[itk].TrjDir[itj](0)<<" "<<trk[itk].TrjDir[itj](1)<<" "<<trk[itk].TrjDir[itj](2);
883  // increase the size of the hit vectors by 1 for this track
884  indx = hitX.size();
885  hitWID.resize(indx + 1);
886  hitX.resize(indx + 1);
887  hitXErr.resize(indx + 1);
888  trkDir.resize(indx + 1);
889  trkDir[indx] = trk[itk].TrjDir[itj];
890  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
891  if(trk[itk].TrkHits[ipl].size() < 2) continue;
892  // make slots for the hits on this track in this plane
893  nHitsFit = trk[itk].TrkHits[ipl].size();
894  if(nHitsFit > fNVtxTrkHitsFit) nHitsFit = fNVtxTrkHitsFit;
895  indx2 = hitWID[indx].size();
896  hitWID[indx].resize(indx2 + nHitsFit);
897  hitX[indx].resize(indx2 + nHitsFit);
898  hitXErr[indx].resize(indx2 + nHitsFit);
899  for(unsigned short ii = 0; ii < nHitsFit; ++ii) {
900  if(end == 0) {
901  iht = ii;
902  } else {
903  iht = trk[itk].TrkHits[ipl].size() - ii - 1;
904  }
905  hitWID[indx][indx2 + ii] = trk[itk].TrkHits[ipl][iht]->WireID();
906  thePln = trk[itk].TrkHits[ipl][iht]->WireID().Plane;
907  theTPC = trk[itk].TrkHits[ipl][iht]->WireID().TPC;
908  theCst = trk[itk].TrkHits[ipl][iht]->WireID().Cryostat;
909  hitX[indx][indx2 + ii] = detprop->ConvertTicksToX(trk[itk].TrkHits[ipl][iht]->PeakTime(), thePln, theTPC, theCst);
910  hitXErr[indx][indx2 + ii] = fHitFitErrFac * trk[itk].TrkHits[ipl][iht]->RMS();
911 // mf::LogVerbatim("CCTM")<<"CCTM "<<itk<<" indx "<<indx<<" ii "<<ii<<" WID "<<trk[itk].TrkHits[ipl][iht]->WireID()
912 // <<" X "<<hitX[indx][indx2 + ii]<<" XErr "<<hitXErr[indx][indx2 + ii]<<" RMS "<<trk[itk].TrkHits[ipl][iht]->RMS()
913 // <<" SigmaPeakTime "<<trk[itk].TrkHits[ipl][iht]->SigmaPeakTime();
914  } // ii
915  } // ipl
916  } // end
917  } // itk
918  if(hitX.size() < 2) {
919  mf::LogVerbatim("CCTM")<<"Not enough hits to fit vtx "<<ivx;
920  continue;
921  } // hitX.size() < 2
922  pos(0) = vtx[ivx].X;
923  pos(1) = vtx[ivx].Y;
924  pos(2) = vtx[ivx].Z;
925  fVertexFitAlg.VertexFit(hitWID, hitX, hitXErr, pos, posErr, trkDir, trkDirErr, ChiDOF);
926 /*
927  mf::LogVerbatim("CCTM")<<"FV: CC Vtx pos "<<vtx[ivx].X<<" "<<vtx[ivx].Y<<" "<<vtx[ivx].Z;
928  mf::LogVerbatim("CCTM")<<"FV: Fitted "<<pos[0]<<" "<<pos[1]<<" "<<pos[2]<<" ChiDOF "<<ChiDOF;
929  mf::LogVerbatim("CCTM")<<"FV: Errors "<<posErr[0]<<" "<<posErr[1]<<" "<<posErr[2];
930 */
931  if(ChiDOF > 3000) continue;
932  // update the vertex position
933  vtx[ivx].X = pos(0);
934  vtx[ivx].Y = pos(1);
935  vtx[ivx].Z = pos(2);
936  // and the track trajectory
937  unsigned short fitTrk = 0;
938  for(unsigned short itk = 0; itk < trk.size(); ++itk) {
939  for(unsigned short end = 0; end < 2; ++end) {
940  if(trk[itk].VtxIndex[end] != ivx) continue;
941  unsigned short itj = 0;
942  if(end == 1) itj = trk[itk].TrjPos.size() - 1;
943  trk[itk].TrjDir[itj] = trkDir[fitTrk];
944  ++fitTrk;
945  } // end
946  } // itk
947  } // ivx
948  } // FitVertices
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< vtxPar > vtx
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
void VertexFit(std::vector< std::vector< geo::WireID >> const &hitWID, std::vector< std::vector< double >> const &hitX, std::vector< std::vector< double >> const &hitXErr, TVector3 &VtxPos, TVector3 &VtxPosErr, std::vector< TVector3 > &TrkDir, std::vector< TVector3 > &TrkDirErr, float &ChiDOF) const
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
const detinfo::DetectorProperties * detprop
unsigned short fNVtxTrkHitsFit
EngineCreator::seed_t EngineCreator::get_seed_value ( fhicl::ParameterSet const &  pset,
char const  key[] = "seed",
seed_t const  implicit_seed = -1 
)
inherited

Definition at line 49 of file EngineCreator.cc.

References fhicl::ParameterSet::get().

Referenced by art::MixFilter< T >::initEngine_().

52 {
53  auto const& explicit_seeds = pset.get<std::vector<int>>(key, {});
54  return explicit_seeds.empty() ? implicit_seed : explicit_seeds.front();
55 }
template<typename PROD , BranchType B>
ProductID art::EDProducer::getProductID ( std::string const &  instanceName = {}) const
inlineinherited

Definition at line 123 of file EDProducer.h.

References art::EDProducer::moduleDescription_.

124  {
125  return ProducerBase::getProductID<PROD, B>(moduleDescription_,
126  instanceName);
127  }
ModuleDescription moduleDescription_
Definition: EDProducer.h:115
template<typename PROD , BranchType B>
ProductID art::ProducerBase::getProductID ( ModuleDescription const &  moduleDescription,
std::string const &  instanceName 
) const
inherited

Definition at line 56 of file ProducerBase.h.

References B, and art::ModuleDescription::moduleLabel().

Referenced by art::ProducerBase::modifiesEvent().

58  {
59  auto const& pd =
60  get_ProductDescription<PROD>(B, md.moduleLabel(), instanceName);
61  return pd.productID();
62  }
Int_t B
Definition: plot.C:25
void trkf::CCTrackMaker::MakeClusterChains ( art::FindManyP< recob::Hit > const &  fmCluHits)
private

Definition at line 1492 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::ClsChainPar::Angle, trkf::CCTrackMaker::ClsChainPar::ChgNear, trkf::CCTrackMaker::ClsChainPar::ClsIndex, trkf::CCTrackMaker::ClsChainPar::Dir, evd::details::end(), trkf::CCTrackMaker::ClsChainPar::InTrack, trkf::CCTrackMaker::ClsChainPar::Length, trkf::CCTrackMaker::ClsChainPar::mBrkIndex, trkf::CCTrackMaker::ClsChainPar::Order, tca::PrintClusters(), trkf::CCTrackMaker::ClsChainPar::Slope, trkf::CCTrackMaker::ClsChainPar::Time, trkf::CCTrackMaker::ClsChainPar::TotChg, trkf::CCTrackMaker::ClsChainPar::VtxIndex, trkf::CCTrackMaker::ClsChainPar::Wire, X, and trkf::CCTrackMaker::ClsChainPar::X.

1493  {
1494 
1495  unsigned short ipl, icl, icl1, icl2;
1496  float dw, dx, dWCut, dw1Max, dw2Max;
1497  float dA, dA2, dACut = fMaxDAng, chgAsymCut;
1498  float dXCut, chgasym, mrgErr;
1499  // long straight clusters
1500  bool ls1, ls2;
1501  bool gotprt = false;
1502  for(ipl = 0; ipl < nplanes; ++ipl) {
1503  if(cls[ipl].size() > 1) {
1504  for(icl1 = 0; icl1 < cls[ipl].size() - 1; ++icl1) {
1505  prt = (fDebugAlg == 666 && ipl == fDebugPlane && icl1 == fDebugCluster);
1506  if(prt) gotprt = true;
1507  // maximum delta Wire overlap is 10% of the total length
1508  dw1Max = 0.6 * cls[ipl][icl1].Length;
1509  ls1 = (cls[ipl][icl1].Length > 100 && fabs(cls[ipl][icl1].Angle[0] - cls[ipl][icl1].Angle[1]) < 0.04);
1510  for(icl2 = icl1 + 1; icl2 < cls[ipl].size(); ++icl2) {
1511  ls2 = (cls[ipl][icl2].Length > 100 && fabs(cls[ipl][icl2].Angle[0] - cls[ipl][icl2].Angle[1]) < 0.04);
1512  dw2Max = 0.6 * cls[ipl][icl2].Length;
1513  // set overlap cut to be the shorter of the two
1514  dWCut = dw1Max;
1515  if(dw2Max < dWCut) dWCut = dw2Max;
1516  // but not exceeding 20 for very long clusters
1517  if(dWCut > 100) dWCut = 100;
1518  if(dWCut < 2) dWCut = 2;
1519  chgAsymCut = fMergeChgAsym;
1520  // Compare end 1 of icl1 with end 0 of icl2
1521 
1522  if(prt) mf::LogVerbatim("CCTM")<<"MCC P:C:W icl1 "<<ipl<<":"<<icl1<<":"<<cls[ipl][icl1].Wire[1]<<" vtx "<<cls[ipl][icl1].VtxIndex[1]<<" ls1 "<<ls1<<" icl2 "<<ipl<<":"<<icl2<<":"<<cls[ipl][icl2].Wire[0]<<" vtx "<<cls[ipl][icl2].VtxIndex[0]<<" ls2 "<<ls2<<" dWCut "<<dWCut;
1523  if(std::abs(cls[ipl][icl1].Wire[1] - cls[ipl][icl2].Wire[0]) > dWCut) continue;
1524  // ignore if the clusters begin/end on the same wire
1525 // if(cls[ipl][icl1].Wire[1] == cls[ipl][icl2].Wire[0]) continue;
1526  // or if the angle exceeds the cut
1527  float af = AngleFactor(cls[ipl][icl1].Slope[1]);
1528  dACut = fMaxDAng * af;
1529  dXCut = fChainMaxdX * 5 * af;
1530  dA = fabs(cls[ipl][icl1].Angle[1] - cls[ipl][icl2].Angle[0]);
1531  // compare the match angle at the opposite ends of the clusters.
1532  // May have a bad end/begin angle if there is a delta-ray in the middle
1533  dA2 = fabs(cls[ipl][icl1].Angle[0] - cls[ipl][icl2].Angle[1]);
1534 
1535  if(prt) mf::LogVerbatim("CCTM")<<" dA "<<dA<<" dA2 "<<dA2<<" DACut "<<dACut<<" dXCut "<<dXCut;
1536 
1537  if(dA2 < dA) dA = dA2;
1538  // ignore vertices that have only two associated clusters and
1539  // the angle is small
1540  if(dA < fChainVtxAng && cls[ipl][icl1].VtxIndex[1] >= 0) {
1541  dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1542  dx = cls[ipl][icl1].X[1] + cls[ipl][icl1].Slope[1] * dw * fWirePitch - cls[ipl][icl2].X[0];
1543  unsigned short ivx = cls[ipl][icl1].VtxIndex[1];
1544  if(vtx[ivx].nClusInPln[ipl] == 2 && fabs(dx) < 1) {
1545  cls[ipl][icl1].VtxIndex[1] = -2;
1546  cls[ipl][icl2].VtxIndex[0] = -2;
1547  vtx[ivx].nClusInPln[ipl] = 0;
1548  if(prt) mf::LogVerbatim("CCTM")<<" clobbered vertex "<<ivx;
1549  } // vertices match
1550  } // dA < 0.1 && ...
1551 
1552  // don't merge if a vertex exists at these ends
1553  if(cls[ipl][icl1].VtxIndex[1] >= 0) continue;
1554  if(cls[ipl][icl2].VtxIndex[0] >= 0) continue;
1555 
1556  // expand the angle match cut for clusters that appear to be stopping
1557  if(cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1] < 3 &&
1558  (cls[ipl][icl1].Length < 3 || cls[ipl][icl2].Length < 3) ) {
1559  if(prt) mf::LogVerbatim("CCTM")<<"Stopping cluster";
1560  dACut *= 1.5;
1561  chgAsymCut *= 1.5;
1562  dXCut *= 3;
1563  } // stopping US cluster
1564 
1565  // find the angle made by the endpoints of the clusters
1566  dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1567  if(dw != 0) {
1568  dx = cls[ipl][icl2].X[0] - cls[ipl][icl1].X[1];
1569  float dA3 = std::abs(atan(dx / dw) - cls[ipl][icl1].Angle[1]);
1570  if(prt) mf::LogVerbatim("CCTM")<<" dA3 "<<dA3;
1571  if(dA3 > dA) dA = dA3;
1572  }
1573 
1574  // angle matching
1575  if(dA > dACut) continue;
1576 
1577  if(prt) mf::LogVerbatim("CCTM")<<" rough dX "<<fabs(cls[ipl][icl1].X[1] - cls[ipl][icl2].X[0])<<" cut = 20";
1578 
1579  // make a rough dX cut
1580  if(fabs(cls[ipl][icl1].X[1] - cls[ipl][icl2].X[0]) > 20) continue;
1581 
1582  // handle cosmic ray clusters that are broken at delta rays
1583  if(ls1 || ls2) {
1584  // tighter angle cuts but no charge cut
1585  if(dA > fChainVtxAng) continue;
1586  } else {
1587  chgasym = fabs(cls[ipl][icl1].Charge[1] - cls[ipl][icl2].Charge[0]);
1588  chgasym /= cls[ipl][icl1].Charge[1] + cls[ipl][icl2].Charge[0];
1589  if(prt) mf::LogVerbatim("CCTM")<<" chgasym "<<chgasym<<" cut "<<chgAsymCut;
1590  if(chgasym > chgAsymCut) continue;
1591  } // ls1 || ls2
1592  // project the longer cluster to the end of the shorter one
1593  if(cls[ipl][icl1].Length > cls[ipl][icl2].Length) {
1594  dw = fWirePitch * (cls[ipl][icl2].Wire[0] - cls[ipl][icl1].Wire[1]);
1595  dx = cls[ipl][icl1].X[1] + cls[ipl][icl1].Slope[1] * dw * fWirePitch - cls[ipl][icl2].X[0];
1596  } else {
1597  dw = fWirePitch * (cls[ipl][icl1].Wire[1] - cls[ipl][icl2].Wire[0]);
1598  dx = cls[ipl][icl2].X[0] + cls[ipl][icl2].Slope[0] * dw * fWirePitch - cls[ipl][icl1].X[1];
1599  }
1600 
1601  // handle overlapping clusters
1602  if(dA2 < 0.01 && abs(dx) > dXCut && dx < -1) {
1603  dx = dXClTraj(fmCluHits, ipl, icl1, 1, icl2);
1604  if(prt) mf::LogVerbatim("CCTM")<<" new dx from dXClTraj "<<dx;
1605  }
1606 
1607  if(prt) mf::LogVerbatim("CCTM")<<" X0 "<<cls[ipl][icl1].X[1]<<" slp "<<cls[ipl][icl1].Slope[1]<<" dw "<<dw<<" oX "<<cls[ipl][icl2].X[0]<<" dx "<<dx<<" cut "<<dXCut;
1608 
1609  if(fabs(dx) > dXCut) continue;
1610 
1611  // calculate a merge error that will be used to adjudicate between multiple merge attempts AngleFactor
1612  float xerr = dx / dXCut;
1613  float aerr = dA / dACut;
1614  mrgErr = xerr * xerr + aerr * aerr;
1615 
1616  if(prt) mf::LogVerbatim("CCTM")<<"icl1 mrgErr "<<mrgErr<<" MergeError "<<cls[ipl][icl1].MergeError[1]<<" icl2 MergeError "<<cls[ipl][icl2].MergeError[0];
1617 
1618  // this merge better than a previous one?
1619  if(mrgErr > cls[ipl][icl1].MergeError[1]) continue;
1620  if(mrgErr > cls[ipl][icl2].MergeError[0]) continue;
1621 
1622  // un-merge icl1 - this should always be true but check anyway
1623  if(cls[ipl][icl1].BrkIndex[1] >= 0) {
1624  unsigned short ocl = cls[ipl][icl1].BrkIndex[1];
1625  if(prt) mf::LogVerbatim("CCTM")<<"clobber old icl1 BrkIndex "<<ocl;
1626  if(cls[ipl][ocl].BrkIndex[0] == icl1) {
1627  cls[ipl][ocl].BrkIndex[0] = -1;
1628  cls[ipl][ocl].MergeError[0] = fMaxMergeError;
1629  }
1630  if(cls[ipl][ocl].BrkIndex[1] == icl1) {
1631  cls[ipl][ocl].BrkIndex[1] = -1;
1632  cls[ipl][ocl].MergeError[1] = fMaxMergeError;
1633  }
1634  } // cls[ipl][icl1].BrkIndex[1] >= 0
1635  cls[ipl][icl1].BrkIndex[1] = icl2;
1636  cls[ipl][icl1].MergeError[1] = mrgErr;
1637 
1638  // un-merge icl2
1639  if(cls[ipl][icl2].BrkIndex[0] >= 0) {
1640  unsigned short ocl = cls[ipl][icl2].BrkIndex[0];
1641  if(prt) mf::LogVerbatim("CCTM")<<"clobber old icl2 BrkIndex "<<ocl;
1642  if(cls[ipl][ocl].BrkIndex[0] == icl1) {
1643  cls[ipl][ocl].BrkIndex[0] = -1;
1644  cls[ipl][ocl].MergeError[0] = fMaxMergeError;
1645  }
1646  if(cls[ipl][ocl].BrkIndex[1] == icl1) {
1647  cls[ipl][ocl].BrkIndex[1] = -1;
1648  cls[ipl][ocl].MergeError[1] = fMaxMergeError;
1649  }
1650  } // cls[ipl][icl2].BrkIndex[0] >= 0
1651  cls[ipl][icl2].BrkIndex[0] = icl1;
1652  cls[ipl][icl2].MergeError[0] = mrgErr;
1653  if(prt) mf::LogVerbatim("CCTM")<<" merge "<<icl1<<" and "<<icl2;
1654 
1655  } // icl2
1656  } // icl1
1657 
1658  // look for broken clusters in which have a C shape similar to a Begin-Begin vertex. The clusters
1659  // will have large and opposite sign angles
1660  bool gotone;
1661  for(icl1 = 0; icl1 < cls[ipl].size() - 1; ++icl1) {
1662  gotone = false;
1663  for(icl2 = icl1 + 1; icl2 < cls[ipl].size(); ++icl2) {
1664  // check both ends
1665  for(unsigned short end = 0; end < 2; ++end) {
1666  // Ignore already identified broken clusters
1667  if(cls[ipl][icl1].BrkIndex[end] >= 0) continue;
1668  if(cls[ipl][icl2].BrkIndex[end] >= 0) continue;
1669 // if(prt) mf::LogVerbatim("CCTM")<<"BrokenC: clusters "<<cls[ipl][icl1].Wire[end]<<":"<<(int)cls[ipl][icl1].Time[end]<<" "<<cls[ipl][icl2].Wire[end]<<":"<<(int)cls[ipl][icl2].Time[end]<<" angles "<<cls[ipl][icl1].Angle[end]<<" "<<cls[ipl][icl2].Angle[end];
1670  // require a large angle cluster
1671  if(fabs(cls[ipl][icl1].Angle[end]) < 1) continue;
1672  // and a second large angle cluster
1673  if(fabs(cls[ipl][icl2].Angle[end]) < 1) continue;
1674  if(prt) mf::LogVerbatim("CCTM")<<"BrokenC: clusters "<<cls[ipl][icl1].Wire[end]<<":"<<(int)cls[ipl][icl1].Time[end]<<" "<<cls[ipl][icl2].Wire[end]<<":"<<(int)cls[ipl][icl2].Time[end]<<" angles "<<cls[ipl][icl1].Angle[end]<<" "<<cls[ipl][icl2].Angle[end]<<" dWire "<<fabs(cls[ipl][icl1].Wire[end] - cls[ipl][icl2].Wire[end]);
1675  if(fabs(cls[ipl][icl1].Wire[end] - cls[ipl][icl2].Wire[end]) > 5) continue;
1676  // This is really crude but maybe OK
1677  // project 1 -> 2
1678  float dsl = cls[ipl][icl2].Slope[end] - cls[ipl][icl1].Slope[end];
1679  float fvw = (cls[ipl][icl1].X[end] - cls[ipl][icl1].Wire[end] * cls[ipl][icl1].Slope[end] - cls[ipl][icl2].X[end] + cls[ipl][icl2].Wire[end] * cls[ipl][icl2].Slope[end]) / dsl;
1680  if(prt) mf::LogVerbatim("CCTM")<<" fvw "<<fvw;
1681  if(fabs(cls[ipl][icl1].Wire[end] - fvw) > 4) continue;
1682  if(fabs(cls[ipl][icl2].Wire[end] - fvw) > 4) continue;
1683  cls[ipl][icl1].BrkIndex[end] = icl2;
1684  // TODO This could use some improvement if necessary
1685  cls[ipl][icl1].MergeError[end] = 1;
1686  cls[ipl][icl2].BrkIndex[end] = icl1;
1687  cls[ipl][icl2].MergeError[end] = 1;
1688  gotone = true;
1689  dx = fabs(cls[ipl][icl1].X[end] - cls[ipl][icl2].X[end]);
1690  if(prt) mf::LogVerbatim("CCTM")<<"BrokenC: icl1:W "<<icl1<<":"<<cls[ipl][icl1].Wire[end]<<" icl2:W "<<icl2<<":"<<cls[ipl][icl2].Wire[end]<<" end "<<end<<" dx "<<dx;
1691  } // end
1692  if(gotone) break;
1693  } // icl2
1694  } // icl1
1695 
1696  } // cls[ipl].size() > 1
1697 
1698  // follow mother-daughter broken clusters and put them in the cluster chain array
1699  unsigned short end, mom, momBrkEnd, dtrBrkEnd, nit;
1700  short dtr;
1701 
1702  std::vector<bool> gotcl(cls[ipl].size());
1703  for(icl = 0; icl < cls[ipl].size(); ++icl) gotcl[icl] = false;
1704  if(prt) mf::LogVerbatim("CCTM")<<"ipl "<<ipl<<" cls.size() "<<cls[ipl].size()<<"\n";
1705 
1706  std::vector<unsigned short> sCluster;
1707  std::vector<unsigned short> sOrder;
1708  for(icl = 0; icl < cls[ipl].size(); ++icl) {
1709  sCluster.clear();
1710  sOrder.clear();
1711  if(gotcl[icl]) continue;
1712  // don't start with a cluster broken at both ends
1713  if(cls[ipl][icl].BrkIndex[0] >= 0 && cls[ipl][icl].BrkIndex[1] >= 0) continue;
1714  for(end = 0; end < 2; ++end) {
1715  if(cls[ipl][icl].BrkIndex[end] < 0) continue;
1716  if(cls[ipl][icl].MergeError[end] > fMergeErrorCut) continue;
1717  gotcl[icl] = true;
1718  mom = icl;
1719  // end where the mom is broken
1720  momBrkEnd = end;
1721  sCluster.push_back(mom);
1722  if(momBrkEnd == 1) {
1723  // typical case - broken at the DS end
1724  sOrder.push_back(0);
1725  } else {
1726  // broken at the US end
1727  sOrder.push_back(1);
1728  }
1729  dtr = cls[ipl][icl].BrkIndex[end];
1730 // std::cout<<"Starting mom:momBrkEnd "<<mom<<":"<<momBrkEnd<<" dtr "<<dtr<<"\n";
1731  nit = 0;
1732  while(dtr >= 0 && dtr < (short)cls[ipl].size() && nit < cls[ipl].size()) {
1733  // determine which end of the dtr should be attached to mom
1734  for(dtrBrkEnd = 0; dtrBrkEnd < 2; ++dtrBrkEnd) if(cls[ipl][dtr].BrkIndex[dtrBrkEnd] == mom) break;
1735  if(dtrBrkEnd == 2) {
1736 // mf::LogError("CCTM")<<"Cant find dtrBrkEnd for cluster "<<icl<<" dtr "<<dtr<<" in plane "<<ipl;
1737  gotcl[icl] = false;
1738  break;
1739  }
1740  // check for reasonable merge error
1741  if(cls[ipl][dtr].MergeError[dtrBrkEnd] < fMergeErrorCut) {
1742  sCluster.push_back(dtr);
1743  sOrder.push_back(dtrBrkEnd);
1744  gotcl[dtr] = true;
1745  }
1746 // std::cout<<" dtr:dtrBrkEnd "<<dtr<<":"<<dtrBrkEnd<<" momBrkEnd "<<momBrkEnd<<"\n";
1747  ++nit;
1748  // set up to check the new mom
1749  mom = dtr;
1750  // at the other end
1751  momBrkEnd = 1 - dtrBrkEnd;
1752  // with the new dtr
1753  dtr = cls[ipl][mom].BrkIndex[momBrkEnd];
1754 // std::cout<<" new mom:momBrkEnd "<<mom<<":"<<momBrkEnd<<" new dtr "<<dtr<<"\n";
1755  } // dtr >= 0 ...
1756  if(dtrBrkEnd == 2) continue;
1757  } // end
1758 
1759  if(!gotcl[icl]) {
1760  // a single unbroken cluster
1761  sCluster.push_back(icl);
1762  sOrder.push_back(0);
1763  }
1764 
1765  if(sCluster.size() == 0) {
1766  mf::LogError("CCTM")<<"MakeClusterChains error in plane "<<ipl<<" cluster "<<icl;
1767  return;
1768  }
1769 /*
1770  std::cout<<ipl<<" icl "<<icl<<" sCluster ";
1771  for(unsigned short ii = 0; ii < sCluster.size(); ++ii) std::cout<<" "<<sCluster[ii]<<":"<<sOrder[ii];
1772  std::cout<<"\n";
1773 */
1774  ClsChainPar ccp;
1775  // fill the struct parameters assuming this is a cluster chain containing only one cluster
1776  unsigned short jcl = sCluster[0];
1777  if(jcl > cls[ipl].size()) std::cout<<"oops MCC\n";
1778  unsigned short oend;
1779  for(end = 0; end < 2; ++end) {
1780  oend = end;
1781  if(sOrder[0] > 0) oend = 1 - end;
1782  ccp.Wire[end] = cls[ipl][jcl].Wire[oend];
1783  ccp.Time[end] = cls[ipl][jcl].Time[oend];
1784  ccp.X[end] = cls[ipl][jcl].X[oend];
1785  ccp.Slope[end] = cls[ipl][jcl].Slope[oend];
1786  ccp.Angle[end] = cls[ipl][jcl].Angle[oend];
1787  ccp.Dir[end] = cls[ipl][icl].Dir[oend];
1788  ccp.VtxIndex[end] = cls[ipl][jcl].VtxIndex[oend];
1789  ccp.ChgNear[end] = cls[ipl][jcl].ChgNear[oend];
1790  ccp.mBrkIndex[end] = cls[ipl][jcl].BrkIndex[oend];
1791  } // end
1792  ccp.Length = cls[ipl][icl].Length;
1793  ccp.TotChg = cls[ipl][icl].TotChg;
1794  ccp.InTrack = -1;
1795 // std::cout<<"sOrder0 "<<sOrder[0]<<" "<<(int)ccp.Wire[0]<<":"<<(int)ccp.Time[0]<<" dir "<<ccp.Dir[0]<<" "<<(int)ccp.Wire[1]<<":"<<(int)ccp.Time[1]<<" dir "<<ccp.Dir[1]<<"\n";
1796 
1797  for(unsigned short ii = 1; ii < sCluster.size(); ++ii) {
1798  jcl = sCluster[ii];
1799  if(jcl > cls[ipl].size()) std::cout<<"oops MCC\n";
1800  // end is the end where the break is being mended
1801  end = sOrder[ii];
1802  if(end > 1) std::cout<<"oops2 MCC\n";
1803  oend = 1 - end;
1804  // update the parameters at the other end of the chain
1805  ccp.Wire[1] = cls[ipl][jcl].Wire[oend];
1806  ccp.Time[1] = cls[ipl][jcl].Time[oend];
1807  ccp.X[1] = cls[ipl][jcl].X[oend];
1808  ccp.Slope[1] = cls[ipl][jcl].Slope[oend];
1809  ccp.Angle[1] = cls[ipl][jcl].Angle[oend];
1810  ccp.Dir[1] = cls[ipl][jcl].Dir[oend];
1811  ccp.VtxIndex[1] = cls[ipl][jcl].VtxIndex[oend];
1812  ccp.ChgNear[1] = cls[ipl][jcl].ChgNear[oend];
1813  ccp.mBrkIndex[1] = cls[ipl][jcl].BrkIndex[oend];
1814  ccp.Length += cls[ipl][jcl].Length;
1815  ccp.TotChg += cls[ipl][jcl].TotChg;
1816 // std::cout<<"Update "<<end<<" "<<(int)ccp.Wire[0]<<":"<<(int)ccp.Time[0]<<" dir "<<ccp.Dir[0]<<" "<<(int)ccp.Wire[1]<<":"<<(int)ccp.Time[1]<<" dir "<<ccp.Dir[1]<<"\n";
1817  } // ii
1818  ccp.ClsIndex = sCluster;
1819  ccp.Order = sOrder;
1820  // redo the direction
1821  if(ccp.Time[1] > ccp.Time[0]) {
1822  ccp.Dir[0] = 1; ccp.Dir[1] = -1;
1823  } else {
1824  ccp.Dir[0] = -1; ccp.Dir[1] = 1;
1825  }
1826  clsChain[ipl].push_back(ccp);
1827 
1828  } // icl
1829 
1830  // re-index mBrkIndex to point to a cluster chain, not a cluster
1831  unsigned short brkCls;
1832  bool gotit;
1833  for(unsigned short ccl = 0; ccl < clsChain[ipl].size(); ++ccl) {
1834  for(unsigned short end = 0; end < 2; ++end) {
1835  if(clsChain[ipl][ccl].mBrkIndex[end] < 0) continue;
1836  brkCls = clsChain[ipl][ccl].mBrkIndex[end];
1837  gotit = false;
1838  // find this cluster index in a cluster chain
1839  for(unsigned short ccl2 = 0; ccl2 < clsChain[ipl].size(); ++ccl2) {
1840  if(ccl2 == ccl) continue;
1841  if(std::find(clsChain[ipl][ccl2].ClsIndex.begin(), clsChain[ipl][ccl2].ClsIndex.end(), brkCls) == clsChain[ipl][ccl2].ClsIndex.end()) continue;
1842  // found it
1843  clsChain[ipl][ccl].mBrkIndex[end] = ccl2;
1844  gotit = true;
1845  break;
1846  } // ccl2
1847 // if(gotit) std::cout<<"gotit ccl "<<ccl<<" end "<<end<<" new mBrkIndex "<<clsChain[ipl][ccl].mBrkIndex[end]<<"\n";
1848  if(!gotit) mf::LogError("CCTM")<<"MCC: Cluster chain "<<ccl<<" end "<<end<<" Failed to find brkCls "<<brkCls<<" in plane "<<ipl;
1849  } // end
1850  } // ccl
1851 
1852  } // ipl
1853 
1854 
1855  if(gotprt) PrintClusters();
1856  prt = false;
1857 
1858  } // MakeClusterChains
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
float dXClTraj(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short ipl, unsigned short icl1, unsigned short end1, unsigned short icl2)
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::array< std::vector< clPar >, 3 > cls
std::array< std::vector< ClsChainPar >, 3 > clsChain
float AngleFactor(float slope)
std::vector< vtxPar > vtx
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
Float_t X
Definition: plot.C:39
void trkf::CCTrackMaker::MakeFamily ( )
private

Definition at line 1004 of file CCTrackMaker_module.cc.

References tmp, X, Y, and Z.

1005  {
1006  // define the track/vertex and mother/daughter relationships
1007 
1008  unsigned short ivx, itr, ipl, ii, jtr;
1009  unsigned short nus, nds, nuhs, ndhs;
1010  float longUSTrk, longDSTrk, qual;
1011 
1012  // min distance^2 between a neutrino vertex candidate and a through
1013  // going muon
1014  float tgMuonCut2 = 9;
1015 
1016  // struct for neutrino vertex candidates
1017  struct NuVtx {
1018  unsigned short VtxIndex;
1019  unsigned short nUSTk;
1020  unsigned short nDSTk;
1021  unsigned short nUSHit;
1022  unsigned short nDSHit;
1023  float longUSTrk;
1024  float longDSTrk;
1025  float Qual;
1026  };
1027  std::vector<NuVtx> nuVtxCand;
1028 
1029  NuVtx aNuVtx;
1030 
1031  // analyze all of the vertices
1032  float best = 999, dx, dy, dz, dr;
1033  short imbest = -1;
1034  bool skipVtx;
1035  unsigned short itj;
1036  for(ivx = 0; ivx < vtx.size(); ++ivx) {
1037  vtx[ivx].Neutrino = false;
1038  nus = 0; nds = 0; nuhs = 0; ndhs = 0;
1039  longUSTrk = 0; longDSTrk = 0;
1040  skipVtx = false;
1041  // skip vertices that are close to through-going muons
1042  for(itr = 0; itr < trk.size(); ++itr) {
1043  if(trk[itr].ID < 0) continue;
1044  if(trk[itr].PDGCode != 13) continue;
1045  for(itj = 0; itj < trk[itr].TrjPos.size(); ++itj) {
1046  dx = trk[itr].TrjPos[itj](0) - vtx[ivx].X;
1047  dy = trk[itr].TrjPos[itj](1) - vtx[ivx].Y;
1048  dz = trk[itr].TrjPos[itj](2) - vtx[ivx].Z;
1049  dr = dx * dx + dy * dy + dz * dz;
1050  if(dr < tgMuonCut2) {
1051  skipVtx = true;
1052  break;
1053  }
1054  if(skipVtx) break;
1055  } // itj
1056  if(skipVtx) break;
1057  } // itr
1058  if(skipVtx) continue;
1059  for(itr = 0; itr < trk.size(); ++itr) {
1060  if(trk[itr].ID < 0) continue;
1061  if(trk[itr].VtxIndex[0] == ivx) {
1062  // DS-going track
1063  ++nds;
1064  if(trk[itr].Length > longDSTrk) longDSTrk = trk[itr].Length;
1065  for(ipl = 0; ipl < nplanes; ++ipl) ndhs += trk[itr].TrkHits[ipl].size();
1066 // std::cout<<"MakeFamily: ivx "<<ivx<<" DS itr "<<trk[itr].ID<<" len "<<trk[itr].Length<<"\n";
1067  } // DS-going track
1068  // Reject this vertex as a neutrino candidate if the track being
1069  // considered has a starting vertex
1070  if(trk[itr].VtxIndex[1] == ivx && trk[itr].VtxIndex[0] >= 0) {
1071  skipVtx = true;
1072  break;
1073  } // trk[itr].VtxIndex[0] > 0
1074  if(trk[itr].VtxIndex[1] == ivx && trk[itr].VtxIndex[0] < 0) {
1075  // US-going track w no US vertex
1076  ++nus;
1077  if(trk[itr].Length > longUSTrk) longUSTrk = trk[itr].Length;
1078  for(ipl = 0; ipl < nplanes; ++ipl) nuhs += trk[itr].TrkHits[ipl].size();
1079 // std::cout<<"MakeFamily: ivx "<<ivx<<" US itr "<<trk[itr].ID<<" len "<<trk[itr].Length<<"\n";
1080  } // US-going track
1081  } // itr
1082  if(skipVtx) continue;
1083  if(nds == 0) continue;
1084  qual = 1 / (float)nds;
1085  qual /= (float)ndhs;
1086  if(nus > 0) qual *= (float)nuhs / (float)ndhs;
1087  if(qual < best) {
1088  best = qual;
1089  imbest = ivx;
1090  }
1091  if(nds > 0 && longDSTrk > 5) {
1092  // at least one longish track going DS
1093  aNuVtx.VtxIndex = ivx;
1094  aNuVtx.nUSTk = nus;
1095  aNuVtx.nDSTk = nds;
1096  aNuVtx.nUSHit = nuhs;
1097  aNuVtx.nDSHit = ndhs;
1098  aNuVtx.longUSTrk = longUSTrk;
1099  aNuVtx.longDSTrk = longDSTrk;
1100  aNuVtx.Qual = qual;
1101  nuVtxCand.push_back(aNuVtx);
1102  }
1103  } // ivx
1104 /*
1105  mf::LogVerbatim("CCTM")<<"Neutrino vtx candidates";
1106  for(unsigned short ican = 0; ican < nuVtxCand.size(); ++ican)
1107  mf::LogVerbatim("CCTM")<<"Can "<<ican<<" vtx "<<nuVtxCand[ican].VtxIndex<<" nUSTk "<<nuVtxCand[ican].nUSTk
1108  <<" nUSHit "<<nuVtxCand[ican].nUSHit<<" longUS "<<nuVtxCand[ican].longUSTrk<<" nDSTk "<<nuVtxCand[ican].nDSTk
1109  <<" nDSHit "<<nuVtxCand[ican].nDSHit<<" longDS "<<nuVtxCand[ican].longDSTrk<<" Qual "<<nuVtxCand[ican].Qual;
1110 */
1111  if(imbest < 0) return;
1112 
1113  // Found the neutrino interaction vertex
1114  ivx = imbest;
1115  vtx[ivx].Neutrino = true;
1116  // Put a 0 into the PFParticle -> track vector to identify a neutrino
1117  // track with no trajectory or hits
1118  pfpToTrkID.push_back(0);
1119 
1120  // list of DS-going current generation daughters so we can fix next
1121  // generation daughter assignments. This code section assumes that there
1122  // are no decays or 2ndry interactions with US-going primary tracks.
1123  std::vector<unsigned short> dtrGen;
1124  std::vector<unsigned short> dtrNextGen;
1125  for(itr = 0; itr < trk.size(); ++itr) {
1126  if(trk[itr].ID < 0) continue;
1127  if(trk[itr].VtxIndex[0] == ivx) {
1128  // DS-going primary track
1129  trk[itr].MomID = 0;
1130  // call every track coming from a neutrino vertex a proton
1131  trk[itr].PDGCode = 2212;
1132  pfpToTrkID.push_back(trk[itr].ID);
1133  dtrGen.push_back(itr);
1134  } // DS-going primary track
1135  if(trk[itr].VtxIndex[1] == ivx) {
1136  // US-going primary track
1137  trk[itr].MomID = 0;
1138  // call every track coming from a neutrino vertex a proton
1139  trk[itr].PDGCode = 2212;
1140  pfpToTrkID.push_back(trk[itr].ID);
1141  // reverse the track trajectory
1142  std::reverse(trk[itr].TrjPos.begin(), trk[itr].TrjPos.end());
1143  for(ii = 0; ii < trk[itr].TrjDir.size(); ++ii)
1144  trk[itr].TrjDir[ii] = -trk[itr].TrjDir[ii];
1145  } // DS-going primary track
1146  } // itr
1147 
1148  if(dtrGen.size() == 0) return;
1149 
1150  unsigned short tmp, indx;
1151  unsigned short nit = 0;
1152 
1153  // follow daughters through all generations (< 10). Daughter tracks
1154  // may go US or DS
1155  while(nit < 10) {
1156  ++nit;
1157  dtrNextGen.clear();
1158  // Look for next generation daughters
1159  for(ii = 0; ii < dtrGen.size(); ++ii) {
1160  itr = dtrGen[ii];
1161  if(trk[itr].VtxIndex[1] >= 0) {
1162  // found a DS vertex
1163  ivx = trk[itr].VtxIndex[1];
1164  // look for a track associated with this vertex
1165  for(jtr = 0; jtr < trk.size(); ++jtr) {
1166  if(jtr == itr) continue;
1167  if(trk[jtr].VtxIndex[0] == ivx) {
1168  // DS-going track
1169  indx = trk[itr].DtrID.size();
1170  trk[itr].DtrID.resize(indx + 1);
1171  trk[itr].DtrID[indx] = jtr;
1172 // std::cout<<"itr "<<itr<<" dtr "<<jtr<<" DtrID size "<<trk[itr].DtrID.size()<<"\n";
1173  trk[jtr].MomID = trk[itr].ID;
1174  // call all daughters pions
1175  trk[jtr].PDGCode = 211;
1176  dtrNextGen.push_back(jtr);
1177  pfpToTrkID.push_back(trk[jtr].ID);
1178  } // DS-going track
1179  if(trk[jtr].VtxIndex[1] == ivx) {
1180  // US-going track
1181  indx = trk[itr].DtrID.size();
1182  trk[itr].DtrID.resize(indx + 1);
1183  trk[itr].DtrID[indx] = jtr;
1184 // std::cout<<"itr "<<itr<<" dtr "<<jtr<<" DtrID size "<<trk[itr].DtrID.size()<<"\n";
1185  trk[jtr].MomID = trk[itr].ID;
1186  // call all daughters pions
1187  trk[jtr].PDGCode = 211;
1188  dtrNextGen.push_back(jtr);
1189  pfpToTrkID.push_back(trk[jtr].ID);
1190  // reverse the track trajectory
1191  std::reverse(trk[jtr].TrjPos.begin(), trk[jtr].TrjPos.end());
1192  for(unsigned short jj = 0; jj < trk[jtr].TrjDir.size(); ++jj)
1193  trk[jtr].TrjDir[jj] = -trk[jtr].TrjDir[jj];
1194  // interchange the trk - vtx assignments
1195  tmp = trk[jtr].VtxIndex[0];
1196  trk[jtr].VtxIndex[0] = trk[jtr].VtxIndex[1];
1197  trk[jtr].VtxIndex[1] = tmp;
1198  } // DS-going track
1199  } // jtr
1200  } // trk[itr].VtxIndex[0] >= 0
1201  } // ii (itr)
1202  // break out if no next gen daughters found
1203  if(dtrNextGen.size() == 0) break;
1204  dtrGen = dtrNextGen;
1205  } // nit
1206 
1207  } // MakeFamily
Float_t Y
Definition: plot.C:39
Float_t tmp
Definition: plot.C:37
std::vector< unsigned short > pfpToTrkID
Float_t Z
Definition: plot.C:39
std::vector< vtxPar > vtx
Float_t X
Definition: plot.C:39
template<typename T , BranchType = InEvent>
ProductToken<T> art::Consumer::mayConsume ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ProductToken<T> art::Consumer::mayConsume ( InputTag const &  it)
inherited

Definition at line 190 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

191 {
192  if (!moduleContext_)
193  return ProductToken<T>::invalid();
194 
195  consumables_[BT].emplace_back(ConsumableType::Product,
196  TypeID{typeid(T)},
197  it.label(),
198  it.instance(),
199  it.process());
200  return ProductToken<T>{it};
201 }
static ProductToken< T > invalid()
Definition: ProductToken.h:47
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename T , art::BranchType BT>
void art::Consumer::mayConsumeMany ( )
inherited

Definition at line 205 of file Consumer.h.

206 {
207  if (!moduleContext_)
208  return;
209 
210  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
211 }
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
template<typename Element , BranchType = InEvent>
ViewToken<Element> art::Consumer::mayConsumeView ( InputTag const &  )
inherited
template<typename T , art::BranchType BT>
art::ViewToken<T> art::Consumer::mayConsumeView ( InputTag const &  it)
inherited

Definition at line 215 of file Consumer.h.

References art::InputTag::instance(), art::InputTag::label(), and art::InputTag::process().

216 {
217  if (!moduleContext_)
218  return ViewToken<T>::invalid();
219 
220  consumables_[BT].emplace_back(ConsumableType::ViewElement,
221  TypeID{typeid(T)},
222  it.label(),
223  it.instance(),
224  it.process());
225  return ViewToken<T>{it};
226 }
static ViewToken< Element > invalid()
Definition: ProductToken.h:75
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
bool art::ProducerBase::modifiesEvent ( ) const
inlineinherited

Definition at line 40 of file ProducerBase.h.

References art::ProducerBase::getProductID().

41  {
42  return true;
43  }
void trkf::CCTrackMaker::PlnMatch ( art::FindManyP< recob::Hit > const &  fmCluHits)
private

Definition at line 2178 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::MatchPars::Chg, trkf::CCTrackMaker::MatchPars::Cls, trkf::CCTrackMaker::MatchPars::End, trkf::CCTrackMaker::MatchPars::Err, geo::kX, trkf::CCTrackMaker::MatchPars::oErr, trkf::CCTrackMaker::MatchPars::oVtx, trkf::CCTrackMaker::MatchPars::Vtx, and X.

2179  {
2180  // Match clusters in all planes
2181  // unsigned short ipl, icl, jpl, jcl, kpl, kcl;
2182  bool ignoreSign;
2183  float kSlp, kAng, kX, kWir, okWir;
2184  short idir, ioend, jdir, joend, kdir;
2185 
2186  double yp, zp;
2187  float tpcSizeY = geom->DetHalfWidth();
2188  float tpcSizeZ = geom->DetLength();
2189 
2190 
2191  float dxcut = 2;
2192  float dxkcut;
2193  float dwcut = 6;
2194  if(fuBCode) {
2195  dxcut = 20;
2196  dwcut = 60;
2197  }
2198 
2199  // temp array for making a rough charge asymmetry cut
2200  std::array<float, 3> mchg;
2201 
2202  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
2203  for(unsigned short icl = 0; icl < clsChain[ipl].size(); ++icl) {
2204  if(clsChain[ipl][icl].InTrack >= 0) continue;
2205  // skip short clusters
2206  if(clsChain[ipl][icl].Length < fMatchMinLen[algIndex]) continue;
2207  unsigned short jpl = (ipl + 1) % nplanes;
2208  unsigned short kpl = (jpl + 1) % nplanes;
2209  for(unsigned short jcl = 0; jcl < clsChain[jpl].size(); ++jcl) {
2210  if(clsChain[jpl][jcl].InTrack >= 0) continue;
2211  // skip short clusters
2212  if(clsChain[jpl][jcl].Length < fMatchMinLen[algIndex]) continue;
2213  // make first charge asymmetry cut
2214  mchg[0] = clsChain[ipl][icl].TotChg;
2215  mchg[1] = clsChain[jpl][jcl].TotChg;
2216  mchg[2] = mchg[1];
2217  if(fChgAsymFactor[algIndex] > 0 && ChargeAsym(mchg) > 0.5) continue;
2218  for(unsigned short iend = 0; iend < 2; ++iend) {
2219  idir = clsChain[ipl][icl].Dir[iend];
2220  for(unsigned short jend = 0; jend < 2; ++jend) {
2221  jdir = clsChain[jpl][jcl].Dir[jend];
2222  if(idir != 0 && jdir != 0 && idir != jdir) continue;
2223  // make an X cut
2224  if(fabs(clsChain[ipl][icl].X[iend] - clsChain[jpl][jcl].X[jend]) > dxcut) continue;
2225  ioend = 1 - iend; joend = 1 - jend;
2226  // Find the expected third (k) plane parameters
2227  kSlp = geom->ThirdPlaneSlope(ipl, clsChain[ipl][icl].Slope[iend], jpl, clsChain[jpl][jcl].Slope[jend], tpc, cstat);
2228  kAng = atan(kSlp);
2229  // Ensure the match end is within the TPC
2230  geom->IntersectionPoint((unsigned int)(0.5+clsChain[ipl][icl].Wire[iend]),
2231  (unsigned int)(0.5+clsChain[jpl][jcl].Wire[jend]),
2232  ipl, jpl, cstat, tpc, yp, zp);
2233  if(yp > tpcSizeY || yp < -tpcSizeY) continue;
2234  if(zp < 0 || zp > tpcSizeZ) continue;
2235  kX = 0.5 * (clsChain[ipl][icl].X[iend] + clsChain[jpl][jcl].X[jend]);
2236  kWir = geom->WireCoordinate(yp, zp, kpl, tpc, cstat);
2237  // now look at the other end
2238  geom->IntersectionPoint((unsigned int)(0.5+clsChain[ipl][icl].Wire[ioend]),
2239  (unsigned int)(0.5+clsChain[jpl][jcl].Wire[joend]),
2240  ipl, jpl, cstat, tpc, yp, zp);
2241  if(yp > tpcSizeY || yp < -tpcSizeY) continue;
2242  if(zp < 0 || zp > tpcSizeZ) continue;
2243  okWir = geom->WireCoordinate(yp, zp, kpl, tpc, cstat);
2244  if(prt) mf::LogVerbatim("CCTM")<<"PlnMatch: chk i "<<ipl<<":"<<icl<<":"<<iend
2245  <<" idir "<<idir<<" X "<<clsChain[ipl][icl].X[iend]<<" j "<<jpl<<":"<<jcl<<":"<<jend
2246  <<" jdir "<<jdir<<" X "<<clsChain[jpl][jcl].X[jend];
2247 
2248  if(prt) mf::LogVerbatim("CCTM")<<"PlnMatch: chk j "<<ipl<<":"<<icl<<":"<<iend
2249  <<" "<<jpl<<":"<<jcl<<":"<<jend<<" iSlp "<<std::setprecision(2)<<clsChain[ipl][icl].Slope[iend]
2250  <<" jSlp "<<std::setprecision(2)<<clsChain[jpl][jcl].Slope[jend]<<" kWir "<<(int)kWir
2251  <<" okWir "<<(int)okWir<<" kSlp "<<std::setprecision(2)<<kSlp<<" kAng "
2252  <<std::setprecision(2)<<kAng<<" kX "<<std::setprecision(1)<<kX;
2253 
2254  // handle the case near pi/2, where the errors on large slopes
2255  // could result in a wrong-sign kAng
2256  ignoreSign = (fabs(kSlp) > 1.5);
2257  if(ignoreSign) kAng = fabs(kAng);
2258  dxkcut = dxcut * AngleFactor(kSlp);
2259  bool gotkcl = false;
2260  for(unsigned short kcl = 0; kcl < clsChain[kpl].size(); ++kcl) {
2261  if(clsChain[kpl][kcl].InTrack >= 0) continue;
2262  // make second charge asymmetry cut
2263  mchg[0] = clsChain[ipl][icl].TotChg;
2264  mchg[1] = clsChain[jpl][jcl].TotChg;
2265  mchg[2] = clsChain[kpl][kcl].TotChg;
2266  if(fChgAsymFactor[algIndex] > 0 && ChargeAsym(mchg) > 0.5) continue;
2267  for(unsigned short kend = 0; kend < 2; ++kend) {
2268  kdir = clsChain[kpl][kcl].Dir[kend];
2269  if(idir != 0 && kdir != 0 && idir != kdir) continue;
2270  if(prt) mf::LogVerbatim("CCTM")<<" kcl "<<kcl<<" kend "<<kend
2271  <<" dx "<<std::abs(clsChain[kpl][kcl].X[kend] - kX)<<" dxkcut "<<dxkcut;
2272  if(std::abs(clsChain[kpl][kcl].X[kend] - kX) > dxkcut) continue;
2273  // rough dWire cut
2274  if(prt) mf::LogVerbatim("CCTM")<<" kcl "<<kcl<<" kend "<<kend
2275  <<" dw "<<(clsChain[kpl][kcl].Wire[kend] - kWir)<<" ignoreSign "<<ignoreSign;
2276  if(fabs(clsChain[kpl][kcl].Wire[kend] - kWir) > dwcut) continue;
2277  if(prt) mf::LogVerbatim("CCTM")<<" chk k "<<kpl<<":"<<kcl<<":"<<kend;
2278  MatchPars match;
2279  match.Cls[ipl] = icl; match.End[ipl] = iend;
2280  match.Cls[jpl] = jcl; match.End[jpl] = jend;
2281  match.Cls[kpl] = kcl; match.End[kpl] = kend;
2282  match.Err = 100;
2283  if(DupMatch(match)) continue;
2284  match.Chg[ipl] = 0; match.Chg[jpl] = 0; match.Chg[kpl] = 0;
2285  match.Vtx = clsChain[ipl][icl].VtxIndex[iend];
2286  match.oVtx = -1;
2287  FillEndMatch(match);
2288  if(prt) mf::LogVerbatim("CCTM")<<" PlnMatch: match k "<<kpl<<":"<<match.Cls[kpl]
2289  <<":"<<match.End[kpl]<<" oChg "<<match.Chg[kpl]<<" mErr "<<match.Err<<" oErr "<<match.oErr;
2290  if(match.Chg[kpl] == 0) continue;
2291  if(match.Err > 10 || match.oErr > 10) continue;
2292  if(prt) mf::LogVerbatim("CCTM")<<" dup? ";
2293  if(DupMatch(match)) continue;
2294  matcomb.push_back(match);
2295  gotkcl = true;
2296  } // kend
2297  } // kcl
2298  if(prt) mf::LogVerbatim("CCTM")<<" PlnMatch: gotkcl "<<gotkcl;
2299  if(!gotkcl) {
2300  // make a 2-plane match and try again
2301  MatchPars match;
2302  match.Cls[ipl] = icl; match.End[ipl] = iend;
2303  match.Cls[jpl] = jcl; match.End[jpl] = jend;
2304  match.Cls[kpl] = -1; match.End[kpl] = 0;
2305  match.Err = 100;
2306  if(DupMatch(match)) continue;
2307  match.Chg[ipl] = 0; match.Chg[jpl] = 0; match.Chg[kpl] = 0;
2308  match.Vtx = clsChain[ipl][icl].VtxIndex[iend];
2309  match.oVtx = -1;
2310  FillEndMatch(match);
2311  if(prt) mf::LogVerbatim("CCTM")<<" Tried 2-plane match"<<" k "<<kpl<<":"<<match.Cls[kpl]
2312  <<":"<<match.End[kpl]<<" Chg "<<match.Chg[kpl]<<" Err "<<match.Err<<" match.oErr "<<match.oErr;
2313  if(match.Chg[kpl] <= 0) continue;
2314  if(match.Err > 10 || match.oErr > 10) continue;
2315  matcomb.push_back(match);
2316  } // !gotkcl
2317  } // jend
2318  } // iend
2319  } // jcl
2320  } // icl
2321  } // ipl
2322 
2323  if(matcomb.size() == 0) return;
2324 
2325  } // PlnMatch
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< MatchPars > matcomb
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
std::vector< float > fChgAsymFactor
Planes which measure X direction.
Definition: geo_types.h:81
double ThirdPlaneSlope(geo::PlaneID const &pid1, double slope1, geo::PlaneID const &pid2, double slope2, geo::PlaneID const &output_plane) const
Returns the slope on the third plane, given it in the other two.
std::array< std::vector< ClsChainPar >, 3 > clsChain
bool DupMatch(MatchPars &match)
std::vector< float > fMatchMinLen
float AngleFactor(float slope)
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
void FillEndMatch(MatchPars &match)
art::ServiceHandle< geo::Geometry > geom
float ChargeAsym(std::array< float, 3 > &mChg)
Float_t X
Definition: plot.C:39
void art::Consumer::prepareForJob ( fhicl::ParameterSet const &  pset)
protectedinherited

Definition at line 89 of file Consumer.cc.

References fhicl::ParameterSet::get_if_present().

Referenced by art::EDProducer::doBeginJob(), art::EDFilter::doBeginJob(), and art::EDAnalyzer::doBeginJob().

90 {
91  if (!moduleContext_)
92  return;
93 
94  pset.get_if_present("errorOnMissingConsumes", requireConsumes_);
95  for (auto& consumablesPerBranch : consumables_) {
96  cet::sort_all(consumablesPerBranch);
97  }
98 }
bool requireConsumes_
Definition: Consumer.h:137
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
void trkf::CCTrackMaker::PrintClusters ( ) const
private

Definition at line 3236 of file CCTrackMaker_module.cc.

References evd::details::end(), art::right(), X, Y, and Z.

3237  {
3238 
3239  unsigned short iTime;
3240  mf::LogVerbatim myprt("CCTM");
3241  myprt<<"******* PrintClusters ********* Num_Clusters_in Wire:Time\n";
3242  myprt<<"vtx Index X Y Z Pln0 Pln1 Pln2 Pln0 Pln1 Pln2\n";
3243  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
3244  myprt<<std::right<<std::setw(3)<<ivx<<std::setw(7)<<ivx;
3245  myprt<<std::fixed;
3246  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].X;
3247  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Y;
3248  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Z;
3249  myprt<<std::right<<std::setw(5)<<vtx[ivx].nClusInPln[0];
3250  myprt<<std::right<<std::setw(5)<<vtx[ivx].nClusInPln[1];
3251  myprt<<std::right<<std::setw(5)<<vtx[ivx].nClusInPln[2];
3252  myprt<<" ";
3253  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3254  int time = (0.5 + detprop->ConvertXToTicks(vtx[ivx].X, ipl, tpc, cstat));
3255  int wire = geom->WireCoordinate(vtx[ivx].Y, vtx[ivx].Z, ipl, tpc, cstat);
3256  myprt<<std::right<<std::setw(7)<<wire<<":"<<time;
3257  }
3258 
3259  myprt<<"\n";
3260  } // ivx
3261 
3262  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3263  myprt<<">>>>>>>>>> Cluster chains in Plane "<<ipl<<"\n";
3264  myprt<<"ipl ccl Len Chg W0:T0 Ang0 Dir0 Vx0 mBk0 W1:T1 Ang1 Dir1 Vx1 mBk1 InTk cls:Order \n";
3265  for(unsigned short ccl = 0; ccl < clsChain[ipl].size(); ++ccl) {
3266  myprt<<std::right<<std::setw(3)<<ipl;
3267  myprt<<std::right<<std::setw(5)<<ccl;
3268  myprt<<std::right<<std::setw(6)<<clsChain[ipl][ccl].Length;
3269  myprt<<std::right<<std::setw(8)<<(int)clsChain[ipl][ccl].TotChg;
3270  for(unsigned short end = 0; end < 2; ++end) {
3271  iTime = clsChain[ipl][ccl].Time[end];
3272  myprt<<std::right<<std::setw(5)<<(int)clsChain[ipl][ccl].Wire[end]
3273  <<":"<<std::setprecision(1)<<iTime;
3274  if(iTime < 10) {
3275  myprt<<" ";
3276  } else if(iTime < 100) {
3277  myprt<<" ";
3278  } else if(iTime < 1000) myprt<<" ";
3279  myprt<<std::right<<std::setw(7)<<std::setprecision(2)<<clsChain[ipl][ccl].Angle[end];
3280  myprt<<std::right<<std::setw(5)<<clsChain[ipl][ccl].Dir[end];
3281  myprt<<std::right<<std::setw(5)<<clsChain[ipl][ccl].VtxIndex[end];
3282  myprt<<std::fixed<<std::right<<std::setw(6)<<std::setprecision(1)<<clsChain[ipl][ccl].mBrkIndex[end];
3283 // myprt<<std::fixed<<std::right<<std::setw(6)<<std::setprecision(1)<<clsChain[ipl][ccl].ChgNear[end];
3284  }
3285  myprt<<std::right<<std::setw(7)<<clsChain[ipl][ccl].InTrack;
3286  myprt<<" ";
3287  for(unsigned short ii = 0; ii < clsChain[ipl][ccl].ClsIndex.size(); ++ii)
3288  myprt<<" "<<clsChain[ipl][ccl].ClsIndex[ii]<<":"<<clsChain[ipl][ccl].Order[ii];
3289  myprt<<"\n";
3290  } // ccl
3291  if(fPrintAllClusters) {
3292  myprt<<">>>>>>>>>> Clusters in Plane "<<ipl<<"\n";
3293  myprt<<"ipl icl Evt Len Chg W0:T0 Ang0 Dir0 Vx0 CN0 W1:T1 Ang1 Dir1 Vx1 CN1 InTk Brk0 MrgEr0 Brk1 MrgEr1\n";
3294  for(unsigned short icl = 0; icl < cls[ipl].size(); ++icl) {
3295  myprt<<std::right<<std::setw(3)<<ipl;
3296  myprt<<std::right<<std::setw(5)<<icl;
3297  myprt<<std::right<<std::setw(5)<<cls[ipl][icl].EvtIndex;
3298  myprt<<std::right<<std::setw(6)<<cls[ipl][icl].Length;
3299  myprt<<std::right<<std::setw(8)<<(int)cls[ipl][icl].TotChg;
3300  for(unsigned short end = 0; end < 2; ++end) {
3301  iTime = cls[ipl][icl].Time[end];
3302  myprt<<std::right<<std::setw(5)<<(int)cls[ipl][icl].Wire[end]<<":"<<iTime;
3303  if(iTime < 10) {
3304  myprt<<" ";
3305  } else if(iTime < 100) {
3306  myprt<<" ";
3307  } else if(iTime < 1000) myprt<<" ";
3308  myprt<<std::right<<std::setw(7)<<std::setprecision(2)<<cls[ipl][icl].Angle[end];
3309  myprt<<std::right<<std::setw(5)<<cls[ipl][icl].Dir[end];
3310  myprt<<std::right<<std::setw(5)<<cls[ipl][icl].VtxIndex[end];
3311  myprt<<std::fixed<<std::right<<std::setw(5)<<std::setprecision(1)<<cls[ipl][icl].ChgNear[end];
3312  }
3313  myprt<<std::fixed;
3314  myprt<<std::right<<std::setw(5)<<cls[ipl][icl].InTrack;
3315  myprt<<std::right<<std::setw(5)<<(int)cls[ipl][icl].BrkIndex[0];
3316  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<cls[ipl][icl].MergeError[0];
3317  myprt<<std::right<<std::setw(5)<<(int)cls[ipl][icl].BrkIndex[1];
3318  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<cls[ipl][icl].MergeError[1];
3319  myprt<<"\n";
3320  } // icl
3321  } // fPrintAllClusters
3322  } // ipl
3323  } // PrintClusters
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
Float_t Y
Definition: plot.C:39
std::array< std::vector< clPar >, 3 > cls
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
Float_t Z
Definition: plot.C:39
std::array< std::vector< ClsChainPar >, 3 > clsChain
std::vector< vtxPar > vtx
art::ServiceHandle< geo::Geometry > geom
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
Float_t X
Definition: plot.C:39
const detinfo::DetectorProperties * detprop
void trkf::CCTrackMaker::PrintTracks ( ) const
private

Definition at line 3189 of file CCTrackMaker_module.cc.

References art::right().

3190  {
3191  mf::LogVerbatim myprt("CCTM");
3192  myprt<<"********* PrintTracks \n";
3193  myprt<<"vtx Index X Y Z\n";
3194  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
3195  myprt<<std::right<<std::setw(4)<<ivx<<std::setw(4)<<vtx[ivx].EvtIndex;
3196  myprt<<std::fixed;
3197  myprt<<std::right<<std::setw(10)<<std::setprecision(1)<<vtx[ivx].X;
3198  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Y;
3199  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Z;
3200  if(vtx[ivx].Neutrino) myprt<<" Neutrino vertex";
3201  myprt<<"\n";
3202  } // ivx
3203 
3204  myprt<<">>>>>>>>>> Tracks \n";
3205  myprt<<"trk ID Proc nht nTrj sX sY sZ eX eY eZ sVx eVx sGd eGd ChgOrd dirZ Mom PDG ClsIndices\n";
3206  for(unsigned short itr = 0; itr < trk.size(); ++itr) {
3207  myprt<<std::right<<std::setw(3)<<itr<<std::setw(4)<<trk[itr].ID;
3208  myprt<<std::right<<std::setw(5)<<std::setw(4)<<trk[itr].Proc;
3209  unsigned short nht = 0;
3210  for(unsigned short ii = 0; ii < 3; ++ii) nht += trk[itr].TrkHits[ii].size();
3211  myprt<<std::right<<std::setw(5)<<nht;
3212  myprt<<std::setw(4)<<trk[itr].TrjPos.size();
3213  myprt<<std::fixed;
3214  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[0](0);
3215  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[0](1);
3216  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[0](2);
3217  unsigned short itj = trk[itr].TrjPos.size() - 1;
3218  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[itj](0);
3219  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[itj](1);
3220  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[itj](2);
3221  myprt<<std::setw(4)<<trk[itr].VtxIndex[0]<<std::setw(4)<<trk[itr].VtxIndex[1];
3222  myprt<<std::setw(4)<<trk[itr].GoodEnd[0];
3223  myprt<<std::setw(4)<<trk[itr].GoodEnd[1];
3224  myprt<<std::setw(4)<<trk[itr].ChgOrder;
3225  myprt<<std::right<<std::setw(10)<<std::setprecision(3)<<trk[itr].TrjDir[itj](2);
3226  myprt<<std::right<<std::setw(4)<<trk[itr].MomID;
3227  myprt<<std::right<<std::setw(5)<<trk[itr].PDGCode<<" ";
3228  for(unsigned short ii = 0; ii < trk[itr].ClsEvtIndices.size(); ++ii) myprt<<" "<<trk[itr].ClsEvtIndices[ii];
3229  myprt<<"\n";
3230  } // itr
3231 
3232  } // PrintTracks
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
std::vector< vtxPar > vtx
void trkf::CCTrackMaker::produce ( art::Event evt)
virtual

Implements art::EDProducer.

Definition at line 388 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::clPar::Angle, trkf::CCTrackMaker::clPar::BrkIndex, trkf::CCTrackMaker::clPar::Charge, trkf::CCTrackMaker::clPar::ChgNear, art::Handle< T >::clear(), recob::tracking::convertCollToPoint(), recob::tracking::convertCollToVector(), util::CreateAssn(), art::FindManyP< ProdB, Data >::data(), trkf::CCTrackMaker::clPar::Dir, evd::details::end(), recob::Cluster::EndAngle(), recob::Cluster::EndCharge(), recob::Cluster::EndTick(), recob::Cluster::EndWire(), trkf::CCTrackMaker::clPar::EvtIndex, trkf::CCTrackMaker::vtxPar::EvtIndex, art::fill_ptr_vector(), tca::FillWireHitRange(), art::DataViewImpl::getByLabel(), trkf::CCTrackMaker::vtxPar::ID, CluLen::index, recob::Cluster::Integral(), trkf::CCTrackMaker::clPar::InTrack, CluLen::length, trkf::CCTrackMaker::clPar::Length, lessThan(), trkf::CCTrackMaker::clPar::MergeError, trkf::CCTrackMaker::clPar::mVtxIndex, trkf::CCTrackMaker::vtxPar::nClusInPln, recob::tracking::Plane::Plane(), tca::PrintClusters(), art::Event::put(), seed, trkf::CCTrackMaker::clPar::Slope, recob::Cluster::StartAngle(), recob::Cluster::StartCharge(), recob::Cluster::StartTick(), recob::Cluster::StartWire(), trkf::CCTrackMaker::clPar::Time, trkf::CCTrackMaker::clPar::TotChg, track, trkf::CCTrackMaker::clPar::VtxIndex, trkf::CCTrackMaker::clPar::Wire, trkf::CCTrackMaker::clPar::X, trkf::CCTrackMaker::vtxPar::X, trkf::CCTrackMaker::vtxPar::Y, and trkf::CCTrackMaker::vtxPar::Z.

389  {
390 
391  detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
392 
394 
395  fChgWindow = 40; // window (ticks) for identifying shower-like clusters
396 
397  std::unique_ptr<std::vector<recob::Track>> tcol(new std::vector<recob::Track>);
398  std::unique_ptr<art::Assns<recob::Track, recob::Hit> > thassn (new art::Assns<recob::Track, recob::Hit>);
399 
400  std::unique_ptr<std::vector<recob::Vertex>> vcol(new std::vector<recob::Vertex>);
401 
402  std::unique_ptr<std::vector<recob::PFParticle>> pcol(new std::vector<recob::PFParticle>);
403 
404  std::unique_ptr< art::Assns<recob::PFParticle, recob::Track> > ptassn( new art::Assns<recob::PFParticle, recob::Track> );
405  std::unique_ptr< art::Assns<recob::PFParticle, recob::Cluster> > pcassn( new art::Assns<recob::PFParticle, recob::Cluster> );
406  std::unique_ptr< art::Assns<recob::PFParticle, recob::Seed> > psassn( new art::Assns<recob::PFParticle, recob::Seed> );
407  std::unique_ptr< art::Assns<recob::PFParticle, recob::Vertex> > pvassn( new art::Assns<recob::PFParticle, recob::Vertex> );
408 
409  // seed collection
410  std::unique_ptr<std::vector<recob::Seed>> scol(new std::vector<recob::Seed>);
411  std::unique_ptr<art::Assns<recob::Seed, recob::Hit> > shassn (new art::Assns<recob::Seed, recob::Hit>);
412 
413  // all hits
414  art::Handle< std::vector<recob::Hit> > allhitsListHandle;
415  // cluster list
416  art::Handle< std::vector<recob::Cluster> > clusterListHandle;
417  std::vector<art::Ptr<recob::Cluster>> clusterlist;
418  // ClusterCrawler Vertices
420  std::vector<art::Ptr<recob::Vertex>> vtxlist;
421 
422  // get Hits
423  allhits.clear();
424  if (evt.getByLabel(fHitModuleLabel, allhitsListHandle))
425  art::fill_ptr_vector(allhits, allhitsListHandle);
426 
427  // get Clusters
428  if (evt.getByLabel(fClusterModuleLabel, clusterListHandle))
429  art::fill_ptr_vector(clusterlist, clusterListHandle);
430  if(clusterlist.size() == 0) return;
431  // get cluster - hit associations
432  art::FindManyP<recob::Hit> fmCluHits(clusterListHandle, evt, fClusterModuleLabel);
433  // pfmCluHits.reset(something goes here);
434 
435  // get Vertices
436  if (evt.getByLabel(fVertexModuleLabel, VtxListHandle))
437  art::fill_ptr_vector(vtxlist, VtxListHandle);
439 
440  std::vector<CluLen> clulens;
441 
442  unsigned short ipl, icl, end, itr, tID, tIndex;
443 
444  // maximum error (see MakeClusterChains) for considering clusters broken
445  fMaxMergeError = 30;
446  // Cut on the error for a definitely broken cluster. Clusters with fMergeErrorCut < MergeError < fMaxMergeError
447  // are possibly broken clusters but we will consider these when matching between planes
448  fMergeErrorCut = 10;
449 
450  std::vector< art::Ptr<recob::Hit > > tmpHits;
451  std::vector< art::Ptr<recob::Cluster > > tmpCls;
452  std::vector< art::Ptr<recob::Vertex > > tmpVtx;
453 
454  // vector for PFParticle constructor
455  std::vector<size_t> dtrIndices;
456 
457  // some vectors for recob::Seed
458  double sPos[3], sDir[3];
459  double sErr[3] = {0,0,0};
460 
461  // check consistency between clusters and associated hits
462  std::vector<art::Ptr<recob::Hit>> clusterhits;
463  for(icl = 0; icl < clusterlist.size(); ++icl) {
464  ipl = clusterlist[icl]->Plane().Plane;
465  clusterhits = fmCluHits.at(icl);
466  if(clusterhits[0]->WireID().Wire != std::nearbyint(clusterlist[icl]->EndWire())) {
467  std::cout<<"CCTM Cluster-Hit End wire mis-match "<<clusterhits[0]->WireID().Wire<<" vs "<<std::nearbyint(clusterlist[icl]->EndWire())<<" Bail out! \n";
468  return;
469  }
470  for(unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
471  if(clusterhits[iht]->WireID().Plane != ipl) {
472  std::cout<<"CCTM Cluster-Hit plane mis-match "<<ipl<<" vs "<<clusterhits[iht]->WireID().Plane<<" on hit "<<iht<<" Bail out! \n";
473  return;
474  } // hit-cluster plane mis-match
475  } // iht
476  } // icl
477  // end check consistency
478 
479 // std::cout<<"************ event "<<evt.event()<<"\n";
480 
481  vtx.clear();
482  trk.clear();
483  for(cstat = 0; cstat < geom->Ncryostats(); ++cstat) {
484  for(tpc = 0; tpc < geom->Cryostat(cstat).NTPC(); ++tpc) {
486  if(nplanes > 3) continue;
487  for(ipl = 0; ipl < 3; ++ipl) {
488  cls[ipl].clear();
489  clsChain[ipl].clear();
490  trkHits[ipl].clear();
491  } // ipl
492  // FillWireHitRange also calculates the charge in each plane
494  for(ipl = 0; ipl < nplanes; ++ipl) {
495  clulens.clear();
496  // sort clusters by increasing End wire number
497  for(icl = 0; icl < clusterlist.size(); ++icl) {
498  if(clusterlist[icl]->Plane().Cryostat != cstat) continue;
499  if(clusterlist[icl]->Plane().TPC != tpc) continue;
500  if(clusterlist[icl]->Plane().Plane != ipl) continue;
501  CluLen clulen;
502  clulen.index = icl;
503  clulen.length = clusterlist[icl]->EndWire();
504  clulens.push_back(clulen);
505  }
506  if(clulens.size() == 0) continue;
507  // sort clusters
508  std::sort (clulens.begin(),clulens.end(), lessThan);
509  if(clulens.size() == 0) continue;
510  for(unsigned short ii = 0; ii < clulens.size(); ++ii) {
511  const unsigned short icl = clulens[ii].index;
512  clPar clstr;
513  clstr.EvtIndex = icl;
514  recob::Cluster const& cluster = *(clusterlist[icl]);
515  // Begin info -> end index 1 (DS)
516  clstr.Wire[1] = cluster.StartWire();
517  clstr.Time[1] = cluster.StartTick();
518  clstr.X[1] = (float)detprop->ConvertTicksToX(cluster.StartTick(), ipl, tpc, cstat);
519  clstr.Angle[1] = cluster.StartAngle();
520  clstr.Slope[1] = std::tan(cluster.StartAngle());
521  clstr.Dir[1] = 0;
522 // if(fabs(clstr.Slope[1]) > 0.02) clstr.Dir[1] = -1 * (2*(clstr.Slope[1]>0)-1);
523  clstr.Charge[1] = ChgNorm[ipl] * cluster.StartCharge();
524  // this will be filled later
525  clstr.ChgNear[1] = 0;
526  clstr.VtxIndex[1] = -1;
527  clstr.mVtxIndex[1] = -1;
528  clstr.BrkIndex[1] = -1;
529  clstr.MergeError[1] = fMaxMergeError;
530  // End info -> end index 0 (US)
531  clstr.Wire[0] = cluster.EndWire();
532  clstr.Time[0] = cluster.EndTick();
533  clstr.X[0] = (float)detprop->ConvertTicksToX(cluster.EndTick(), ipl, tpc, cstat);
534  clstr.Angle[0] = cluster.EndAngle();
535  clstr.Slope[0] = std::tan(cluster.EndAngle());
536  clstr.Dir[0] = 0;
537 // if(fabs(clstr.Slope[0]) > 0.02) clstr.Dir[0] = 1 * (2*(clstr.Slope[0]>0)-1);
538  if(clstr.Time[1] > clstr.Time[0]) {
539  clstr.Dir[0] = 1; clstr.Dir[1] = -1;
540  } else {
541  clstr.Dir[0] = -1; clstr.Dir[1] = 1;
542  }
543  clstr.Charge[0] = ChgNorm[ipl] * cluster.EndCharge();
544  // this will be filled later
545  clstr.ChgNear[1] = 0;
546  clstr.VtxIndex[0] = -1;
547  clstr.mVtxIndex[0] = -1;
548  clstr.BrkIndex[0] = -1;
549  clstr.MergeError[0] = fMaxMergeError;
550  // other info
551  clstr.InTrack = -1;
552  clstr.Length = (unsigned short)(0.5 + clstr.Wire[1] - clstr.Wire[0]);
553  clstr.TotChg = ChgNorm[ipl] * cluster.Integral();
554  if(clstr.TotChg <= 0) clstr.TotChg = 1;
555  clusterhits = fmCluHits.at(icl);
556  if(clusterhits.size() == 0) {
557  mf::LogError("CCTM")<<"No associated cluster hits "<<icl;
558  continue;
559  }
560  // correct charge for missing cluster hits
561  clstr.TotChg *= clstr.Length / (float)clusterhits.size();
562  cls[ipl].push_back(clstr);
563  } // ii (icl)
564  } // ipl
565 
566 
567 // std::cout<<"FillChgNear "<<evt.event()<<"\n";
568  FillChgNear();
569 
570  // and finally the vertices
571  double xyz[3];
572  for(unsigned short ivx = 0; ivx < vtxlist.size(); ++ivx) {
573  vtxPar aVtx;
574  aVtx.ID = ivx + 1;
575  aVtx.EvtIndex = ivx;
576  vtxlist[ivx]->XYZ(xyz);
577  aVtx.X = xyz[0];
578  aVtx.Y = xyz[1];
579  aVtx.Z = xyz[2];
580  aVtx.nClusInPln[0] = 0;
581  aVtx.nClusInPln[1] = 0;
582  aVtx.nClusInPln[2] = 0;
583  std::vector<art::Ptr<recob::Cluster>> const& vtxCls = fmVtxCls.at(ivx);
584  std::vector<const unsigned short*> const& vtxClsEnd = fmVtxCls.data(ivx);
585  for(unsigned short vcass = 0; vcass < vtxCls.size(); ++vcass) {
586  icl = vtxCls[vcass].key();
587  // the cluster plane
588  ipl = vtxCls[vcass]->Plane().Plane;
589  end = *vtxClsEnd[vcass];
590  if(end > 1) throw cet::exception("CCTM")<<"Invalid end data from vertex - cluster association"<<end;
591  bool gotit = false;
592  // CCTM end is opposite of CC end
593  end = 1 - end;
594  for(unsigned short jcl = 0; jcl < cls[ipl].size(); ++jcl) {
595  if(cls[ipl][jcl].EvtIndex == icl) {
596  cls[ipl][jcl].VtxIndex[end] = ivx;
597  ++aVtx.nClusInPln[ipl];
598  gotit = true;
599  break;
600  } // index check
601  } // jcl
602  if(!gotit) throw cet::exception("CCTM")<<"Bad index from vertex - cluster association"<<icl;
603  } // icl
604  vtx.push_back(aVtx);
605  } // ivx
606  // Find broken clusters
607  MakeClusterChains(fmCluHits);
609 
610  // call algorithms in the specified order
611  matcomb.clear();
612  for(algIndex = 0; algIndex < fMatchAlgs.size(); ++algIndex) {
613  if(fMatchAlgs[algIndex] == 1) {
614  prt = (fDebugAlg == 1);
615  VtxMatch(fmCluHits);
616  if(fMakeAlgTracks[algIndex]) SortMatches(fmCluHits, 1);
617  } else
618  if(fMatchAlgs[algIndex] == 2) {
619  prt = (fDebugAlg == 2);
620  PlnMatch(fmCluHits);
621  if(fMakeAlgTracks[algIndex]) SortMatches(fmCluHits, 2);
622  }
623  if(prt) PrintClusters();
624  } // algIndex
625  prt = false;
626  pfpToTrkID.clear();
627  // Determine the vertex/track hierarchy
628  if(fMakePFPs) {
629  TagCosmics();
630  MakeFamily();
631  }
632  FitVertices();
633 
634  // Make PFParticles -> tracks
635  for(unsigned short ipf = 0; ipf < pfpToTrkID.size(); ++ipf) {
636  // trackID of this PFP
637  tID = pfpToTrkID[ipf];
638  if(tID > trk.size()+1) {
639  mf::LogWarning("CCTM")<<"Bad track ID";
640  continue;
641  }
642  dtrIndices.clear();
643  // load the daughter PFP indices
644  mf::LogVerbatim("CCTM")<<"PFParticle "<<ipf<<" tID "<<tID;
645  for(unsigned short jpf = 0; jpf < pfpToTrkID.size(); ++jpf) {
646  itr = pfpToTrkID[jpf] - 1; // convert from track ID to track index
647  if(trk[itr].MomID == tID) dtrIndices.push_back(jpf);
648  if(trk[itr].MomID == tID) mf::LogVerbatim("CCTM")<<" dtr jpf "<<jpf<<" itr "<<itr;
649  } // jpf
650  unsigned short parentIndex = USHRT_MAX;
651  if(tID == 0) {
652  // make neutrino PFP USHRT_MAX == primary PFP
653  recob::PFParticle pfp(14, ipf, parentIndex, dtrIndices);
654  pcol->emplace_back(std::move(pfp));
655  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
656  if(!vtx[ivx].Neutrino) continue;
657  // make the vertex
658  xyz[0] = vtx[ivx].X;
659  xyz[1] = vtx[ivx].Y;
660  xyz[2] = vtx[ivx].Z;
661  size_t vStart = vcol->size();
662  recob::Vertex vertex(xyz, vtx[ivx].ID);
663  vcol->emplace_back(std::move(vertex));
664  size_t vEnd = vcol->size();
665  // PFParticle - vertex association
666  util::CreateAssn(*this, evt, *pcol, *vcol, *pvassn, vStart, vEnd);
667  vtx[ivx].ID = -vtx[ivx].ID;
668  break;
669  } // ivx
670  } else if(tID > 0){
671  // make non-neutrino PFP. Need to find the parent PFP index
672  // Track index of this PFP
673  tIndex = tID - 1;
674  // trackID of this PFP parent
675  for(unsigned short ii = 0; ii < pfpToTrkID.size(); ++ii) {
676  if(pfpToTrkID[ii] == trk[tIndex].MomID) {
677  parentIndex = ii;
678  break;
679  }
680  } // ii
681  // PFParticle
682  mf::LogVerbatim("CCTM")<<"daughters tID "<<tID<<" pdg "<<trk[tIndex].PDGCode<<" ipf "<<ipf<<" parentIndex "<<parentIndex<<" dtr size "<<dtrIndices.size();
683  recob::PFParticle pfp(trk[tIndex].PDGCode, ipf, parentIndex, dtrIndices);
684  pcol->emplace_back(std::move(pfp));
685  // track
686  // make the track
687  size_t tStart = tcol->size();
690  recob::Track::Flags_t(trk[itr].TrjPos.size()), false),
692  tcol->emplace_back(std::move(track));
693  size_t tEnd = tcol->size();
694  // PFParticle - track association
695  util::CreateAssn(*this, evt, *pcol, *tcol, *ptassn, tStart, tEnd);
696  // flag this track as already put in the event
697  trk[tIndex].ID = -trk[tIndex].ID;
698  // track -> hits association
699  tmpHits.clear();
700  for(ipl = 0; ipl < nplanes; ++ipl)
701  tmpHits.insert(tmpHits.end(), trk[tIndex].TrkHits[ipl].begin(), trk[tIndex].TrkHits[ipl].end());
702  util::CreateAssn(*this, evt, *tcol, tmpHits, *thassn);
703  // Find seed hits and the end of the track that is best
704  end = 0;
705 // FindSeedHits(tIndex, end);
706  unsigned short itj = 0;
707  if(end > 0) itj = trk[tIndex].TrjPos.size() - 1;
708  for(unsigned short ii = 0; ii < 3; ++ii) {
709  sPos[ii] = trk[tIndex].TrjPos[itj](ii);
710  sDir[ii] = trk[tIndex].TrjDir[itj](ii);
711  } // ii
712  size_t sStart = scol->size();
713  recob::Seed seed(sPos, sDir, sErr, sErr);
714  scol->emplace_back(std::move(seed));
715  size_t sEnd = scol->size();
716  // PFP-seed association
717  util::CreateAssn(*this, evt, *pcol, *scol, *psassn, sStart, sEnd);
718  // Seed-hit association
719  tmpHits.clear();
720  for(ipl = 0; ipl < nplanes; ++ipl)
721  tmpHits.insert(tmpHits.end(), seedHits[ipl].begin(), seedHits[ipl].end());
722  util::CreateAssn(*this, evt, *scol, tmpHits, *shassn);
723  // cluster association
724  // PFP-cluster association
725  tmpCls.clear();
726  for(unsigned short ii = 0; ii < trk[tIndex].ClsEvtIndices.size(); ++ii) {
727  icl = trk[tIndex].ClsEvtIndices[ii];
728  tmpCls.push_back(clusterlist[icl]);
729  } // ii
730  util::CreateAssn(*this, evt, *pcol, tmpCls, *pcassn);
731  } // non-neutrino PFP
732  } // ipf
733  // make non-PFP tracks
734  for(unsigned short itr = 0; itr < trk.size(); ++itr) {
735  // ignore already saved tracks
736  if(trk[itr].ID < 0) continue;
739  recob::Track::Flags_t(trk[itr].TrjPos.size()), false),
741  tcol->emplace_back(std::move(track));
742  tmpHits.clear();
743  for(ipl = 0; ipl < nplanes; ++ipl)
744  tmpHits.insert(tmpHits.end(), trk[itr].TrkHits[ipl].begin(), trk[itr].TrkHits[ipl].end());
745  util::CreateAssn(*this, evt, *tcol, tmpHits, *thassn);
746  } // itr
747  // make remnant vertices
748  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
749  if(vtx[ivx].ID < 0) continue;
750  xyz[0] = vtx[ivx].X;
751  xyz[1] = vtx[ivx].Y;
752  xyz[2] = vtx[ivx].Z;
753  recob::Vertex vertex(xyz, vtx[ivx].ID);
754  vcol->emplace_back(std::move(vertex));
755  }
756  if(fDebugAlg > 0) PrintTracks();
757 
758  double orphanLen = 0;
759  for(ipl = 0; ipl < nplanes; ++ipl) {
760  for(icl = 0; icl < cls[ipl].size(); ++icl) {
761  if(cls[ipl][icl].Length > 40 && cls[ipl][icl].InTrack < 0) {
762  orphanLen += cls[ipl][icl].Length;
763  // unused cluster
764  mf::LogVerbatim("CCTM")<<"Orphan long cluster "<<ipl<<":"<<icl<<":"<<cls[ipl][icl].Wire[0]
765  <<":"<<(int)cls[ipl][icl].Time[0]<<" length "<<cls[ipl][icl].Length;
766  }
767  } // icl
768 
769  cls[ipl].clear();
770  clsChain[ipl].clear();
771  } // ipl
772  std::cout<<"Total orphan length "<<orphanLen<<"\n";
773  trkHits[ipl].clear();
774  seedHits[ipl].clear();
775  vxCls[ipl].clear();
776  } // tpc
777  } // cstat
778 
779  evt.put(std::move(pcol));
780  evt.put(std::move(ptassn));
781  evt.put(std::move(pcassn));
782  evt.put(std::move(pvassn));
783  evt.put(std::move(psassn));
784  evt.put(std::move(tcol));
785  evt.put(std::move(thassn));
786  evt.put(std::move(scol));
787  evt.put(std::move(vcol));
788 
789  // final cleanup
790  vtx.clear();
791  trk.clear();
792  allhits.clear();
793  matcomb.clear();
794  pfpToTrkID.clear();
795 
796 
797  } // produce
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< MatchPars > matcomb
std::string fVertexModuleLabel
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
Definition: TrackingTypes.h:85
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
Definition: TrackingTypes.h:58
unsigned int Nplanes() const
Number of planes in this tpc.
Definition: TPCGeo.h:145
std::vector< art::Ptr< recob::Hit > > allhits
TrackTrajectory::Flags_t Flags_t
Definition: Track.h:71
float StartWire() const
Returns the wire coordinate of the start of the cluster.
Definition: Cluster.h:286
Plane(const Point_t &planePos, const Vector_t &planeDir)
Constructor from reference position on the plane and direction orthogonal to the plane.
Definition: TrackingPlane.h:61
std::string fClusterModuleLabel
Set of hits with a 2D structure.
Definition: Cluster.h:71
float EndTick() const
Returns the tick coordinate of the end of the cluster.
Definition: Cluster.h:342
std::vector< unsigned short > pfpToTrkID
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
std::array< float, 3 > ChgNorm
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
std::array< std::vector< clPar >, 3 > cls
float StartAngle() const
Returns the starting angle of the cluster.
Definition: Cluster.h:475
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > seedHits
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
std::array< std::vector< ClsChainPar >, 3 > clsChain
float EndCharge() const
Returns the charge on the last wire of the cluster.
Definition: Cluster.h:498
long seed
Definition: chem4.cc:68
void MakeClusterChains(art::FindManyP< recob::Hit > const &fmCluHits)
A trajectory in space reconstructed from hits.
unsigned int NTPC() const
Number of TPCs in this cryostat.
Definition: CryostatGeo.h:155
std::vector< vtxPar > vtx
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
Definition: TrackingTypes.h:55
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > trkHits
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
Hierarchical representation of particle flow.
Definition: PFParticle.h:44
float StartCharge() const
Returns the charge on the first wire of the cluster.
Definition: Cluster.h:454
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
art::ServiceHandle< geo::Geometry > geom
bool lessThan(CluLen c1, CluLen c2)
void SortMatches(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short procCode)
void VtxMatch(art::FindManyP< recob::Hit > const &fmCluHits)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
void PlnMatch(art::FindManyP< recob::Hit > const &fmCluHits)
std::vector< bool > fMakeAlgTracks
std::vector< short > fMatchAlgs
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:464
float EndAngle() const
Returns the ending angle of the cluster.
Definition: Cluster.h:519
recob::tracking::Plane Plane
Definition: TrackState.h:17
Float_t track
Definition: plot.C:34
float StartTick() const
Returns the tick coordinate of the start of the cluster.
Definition: Cluster.h:297
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:52
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
const detinfo::DetectorProperties * detprop
std::array< std::vector< unsigned short >, 3 > vxCls
float Integral() const
Returns the total charge of the cluster from hit shape.
Definition: Cluster.h:600
float EndWire() const
Returns the wire coordinate of the end of the cluster.
Definition: Cluster.h:329
vertex reconstruction
void trkf::CCTrackMaker::reconfigure ( fhicl::ParameterSet const &  p)

Definition at line 321 of file CCTrackMaker_module.cc.

References fhicl::ParameterSet::get().

322  {
323  fHitModuleLabel = pset.get< std::string >("HitModuleLabel");
324  fClusterModuleLabel = pset.get< std::string >("ClusterModuleLabel");
325  fVertexModuleLabel = pset.get< std::string >("VertexModuleLabel");
326  // track matching
327  fMatchAlgs = pset.get< std::vector<short> >("MatchAlgs");
328  fXMatchErr = pset.get< std::vector<float> >("XMatchErr");
329  fAngleMatchErr = pset.get< std::vector<float> >("AngleMatchErr");
330  fChgAsymFactor = pset.get< std::vector<float> >("ChgAsymFactor");
331  fMatchMinLen = pset.get< std::vector<float> >("MatchMinLen");
332  fMakeAlgTracks = pset.get< std::vector<bool> >("MakeAlgTracks");
333  // Cluster merging
334  fMaxDAng = pset.get< float >("MaxDAng");
335  fChainMaxdX = pset.get< float >("ChainMaxdX");
336  fChainVtxAng = pset.get< float >("ChainVtxAng");
337  fMergeChgAsym = pset.get< float >("MergeChgAsym");
338  // Cosmic ray tagging
339  fFiducialCut = pset.get< float >("FiducialCut");
340  fDeltaRayCut = pset.get< float >("DeltaRayCut");
341  // make PFParticles
342  fMakePFPs = pset.get< bool >("MakePFPs");
343  // vertex fitting
344  fNVtxTrkHitsFit = pset.get< unsigned short >("NVtxTrkHitsFit");
345  fHitFitErrFac = pset.get< float >("HitFitErrFac");
346  // uB code
347  fuBCode = pset.get< bool >("uBCode");
348  // debugging inputs
349  fDebugAlg = pset.get< short >("DebugAlg");
350  fDebugPlane = pset.get< short >("DebugPlane");
351  fDebugCluster = pset.get< short >("DebugCluster");
352  fPrintAllClusters = pset.get< bool >("PrintAllClusters");
353 
354  // Consistency check
355  if(fMatchAlgs.size() > fXMatchErr.size() || fMatchAlgs.size() > fAngleMatchErr.size()
356  || fMatchAlgs.size() > fChgAsymFactor.size() || fMatchAlgs.size() > fMatchMinLen.size()
357  || fMatchAlgs.size() > fMakeAlgTracks.size()) {
358  mf::LogError("CCTM")<<"Incompatible fcl input vector sizes";
359  return;
360  }
361  // Reality check
362  for(unsigned short ii = 0; ii < fMatchAlgs.size(); ++ii) {
363  if(fAngleMatchErr[ii] <= 0 || fXMatchErr[ii] <= 0) {
364  mf::LogError("CCTM")<<"Invalid matching parameters "<<fAngleMatchErr[ii]<<" "<<fXMatchErr[ii];
365  return;
366  }
367  } // ii
368 
369  } // reconfigure
std::string fVertexModuleLabel
std::vector< float > fChgAsymFactor
std::string fClusterModuleLabel
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::vector< float > fAngleMatchErr
std::vector< float > fMatchMinLen
std::vector< bool > fMakeAlgTracks
std::vector< short > fMatchAlgs
std::vector< float > fXMatchErr
unsigned short fNVtxTrkHitsFit
void art::Consumer::showMissingConsumes ( ) const
protectedinherited

Definition at line 125 of file Consumer.cc.

Referenced by art::EDProducer::doEndJob(), art::EDFilter::doEndJob(), art::EDAnalyzer::doEndJob(), and art::RootOutput::endJob().

126 {
127  if (!moduleContext_)
128  return;
129 
130  // If none of the branches have missing consumes statements, exit early.
131  if (std::all_of(cbegin(missingConsumes_),
132  cend(missingConsumes_),
133  [](auto const& perBranch) { return perBranch.empty(); }))
134  return;
135 
136  constexpr cet::HorizontalRule rule{60};
137  mf::LogPrint log{"MTdiagnostics"};
138  log << '\n'
139  << rule('=') << '\n'
140  << "The following consumes (or mayConsume) statements are missing from\n"
141  << module_context(moduleDescription_) << '\n'
142  << rule('-') << '\n';
143 
144  cet::for_all_with_index(
145  missingConsumes_, [&log](std::size_t const i, auto const& perBranch) {
146  for (auto const& pi : perBranch) {
147  log << " "
148  << assemble_consumes_statement(static_cast<BranchType>(i), pi)
149  << '\n';
150  }
151  });
152  log << rule('=');
153 }
cet::exempt_ptr< ModuleDescription const > moduleDescription_
Definition: Consumer.h:140
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
bool moduleContext_
Definition: Consumer.h:136
ConsumableProductSets missingConsumes_
Definition: Consumer.h:139
void trkf::CCTrackMaker::SortMatches ( art::FindManyP< recob::Hit > const &  fmCluHits,
unsigned short  procCode 
)
private

Definition at line 2374 of file CCTrackMaker_module.cc.

References evd::details::begin(), evd::details::end(), trkf::fill(), CluLen::index, CluLen::length, lessThan(), and art::right().

2375  {
2376  // sort cluster matches by increasing total match error. Find the minimum total error of all
2377  // cluster match combinations and make tracks from them
2378  CluLen merr;
2379  std::vector<CluLen> materr;
2380  unsigned int ii, im;
2381 
2382  if(matcomb.size() == 0) return;
2383 
2384  // sort by decreasing error
2385  for(ii = 0; ii < matcomb.size(); ++ii) {
2386  merr.index = ii;
2387  merr.length = matcomb[ii].Err + matcomb[ii].oErr;
2388  materr.push_back(merr);
2389  } // ii
2390  std::sort(materr.begin(), materr.end(), lessThan);
2391 
2392  if(prt) {
2393  mf::LogVerbatim myprt("CCTM");
2394  myprt<<"SortMatches\n";
2395  myprt<<" ii im Vx Err dW dA dX oVx oErr odW odA odX Asym icl jcl kcl \n";
2396  for(ii = 0; ii < materr.size(); ++ii) {
2397  im = materr[ii].index;
2398  float asym = fabs(matcomb[im].Chg[0] - matcomb[im].Chg[1]) /
2399  (matcomb[im].Chg[0] + matcomb[im].Chg[1]);
2400  asym *= fabs(matcomb[im].Chg[1] - matcomb[im].Chg[2]) /
2401  (matcomb[im].Chg[1] + matcomb[im].Chg[2]);
2402  myprt<<std::fixed<<std::right
2403  <<std::setw(5)<<ii<<std::setw(5)<<im
2404  <<std::setw(4)<<matcomb[im].Vtx
2405  <<std::setw(7)<<std::setprecision(2)<<matcomb[im].Err
2406  <<std::setw(7)<<std::setprecision(1)<<matcomb[im].dWir
2407  <<std::setw(7)<<std::setprecision(2)<<matcomb[im].dAng
2408  <<std::setw(7)<<std::setprecision(2)<<matcomb[im].dX
2409  <<std::setw(4)<<matcomb[im].oVtx
2410  <<std::setw(7)<<std::setprecision(2)<<matcomb[im].oErr
2411  <<std::setw(7)<<std::setprecision(1)<<matcomb[im].odWir
2412  <<std::setw(7)<<std::setprecision(2)<<matcomb[im].odAng
2413  <<std::setw(7)<<std::setprecision(2)<<matcomb[im].odX
2414  <<std::setw(7)<<std::setprecision(3)<<asym
2415  <<" 0:"<<matcomb[im].Cls[0]<<":"<<matcomb[im].End[0]
2416  <<" 1:"<<matcomb[im].Cls[1]<<":"<<matcomb[im].End[1];
2417  if(nplanes > 2) myprt<<" 2:"<<matcomb[im].Cls[2]<<":"<<matcomb[im].End[2];
2418  myprt<<"\n";
2419  } // ii
2420  } // prt
2421 
2422  // define an array to ensure clusters are only used once
2423  std::array<std::vector<bool>, 3> pclUsed;
2424  unsigned short ipl;
2425  for(ipl = 0; ipl < nplanes; ++ipl) {
2426  pclUsed[ipl].resize(clsChain[ipl].size());
2427 // std::fill(pclUsed[ipl].begin(), pclUsed[ipl].end(), false);
2428  }
2429 
2430  // count the total number of clusters and length used in matcomb
2431  unsigned short matcombTotCl = 0;
2432  float matcombTotLen = 0;
2433  unsigned short icl;
2434  for(ii = 0; ii < matcomb.size(); ++ii) {
2435  for(ipl = 0; ipl < nplanes; ++ipl) {
2436  if(matcomb[ii].Cls[ipl] < 0) continue;
2437  icl = matcomb[ii].Cls[ipl];
2438  ++matcombTotCl;
2439  matcombTotLen += clsChain[ipl][icl].Length;
2440  }
2441  }
2442 
2443  if(prt) mf::LogVerbatim("CCTM")<<"Number of clusters to match "<<matcombTotCl <<" total length "<<matcombTotLen;
2444 
2445  if(matcombTotLen <= 0) {
2446  mf::LogError("CCTM")<<"SortMatches: bad matcomb total length "<<matcombTotLen;
2447  return;
2448  }
2449 
2450  // vector of matcomb indices of unique cluster matches
2451  std::vector<unsigned short> matIndex;
2452  // vector of matcomb indices of unique cluster matches that have the best total error
2453  std::vector<unsigned short> bestMatIndex;
2454  float totLen, totErr, bestTotErr = 9999;
2455  // start with the best match
2456  unsigned short jj, jm, nused, jcl;
2457  // fraction of the length of all clustters in matcomb that are used in a match
2458  float fracLen;
2459 
2460  for(ii = 0; ii < materr.size(); ++ii) {
2461  im = materr[ii].index;
2462  matIndex.clear();
2463  // skip really bad matches
2464  if(matcomb[im].Err > bestTotErr) continue;
2465  totLen = 0;
2466  // initialize pclUsed and flag the clusters in this match
2467  // mf::LogVerbatim("CCTM")<<"chk ii "<<ii<<" clusters "<<matcomb[im].Cls[0]<<" "<<matcomb[im].Cls[1]<<" "<<matcomb[im].Cls[2];
2468  for(ipl = 0; ipl < nplanes; ++ipl) {
2469  // initialize to no clusters used
2470  std::fill(pclUsed[ipl].begin(), pclUsed[ipl].end(), false);
2471  // check for 2 plane match
2472  if(matcomb[im].Cls[ipl] < 0) continue;
2473  icl = matcomb[im].Cls[ipl];
2474  pclUsed[ipl][icl] = true;
2475  totLen += clsChain[ipl][icl].Length;
2476  } // ipl
2477  // Initialize the error sum
2478  totErr = matcomb[im].Err;
2479  // Save the index
2480  matIndex.push_back(im);
2481  // look for matches in the rest of the list that are not already matched.
2482  for(jj = 0; jj < materr.size(); ++jj) {
2483  if(jj == ii) continue;
2484  jm = materr[jj].index;
2485  // skip really bad matches
2486  if(matcomb[jm].Err > bestTotErr) continue;
2487  // mf::LogVerbatim("CCTM")<<"chk match jj "<<jj<<" clusters "<<matcomb[jm].Cls[0]<<" "<<matcomb[jm].Cls[1]<<" "<<matcomb[jm].Cls[2];
2488  // check for non-unique cluster indices
2489  nused = 0;
2490  for(ipl = 0; ipl < nplanes; ++ipl) {
2491  if(matcomb[jm].Cls[ipl] < 0) continue;
2492  jcl = matcomb[jm].Cls[ipl];
2493  if(pclUsed[ipl][jcl]) ++nused;
2494  // This cluster chain was used in a previous match
2495  if(nused > 0) break;
2496  totLen += clsChain[ipl][jcl].Length;
2497  } // ipl
2498  // at least one of the clusters in this match have been used
2499  if(nused != 0) continue;
2500  // found a match with an unmatched set of clusters. Update the total error and flag them
2501  totErr += matcomb[jm].Err;
2502  matIndex.push_back(jm);
2503  // Flag the clusters used and see if all of them are used
2504  for(ipl = 0; ipl < nplanes; ++ipl) {
2505  if(matcomb[jm].Cls[ipl] < 0) continue;
2506  jcl = matcomb[jm].Cls[ipl];
2507  pclUsed[ipl][jcl] = true;
2508  } // ipl
2509  } // jm
2510  if(totLen == 0) continue;
2511  nused = 0;
2512  for(ipl = 0; ipl < nplanes; ++ipl) {
2513  for(unsigned short indx = 0; indx < pclUsed[ipl].size(); ++indx) if(pclUsed[ipl][indx]) ++nused;
2514  } // ipl
2515  if(totLen > matcombTotLen) std::cout<<"Oops "<<totLen<<" "<<matcombTotLen<<"\n";
2516  // weight the total error by the total length of all clusters
2517  fracLen = totLen / matcombTotLen;
2518 // totErr = totErr * nused / totLen;
2519 // totErr = totErr * matIndex.size() / fracLen;
2520  totErr /= fracLen;
2521  if(prt) {
2522  mf::LogVerbatim myprt("CCTM");
2523  myprt<<"match "<<im<<" totErr "<<totErr<<" nused "<<nused<<" fracLen "<<fracLen<<" totLen "<<totLen<<" mat: ";
2524  for(unsigned short indx = 0; indx < matIndex.size(); ++indx) myprt<<" "<<matIndex[indx];
2525  } // prt
2526  // check for more used clusters and a better total error
2527 // if(totErr < bestTotErr) {
2528  if(totErr < bestTotErr) {
2529  bestTotErr = totErr;
2530  bestMatIndex = matIndex;
2531  if(nused == matcombTotCl) break;
2532  if(prt) {
2533  mf::LogVerbatim myprt("CCTM");
2534  myprt<<"bestTotErr "<<bestTotErr<<" nused "<<nused<<" matcombTotCl "<<matcombTotCl<<" mat: ";
2535  for(unsigned short indx = 0; indx < bestMatIndex.size(); ++indx) myprt<<" "<<bestMatIndex[indx];
2536  } // prt
2537  // stop looking if we have found everything
2538  if(fracLen > 0.999) break;
2539  } // totErr < bestTotErr
2540  } // im
2541 
2542  if(bestTotErr > 9000) return;
2543 
2544  for(ii = 0; ii < bestMatIndex.size(); ++ii) {
2545  im = bestMatIndex[ii];
2546  // if(prt) mf::LogVerbatim("CCTM")<<"SM: "<<ii<<" im "<<im<<" 0:"<<matcomb[im].Cls[0]<<":"<<matcomb[im].End[0]<<" 1:"<<matcomb[im].Cls[1]<<":"<<matcomb[im].End[1]<<" 2:"<<matcomb[im].Cls[2]<<":"<<matcomb[im].End[2];
2547  // std::cout<<"FillTrkHits "<<ii<<"\n";
2548  FillTrkHits(fmCluHits, im);
2549  // look for missing clusters?
2550  // store this track with processor code 1
2551  StoreTrack(fmCluHits, im, procCode);
2552  } // ii
2553 
2554  } // SortMatches
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< MatchPars > matcomb
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::array< std::vector< ClsChainPar >, 3 > clsChain
void FillTrkHits(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat)
std::vector< evd::details::RawDigitInfo_t >::const_iterator begin(RawDigitCacheDataClass const &cache)
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
void StoreTrack(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short imat, unsigned short procCode)
bool lessThan(CluLen c1, CluLen c2)
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
void trkf::CCTrackMaker::StoreTrack ( art::FindManyP< recob::Hit > const &  fmCluHits,
unsigned short  imat,
unsigned short  procCode 
)
private

Definition at line 1876 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::TrkPar::ChgOrder, trkf::CCTrackMaker::TrkPar::ClsEvtIndices, dir, trkf::CCTrackMaker::TrkPar::DtrID, evd::details::end(), trkf::CCTrackMaker::TrkPar::EndInTPC, trkf::CCTrackMaker::TrkPar::GoodEnd, trkf::CCTrackMaker::TrkPar::ID, trkf::CCTrackMaker::TrkPar::Length, trkf::CCTrackMaker::TrkPar::MomID, norm, trkf::CCTrackMaker::TrkPar::PDGCode, trkf::CCTrackMaker::TrkPar::Proc, trkf::CCTrackMaker::TrkPar::TrjDir, trkf::CCTrackMaker::TrkPar::TrjPos, trkf::CCTrackMaker::TrkPar::TrkHits, trkf::CCTrackMaker::TrkPar::VtxIndex, X, Y, and Z.

1878  {
1879  // store the current "under construction" track in the trk vector
1880 
1881  TrkPar newtrk;
1882 
1883  if(imat > matcomb.size() - 1) {
1884  mf::LogError("CCTM")<<"Bad imat in StoreTrack";
1885  return;
1886  }
1887 
1888  // ensure there are at least 2 hits in at least 2 planes
1889  unsigned short nhitinpl = 0;
1890  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) if(trkHits[ipl].size() > 1) ++nhitinpl;
1891  if(nhitinpl < 2) {
1892  mf::LogError("CCTM")<<"StoreTrack: Not enough hits in each plane\n";
1893  return;
1894  }
1895  if(prt) mf::LogVerbatim("CCTM")<<"In StoreTrack: matcomb "<<imat<<" cluster chains "<<matcomb[imat].Cls[0]<<" "<<matcomb[imat].Cls[1]<<" "<<matcomb[imat].Cls[2];
1896 
1897  // Track hit vectors for fitting the trajectory
1898  std::array<std::vector<geo::WireID>,3> trkWID;
1899  std::array<std::vector<double>,3> trkX;
1900  std::array<std::vector<double>,3> trkXErr;
1901 
1902  // track trajectory for a track
1903  std::vector<TVector3> trkPos;
1904  std::vector<TVector3> trkDir;
1905 
1906  newtrk.ID = trk.size() + 1;
1907  newtrk.Proc = procCode;
1908  newtrk.TrkHits = trkHits;
1909  // BUG the double brace syntax is required to work around clang bug 21629
1910  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1911  newtrk.VtxIndex = {{-1, -1}};
1912  newtrk.ChgOrder = 0;
1913  newtrk.MomID = -1;
1914  // BUG the double brace syntax is required to work around clang bug 21629
1915  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1916  newtrk.EndInTPC = {{false, false}};
1917  newtrk.GoodEnd = {{false, false}};
1918  newtrk.DtrID = {0};
1919  newtrk.PDGCode = -1;
1920 
1921  unsigned short ipl, icl, iht;
1922 
1923  if(prt) mf::LogVerbatim("CCTM")<<"CCTM: Make traj for track "<<newtrk.ID<<" procCode "<<procCode<<" nhits in planes "<<trkHits[0].size()<<" "<<trkHits[1].size()<<" "<<trkHits[2].size();
1924  // make the track trajectory
1925  if(nplanes == 2) {
1926  trkWID[2].resize(0);
1927  trkX[2].resize(0);
1928  trkXErr[2].resize(0);
1929  }
1930  for(ipl = 0; ipl < nplanes; ++ipl) {
1931  trkWID[ipl].resize(trkHits[ipl].size());
1932  trkX[ipl].resize(trkHits[ipl].size());
1933  trkXErr[ipl].resize(trkHits[ipl].size());
1934  for(iht = 0; iht < trkHits[ipl].size(); ++iht) {
1935  trkWID[ipl][iht] = trkHits[ipl][iht]->WireID();
1936  trkX[ipl][iht] = detprop->ConvertTicksToX(trkHits[ipl][iht]->PeakTime(),ipl, tpc, cstat);
1937  trkXErr[ipl][iht] = fHitFitErrFac * trkHits[ipl][iht]->RMS() * trkHits[ipl][iht]->Multiplicity();
1938 // std::cout<<iht<<" "<<trkWID[ipl][iht]<<" "<<trkX[ipl][iht]<<" "<<trkXErr[ipl][iht]<<"\n";
1939  } // iht
1940  } // ipl
1941  fTrackTrajectoryAlg.TrackTrajectory(trkWID, trkX, trkXErr, trkPos, trkDir);
1942  if(trkPos.size() < 2) {
1943  mf::LogError("CCTM")<<"StoreTrack: No trajectory points on failed track "<<newtrk.ID
1944  <<" in StoreTrack: matcomb "<<imat<<" cluster chains "<<matcomb[imat].Cls[0]<<" "<<matcomb[imat].Cls[1]<<" "<<matcomb[imat].Cls[2];
1945  // make a garbage trajectory
1946  trkPos.resize(2);
1947  trkPos[1](2) = 1;
1948  trkDir.resize(2);
1949  trkDir[1](2) = 1;
1950  }
1951  newtrk.TrjPos = trkPos;
1952  newtrk.TrjDir = trkDir;
1953 
1954  if(prt) mf::LogVerbatim("CCTM")<<" number of traj points "<<trkPos.size();
1955 
1956  // determine if each end is good in the sense that there are hits in each plane
1957  // that are consistent in time and are presumed to form a good 3D space point
1958  unsigned short end, nClose, indx, jndx;
1959  float xErr;
1960  for(end = 0; end < 2; ++end) {
1961  nClose = 0;
1962  for(ipl = 0; ipl < nplanes - 1; ++ipl) {
1963  if(trkX[ipl].size() == 0) continue;
1964  for(unsigned short jpl = ipl + 1; jpl < nplanes; ++jpl) {
1965  if(trkX[jpl].size() == 0) continue;
1966  if(end == 0) {
1967  indx = 0;
1968  jndx = 0;
1969  } else {
1970  indx = trkXErr[ipl].size() - 1;
1971  jndx = trkXErr[jpl].size() - 1;
1972  }
1973  xErr = 3 * (trkXErr[ipl][indx] + trkXErr[jpl][jndx]);
1974  if(std::abs(trkX[ipl][indx] - trkX[jpl][jndx]) < xErr) ++nClose;
1975  } // jpl
1976  } // ipl
1977  if(nClose == nplanes) newtrk.GoodEnd[end] = true;
1978  } // end
1979 
1980  // set trajectory end points to a vertex if one exists
1981  unsigned short ivx, itj, ccl;
1982  float dx, dy, dz, dr0, dr1;
1983  unsigned short attachEnd;
1984  for(end = 0; end < 2; ++end) {
1985  ivx = USHRT_MAX;
1986  if(end == 0 && matcomb[imat].Vtx >= 0) ivx = matcomb[imat].Vtx;
1987  if(end == 1 && matcomb[imat].oVtx >= 0) ivx = matcomb[imat].oVtx;
1988  if(ivx == USHRT_MAX) continue;
1989  // determine the proper end using the TrjPos order and brute force
1990  itj = 0;
1991  dx = vtx[ivx].X - newtrk.TrjPos[itj](0);
1992  dy = vtx[ivx].Y - newtrk.TrjPos[itj](1);
1993  dz = vtx[ivx].Z - newtrk.TrjPos[itj](2);
1994  dr0 = dx*dx + dy*dy + dz*dz;
1995  itj = newtrk.TrjPos.size() - 1;
1996  dx = vtx[ivx].X - newtrk.TrjPos[itj](0);
1997  dy = vtx[ivx].Y - newtrk.TrjPos[itj](1);
1998  dz = vtx[ivx].Z - newtrk.TrjPos[itj](2);
1999  dr1 = dx*dx + dy*dy + dz*dz;
2000  attachEnd = 1;
2001  if(dr0 < dr1) {
2002  itj = 0;
2003  attachEnd = 0;
2004  // a really bad match to the vertex
2005  if(dr0 > 5) return;
2006  } else {
2007  // a really bad match to the vertex
2008  if(dr1 > 5) return;
2009  }
2010  newtrk.TrjPos[itj](0) = vtx[ivx].X;
2011  newtrk.TrjPos[itj](1) = vtx[ivx].Y;
2012  newtrk.TrjPos[itj](2) = vtx[ivx].Z;
2013  newtrk.VtxIndex[attachEnd] = ivx;
2014  // correct the trajectory direction
2015  TVector3 dir;
2016  if(itj == 0) {
2017  dir = newtrk.TrjPos[1] - newtrk.TrjPos[0];
2018  newtrk.TrjDir[0] = dir.Unit();
2019  } else {
2020  dir = newtrk.TrjPos[itj - 1] - newtrk.TrjPos[itj];
2021  newtrk.TrjDir[itj] = dir.Unit();
2022  }
2023  } // end
2024 
2025  if(newtrk.VtxIndex[0] >= 0 && newtrk.VtxIndex[0] == newtrk.VtxIndex[1]) {
2026  mf::LogError("CCTM")<<"StoreTrack: Trying to attach a vertex to both ends of a track. imat = "<<imat;
2027  return;
2028  }
2029 
2030  // calculate the length
2031  newtrk.Length = 0;
2032  float norm;
2033  double X, Y, Z;
2034  for(unsigned short itj = 1; itj < newtrk.TrjPos.size(); ++itj) {
2035  X = newtrk.TrjPos[itj](0) - newtrk.TrjPos[itj-1](0);
2036  Y = newtrk.TrjPos[itj](1) - newtrk.TrjPos[itj-1](1);
2037  Z = newtrk.TrjPos[itj](2) - newtrk.TrjPos[itj-1](2);
2038  norm = sqrt(X*X + Y*Y + Z*Z);
2039  newtrk.Length += norm;
2040  }
2041 
2042  // store the cluster -> track assignment
2043  newtrk.ClsEvtIndices.clear();
2044  for(ipl = 0; ipl < nplanes; ++ipl) {
2045  if(matcomb[imat].Cls[ipl] < 0) continue;
2046  ccl = matcomb[imat].Cls[ipl];
2047  if(ccl > clsChain[ipl].size()) std::cout<<"oops StoreTrack\n";
2048  clsChain[ipl][ccl].InTrack = newtrk.ID;
2049  for(unsigned short icc = 0; icc < clsChain[ipl][ccl].ClsIndex.size(); ++icc) {
2050  icl = clsChain[ipl][ccl].ClsIndex[icc];
2051  if(icl > cls[ipl].size()) std::cout<<"oops StoreTrack\n";
2052  cls[ipl][icl].InTrack = newtrk.ID;
2053  if(cls[ipl][icl].EvtIndex > fmCluHits.size() - 1) {
2054  std::cout<<"ooops2 store track EvtIndex "<<cls[ipl][icl].EvtIndex<<" size "<<fmCluHits.size()<<" icl "<<icl<<"\n";
2055  continue;
2056  }
2057  newtrk.ClsEvtIndices.push_back(cls[ipl][icl].EvtIndex);
2058  } // icc
2059  } // ipl
2060 
2061  if(prt) mf::LogVerbatim("CCTM")<<" track ID "<<newtrk.ID<<" stored in StoreTrack";
2062 
2063  trk.push_back(newtrk);
2064  } // StoreTrack
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< MatchPars > matcomb
Float_t Y
Definition: plot.C:39
TrackTrajectoryAlg fTrackTrajectoryAlg
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
std::array< std::vector< clPar >, 3 > cls
Float_t Z
Definition: plot.C:39
std::array< std::vector< ClsChainPar >, 3 > clsChain
std::vector< vtxPar > vtx
void TrackTrajectory(std::array< std::vector< geo::WireID >, 3 > trkWID, std::array< std::vector< double >, 3 > trkX, std::array< std::vector< double >, 3 > trkXErr, std::vector< TVector3 > &TrajPos, std::vector< TVector3 > &TrajDir)
std::array< std::vector< art::Ptr< recob::Hit > >, 3 > trkHits
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
Float_t norm
TDirectory * dir
Definition: macro.C:5
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
Float_t X
Definition: plot.C:39
const detinfo::DetectorProperties * detprop
void trkf::CCTrackMaker::TagCosmics ( )
private

Definition at line 1210 of file CCTrackMaker_module.cc.

References geo::TPCGeo::LocalToWorld().

1211  {
1212  // Make cosmic ray PFParticles
1213  unsigned short ipf, itj;
1214  bool skipit = true;
1215 
1216  // Y,Z limits of the detector
1217  double local[3] = {0.,0.,0.};
1218  double world[3] = {0.,0.,0.};
1219 
1220  const geo::TPCGeo &thetpc = geom->TPC(tpc, cstat);
1221  thetpc.LocalToWorld(local,world);
1222  float XLo = world[0] - geom->DetHalfWidth(tpc,cstat) + fFiducialCut;
1223  float XHi = world[0] + geom->DetHalfWidth(tpc,cstat) - fFiducialCut;
1224  float YLo = world[1] - geom->DetHalfHeight(tpc,cstat) + fFiducialCut;
1225  float YHi = world[1] + geom->DetHalfHeight(tpc,cstat) - fFiducialCut;
1226  float ZLo = world[2] - geom->DetLength(tpc,cstat)/2 + fFiducialCut;
1227  float ZHi = world[2] + geom->DetLength(tpc,cstat)/2 - fFiducialCut;
1228 
1229  bool startsIn, endsIn;
1230 
1231  for(unsigned short itk = 0; itk < trk.size(); ++itk) {
1232  // ignore already used tracks
1233  if(trk[itk].ID < 0) continue;
1234  // ignore short tracks (< 10 cm)
1235  if(trk[itk].Length < 10) continue;
1236  // check for already identified PFPs
1237  skipit = false;
1238  for(ipf = 0; ipf < pfpToTrkID.size(); ++ipf) {
1239  if(pfpToTrkID[ipf] == trk[itk].ID) {
1240  skipit = true;
1241  break;
1242  }
1243  } // ipf
1244  if(skipit) continue;
1245  startsIn = true;
1246  if(trk[itk].TrjPos[0](0) < XLo || trk[itk].TrjPos[0](0) > XHi) startsIn = false;
1247  if(trk[itk].TrjPos[0](1) < YLo || trk[itk].TrjPos[0](1) > YHi) startsIn = false;
1248  if(trk[itk].TrjPos[0](2) < ZLo || trk[itk].TrjPos[0](2) > ZHi) startsIn = false;
1249 // std::cout<<"Trk "<<trk[itk].ID<<" X0 "<<(int)trk[itk].TrjPos[0](0)<<" Y0 "<<(int)trk[itk].TrjPos[0](1)<<" Z0 "<<(int)trk[itk].TrjPos[0](2)<<" startsIn "<<startsIn<<"\n";
1250  if(startsIn) continue;
1251  endsIn = true;
1252  itj = trk[itk].TrjPos.size() - 1;
1253  if(trk[itk].TrjPos[itj](0) < XLo || trk[itk].TrjPos[itj](0) > XHi) endsIn = false;
1254  if(trk[itk].TrjPos[itj](1) < YLo || trk[itk].TrjPos[itj](1) > YHi) endsIn = false;
1255  if(trk[itk].TrjPos[itj](2) < ZLo || trk[itk].TrjPos[itj](2) > ZHi) endsIn = false;
1256 // std::cout<<" X1 "<<(int)trk[itk].TrjPos[itj](0)<<" Y1 "<<(int)trk[itk].TrjPos[itj](1)<<" Z1 "<<(int)trk[itk].TrjPos[itj](2)<<" endsIn "<<endsIn<<"\n";
1257  if(endsIn) continue;
1258  // call it a cosmic muon
1259  trk[itk].PDGCode = 13;
1260  pfpToTrkID.push_back(trk[itk].ID);
1261  } // itk
1262 
1263  if(fDeltaRayCut <= 0) return;
1264 
1265  for(unsigned short itk = 0; itk < trk.size(); ++itk) {
1266  // find a tagged cosmic ray
1267  if(trk[itk].PDGCode != 13) continue;
1268 
1269  } // itk
1270 
1271  } // TagCosmics
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
Geometry information for a single TPC.
Definition: TPCGeo.h:37
std::vector< unsigned short > pfpToTrkID
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
art::ServiceHandle< geo::Geometry > geom
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
Definition: TPCGeo.h:490
void art::Consumer::validateConsumedProduct ( BranchType const  bt,
ProductInfo const &  pi 
)
protectedinherited

Definition at line 101 of file Consumer.cc.

References art::errors::ProductRegistrationFailure.

103 {
104  // Early exits if consumes tracking has been disabled or if the
105  // consumed product is an allowed consumable.
106  if (!moduleContext_)
107  return;
108 
109  if (cet::binary_search_all(consumables_[bt], pi))
110  return;
111 
112  if (requireConsumes_) {
114  "Consumer: an error occurred during validation of a "
115  "retrieved product\n\n")
116  << "The following consumes (or mayConsume) statement is missing from\n"
117  << module_context(moduleDescription_) << ":\n\n"
118  << " " << assemble_consumes_statement(bt, pi) << "\n\n";
119  }
120 
121  missingConsumes_[bt].insert(pi);
122 }
cet::exempt_ptr< ModuleDescription const > moduleDescription_
Definition: Consumer.h:140
bool requireConsumes_
Definition: Consumer.h:137
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
ConsumableProducts consumables_
Definition: Consumer.h:138
bool moduleContext_
Definition: Consumer.h:136
ConsumableProductSets missingConsumes_
Definition: Consumer.h:139
void trkf::CCTrackMaker::VtxMatch ( art::FindManyP< recob::Hit > const &  fmCluHits)
private

Definition at line 1274 of file CCTrackMaker_module.cc.

References trkf::CCTrackMaker::MatchPars::Chg, clear(), trkf::CCTrackMaker::MatchPars::Cls, trkf::CCTrackMaker::MatchPars::End, trkf::CCTrackMaker::MatchPars::Err, trkf::CCTrackMaker::MatchPars::oErr, trkf::CCTrackMaker::MatchPars::oVtx, trkf::CCTrackMaker::MatchPars::Vtx, and X.

1275  {
1276  // Use vertex assignments to match clusters
1277  unsigned short ivx, ii, ipl, icl, jj, jpl, jcl, kk, kpl, kcl;
1278  short idir, iend, jdir, jend, kdir, kend, ioend;
1279 
1280  for(ivx = 0; ivx < vtx.size(); ++ivx) {
1281 
1282  // list of cluster chains associated with this vertex in each plane
1283  for(ipl = 0; ipl < nplanes; ++ipl) {
1284  vxCls[ipl].clear();
1285  for(icl = 0; icl < clsChain[ipl].size(); ++icl) {
1286  if(clsChain[ipl][icl].InTrack >= 0) continue;
1287  for(iend = 0; iend < 2; ++iend) {
1288  if(clsChain[ipl][icl].VtxIndex[iend] == vtx[ivx].EvtIndex) vxCls[ipl].push_back(icl);
1289  } // end
1290  } // icl
1291  } // ipl
1292 
1293  if(prt) {
1294  mf::LogVerbatim myprt("CCTM");
1295  myprt<<"VtxMatch: Vertex ID "<<vtx[ivx].EvtIndex<<"\n";
1296  for(ipl = 0; ipl < nplanes; ++ipl) {
1297  myprt<<"ipl "<<ipl<<" cls";
1298  for(unsigned short ii = 0; ii < vxCls[ipl].size(); ++ii) myprt<<" "<<vxCls[ipl][ii];
1299  myprt<<"\n";
1300  } // ipl
1301  } // prt
1302  // match between planes, requiring clusters matched to this vertex
1303  iend = 0; jend = 0;
1304  bool gotkcl;
1305  float totErr;
1306  for(ipl = 0; ipl < nplanes; ++ipl) {
1307  if(nplanes == 2 && ipl > 0) continue;
1308  for(ii = 0; ii < vxCls[ipl].size(); ++ii) {
1309  icl = vxCls[ipl][ii];
1310  // ignore used clusters
1311  if(clsChain[ipl][icl].InTrack >= 0) continue;
1312  jpl = (ipl + 1) % nplanes;
1313  kpl = (jpl + 1) % nplanes;
1314  for(jj = 0; jj < vxCls[jpl].size(); ++jj) {
1315  jcl = vxCls[jpl][jj];
1316  if(clsChain[jpl][jcl].InTrack >= 0) continue;
1317  for(iend = 0; iend < 2; ++iend) {
1318  if(clsChain[ipl][icl].VtxIndex[iend] != vtx[ivx].EvtIndex) continue;
1319  ioend = 1 - iend;
1320  idir = clsChain[ipl][icl].Dir[iend];
1321  for(jend = 0; jend < 2; ++jend) {
1322  if(clsChain[jpl][jcl].VtxIndex[jend] != vtx[ivx].EvtIndex) continue;
1323  jdir = clsChain[jpl][jcl].Dir[jend];
1324  if(idir != 0 && jdir != 0 && idir != jdir) continue;
1325  // ignore outrageously bad other end X matches
1326  if(fabs(clsChain[jpl][jcl].X[1 - jend] - clsChain[ipl][icl].X[ioend]) > 50) continue;
1327  MatchPars match;
1328  match.Cls[ipl] = icl; match.End[ipl] = iend;
1329  match.Cls[jpl] = jcl; match.End[jpl] = jend;
1330  match.Vtx = ivx; match.oVtx = -1;
1331  // set large so that DupMatch doesn't get confused when called before FillEndMatch
1332  match.Err = 1E6; match.oErr = 1E6;
1333  if(nplanes == 2) {
1334 // mf::LogVerbatim("CCTM")<<"chk "<<ipl<<":"<<match.Cls[ipl]<<":"<<match.End[ipl]<<" and "<<jpl<<":"<<match.Cls[jpl]<<":"<<match.End[jpl];
1335  FillEndMatch2(match);
1336  if(prt) mf::LogVerbatim("CCTM")<<"FillEndMatch2: Err "<<match.Err<<" oErr "<<match.oErr;
1337  if(match.Err + match.oErr > 100) continue;
1338  if(DupMatch(match)) continue;
1339  matcomb.push_back(match);
1340  continue;
1341  }
1342  match.Cls[kpl] = -1; match.End[kpl] = 0;
1343  if(prt) mf::LogVerbatim("CCTM")<<"VtxMatch: check "<<ipl<<":"<<icl<<":"<<iend<<" and "<<jpl<<":"<<jcl<<":"<<jend<<" for cluster in kpl "<<kpl;
1344  gotkcl = false;
1345  for(kk = 0; kk < vxCls[kpl].size(); ++kk) {
1346  kcl = vxCls[kpl][kk];
1347  if(clsChain[kpl][kcl].InTrack >= 0) continue;
1348  for(kend = 0; kend < 2; ++kend) {
1349  kdir = clsChain[kpl][kcl].Dir[kend];
1350  if(idir != 0 && kdir != 0 && idir != kdir) continue;
1351  if(clsChain[kpl][kcl].VtxIndex[kend] != vtx[ivx].EvtIndex) continue;
1352  // rough check of other end match
1353  // TODO: SHOWER-LIKE CLUSTER CHECK
1354  match.Cls[kpl] = kcl; match.End[kpl] = kend;
1355  // first call to ignore redundant matches
1356  if(DupMatch(match)) continue;
1357  FillEndMatch(match);
1358 // mf::LogVerbatim("CCTM")<<" Chg "<<match.Chg[kpl]<<" Err "<<match.Err<<" oErr "<<match.oErr;
1359  // ignore if no signal at the other end
1360  if(match.Chg[kpl] <= 0) continue;
1361  if(match.Err + match.oErr > 100) continue;
1362  // second call to keep matches with better error
1363  if(DupMatch(match)) continue;
1364  matcomb.push_back(match);
1365  gotkcl = true;
1366 // break;
1367  } // kend
1368  } // kk -> kcl
1369  if(gotkcl) continue;
1370  // look for a cluster that missed the vertex assignment
1371  float best = 10;
1372  short kbst = -1;
1373  unsigned short kbend = 0;
1374  if(prt) mf::LogVerbatim("CCTM")<<"VtxMatch: look for missed cluster chain in kpl";
1375  for(kcl = 0; kcl < clsChain[kpl].size(); ++kcl) {
1376  if(clsChain[kpl][kcl].InTrack >= 0) continue;
1377  for(kend = 0; kend < 2; ++kend) {
1378  kdir = clsChain[kpl][kcl].Dir[kend];
1379  if(idir != 0 && kdir != 0 && idir != kdir) continue;
1380  if(clsChain[kpl][kcl].VtxIndex[kend] >= 0) continue;
1381  // make a rough dX cut at the match end
1382  if(fabs(clsChain[kpl][kcl].X[kend] - vtx[ivx].X) > 5) continue;
1383  // and at the other end
1384  if(fabs(clsChain[kpl][kcl].X[1 - kend] - clsChain[ipl][icl].X[ioend]) > 50) continue;
1385  // check the error
1386  match.Cls[kpl] = kcl; match.End[kpl] = kend;
1387  if(DupMatch(match)) continue;
1388  FillEndMatch(match);
1389  totErr = match.Err + match.oErr;
1390  if(prt) {
1391  mf::LogVerbatim myprt("CCTM");
1392  myprt<<"VtxMatch: Chk missing cluster match ";
1393  for(unsigned short ii = 0; ii < nplanes; ++ii)
1394  myprt<<" "<<ii<<":"<<match.Cls[ii]<<":"<<match.End[ii];
1395  myprt<<" Err "<<match.Err<<"\n";
1396  }
1397  if(totErr > 100) continue;
1398  if(totErr < best) {
1399  best = totErr;
1400  kbst = kcl;
1401  kbend = kend;
1402  }
1403  } // kend
1404  } // kcl
1405  if(kbst >= 0) {
1406  // found a decent match
1407  match.Cls[kpl] = kbst; match.End[kpl] = kbend;
1408  FillEndMatch(match);
1409  matcomb.push_back(match);
1410  // assign the vertex to this cluster
1411  clsChain[kpl][kbst].VtxIndex[kbend] = ivx;
1412  // and update vxCls
1413  vxCls[kpl].push_back(kbst);
1414  } else {
1415  // Try a 2 plane match if a 3 plane match didn't work
1416  match.Cls[kpl] = -1; match.End[kpl] = 0;
1417  if(DupMatch(match)) continue;
1418  FillEndMatch(match);
1419  if(match.Err + match.oErr < 100) matcomb.push_back(match);
1420  }
1421  } // jend
1422  } // iend
1423  } // jj
1424  } // ii -> icl
1425  } // ipl
1426 
1427  if(matcomb.size() == 0) continue;
1428  SortMatches(fmCluHits, 1);
1429 
1430  } // ivx
1431 
1432  for(ipl = 0; ipl < 3; ++ipl) vxCls[ipl].clear();
1433 
1434  } // VtxMatch
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< MatchPars > matcomb
std::array< std::vector< ClsChainPar >, 3 > clsChain
bool DupMatch(MatchPars &match)
std::vector< vtxPar > vtx
void FillEndMatch(MatchPars &match)
void FillEndMatch2(MatchPars &match)
void SortMatches(art::FindManyP< recob::Hit > const &fmCluHits, unsigned short procCode)
Float_t X
Definition: plot.C:39
vec_iX clear()
std::array< std::vector< unsigned short >, 3 > vxCls

Member Data Documentation

unsigned short trkf::CCTrackMaker::algIndex
private

Definition at line 88 of file CCTrackMaker_module.cc.

std::vector<art::Ptr<recob::Hit> > trkf::CCTrackMaker::allhits
private

Definition at line 137 of file CCTrackMaker_module.cc.

std::array< float, 3> trkf::CCTrackMaker::ChgNorm
private

Definition at line 220 of file CCTrackMaker_module.cc.

std::array<std::vector<clPar>, 3> trkf::CCTrackMaker::cls
private

Definition at line 159 of file CCTrackMaker_module.cc.

std::array<std::vector<ClsChainPar>, 3> trkf::CCTrackMaker::clsChain
private

Definition at line 179 of file CCTrackMaker_module.cc.

unsigned int trkf::CCTrackMaker::cstat
private

Definition at line 127 of file CCTrackMaker_module.cc.

const detinfo::DetectorProperties* trkf::CCTrackMaker::detprop
private

Definition at line 82 of file CCTrackMaker_module.cc.

std::vector<float> trkf::CCTrackMaker::fAngleMatchErr
private

Definition at line 91 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fChainMaxdX
private

Definition at line 98 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fChainVtxAng
private

Definition at line 99 of file CCTrackMaker_module.cc.

std::vector<float> trkf::CCTrackMaker::fChgAsymFactor
private

Definition at line 92 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fChgWindow
private

Definition at line 104 of file CCTrackMaker_module.cc.

std::string trkf::CCTrackMaker::fClusterModuleLabel
private

Definition at line 77 of file CCTrackMaker_module.cc.

short trkf::CCTrackMaker::fDebugAlg
private

Definition at line 120 of file CCTrackMaker_module.cc.

short trkf::CCTrackMaker::fDebugCluster
private

Definition at line 122 of file CCTrackMaker_module.cc.

short trkf::CCTrackMaker::fDebugPlane
private

Definition at line 121 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fDeltaRayCut
private

Definition at line 108 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fFiducialCut
private

Definition at line 107 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fHitFitErrFac
private

Definition at line 114 of file CCTrackMaker_module.cc.

std::string trkf::CCTrackMaker::fHitModuleLabel
private

Definition at line 76 of file CCTrackMaker_module.cc.

std::array<unsigned int, 3> trkf::CCTrackMaker::firstHit
private

Definition at line 133 of file CCTrackMaker_module.cc.

std::array<unsigned int, 3> trkf::CCTrackMaker::firstWire
private

Definition at line 131 of file CCTrackMaker_module.cc.

std::vector<bool> trkf::CCTrackMaker::fMakeAlgTracks
private

Definition at line 94 of file CCTrackMaker_module.cc.

bool trkf::CCTrackMaker::fMakePFPs
private

Definition at line 110 of file CCTrackMaker_module.cc.

std::vector<short> trkf::CCTrackMaker::fMatchAlgs
private

Definition at line 89 of file CCTrackMaker_module.cc.

std::vector<float> trkf::CCTrackMaker::fMatchMinLen
private

Definition at line 93 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fMaxDAng
private

Definition at line 97 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fMaxMergeError
private

Definition at line 101 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fMergeChgAsym
private

Definition at line 100 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fMergeErrorCut
private

Definition at line 102 of file CCTrackMaker_module.cc.

unsigned short trkf::CCTrackMaker::fNVtxTrkHitsFit
private

Definition at line 113 of file CCTrackMaker_module.cc.

bool trkf::CCTrackMaker::fPrintAllClusters
private

Definition at line 123 of file CCTrackMaker_module.cc.

TrackTrajectoryAlg trkf::CCTrackMaker::fTrackTrajectoryAlg
private

Definition at line 84 of file CCTrackMaker_module.cc.

bool trkf::CCTrackMaker::fuBCode
private

Definition at line 117 of file CCTrackMaker_module.cc.

VertexFitAlg trkf::CCTrackMaker::fVertexFitAlg
private

Definition at line 85 of file CCTrackMaker_module.cc.

std::string trkf::CCTrackMaker::fVertexModuleLabel
private

Definition at line 78 of file CCTrackMaker_module.cc.

float trkf::CCTrackMaker::fWirePitch
private

Definition at line 105 of file CCTrackMaker_module.cc.

std::vector<float> trkf::CCTrackMaker::fXMatchErr
private

Definition at line 90 of file CCTrackMaker_module.cc.

art::ServiceHandle<geo::Geometry> trkf::CCTrackMaker::geom
private

Definition at line 81 of file CCTrackMaker_module.cc.

std::array<unsigned int, 3> trkf::CCTrackMaker::lastHit
private

Definition at line 134 of file CCTrackMaker_module.cc.

std::array<unsigned int, 3> trkf::CCTrackMaker::lastWire
private

Definition at line 132 of file CCTrackMaker_module.cc.

std::vector<MatchPars> trkf::CCTrackMaker::matcomb
private

Definition at line 245 of file CCTrackMaker_module.cc.

unsigned short trkf::CCTrackMaker::nplanes
private

Definition at line 126 of file CCTrackMaker_module.cc.

std::vector<unsigned short> trkf::CCTrackMaker::pfpToTrkID
private

Definition at line 225 of file CCTrackMaker_module.cc.

bool trkf::CCTrackMaker::prt
private

Definition at line 124 of file CCTrackMaker_module.cc.

std::array< std::vector<art::Ptr<recob::Hit> >, 3> trkf::CCTrackMaker::seedHits
private

Definition at line 218 of file CCTrackMaker_module.cc.

unsigned int trkf::CCTrackMaker::tpc
private

Definition at line 128 of file CCTrackMaker_module.cc.

std::vector<TrkPar> trkf::CCTrackMaker::trk
private

Definition at line 213 of file CCTrackMaker_module.cc.

std::array< std::vector<art::Ptr<recob::Hit> >, 3> trkf::CCTrackMaker::trkHits
private

Definition at line 216 of file CCTrackMaker_module.cc.

std::vector<vtxPar> trkf::CCTrackMaker::vtx
private

Definition at line 192 of file CCTrackMaker_module.cc.

std::array<std::vector<unsigned short>, 3> trkf::CCTrackMaker::vxCls
private

Definition at line 195 of file CCTrackMaker_module.cc.

std::array<std::vector< std::pair<int, int> >, 3> trkf::CCTrackMaker::WireHitRange
private

Definition at line 135 of file CCTrackMaker_module.cc.


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