LArSoft  v06_85_00
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 3329 of file CCTrackMaker_module.cc.

3330  {
3331  float slp = fabs(slope);
3332  if(slp > 10.) slp = 30.;
3333  // return a value between 1 and 46
3334  return 1 + 0.05 * slp * slp;
3335  } // 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 3095 of file CCTrackMaker_module.cc.

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

Definition at line 3338 of file CCTrackMaker_module.cc.

References t1, and t2.

3339  {
3340  // returns the hit charge along a line between (wire1, time1) and
3341  // (wire2, time2)
3342 
3343  // put in increasing wire order (wire2 > wire1)
3344  unsigned short w1 = wire1;
3345  unsigned short w2 = wire2;
3346  double t1 = time1;
3347  double t2 = time2;
3348  double slp, prtime;
3349  if(w1 == w2) {
3350  slp = 0;
3351  } else {
3352  if(w1 > w2) {
3353  w1 = wire2;
3354  w2 = wire1;
3355  t1 = time2;
3356  t2 = time1;
3357  }
3358  slp = (t2 - t1) / (w2 - w1);
3359  }
3360 
3361  unsigned short wire;
3362 
3363  float chg = 0;
3364  for(unsigned short hit = 0; hit < allhits.size(); ++hit) {
3365  if(allhits[hit]->WireID().Cryostat != cstat) continue;
3366  if(allhits[hit]->WireID().TPC != tpc) continue;
3367  if(allhits[hit]->WireID().Plane != ipl) continue;
3368  wire = allhits[hit]->WireID().Wire;
3369  if(wire < w1) continue;
3370  if(wire > w2) continue;
3371  prtime = t1 + (wire - w1) * slp;
3372  // std::cout<<"prtime "<<wire<<":"<<(int)prtime<<" hit "<<allhits[hit]->PeakTimeMinusRMS(3)<<" "<<allhits[hit]->PeakTimePlusRMS(3)<<"\n";
3373  if(prtime > allhits[hit]->PeakTimePlusRMS(3)) continue;
3374  if(prtime < allhits[hit]->PeakTimeMinusRMS(3)) continue;
3375  chg += ChgNorm[ipl] * allhits[hit]->Integral();
3376  } // hit
3377  return chg;
3378  } // 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 2331 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.

2332  {
2333 
2334  unsigned short nMatCl, nMiss;
2335  float toterr = match.Err + match.oErr;
2336  for(unsigned int imat = 0; imat < matcomb.size(); ++imat) {
2337  // check for exact matches
2338  if(match.Cls[0] == matcomb[imat].Cls[0] &&
2339  match.Cls[1] == matcomb[imat].Cls[1] &&
2340  match.Cls[2] == matcomb[imat].Cls[2]) {
2341 
2342  // compare the error
2343  if(toterr < matcomb[imat].Err + matcomb[imat].oErr) {
2344  // keep the better one
2345  matcomb[imat].End[0] = match.End[0];
2346  matcomb[imat].End[1] = match.End[1];
2347  matcomb[imat].End[2] = match.End[2];
2348  matcomb[imat].Vtx = match.Vtx;
2349  matcomb[imat].dWir = match.dWir;
2350  matcomb[imat].dAng = match.dAng;
2351  matcomb[imat].dX = match.dX;
2352  matcomb[imat].Err = match.Err;
2353  matcomb[imat].oVtx = match.oVtx;
2354  matcomb[imat].odWir = match.odWir;
2355  matcomb[imat].odAng = match.odAng;
2356  matcomb[imat].odX = match.odX;
2357  matcomb[imat].oErr = match.oErr;
2358  }
2359  return true;
2360  } // test
2361  // check for a 3-plane match vs 2-plane match
2362  nMatCl = 0;
2363  nMiss = 0;
2364  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
2365  if(match.Cls[ipl] >= 0) {
2366  if(match.Cls[ipl] == matcomb[imat].Cls[ipl] && (match.End[0] == matcomb[imat].End[0] || match.End[1] == matcomb[imat].End[1])) ++nMatCl;
2367  } else {
2368  ++nMiss;
2369  }
2370  } // ipl
2371  if(nMatCl == 2 && nMiss == 1) return true;
2372  } // imat
2373  return false;
2374  } // 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 1864 of file CCTrackMaker_module.cc.

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

Definition at line 954 of file CCTrackMaker_module.cc.

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

955  {
956  // fills the CHgNear array
957 
958  unsigned short wire, nwires, indx;
959  float dir, ctime, cx, chgWinLo, chgWinHi;
960  float cnear;
961 
962  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
963  for(unsigned short icl = 0; icl < cls[ipl].size(); ++icl) {
964  // find the nearby charge at the US and DS ends
965  nwires = cls[ipl][icl].Length / 2;
966  if(nwires < 2) continue;
967  // maximum of 30 wires for long clusters
968  if(nwires > 30) nwires = 30;
969  for(unsigned short end = 0; end < 2; ++end) {
970  cnear = 0;
971  // direction for adding/subtracting wire numbers
972  dir = 1 - 2 * end;
973  for(unsigned short w = 0; w < nwires; ++w) {
974  wire = cls[ipl][icl].Wire[end] + dir * w;
975  cx = cls[ipl][icl].X[end] + dir * w * cls[ipl][icl].Slope[end] * fWirePitch;
976  ctime = detprop->ConvertXToTicks(cx, ipl, tpc, cstat);
977  chgWinLo = ctime - fChgWindow;
978  chgWinHi = ctime + fChgWindow;
979  indx = wire - firstWire[ipl];
980  if(WireHitRange[ipl][indx].first < 0) continue;
981  unsigned int firhit = WireHitRange[ipl][indx].first;
982  unsigned int lashit = WireHitRange[ipl][indx].second;
983  for(unsigned int hit = firhit; hit < lashit; ++hit) {
984  if(hit > allhits.size() - 1) {
985  mf::LogError("CCTM")<<"FillChgNear bad lashit "<<lashit<<" size "<<allhits.size()<<"\n";
986  continue;
987  }
988  if(allhits[hit]->PeakTime() < chgWinLo) continue;
989  if(allhits[hit]->PeakTime() > chgWinHi) continue;
990  cnear += allhits[hit]->Integral();
991  } // hit
992  } // w
993  cnear /= (float)(nwires-1);
994  if(cnear > cls[ipl][icl].Charge[end]) {
995  cls[ipl][icl].ChgNear[end] = ChgNorm[ipl] * cnear / cls[ipl][icl].Charge[end];
996  } else {
997  cls[ipl][icl].ChgNear[end] = 0;
998  }
999  } // end
1000  } // icl
1001  } //ipl
1002 
1003  } // 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 2644 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.

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

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

References clear().

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

References DEFINE_ART_MODULE, and w.

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

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

1441  {
1442  // Project clusters to vertices and fill mVtxIndex. No requirement is
1443  // made that charge exists on the line between the Begin (End) of the
1444  // cluster and the vertex
1445  unsigned short ipl, icl, end, ivx, oend;
1446  float best, dWire, dX;
1447  short ibstvx;
1448 
1449  if(vtx.size() == 0) return;
1450 
1451  for(ipl = 0; ipl < nplanes; ++ipl) {
1452  for(icl = 0; icl < cls[ipl].size(); ++icl) {
1453  for(end = 0; end < 2; ++end) {
1454  // ignore already attached clusters
1455  if(cls[ipl][icl].VtxIndex[end] >= 0) continue;
1456  ibstvx = -1;
1457  best = 1.;
1458  // index of the other end
1459  oend = 1 - end;
1460  for(ivx = 0; ivx < vtx.size(); ++ ivx) {
1461  // ignore if the other end is attached to this vertex (which can happen with short clusters)
1462  if(cls[ipl][icl].VtxIndex[oend] == ivx) continue;
1463  dWire = geom->WireCoordinate(vtx[ivx].Y, vtx[ivx].Z, ipl, tpc, cstat) - cls[ipl][icl].Wire[end];
1464  /*
1465  if(prt) std::cout<<"FMV: ipl "<<ipl<<" icl "<<icl<<" end "<<end
1466  <<" vtx wire "<<geom->WireCoordinate(vtx[ivx].Y, vtx[ivx].Z, ipl, tpc, cstat)
1467  <<" cls wire "<<cls[ipl][icl].Wire[end]
1468  <<" dWire "<<dWire<<"\n";
1469  */
1470  if(end == 0) {
1471  if(dWire > 30 || dWire < -2) continue;
1472  } else {
1473  if(dWire < -30 || dWire > 2) continue;
1474  }
1475  // project the cluster to the vertex wire
1476  dX = fabs(cls[ipl][icl].X[end] + cls[ipl][icl].Slope[end] * fWirePitch * dWire - vtx[ivx].X);
1477  // if(prt) std::cout<<"dX "<<dX<<"\n";
1478  if(dX < best) {
1479  best = dX;
1480  ibstvx = ivx;
1481  }
1482  } // ivx
1483  if(ibstvx >= 0) {
1484  // attach
1485  cls[ipl][icl].VtxIndex[end] = ibstvx;
1486  cls[ipl][icl].mVtxIndex[end] = ibstvx;
1487  }
1488  } // end
1489  } // icl
1490  } // ipl
1491 
1492  } // 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 3000 of file CCTrackMaker_module.cc.

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

3001  {
3002  // Cluster chain kkcl is broken due to a failure in MakeClusterChains. Find the intersection of
3003  // the other two clusters in match at the appropriate end of cluster kkcl
3004 
3005  kkWir = -1;
3006  // find the match point at the other end of the original match point
3007  kkend = 1 - kkend;
3008  // mf::LogVerbatim("CCTM")<<"FMPM "<<kkpl<<":"<<kkcl<<":"<<kkend;
3009  kkX = clsChain[kkpl][kkcl].X[kkend];
3010  float matchTime = detprop->ConvertXToTicks(kkX, kkpl, tpc, cstat);
3011 
3012  // vector of wire numbers that have the most similar time
3013  std::vector<unsigned int> wirs;
3014  std::vector<unsigned int> plns;
3015  std::vector<art::Ptr<recob::Hit>> clusterhits;
3016  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3017  if(ipl == kkpl) continue;
3018  // this shouldn't happen but check anyway
3019  if(match.Cls[ipl] < 0) continue;
3020  float dTime, best = 99999;
3021  unsigned short wire = 0;
3022  unsigned short icl, ccl = match.Cls[ipl];
3023  // loop over all clusters in the chain
3024  for(unsigned short ii = 0; ii < clsChain[kkpl][ccl].ClsIndex.size(); ++ii) {
3025  icl = clsChain[kkpl][ccl].ClsIndex[ii];
3026  if(cls[ipl][icl].EvtIndex > fmCluHits.size() -1) {
3027  std::cout<<"Bad ClsIndex in FMPM\n";
3028  exit(1);
3029  }
3030  clusterhits = fmCluHits.at(cls[ipl][icl].EvtIndex);
3031  // loop over all the hits in each cluster
3032  for(unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
3033  dTime = fabs(clusterhits[iht]->PeakTime() - matchTime);
3034  if(dTime < best) {
3035  best = dTime;
3036  wire = clusterhits[iht]->WireID().Wire;
3037  }
3038  } // iht
3039  } // ii
3040  wirs.push_back(wire);
3041  plns.push_back(ipl);
3042  // mf::LogVerbatim("CCTM")<<" ipl "<<ipl<<" wire "<<wire;
3043  } // ipl
3044  if(wirs.size() != 2) return;
3045  double Y, Z;
3046  geom->IntersectionPoint(wirs[0], wirs[1], plns[0], plns[1], cstat, tpc, Y, Z);
3047  kkWir = geom->WireCoordinate(Y, Z, kkpl, tpc, cstat);
3048 
3049  } // 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 3052 of file CCTrackMaker_module.cc.

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

3053  {
3054  // try to attach a missing cluster to the cluster chain kcl. kend is the "match end"
3055 
3056  unsigned short okend;
3057  float dxcut;
3058 
3059  if(kcl >= 0) return false;
3060 
3061  // Look for a missing cluster with loose cuts
3062  float kslp = fabs((okX - kX) / (okWir - kWir));
3063  if(kslp > 20) kslp = 20;
3064  // expand dX cut assuming there is a missing hit on the end of a cluster => 1 wire
3065  dxcut = 3 * fXMatchErr[algIndex] + kslp;
3066  unsigned short nfound = 0;
3067  unsigned short foundCl = 0, foundEnd = 0;
3068  for(unsigned short ccl = 0; ccl < clsChain[kpl].size(); ++ccl) {
3069  if(clsChain[kpl][ccl].InTrack >= 0) continue;
3070  // require a match at both ends
3071  for(unsigned short end = 0; end < 2; ++end) {
3072  okend = 1 - end;
3073  if(fabs(clsChain[kpl][ccl].Wire[end] - kWir) > 4) continue;
3074  if(fabs(clsChain[kpl][ccl].Wire[okend] - okWir) > 4) continue;
3075  // 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;
3076  // require at least one end to match
3077  if(fabs(clsChain[kpl][ccl].X[end] - kX) > dxcut && fabs(clsChain[kpl][ccl].X[okend] - okX) > dxcut) continue;
3078  ++nfound;
3079  foundCl = ccl;
3080  foundEnd = end;
3081  } // end
3082  } // ccl
3083  if(nfound == 0) return false;
3084  if(nfound > 1) {
3085  mf::LogVerbatim("CCTM")<<"FindMissingCluster: Found too many matches. Write some code "<<nfound;
3086  return false;
3087  }
3088  kcl = foundCl;
3089  kend = foundEnd;
3090  return true;
3091 
3092  } // 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 854 of file CCTrackMaker_module.cc.

References evd::details::end().

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

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

References tmp, X, Y, and Z.

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

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

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

3240  {
3241 
3242  unsigned short iTime;
3243  mf::LogVerbatim myprt("CCTM");
3244  myprt<<"******* PrintClusters ********* Num_Clusters_in Wire:Time\n";
3245  myprt<<"vtx Index X Y Z Pln0 Pln1 Pln2 Pln0 Pln1 Pln2\n";
3246  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
3247  myprt<<std::right<<std::setw(3)<<ivx<<std::setw(7)<<ivx;
3248  myprt<<std::fixed;
3249  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].X;
3250  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Y;
3251  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Z;
3252  myprt<<std::right<<std::setw(5)<<vtx[ivx].nClusInPln[0];
3253  myprt<<std::right<<std::setw(5)<<vtx[ivx].nClusInPln[1];
3254  myprt<<std::right<<std::setw(5)<<vtx[ivx].nClusInPln[2];
3255  myprt<<" ";
3256  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3257  int time = (0.5 + detprop->ConvertXToTicks(vtx[ivx].X, ipl, tpc, cstat));
3258  int wire = geom->WireCoordinate(vtx[ivx].Y, vtx[ivx].Z, ipl, tpc, cstat);
3259  myprt<<std::right<<std::setw(7)<<wire<<":"<<time;
3260  }
3261 
3262  myprt<<"\n";
3263  } // ivx
3264 
3265  for(unsigned short ipl = 0; ipl < nplanes; ++ipl) {
3266  myprt<<">>>>>>>>>> Cluster chains in Plane "<<ipl<<"\n";
3267  myprt<<"ipl ccl Len Chg W0:T0 Ang0 Dir0 Vx0 mBk0 W1:T1 Ang1 Dir1 Vx1 mBk1 InTk cls:Order \n";
3268  for(unsigned short ccl = 0; ccl < clsChain[ipl].size(); ++ccl) {
3269  myprt<<std::right<<std::setw(3)<<ipl;
3270  myprt<<std::right<<std::setw(5)<<ccl;
3271  myprt<<std::right<<std::setw(6)<<clsChain[ipl][ccl].Length;
3272  myprt<<std::right<<std::setw(8)<<(int)clsChain[ipl][ccl].TotChg;
3273  for(unsigned short end = 0; end < 2; ++end) {
3274  iTime = clsChain[ipl][ccl].Time[end];
3275  myprt<<std::right<<std::setw(5)<<(int)clsChain[ipl][ccl].Wire[end]
3276  <<":"<<std::setprecision(1)<<iTime;
3277  if(iTime < 10) {
3278  myprt<<" ";
3279  } else if(iTime < 100) {
3280  myprt<<" ";
3281  } else if(iTime < 1000) myprt<<" ";
3282  myprt<<std::right<<std::setw(7)<<std::setprecision(2)<<clsChain[ipl][ccl].Angle[end];
3283  myprt<<std::right<<std::setw(5)<<clsChain[ipl][ccl].Dir[end];
3284  myprt<<std::right<<std::setw(5)<<clsChain[ipl][ccl].VtxIndex[end];
3285  myprt<<std::fixed<<std::right<<std::setw(6)<<std::setprecision(1)<<clsChain[ipl][ccl].mBrkIndex[end];
3286 // myprt<<std::fixed<<std::right<<std::setw(6)<<std::setprecision(1)<<clsChain[ipl][ccl].ChgNear[end];
3287  }
3288  myprt<<std::right<<std::setw(7)<<clsChain[ipl][ccl].InTrack;
3289  myprt<<" ";
3290  for(unsigned short ii = 0; ii < clsChain[ipl][ccl].ClsIndex.size(); ++ii)
3291  myprt<<" "<<clsChain[ipl][ccl].ClsIndex[ii]<<":"<<clsChain[ipl][ccl].Order[ii];
3292  myprt<<"\n";
3293  } // ccl
3294  if(fPrintAllClusters) {
3295  myprt<<">>>>>>>>>> Clusters in Plane "<<ipl<<"\n";
3296  myprt<<"ipl icl Evt Len Chg W0:T0 Ang0 Dir0 Vx0 CN0 W1:T1 Ang1 Dir1 Vx1 CN1 InTk Brk0 MrgEr0 Brk1 MrgEr1\n";
3297  for(unsigned short icl = 0; icl < cls[ipl].size(); ++icl) {
3298  myprt<<std::right<<std::setw(3)<<ipl;
3299  myprt<<std::right<<std::setw(5)<<icl;
3300  myprt<<std::right<<std::setw(5)<<cls[ipl][icl].EvtIndex;
3301  myprt<<std::right<<std::setw(6)<<cls[ipl][icl].Length;
3302  myprt<<std::right<<std::setw(8)<<(int)cls[ipl][icl].TotChg;
3303  for(unsigned short end = 0; end < 2; ++end) {
3304  iTime = cls[ipl][icl].Time[end];
3305  myprt<<std::right<<std::setw(5)<<(int)cls[ipl][icl].Wire[end]<<":"<<iTime;
3306  if(iTime < 10) {
3307  myprt<<" ";
3308  } else if(iTime < 100) {
3309  myprt<<" ";
3310  } else if(iTime < 1000) myprt<<" ";
3311  myprt<<std::right<<std::setw(7)<<std::setprecision(2)<<cls[ipl][icl].Angle[end];
3312  myprt<<std::right<<std::setw(5)<<cls[ipl][icl].Dir[end];
3313  myprt<<std::right<<std::setw(5)<<cls[ipl][icl].VtxIndex[end];
3314  myprt<<std::fixed<<std::right<<std::setw(5)<<std::setprecision(1)<<cls[ipl][icl].ChgNear[end];
3315  }
3316  myprt<<std::fixed;
3317  myprt<<std::right<<std::setw(5)<<cls[ipl][icl].InTrack;
3318  myprt<<std::right<<std::setw(5)<<(int)cls[ipl][icl].BrkIndex[0];
3319  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<cls[ipl][icl].MergeError[0];
3320  myprt<<std::right<<std::setw(5)<<(int)cls[ipl][icl].BrkIndex[1];
3321  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<cls[ipl][icl].MergeError[1];
3322  myprt<<"\n";
3323  } // icl
3324  } // fPrintAllClusters
3325  } // ipl
3326  } // 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 3192 of file CCTrackMaker_module.cc.

References art::right().

3193  {
3194  mf::LogVerbatim myprt("CCTM");
3195  myprt<<"********* PrintTracks \n";
3196  myprt<<"vtx Index X Y Z\n";
3197  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
3198  myprt<<std::right<<std::setw(4)<<ivx<<std::setw(4)<<vtx[ivx].EvtIndex;
3199  myprt<<std::fixed;
3200  myprt<<std::right<<std::setw(10)<<std::setprecision(1)<<vtx[ivx].X;
3201  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Y;
3202  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<vtx[ivx].Z;
3203  if(vtx[ivx].Neutrino) myprt<<" Neutrino vertex";
3204  myprt<<"\n";
3205  } // ivx
3206 
3207  myprt<<">>>>>>>>>> Tracks \n";
3208  myprt<<"trk ID Proc nht nTrj sX sY sZ eX eY eZ sVx eVx sGd eGd ChgOrd dirZ Mom PDG ClsIndices\n";
3209  for(unsigned short itr = 0; itr < trk.size(); ++itr) {
3210  myprt<<std::right<<std::setw(3)<<itr<<std::setw(4)<<trk[itr].ID;
3211  myprt<<std::right<<std::setw(5)<<std::setw(4)<<trk[itr].Proc;
3212  unsigned short nht = 0;
3213  for(unsigned short ii = 0; ii < 3; ++ii) nht += trk[itr].TrkHits[ii].size();
3214  myprt<<std::right<<std::setw(5)<<nht;
3215  myprt<<std::setw(4)<<trk[itr].TrjPos.size();
3216  myprt<<std::fixed;
3217  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[0](0);
3218  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[0](1);
3219  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[0](2);
3220  unsigned short itj = trk[itr].TrjPos.size() - 1;
3221  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[itj](0);
3222  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[itj](1);
3223  myprt<<std::right<<std::setw(7)<<std::setprecision(1)<<trk[itr].TrjPos[itj](2);
3224  myprt<<std::setw(4)<<trk[itr].VtxIndex[0]<<std::setw(4)<<trk[itr].VtxIndex[1];
3225  myprt<<std::setw(4)<<trk[itr].GoodEnd[0];
3226  myprt<<std::setw(4)<<trk[itr].GoodEnd[1];
3227  myprt<<std::setw(4)<<trk[itr].ChgOrder;
3228  myprt<<std::right<<std::setw(10)<<std::setprecision(3)<<trk[itr].TrjDir[itj](2);
3229  myprt<<std::right<<std::setw(4)<<trk[itr].MomID;
3230  myprt<<std::right<<std::setw(5)<<trk[itr].PDGCode<<" ";
3231  for(unsigned short ii = 0; ii < trk[itr].ClsEvtIndices.size(); ++ii) myprt<<" "<<trk[itr].ClsEvtIndices[ii];
3232  myprt<<"\n";
3233  } // itr
3234 
3235  } // 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(), 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, util::kBogusD, 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  // some junk vectors to satisfy the recob::Track constructor
451  std::vector< std::vector<double> > dQdx;
452  std::vector<double> mom(2, util::kBogusD);
453  // prepare a bogus covariance matrix so that the TrackAna module doesn't bomb
454  TMatrixD cov(5,5);
455  for(unsigned short ii = 0; ii < 5; ++ii) cov(ii, ii) = 1;
456  std::vector<TMatrixD> tmpCov;
457  tmpCov.push_back(cov);
458  tmpCov.push_back(cov);
459  std::vector< art::Ptr<recob::Hit > > tmpHits;
460  std::vector< art::Ptr<recob::Cluster > > tmpCls;
461  std::vector< art::Ptr<recob::Vertex > > tmpVtx;
462 
463  // vector for PFParticle constructor
464  std::vector<size_t> dtrIndices;
465 
466  // some vectors for recob::Seed
467  double sPos[3], sDir[3];
468  double sErr[3] = {0,0,0};
469 
470  // check consistency between clusters and associated hits
471  std::vector<art::Ptr<recob::Hit>> clusterhits;
472  for(icl = 0; icl < clusterlist.size(); ++icl) {
473  ipl = clusterlist[icl]->Plane().Plane;
474  clusterhits = fmCluHits.at(icl);
475  if(clusterhits[0]->WireID().Wire != std::nearbyint(clusterlist[icl]->EndWire())) {
476  std::cout<<"CCTM Cluster-Hit End wire mis-match "<<clusterhits[0]->WireID().Wire<<" vs "<<std::nearbyint(clusterlist[icl]->EndWire())<<" Bail out! \n";
477  return;
478  }
479  for(unsigned short iht = 0; iht < clusterhits.size(); ++iht) {
480  if(clusterhits[iht]->WireID().Plane != ipl) {
481  std::cout<<"CCTM Cluster-Hit plane mis-match "<<ipl<<" vs "<<clusterhits[iht]->WireID().Plane<<" on hit "<<iht<<" Bail out! \n";
482  return;
483  } // hit-cluster plane mis-match
484  } // iht
485  } // icl
486  // end check consistency
487 
488 // std::cout<<"************ event "<<evt.event()<<"\n";
489 
490  vtx.clear();
491  trk.clear();
492  for(cstat = 0; cstat < geom->Ncryostats(); ++cstat) {
493  for(tpc = 0; tpc < geom->Cryostat(cstat).NTPC(); ++tpc) {
495  if(nplanes > 3) continue;
496  for(ipl = 0; ipl < 3; ++ipl) {
497  cls[ipl].clear();
498  clsChain[ipl].clear();
499  trkHits[ipl].clear();
500  } // ipl
501  // FillWireHitRange also calculates the charge in each plane
503  for(ipl = 0; ipl < nplanes; ++ipl) {
504  clulens.clear();
505  // sort clusters by increasing End wire number
506  for(icl = 0; icl < clusterlist.size(); ++icl) {
507  if(clusterlist[icl]->Plane().Cryostat != cstat) continue;
508  if(clusterlist[icl]->Plane().TPC != tpc) continue;
509  if(clusterlist[icl]->Plane().Plane != ipl) continue;
510  CluLen clulen;
511  clulen.index = icl;
512  clulen.length = clusterlist[icl]->EndWire();
513  clulens.push_back(clulen);
514  }
515  if(clulens.size() == 0) continue;
516  // sort clusters
517  std::sort (clulens.begin(),clulens.end(), lessThan);
518  if(clulens.size() == 0) continue;
519  for(unsigned short ii = 0; ii < clulens.size(); ++ii) {
520  const unsigned short icl = clulens[ii].index;
521  clPar clstr;
522  clstr.EvtIndex = icl;
523  recob::Cluster const& cluster = *(clusterlist[icl]);
524  // Begin info -> end index 1 (DS)
525  clstr.Wire[1] = cluster.StartWire();
526  clstr.Time[1] = cluster.StartTick();
527  clstr.X[1] = (float)detprop->ConvertTicksToX(cluster.StartTick(), ipl, tpc, cstat);
528  clstr.Angle[1] = cluster.StartAngle();
529  clstr.Slope[1] = std::tan(cluster.StartAngle());
530  clstr.Dir[1] = 0;
531 // if(fabs(clstr.Slope[1]) > 0.02) clstr.Dir[1] = -1 * (2*(clstr.Slope[1]>0)-1);
532  clstr.Charge[1] = ChgNorm[ipl] * cluster.StartCharge();
533  // this will be filled later
534  clstr.ChgNear[1] = 0;
535  clstr.VtxIndex[1] = -1;
536  clstr.mVtxIndex[1] = -1;
537  clstr.BrkIndex[1] = -1;
538  clstr.MergeError[1] = fMaxMergeError;
539  // End info -> end index 0 (US)
540  clstr.Wire[0] = cluster.EndWire();
541  clstr.Time[0] = cluster.EndTick();
542  clstr.X[0] = (float)detprop->ConvertTicksToX(cluster.EndTick(), ipl, tpc, cstat);
543  clstr.Angle[0] = cluster.EndAngle();
544  clstr.Slope[0] = std::tan(cluster.EndAngle());
545  clstr.Dir[0] = 0;
546 // if(fabs(clstr.Slope[0]) > 0.02) clstr.Dir[0] = 1 * (2*(clstr.Slope[0]>0)-1);
547  if(clstr.Time[1] > clstr.Time[0]) {
548  clstr.Dir[0] = 1; clstr.Dir[1] = -1;
549  } else {
550  clstr.Dir[0] = -1; clstr.Dir[1] = 1;
551  }
552  clstr.Charge[0] = ChgNorm[ipl] * cluster.EndCharge();
553  // this will be filled later
554  clstr.ChgNear[1] = 0;
555  clstr.VtxIndex[0] = -1;
556  clstr.mVtxIndex[0] = -1;
557  clstr.BrkIndex[0] = -1;
558  clstr.MergeError[0] = fMaxMergeError;
559  // other info
560  clstr.InTrack = -1;
561  clstr.Length = (unsigned short)(0.5 + clstr.Wire[1] - clstr.Wire[0]);
562  clstr.TotChg = ChgNorm[ipl] * cluster.Integral();
563  if(clstr.TotChg <= 0) clstr.TotChg = 1;
564  clusterhits = fmCluHits.at(icl);
565  if(clusterhits.size() == 0) {
566  mf::LogError("CCTM")<<"No associated cluster hits "<<icl;
567  continue;
568  }
569  // correct charge for missing cluster hits
570  clstr.TotChg *= clstr.Length / (float)clusterhits.size();
571  cls[ipl].push_back(clstr);
572  } // ii (icl)
573  } // ipl
574 
575 
576 // std::cout<<"FillChgNear "<<evt.event()<<"\n";
577  FillChgNear();
578 
579  // and finally the vertices
580  double xyz[3];
581  for(unsigned short ivx = 0; ivx < vtxlist.size(); ++ivx) {
582  vtxPar aVtx;
583  aVtx.ID = ivx + 1;
584  aVtx.EvtIndex = ivx;
585  vtxlist[ivx]->XYZ(xyz);
586  aVtx.X = xyz[0];
587  aVtx.Y = xyz[1];
588  aVtx.Z = xyz[2];
589  aVtx.nClusInPln[0] = 0;
590  aVtx.nClusInPln[1] = 0;
591  aVtx.nClusInPln[2] = 0;
592  std::vector<art::Ptr<recob::Cluster>> const& vtxCls = fmVtxCls.at(ivx);
593  std::vector<const unsigned short*> const& vtxClsEnd = fmVtxCls.data(ivx);
594  for(unsigned short vcass = 0; vcass < vtxCls.size(); ++vcass) {
595  icl = vtxCls[vcass].key();
596  // the cluster plane
597  ipl = vtxCls[vcass]->Plane().Plane;
598  end = *vtxClsEnd[vcass];
599  if(end > 1) throw cet::exception("CCTM")<<"Invalid end data from vertex - cluster association"<<end;
600  bool gotit = false;
601  // CCTM end is opposite of CC end
602  end = 1 - end;
603  for(unsigned short jcl = 0; jcl < cls[ipl].size(); ++jcl) {
604  if(cls[ipl][jcl].EvtIndex == icl) {
605  cls[ipl][jcl].VtxIndex[end] = ivx;
606  ++aVtx.nClusInPln[ipl];
607  gotit = true;
608  break;
609  } // index check
610  } // jcl
611  if(!gotit) throw cet::exception("CCTM")<<"Bad index from vertex - cluster association"<<icl;
612  } // icl
613  vtx.push_back(aVtx);
614  } // ivx
615  // Find broken clusters
616  MakeClusterChains(fmCluHits);
618 
619  // call algorithms in the specified order
620  matcomb.clear();
621  for(algIndex = 0; algIndex < fMatchAlgs.size(); ++algIndex) {
622  if(fMatchAlgs[algIndex] == 1) {
623  prt = (fDebugAlg == 1);
624  VtxMatch(fmCluHits);
625  if(fMakeAlgTracks[algIndex]) SortMatches(fmCluHits, 1);
626  } else
627  if(fMatchAlgs[algIndex] == 2) {
628  prt = (fDebugAlg == 2);
629  PlnMatch(fmCluHits);
630  if(fMakeAlgTracks[algIndex]) SortMatches(fmCluHits, 2);
631  }
632  if(prt) PrintClusters();
633  } // algIndex
634  prt = false;
635  pfpToTrkID.clear();
636  // Determine the vertex/track hierarchy
637  if(fMakePFPs) {
638  TagCosmics();
639  MakeFamily();
640  }
641  FitVertices();
642 
643  // Make PFParticles -> tracks
644  for(unsigned short ipf = 0; ipf < pfpToTrkID.size(); ++ipf) {
645  // trackID of this PFP
646  tID = pfpToTrkID[ipf];
647  if(tID > trk.size()+1) {
648  mf::LogWarning("CCTM")<<"Bad track ID";
649  continue;
650  }
651  dtrIndices.clear();
652  // load the daughter PFP indices
653  mf::LogVerbatim("CCTM")<<"PFParticle "<<ipf<<" tID "<<tID;
654  for(unsigned short jpf = 0; jpf < pfpToTrkID.size(); ++jpf) {
655  itr = pfpToTrkID[jpf] - 1; // convert from track ID to track index
656  if(trk[itr].MomID == tID) dtrIndices.push_back(jpf);
657  if(trk[itr].MomID == tID) mf::LogVerbatim("CCTM")<<" dtr jpf "<<jpf<<" itr "<<itr;
658  } // jpf
659  unsigned short parentIndex = USHRT_MAX;
660  if(tID == 0) {
661  // make neutrino PFP USHRT_MAX == primary PFP
662  recob::PFParticle pfp(14, ipf, parentIndex, dtrIndices);
663  pcol->emplace_back(std::move(pfp));
664  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
665  if(!vtx[ivx].Neutrino) continue;
666  // make the vertex
667  xyz[0] = vtx[ivx].X;
668  xyz[1] = vtx[ivx].Y;
669  xyz[2] = vtx[ivx].Z;
670  size_t vStart = vcol->size();
671  recob::Vertex vertex(xyz, vtx[ivx].ID);
672  vcol->emplace_back(std::move(vertex));
673  size_t vEnd = vcol->size();
674  // PFParticle - vertex association
675  util::CreateAssn(*this, evt, *pcol, *vcol, *pvassn, vStart, vEnd);
676  vtx[ivx].ID = -vtx[ivx].ID;
677  break;
678  } // ivx
679  } else if(tID > 0){
680  // make non-neutrino PFP. Need to find the parent PFP index
681  // Track index of this PFP
682  tIndex = tID - 1;
683  // trackID of this PFP parent
684  for(unsigned short ii = 0; ii < pfpToTrkID.size(); ++ii) {
685  if(pfpToTrkID[ii] == trk[tIndex].MomID) {
686  parentIndex = ii;
687  break;
688  }
689  } // ii
690  // PFParticle
691  mf::LogVerbatim("CCTM")<<"daughters tID "<<tID<<" pdg "<<trk[tIndex].PDGCode<<" ipf "<<ipf<<" parentIndex "<<parentIndex<<" dtr size "<<dtrIndices.size();
692  recob::PFParticle pfp(trk[tIndex].PDGCode, ipf, parentIndex, dtrIndices);
693  pcol->emplace_back(std::move(pfp));
694  // track
695  // make the track
696  size_t tStart = tcol->size();
697  recob::Track track(trk[tIndex].TrjPos, trk[tIndex].TrjDir, tmpCov, dQdx, mom, tID);
698  tcol->emplace_back(std::move(track));
699  size_t tEnd = tcol->size();
700  // PFParticle - track association
701  util::CreateAssn(*this, evt, *pcol, *tcol, *ptassn, tStart, tEnd);
702  // flag this track as already put in the event
703  trk[tIndex].ID = -trk[tIndex].ID;
704  // track -> hits association
705  tmpHits.clear();
706  for(ipl = 0; ipl < nplanes; ++ipl)
707  tmpHits.insert(tmpHits.end(), trk[tIndex].TrkHits[ipl].begin(), trk[tIndex].TrkHits[ipl].end());
708  util::CreateAssn(*this, evt, *tcol, tmpHits, *thassn);
709  // Find seed hits and the end of the track that is best
710  end = 0;
711 // FindSeedHits(tIndex, end);
712  unsigned short itj = 0;
713  if(end > 0) itj = trk[tIndex].TrjPos.size() - 1;
714  for(unsigned short ii = 0; ii < 3; ++ii) {
715  sPos[ii] = trk[tIndex].TrjPos[itj](ii);
716  sDir[ii] = trk[tIndex].TrjDir[itj](ii);
717  } // ii
718  size_t sStart = scol->size();
719  recob::Seed seed(sPos, sDir, sErr, sErr);
720  scol->emplace_back(std::move(seed));
721  size_t sEnd = scol->size();
722  // PFP-seed association
723  util::CreateAssn(*this, evt, *pcol, *scol, *psassn, sStart, sEnd);
724  // Seed-hit association
725  tmpHits.clear();
726  for(ipl = 0; ipl < nplanes; ++ipl)
727  tmpHits.insert(tmpHits.end(), seedHits[ipl].begin(), seedHits[ipl].end());
728  util::CreateAssn(*this, evt, *scol, tmpHits, *shassn);
729  // cluster association
730  // PFP-cluster association
731  tmpCls.clear();
732  for(unsigned short ii = 0; ii < trk[tIndex].ClsEvtIndices.size(); ++ii) {
733  icl = trk[tIndex].ClsEvtIndices[ii];
734  tmpCls.push_back(clusterlist[icl]);
735  } // ii
736  util::CreateAssn(*this, evt, *pcol, tmpCls, *pcassn);
737  } // non-neutrino PFP
738  } // ipf
739  // make non-PFP tracks
740  for(unsigned short itr = 0; itr < trk.size(); ++itr) {
741  // ignore already saved tracks
742  if(trk[itr].ID < 0) continue;
743  recob::Track track(trk[itr].TrjPos, trk[itr].TrjDir, tmpCov, dQdx, mom, trk[itr].ID);
744  tcol->emplace_back(std::move(track));
745  tmpHits.clear();
746  for(ipl = 0; ipl < nplanes; ++ipl)
747  tmpHits.insert(tmpHits.end(), trk[itr].TrkHits[ipl].begin(), trk[itr].TrkHits[ipl].end());
748  util::CreateAssn(*this, evt, *tcol, tmpHits, *thassn);
749  } // itr
750  // make remnant vertices
751  for(unsigned short ivx = 0; ivx < vtx.size(); ++ivx) {
752  if(vtx[ivx].ID < 0) continue;
753  xyz[0] = vtx[ivx].X;
754  xyz[1] = vtx[ivx].Y;
755  xyz[2] = vtx[ivx].Z;
756  recob::Vertex vertex(xyz, vtx[ivx].ID);
757  vcol->emplace_back(std::move(vertex));
758  }
759  if(fDebugAlg > 0) PrintTracks();
760 
761  double orphanLen = 0;
762  for(ipl = 0; ipl < nplanes; ++ipl) {
763  for(icl = 0; icl < cls[ipl].size(); ++icl) {
764  if(cls[ipl][icl].Length > 40 && cls[ipl][icl].InTrack < 0) {
765  orphanLen += cls[ipl][icl].Length;
766  // unused cluster
767  mf::LogVerbatim("CCTM")<<"Orphan long cluster "<<ipl<<":"<<icl<<":"<<cls[ipl][icl].Wire[0]
768  <<":"<<(int)cls[ipl][icl].Time[0]<<" length "<<cls[ipl][icl].Length;
769  }
770  } // icl
771 
772  cls[ipl].clear();
773  clsChain[ipl].clear();
774  } // ipl
775  std::cout<<"Total orphan length "<<orphanLen<<"\n";
776  trkHits[ipl].clear();
777  seedHits[ipl].clear();
778  vxCls[ipl].clear();
779  } // tpc
780  } // cstat
781 
782  evt.put(std::move(pcol));
783  evt.put(std::move(ptassn));
784  evt.put(std::move(pcassn));
785  evt.put(std::move(pvassn));
786  evt.put(std::move(psassn));
787  evt.put(std::move(tcol));
788  evt.put(std::move(thassn));
789  evt.put(std::move(scol));
790  evt.put(std::move(vcol));
791 
792  // final cleanup
793  vtx.clear();
794  trk.clear();
795  allhits.clear();
796  matcomb.clear();
797  pfpToTrkID.clear();
798 
799 
800  } // produce
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
std::vector< MatchPars > matcomb
std::string fVertexModuleLabel
unsigned int Nplanes() const
Number of planes in this tpc.
Definition: TPCGeo.h:145
std::vector< art::Ptr< recob::Hit > > allhits
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)
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::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)
constexpr double kBogusD
obviously bogus double value
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:51
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 2377 of file CCTrackMaker_module.cc.

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

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

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

References geo::TPCGeo::LocalToWorld().

1214  {
1215  // Make cosmic ray PFParticles
1216  unsigned short ipf, itj;
1217  bool skipit = true;
1218 
1219  // Y,Z limits of the detector
1220  double local[3] = {0.,0.,0.};
1221  double world[3] = {0.,0.,0.};
1222 
1223  const geo::TPCGeo &thetpc = geom->TPC(tpc, cstat);
1224  thetpc.LocalToWorld(local,world);
1225  float XLo = world[0] - geom->DetHalfWidth(tpc,cstat) + fFiducialCut;
1226  float XHi = world[0] + geom->DetHalfWidth(tpc,cstat) - fFiducialCut;
1227  float YLo = world[1] - geom->DetHalfHeight(tpc,cstat) + fFiducialCut;
1228  float YHi = world[1] + geom->DetHalfHeight(tpc,cstat) - fFiducialCut;
1229  float ZLo = world[2] - geom->DetLength(tpc,cstat)/2 + fFiducialCut;
1230  float ZHi = world[2] + geom->DetLength(tpc,cstat)/2 - fFiducialCut;
1231 
1232  bool startsIn, endsIn;
1233 
1234  for(unsigned short itk = 0; itk < trk.size(); ++itk) {
1235  // ignore already used tracks
1236  if(trk[itk].ID < 0) continue;
1237  // ignore short tracks (< 10 cm)
1238  if(trk[itk].Length < 10) continue;
1239  // check for already identified PFPs
1240  skipit = false;
1241  for(ipf = 0; ipf < pfpToTrkID.size(); ++ipf) {
1242  if(pfpToTrkID[ipf] == trk[itk].ID) {
1243  skipit = true;
1244  break;
1245  }
1246  } // ipf
1247  if(skipit) continue;
1248  startsIn = true;
1249  if(trk[itk].TrjPos[0](0) < XLo || trk[itk].TrjPos[0](0) > XHi) startsIn = false;
1250  if(trk[itk].TrjPos[0](1) < YLo || trk[itk].TrjPos[0](1) > YHi) startsIn = false;
1251  if(trk[itk].TrjPos[0](2) < ZLo || trk[itk].TrjPos[0](2) > ZHi) startsIn = false;
1252 // 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";
1253  if(startsIn) continue;
1254  endsIn = true;
1255  itj = trk[itk].TrjPos.size() - 1;
1256  if(trk[itk].TrjPos[itj](0) < XLo || trk[itk].TrjPos[itj](0) > XHi) endsIn = false;
1257  if(trk[itk].TrjPos[itj](1) < YLo || trk[itk].TrjPos[itj](1) > YHi) endsIn = false;
1258  if(trk[itk].TrjPos[itj](2) < ZLo || trk[itk].TrjPos[itj](2) > ZHi) endsIn = false;
1259 // 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";
1260  if(endsIn) continue;
1261  // call it a cosmic muon
1262  trk[itk].PDGCode = 13;
1263  pfpToTrkID.push_back(trk[itk].ID);
1264  } // itk
1265 
1266  if(fDeltaRayCut <= 0) return;
1267 
1268  for(unsigned short itk = 0; itk < trk.size(); ++itk) {
1269  // find a tagged cosmic ray
1270  if(trk[itk].PDGCode != 13) continue;
1271 
1272  } // itk
1273 
1274  } // 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 1277 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.

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