LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
cluster::TrajCluster Class Reference

Produces clusters by the TrajCluster algorithm. More...

Inheritance diagram for cluster::TrajCluster:
art::EDProducer art::ProducerBase art::Consumer art::EngineCreator art::ProductRegistryHelper

Public Types

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

Public Member Functions

 TrajCluster (fhicl::ParameterSet const &pset)
 
void reconfigure (fhicl::ParameterSet const &pset)
 
void produce (art::Event &evt) override
 
void beginJob () override
 
void endJob () override
 
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 Attributes

std::unique_ptr< tca::TrajClusterAlgfTCAlg
 
TTree * showertree
 
art::InputTag fHitModuleLabel
 
art::InputTag fSliceModuleLabel
 
art::InputTag fHitTruthModuleLabel
 
art::InputTag fSpacePointModuleLabel
 
bool fDoWireAssns
 
bool fDoRawDigitAssns
 

Detailed Description

Produces clusters by the TrajCluster algorithm.

Configuration parameters

  • HitFinderModuleLabel (InputTag, mandatory): label of the hits to be used as input (usually the label of the producing module is enough)
  • TrajClusterAlg (parameter set, mandatory): full configuration for TrajClusterAlg algorithm

Definition at line 49 of file TrajCluster_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

cluster::TrajCluster::TrajCluster ( fhicl::ParameterSet const &  pset)
explicit

Definition at line 149 of file TrajCluster_module.cc.

References recob::HitAndAssociationsWriterBase::declare_products(), fDoRawDigitAssns, fDoWireAssns, and reconfigure().

149  {
150 
151  reconfigure(pset);
152 
153  // let HitCollectionAssociator declare that we are going to produce
154  // hits and associations with wires and raw digits
155  // (with no particular product label)
157 
158  produces< std::vector<recob::Cluster> >();
159  produces< std::vector<recob::Vertex> >();
160  produces< std::vector<recob::EndPoint2D> >();
161  produces< std::vector<recob::Seed> >();
162  produces< std::vector<recob::Shower> >();
163  produces< art::Assns<recob::Cluster, recob::Hit> >();
164  produces< art::Assns<recob::Cluster, recob::EndPoint2D, unsigned short> >();
165  produces< art::Assns<recob::Cluster, recob::Vertex, unsigned short> >();
166  produces< art::Assns<recob::Shower, recob::Hit> >();
167 
168  produces< std::vector<recob::PFParticle> >();
169  produces< art::Assns<recob::PFParticle, recob::Cluster> >();
170  produces< art::Assns<recob::PFParticle, recob::Shower> >();
171  produces< art::Assns<recob::PFParticle, recob::Vertex> >();
172  produces< art::Assns<recob::PFParticle, recob::Seed> >();
173 
174  produces< art::Assns<recob::Slice, recob::Cluster> >();
175  produces< art::Assns<recob::Slice, recob::PFParticle> >();
176  produces< art::Assns<recob::Slice, recob::Hit> >();
177 
178  produces< std::vector<anab::CosmicTag>>();
179  produces< art::Assns<recob::PFParticle, anab::CosmicTag>>();
180 
181  // www: declear/create SpacePoint and association between SpacePoint and Hits from TrajCluster (Hit->SpacePoint)
182  produces< art::Assns<recob::SpacePoint, recob::Hit> >();
183  } // TrajCluster::TrajCluster()
static void declare_products(ModuleType &producer, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
Definition: HitCreator.h:1117
void reconfigure(fhicl::ParameterSet const &pset)

Member Function Documentation

void cluster::TrajCluster::beginJob ( )
overridevirtual

Reimplemented from art::EDProducer.

Definition at line 186 of file TrajCluster_module.cc.

References fTCAlg, art::TFileDirectory::make(), and showertree.

187  {
189 
190  showertree = tfs->make<TTree>("showervarstree", "showerVarsTree");
191  fTCAlg->DefineShTree(showertree);
192 // crtree = tfs->make<TTree>("crtree", "Cosmic removal variables");
193 // fTCAlg->DefineCRTree(crtree);
194  }
std::unique_ptr< tca::TrajClusterAlg > fTCAlg
T * make(ARGS...args) const
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
void cluster::TrajCluster::endJob ( )
overridevirtual

Reimplemented from art::EDProducer.

Definition at line 197 of file TrajCluster_module.cc.

References fTCAlg, tca::kKilled, art::left(), and art::right().

198  {
199  std::vector<unsigned int> const& fAlgModCount = fTCAlg->GetAlgModCount();
200  std::vector<std::string> const& fAlgBitNames = fTCAlg->GetAlgBitNames();
201  if(fAlgBitNames.size() != fAlgModCount.size()) return;
202  mf::LogVerbatim myprt("TC");
203  myprt<<"TrajCluster algorithm counts\n";
204  unsigned short icol = 0;
205  for(unsigned short ib = 0; ib < fAlgModCount.size(); ++ib) {
206  if(ib == tca::kKilled) continue;
207  myprt<<std::left<<std::setw(18)<<fAlgBitNames[ib]<<std::right<<std::setw(10)<<fAlgModCount[ib]<<" ";
208  ++icol;
209  if(icol == 4) { myprt<<"\n"; icol = 0; }
210  } // ib
211  } // endJob
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::unique_ptr< tca::TrajClusterAlg > fTCAlg
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
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
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 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 cluster::TrajCluster::produce ( art::Event evt)
overridevirtual

Implements art::EDProducer.

Definition at line 214 of file TrajCluster_module.cc.

References sim::ParticleList::begin(), util::CreateAssn(), util::CreateAssnD(), tca::DebugStuff::Cryostat, geo::CryostatID::Cryostat, tca::TCConfig::dbgStp, tca::debug, tca::DecodeCTP(), DEFINE_ART_MODULE, dir, tca::EncodeCTP(), sim::ParticleList::end(), evd::details::end(), art::Event::event(), fDoRawDigitAssns, fDoWireAssns, fHitModuleLabel, fHitTruthModuleLabel, art::fill_ptr_vector(), fSliceModuleLabel, fSpacePointModuleLabel, fTCAlg, tca::TCConfig::geom, art::FindManyP< ProdB, Data >::get(), art::DataViewImpl::getByLabel(), art::DataViewImpl::getValidHandle(), tca::DebugStuff::Hit, ipart, art::Event::isRealData(), tca::kDebug, tca::kHaloTj, tca::kKilled, anab::kNotTagged, tca::kShowerLike, tca::kTagCosmics, tca::kTestBeam, simb::kUnknown, art::InputTag::label(), tca::TCConfig::matchTruth, geo::GeometryCore::NTPC(), simb::MCTruth::Origin(), geo::origin(), cheat::ParticleInventoryService::ParticleList(), tca::DebugStuff::Plane, geo::PlaneID::Plane, tca::PrintAll(), art::errors::ProductRegistrationFailure, art::Event::put(), recob::HitRefinerAssociator::put_into(), tca::TCConfig::recoSlice, recob::Cluster::Sentry, recob::Shower::set_dedx(), recob::Shower::set_dedx_err(), recob::Shower::set_direction(), recob::Shower::set_direction_err(), recob::Shower::set_id(), recob::Shower::set_length(), recob::Shower::set_open_angle(), recob::Shower::set_start_point(), recob::Shower::set_start_point_err(), recob::Shower::set_total_best_plane(), recob::Shower::set_total_energy(), recob::Shower::set_total_energy_err(), recob::Shower::set_total_MIPenergy(), recob::Shower::set_total_MIPenergy_err(), tca::slices, cluster::SortHits(), tca::tcc, tca::TCConfig::testBeamCuts, tca::DebugStuff::Tick, tmp, tca::DebugStuff::TPC, geo::TPCID::TPC, sim::ParticleList::TrackId(), cheat::ParticleInventoryService::TrackIdToMCTruth_P(), tca::TCConfig::unitsPerTick, recob::HitRefinerAssociator::use_hits(), geo::GeometryCore::View(), tca::DebugStuff::Wire, and Z.

215  {
216  // Get a single hit collection from a HitsModuleLabel or multiple sets of "sliced" hits
217  // (aka clusters of hits that are close to each other in 3D) from a SliceModuleLabel.
218  // A pointer to the full hit collection is passed to TrajClusterAlg. The hits that are
219  // in each slice are tracked to find 2D trajectories (that become clusters),
220  // 2D vertices (EndPoint2D), 3D vertices, PFParticles and Showers. These data products
221  // are then collected and written to the event. Each slice is considered as an independent
222  // collection of hits with the additional requirement that all hits in a slice reside in
223  // one TPC
224 
225  // Define a vector of indices into inputHits (= evt.allHits in TrajClusterAlg)
226  // for each slice for hits associated with 3D-clustered SpacePoints
227  std::vector<std::vector<unsigned int>> slHitsVec;
228  // Slice IDs that will be correlated with sub-slices
229  std::vector<int> slcIDs;
230  // pointers to the slices in the event
231  std::vector<art::Ptr<recob::Slice>> slices;
232  unsigned int nInputHits = 0;
233  // get a handle for the hit collection
234  auto inputHits = art::Handle<std::vector<recob::Hit>>();
235  if(!evt.getByLabel(fHitModuleLabel, inputHits)) throw cet::exception("TrajClusterModule")<<"Failed to get a handle to hit collection '"<<fHitModuleLabel.label()<<"'\n";
236  nInputHits = (*inputHits).size();
237  if(nInputHits > 0) {
238  // This is a pointer to a vector of recob::Hits that exist in the event. The hits
239  // are not copied.
240  if(!fTCAlg->SetInputHits(*inputHits)) throw cet::exception("TrajClusterModule")<<"Failed to process hits from '"<<fHitModuleLabel.label()<<"'\n";
241  if(tca::tcc.dbgStp) std::cout<<"DebugMode: Looking for hit near "<<tca::debug.Cryostat<<":"<<tca::debug.TPC<<":"<<tca::debug.Plane<<":"<<tca::debug.Wire<<":"<<tca::debug.Tick<<"\n";
242  if(fSliceModuleLabel != "NA") {
243  // Expecting to find sliced hits from Slice -> Hits assns
244  auto slcHandle = evt.getValidHandle<std::vector<recob::Slice>>(fSliceModuleLabel);
245  art::fill_ptr_vector(slices, slcHandle);
246  art::FindManyP<recob::Hit> hitFromSlc(slcHandle, evt, fSliceModuleLabel);
247  for(size_t isl = 0; isl < slices.size(); ++isl) {
248  // select slices with user-defined cuts in test beam mode
249  if(tca::tcc.modes[tca::kTestBeam] && tca::tcc.testBeamCuts.size() > 1) {
250  float zlo = slices[isl]->End0Pos().Z();
251  if(slices[isl]->End1Pos().Z() < zlo) zlo = slices[isl]->End1Pos().Z();
252  auto sepVec = slices[isl]->End0Pos() - slices[isl]->End1Pos();
253  float len = sqrt(sepVec.Mag2());
254  bool isBeam = (zlo < tca::tcc.testBeamCuts[0] && len > tca::tcc.testBeamCuts[1]);
255  if(isBeam && tca::tcc.modes[tca::kDebug]) {
256  std::cout<<"Beam slice "<<slices[isl]->ID();
257  std::cout<<" Direction "<<slices[isl]->Direction().X()<<" "<<slices[isl]->Direction().Y()<<" "<<slices[isl]->Direction().Z();
258  std::cout<<" AspectRatio "<<std::setprecision(2)<<slices[isl]->AspectRatio();
259  std::cout<<" Length "<<(int)len;
260  std::cout<<"\n";
261  } // zlo < 10
262  if(!isBeam) continue;
263  } // TestBeam mode
264  auto& hit_in_slc = hitFromSlc.at(isl);
265  if(hit_in_slc.size() < 3) continue;
266  std::vector<unsigned int> slhits(hit_in_slc.size());
267  unsigned int indx = 0;
268  if(hit_in_slc[0].id() != inputHits.id()) throw cet::exception("TrajClusterModule")<<"Input hits from '"<<fHitModuleLabel.label()<<"' have a different product id than hits referenced in '"<<fSliceModuleLabel.label()<<"'\n";
269  for(auto& hit : hit_in_slc) {
270  if(hit.key() > nInputHits - 1) throw cet::exception("TrajClusterModule")<<"Found an invalid slice index "<<hit.key()<<" to the input hit collection of size "<<nInputHits<<"\n";
271  slhits[indx] = hit.key();
272  ++indx;
273  } // hit
274  if(slhits.size() < 3) continue;
275  slHitsVec.push_back(slhits);
276  slcIDs.push_back(slices[isl]->ID());
277  } // isl
278  } else {
279  // There was no pre-processing of the hits to define slices
280  // so put all hits into one slice
281  slHitsVec.resize(1);
282  slHitsVec[0].resize(nInputHits);
283  for(unsigned int iht = 0; iht < nInputHits; ++iht) slHitsVec[0][iht] = iht;
284  slcIDs.resize(1, 1);
285  } // no input slices
286 
287  // split slHitsVec so that all hits in a sub-slice are in the same TPC
288  const geo::GeometryCore* geom = lar::providerFrom<geo::Geometry>();
289  if(geom->NTPC() > 1) {
290  std::vector<std::vector<unsigned int>> tpcSlcHitsVec;
291  std::vector<int> tpcSlcIDs;
292  for(unsigned short isl = 0; isl < slHitsVec.size(); ++isl) {
293  auto& slhits = slHitsVec[isl];
294  if(slhits.size() < 2) continue;
295  // list of hits in this slice in each TPC
296  std::vector<std::vector<unsigned int>> tpcHits;
297  // list of TPCs in this slice
298  std::vector<unsigned short> tpcNum;
299  for(auto iht : slhits) {
300  auto& hit = (*inputHits)[iht];
301  unsigned short tpc = hit.WireID().TPC;
302  unsigned short tpcIndex = 0;
303  for(tpcIndex = 0; tpcIndex < tpcNum.size(); ++tpcIndex) if(tpcNum[tpcIndex] == tpc) break;
304  if(tpcIndex == tpcNum.size()) {
305  // not in tpcNum so make a new entry
306  tpcHits.resize(tpcIndex + 1);
307  tpcNum.push_back(tpc);
308  }
309  tpcHits[tpcIndex].push_back(iht);
310  } // iht
311  for(auto& tHits : tpcHits) {
312  tpcSlcHitsVec.push_back(tHits);
313  tpcSlcIDs.push_back(slcIDs[isl]);
314  }
315  } // slhits
316  // over-write slHitsVec
317  slHitsVec = tpcSlcHitsVec;
318  slcIDs = tpcSlcIDs;
319  } // > 1 TPC
320 
321  // Get truth info before reconstructing
322  // list of selected MCParticles
323  std::vector<simb::MCParticle*> mcpList;
324  // and a vector of MC-matched hits
325  std::vector<unsigned int> mcpListIndex((*inputHits).size(), UINT_MAX);
326  if(!evt.isRealData() && tca::tcc.matchTruth[0] >= 0 && fHitTruthModuleLabel != "NA") {
327  // TODO: Add a check here to ensure that a neutrino vertex exists inside any TPC
328  // when checking neutrino reconstruction performance.
329  // create a list of MCParticles of interest
330  // save MCParticles that have the desired MCTruth origin using
331  // the Origin_t typedef enum: kUnknown, kBeamNeutrino, kCosmicRay, kSuperNovaNeutrino, kSingleParticle
332  simb::Origin_t origin = (simb::Origin_t)tca::tcc.matchTruth[0];
333  // or save them all
334  bool anySource = (origin == simb::kUnknown);
335  // get the assns
338  sim::ParticleList const& plist = pi_serv->ParticleList();
339  for(sim::ParticleList::const_iterator ipart = plist.begin(); ipart != plist.end(); ++ipart) {
340  auto& p = (*ipart).second;
341  int trackID = p->TrackId();
342  art::Ptr<simb::MCTruth> theTruth = pi_serv->TrackIdToMCTruth_P(trackID);
343  int KE = 1000 * (p->E() - p->Mass());
344  if(!anySource && theTruth->Origin() != origin) continue;
345  if(tca::tcc.matchTruth[1] > 1 && KE > 10 && p->Process() == "primary") {
346  std::cout<<"TCM: mcp Origin "<<theTruth->Origin()
347  <<std::setw(8)<<p->TrackId()
348  <<" pdg "<<p->PdgCode()
349  <<std::setw(7)<<KE<<" mom "<<p->Mother()
350  <<" "<<p->Process()
351  <<"\n";
352  }
353  mcpList.push_back(p);
354  } // ipart
355  std::vector<art::Ptr<simb::MCParticle>> particle_vec;
356  std::vector<anab::BackTrackerHitMatchingData const*> match_vec;
357  unsigned int nMatHits = 0;
358  for(unsigned int iht = 0; iht < (*inputHits).size(); ++iht) {
359  particle_vec.clear(); match_vec.clear();
360  try{ particles_per_hit.get(iht, particle_vec, match_vec); }
361  catch(...) {
362  std::cout<<"BackTrackerHitMatchingData not found\n";
363  break;
364  }
365  if(particle_vec.empty()) continue;
366  int trackID = 0;
367  for(unsigned short im = 0; im < match_vec.size(); ++im) {
368  if(match_vec[im]->ideFraction < 0.5) continue;
369  trackID = particle_vec[im]->TrackId();
370  break;
371  } // im
372  if(trackID == 0) continue;
373  // look for this in MCPartList
374  for(unsigned int ipart = 0; ipart < mcpList.size(); ++ipart) {
375  auto& mcp = mcpList[ipart];
376  if(mcp->TrackId() != trackID) continue;
377  mcpListIndex[iht] = ipart;
378  ++nMatHits;
379  break;
380  } // ipart
381  } // iht
382  if(tca::tcc.matchTruth[1] > 1) std::cout<<"Loaded "<<mcpList.size()<<" MCParticles. "<<nMatHits<<"/"<<(*inputHits).size()<<" hits are matched to MCParticles\n";
383  } // fill mcpList
384 
385  // First sort the hits in each sub-slice and then reconstruct
386  for(unsigned short isl = 0; isl < slHitsVec.size(); ++isl) {
387  auto& slhits = slHitsVec[isl];
388  // sort the slice hits by Cryostat, TPC, Wire, Plane, Start Tick and LocalIndex.
389  // This assumes that hits with larger LocalIndex are at larger Tick.
390  std::vector<HitLoc> sortVec(slhits.size());
391  bool badHit = false;
392  for(unsigned short indx = 0; indx < slhits.size(); ++indx) {
393  if(slhits[indx] > nInputHits - 1) {
394  badHit = true;
395  break;
396  }
397  auto& hit = (*inputHits)[slhits[indx]];
398  sortVec[indx].index = indx;
399  sortVec[indx].ctp = tca::EncodeCTP(hit.WireID());
400  sortVec[indx].wire = hit.WireID().Wire;
401  sortVec[indx].tick = hit.StartTick();
402  sortVec[indx].localIndex = hit.LocalIndex();
403  } // iht
404  if(badHit) {
405  std::cout<<"TrajCluster found an invalid slice reference to the input hit collection. Ignoring this slice.\n";
406  continue;
407  }
408  std::sort(sortVec.begin(), sortVec.end(), SortHits);
409  // make a temporary copy of slhits
410  auto tmp = slhits;
411  // put slhits into proper order
412  for(unsigned short ii = 0; ii < slhits.size(); ++ii) slhits[ii] = tmp[sortVec[ii].index];
413  // clear the temp vector
414  tmp.resize(0);
415  // try to find a hit in debug step mode
416  if(tca::tcc.modes[tca::kDebug]) {
417  for(unsigned short indx = 0; indx < slhits.size(); ++indx) {
418  auto& hit = (*inputHits)[slhits[indx]];
419  if((int)hit.WireID().TPC == tca::debug.TPC &&
420  (int)hit.WireID().Plane == tca::debug.Plane &&
421  (int)hit.WireID().Wire == tca::debug.Wire &&
422  hit.PeakTime() > tca::debug.Tick - 10 && hit.PeakTime() < tca::debug.Tick + 10) {
423  std::cout<<"Debug hit "<<slhits[indx]<<" found in sub-slice index "<<isl;
424  std::cout<<"\n";
425  tca::debug.Hit = slhits[indx];
426  tca::tcc.dbgStp = true;
427  break;
428  } // Look for debug hit
429  } // iht
430  } // Debug mode
431  // reconstruct using the hits in this sub-slice. The data products are stored internally in
432  // TrajCluster data structs.
433  fTCAlg->RunTrajClusterAlg(slhits, slcIDs[isl]);
434  } // isl
435 
436  // stitch PFParticles between TPCs, create PFP start vertices, etc
437  fTCAlg->FinishEvent();
438 
439  if(!mcpListIndex.empty()) {
440  fTCAlg->fTM.MatchTruth(mcpList, mcpListIndex);
441  if(tca::tcc.matchTruth[0] >= 0) fTCAlg->fTM.PrintResults(evt.event());
442  } // mcpList not empty
443  if(tca::tcc.dbgSummary) tca::PrintAll("TCM", mcpList);
444  } // input hits exist
445 
446  // Vectors to hold all data products that will go into the event
447  std::vector<recob::Hit> hitCol; // output hit collection
448  std::vector<recob::Cluster> clsCol;
449  std::vector<recob::PFParticle> pfpCol;
450  std::vector<recob::Vertex> vx3Col;
451  std::vector<recob::EndPoint2D> vx2Col;
452  std::vector<recob::Seed> sedCol;
453  std::vector<recob::Shower> shwCol;
454  std::vector<anab::CosmicTag> ctCol;
455  // a vector to correlate inputHits with output hits
456  std::vector<unsigned int> newIndex(nInputHits, UINT_MAX);
457 
458  // assns for those data products
459  // Cluster -> ...
460  std::unique_ptr<art::Assns<recob::Cluster, recob::Hit>>
461  cls_hit_assn(new art::Assns<recob::Cluster, recob::Hit>);
462  // unsigned short is the end to which a vertex is attached
463  std::unique_ptr<art::Assns<recob::Cluster, recob::EndPoint2D, unsigned short>>
465  std::unique_ptr<art::Assns<recob::Cluster, recob::Vertex, unsigned short>>
467  // Shower -> ...
468  std::unique_ptr<art::Assns<recob::Shower, recob::Hit>>
469  shwr_hit_assn(new art::Assns<recob::Shower, recob::Hit>);
470  // PFParticle -> ...
471  std::unique_ptr<art::Assns<recob::PFParticle, recob::Cluster>>
473  std::unique_ptr<art::Assns<recob::PFParticle, recob::Shower>>
475  std::unique_ptr<art::Assns<recob::PFParticle, recob::Vertex>>
477  std::unique_ptr<art::Assns<recob::PFParticle, anab::CosmicTag>>
479  std::unique_ptr<art::Assns<recob::PFParticle, recob::Seed>>
481  // Slice -> ...
482  std::unique_ptr<art::Assns<recob::Slice, recob::Cluster>>
484  std::unique_ptr<art::Assns<recob::Slice, recob::PFParticle>>
486  std::unique_ptr<art::Assns<recob::Slice, recob::Hit>>
487  slc_hit_assn(new art::Assns<recob::Slice, recob::Hit>);
488  // www: Hit -> SpacePoint
489  std::unique_ptr<art::Assns<recob::SpacePoint, recob::Hit>>
491 
492  // temp struct to get the index of a 2D (or 3D vertex) into vx2Col (or vx3Col)
493  // given a slice index and a vertex ID (not UID)
494  struct slcVxStruct {
495  unsigned short slIndx;
496  int ID;
497  unsigned short vxColIndx;
498  };
499  std::vector<slcVxStruct> vx2StrList;
500  // vector to map 3V UID -> ID in each sub-slice
501  std::vector<slcVxStruct> vx3StrList;
502 
503 
504  if(nInputHits > 0) {
505  unsigned short nSlices = fTCAlg->GetSlicesSize();
506  // define a hit collection begin index to pass to CreateAssn for each cluster
507  unsigned int hitColBeginIndex = 0;
508  for(unsigned short isl = 0; isl < nSlices; ++isl) {
509  unsigned short slcIndex = 0;
510  if(!slices.empty()) {
511  for(slcIndex = 0; slcIndex < slices.size(); ++slcIndex) if(slices[slcIndex]->ID() == slcIDs[isl]) break;
512  if(slcIndex == slices.size()) continue;
513  }
514  auto& slc = fTCAlg->GetSlice(isl);
515  // See if there was a serious reconstruction failure that made the sub-slice invalid
516  if(!slc.isValid) continue;
517  // make EndPoint2Ds
518  for(auto& vx2 : slc.vtxs) {
519  if(vx2.ID <= 0) continue;
520  unsigned int vtxID = vx2.UID;
521  unsigned int wire = std::nearbyint(vx2.Pos[0]);
522  geo::PlaneID plID = tca::DecodeCTP(vx2.CTP);
523  geo::WireID wID = geo::WireID(plID.Cryostat, plID.TPC, plID.Plane, wire);
524  geo::View_t view = tca::tcc.geom->View(wID);
525  vx2Col.emplace_back((double)vx2.Pos[1]/tca::tcc.unitsPerTick, // Time
526  wID, // WireID
527  vx2.Score, // strength = score
528  vtxID, // ID
529  view, // View
530  0); // total charge - not relevant
531 
532  // fill the mapping struct
533  slcVxStruct tmp;
534  tmp.slIndx = isl;
535  tmp.ID = vx2.ID;
536  tmp.vxColIndx = vx2Col.size() - 1;
537  vx2StrList.push_back(tmp);
538 
539  } // vx2
540  // make Vertices
541  for(auto& vx3 : slc.vtx3s) {
542  if(vx3.ID <= 0) continue;
543  // ignore incomplete vertices
544  if(vx3.Wire >= 0) continue;
545  unsigned int vtxID = vx3.UID;
546  double xyz[3];
547  xyz[0] = vx3.X;
548  xyz[1] = vx3.Y;
549  xyz[2] = vx3.Z;
550  vx3Col.emplace_back(xyz, vtxID);
551 
552  // fill the mapping struct
553  slcVxStruct tmp;
554  tmp.slIndx = isl;
555  tmp.ID = vx3.ID;
556  tmp.vxColIndx = vx3Col.size() - 1;
557  vx3StrList.push_back(tmp);
558 
559  } // vx3
560  // Convert the tjs to clusters
561  for(auto& tj : slc.tjs) {
562  if(tj.AlgMod[tca::kKilled]) continue;
563  hitColBeginIndex = hitCol.size();
564  for(unsigned short ipt = tj.EndPt[0]; ipt <= tj.EndPt[1]; ++ipt) {
565  auto& tp = tj.Pts[ipt];
566  if(tp.Chg <= 0) continue;
567  // index of inputHits indices of hits used in one TP
568  std::vector<unsigned int> tpHits;
569  for(unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
570  if(!tp.UseHit[ii]) continue;
571  if(tp.Hits[ii] > slc.slHits.size() - 1) {
572  break;
573  } // bad slHits index
574  unsigned int allHitsIndex = slc.slHits[tp.Hits[ii]].allHitsIndex;
575  if(allHitsIndex > nInputHits - 1) {
576  break;
577  } // bad allHitsIndex
578  tpHits.push_back(allHitsIndex);
579  if(newIndex[allHitsIndex] != UINT_MAX) {
580  std::cout<<"Bad Slice "<<isl<<" tp.Hits "<<tp.Hits[ii]<<" allHitsIndex "<<allHitsIndex;
581  std::cout<<" old newIndex "<<newIndex[allHitsIndex];
582  auto& oldhit = (*inputHits)[allHitsIndex];
583  std::cout<<" old "<<oldhit.WireID().Plane<<":"<<oldhit.WireID().Wire<<":"<<(int)oldhit.PeakTime();
584  auto& newhit = hitCol[newIndex[allHitsIndex]];
585  std::cout<<" new "<<newhit.WireID().Plane<<":"<<newhit.WireID().Wire<<":"<<(int)newhit.PeakTime();
586  std::cout<<" hitCol size "<<hitCol.size();
587  std::cout<<"\n";
588  break;
589  }
590 // newIndex[allHitsIndex] = hitCol.size();
591  } // ii
592  // Let the alg define the hit either by merging multiple hits or by a simple copy
593  // of a single hit from inputHits
594  // Merge hits in the TP that are on the same wire or create hits on multiple wires
595  // and update the old hits -> new hits assn (newIndex)
596  if(tj.AlgMod[tca::kHaloTj]) {
597  // dressed muon - don't merge hits
598  for(auto iht : tpHits) {
599  hitCol.push_back((*inputHits)[iht]);
600  newIndex[iht] = hitCol.size() - 1;
601  } // iht
602  } else {
603  fTCAlg->MergeTPHits(tpHits, hitCol, newIndex);
604  }
605  } // tp
606  if(hitCol.empty()) continue;
607  // Sum the charge and make the associations
608  float sumChg = 0;
609  float sumADC = 0;
610  for(unsigned short indx = hitColBeginIndex; indx < hitCol.size(); ++indx) {
611  auto& hit = hitCol[indx];
612  sumChg += hit.Integral();
613  sumADC += hit.SummedADC();
614  if(!slices.empty() && !util::CreateAssn(*this, evt, hitCol, slices[slcIndex], *slc_hit_assn, indx)) {
615  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate hits with Slice";
616  }
617  } // indx
618  geo::View_t view = hitCol[hitColBeginIndex].View();
619  auto& firstTP = tj.Pts[tj.EndPt[0]];
620  auto& lastTP = tj.Pts[tj.EndPt[1]];
621  int clsID = tj.UID;
622  if(tj.AlgMod[tca::kShowerLike]) clsID = -clsID;
623  // dressed muon - give the halo cluster the same ID as the parent
624  if(tj.AlgMod[tca::kHaloTj]) clsID = -tj.ParentID;
625  unsigned short nclhits = hitCol.size() - hitColBeginIndex + 1;
626  clsCol.emplace_back(
627  firstTP.Pos[0], // Start wire
628  0, // sigma start wire
629  firstTP.Pos[1]/tca::tcc.unitsPerTick, // start tick
630  0, // sigma start tick
631  firstTP.AveChg, // start charge
632  firstTP.Ang, // start angle
633  0, // start opening angle (0 for line-like clusters)
634  lastTP.Pos[0], // end wire
635  0, // sigma end wire
636  lastTP.Pos[1]/tca::tcc.unitsPerTick, // end tick
637  0, // sigma end tick
638  lastTP.AveChg, // end charge
639  lastTP.Ang, // end angle
640  0, // end opening angle (0 for line-like clusters)
641  sumChg, // integral
642  0, // sigma integral
643  sumADC, // summed ADC
644  0, // sigma summed ADC
645  nclhits, // n hits
646  0, // wires over hits
647  0, // width (0 for line-like clusters)
648  clsID, // ID from TrajClusterAlg
649  view, // view
650  tca::DecodeCTP(tj.CTP), // planeID
651  recob::Cluster::Sentry // sentry
652  );
653  if(!util::CreateAssn(*this, evt, clsCol, hitCol, *cls_hit_assn, hitColBeginIndex, hitCol.size()))
654  {
655  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate hits with cluster ID "<<tj.UID;
656  } // exception
657  // make Slice -> cluster assn
658  if(!slices.empty()) {
659  if(!util::CreateAssn(*this, evt, clsCol, slices[slcIndex], *slc_cls_assn))
660  {
661  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate slice with PFParticle";
662  } // exception
663  } // slices exist
664  // Make cluster -> 2V and cluster -> 3V assns
665  for(unsigned short end = 0; end < 2; ++end) {
666  if(tj.VtxID[end] <= 0) continue;
667  for(auto& vx2str : vx2StrList) {
668  if(vx2str.slIndx != isl) continue;
669  if(vx2str.ID != tj.VtxID[end]) continue;
670  if(!util::CreateAssnD(*this, evt, *cls_vx2_assn, clsCol.size() - 1, vx2str.vxColIndx, end)) {
671  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate cluster "<<tj.UID<<" with EndPoint2D";
672  } // exception
673  auto& vx2 = slc.vtxs[tj.VtxID[end] - 1];
674  if(vx2.Vx3ID > 0) {
675  for(auto vx3str : vx3StrList) {
676  if(vx3str.slIndx != isl) continue;
677  if(vx3str.ID != vx2.Vx3ID) continue;
678  if(!util::CreateAssnD(*this, evt, *cls_vx3_assn, clsCol.size() - 1, vx3str.vxColIndx, end))
679  {
680  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate cluster "<<tj.UID<<" with Vertex";
681  } // exception
682  break;
683  } // vx3str
684  } // vx2.Vx3ID > 0
685  break;
686  } // vx2str
687  } // end
688  } // tj (aka cluster)
689  // make Showers
690  for(auto& ss3 : slc.showers) {
691  if(ss3.ID <= 0) continue;
693  shower.set_id(ss3.UID);
694  shower.set_total_energy(ss3.Energy);
695  shower.set_total_energy_err(ss3.EnergyErr);
696  shower.set_total_MIPenergy(ss3.MIPEnergy);
697  shower.set_total_MIPenergy_err(ss3.MIPEnergyErr);
698  shower.set_total_best_plane(ss3.BestPlane);
699  TVector3 dir = {ss3.Dir[0], ss3.Dir[1], ss3.Dir[2]};
700  shower.set_direction(dir);
701  TVector3 dirErr = {ss3.DirErr[0], ss3.DirErr[1], ss3.DirErr[2]};
702  shower.set_direction_err(dirErr);
703  TVector3 pos = {ss3.Start[0], ss3.Start[1], ss3.Start[2]};
704  shower.set_start_point(pos);
705  TVector3 posErr = {ss3.StartErr[0], ss3.StartErr[1], ss3.StartErr[2]};
706  shower.set_start_point_err(posErr);
707  shower.set_dedx(ss3.dEdx);
708  shower.set_dedx_err(ss3.dEdxErr);
709  shower.set_length(ss3.Len);
710  shower.set_open_angle(ss3.OpenAngle);
711  shwCol.push_back(shower);
712  // make the shower - hit association
713  std::vector<unsigned int> shwHits(ss3.Hits.size());
714  for(unsigned int iht = 0; iht < ss3.Hits.size(); ++iht) shwHits[iht] = newIndex[ss3.Hits[iht]];
715  if(!util::CreateAssn(*this, evt, *shwr_hit_assn, shwCol.size()-1, shwHits.begin(), shwHits.end()))
716  {
717  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate hits with Shower";
718  } // exception
719  } // ss3
720  } // slice isl
721 
722 
723  // Add PFParticles now that clsCol is filled
724  for(unsigned short isl = 0; isl < nSlices; ++isl) {
725  unsigned short slcIndex = 0;
726  if(!slices.empty()) {
727  for(slcIndex = 0; slcIndex < slices.size(); ++slcIndex) if(slices[slcIndex]->ID() == slcIDs[isl]) break;
728  if(slcIndex == slices.size()) continue;
729  }
730  auto& slc = fTCAlg->GetSlice(isl);
731  // See if there was a serious reconstruction failure that made the slice invalid
732  if(!slc.isValid) continue;
733  // make PFParticles
734  for(size_t ipfp = 0; ipfp < slc.pfps.size(); ++ipfp) {
735  auto& pfp = slc.pfps[ipfp];
736  if(pfp.ID <= 0) continue;
737  // parents and daughters are indexed within a slice so find the index offset in pfpCol
738  size_t self = pfpCol.size();
739  size_t offset = self - ipfp;
740  size_t parentIndex = UINT_MAX;
741  if(pfp.ParentUID > 0) parentIndex = pfp.ParentUID + offset - 1;
742  std::vector<size_t> dtrIndices(pfp.DtrUIDs.size());
743  for(unsigned short idtr = 0; idtr < pfp.DtrUIDs.size(); ++idtr) dtrIndices[idtr] = pfp.DtrUIDs[idtr] + offset - 1;
744  pfpCol.emplace_back(pfp.PDGCode, self, parentIndex, dtrIndices);
745  double sp[] = {pfp.XYZ[0][0],pfp.XYZ[0][1],pfp.XYZ[0][2]};
746  double sd[] = {pfp.Dir[0][0],pfp.Dir[0][1],pfp.Dir[0][2]};
747  double spe[] = {0.,0.,0.};
748  double sde[] = {0.,0.,0.};
749  sedCol.emplace_back(sp,sd,spe,sde);
750  // PFParticle -> clusters
751  std::vector<unsigned int> clsIndices;
752  for(auto tuid : pfp.TjUIDs) {
753  unsigned int clsIndex = 0;
754  for(clsIndex = 0; clsIndex < clsCol.size(); ++clsIndex) if(abs(clsCol[clsIndex].ID()) == tuid) break;
755  if(clsIndex == clsCol.size()) {
756  std::cout<<"TrajCluster module invalid P"<<pfp.UID<<" -> T"<<tuid<<" -> cluster index \n";
757  continue;
758  }
759  clsIndices.push_back(clsIndex);
760  } // tjid
761  if(!util::CreateAssn(*this, evt, *pfp_cls_assn, pfpCol.size()-1, clsIndices.begin(), clsIndices.end()))
762  {
763  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate clusters with PFParticle";
764  } // exception
765  // PFParticle -> Vertex
766  if(pfp.Vx3ID[0] > 0) {
767  for(auto vx3str : vx3StrList) {
768  if(vx3str.slIndx != isl) continue;
769  if(vx3str.ID != pfp.Vx3ID[0]) continue;
770  std::vector<unsigned short> indx(1, vx3str.vxColIndx);
771  if(!util::CreateAssn(*this, evt, *pfp_vx3_assn, pfpCol.size() - 1, indx.begin(), indx.end()))
772  {
773  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate PFParticle "<<pfp.UID<<" with Vertex";
774  } // exception
775  break;
776  } // vx3Index
777  } // start vertex exists
778  // PFParticle -> Seed
779  if(!sedCol.empty()) {
780  if(!util::CreateAssn(*this, evt, pfpCol, sedCol, *pfp_sed_assn, sedCol.size()-1, sedCol.size(), pfpCol.size()-1))
781  {
782  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate seed with PFParticle";
783  } // exception
784  } // seeds exist
785  // PFParticle -> Slice
786  if(!slices.empty()) {
787  if(!util::CreateAssn(*this, evt, pfpCol, slices[slcIndex], *slc_pfp_assn))
788  {
789  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate slice with PFParticle";
790  } // exception
791  } // slices exist
792  // PFParticle -> Shower
793  if(pfp.PDGCode == 1111) {
794  std::vector<unsigned short> shwIndex(1, 0);
795  for(auto& ss3 : slc.showers) {
796  if(ss3.ID <= 0) continue;
797  if(ss3.PFPIndex == ipfp) break;
798  ++shwIndex[0];
799  } // ss3
800  if(shwIndex[0] < shwCol.size()) {
801  if(!util::CreateAssn(*this, evt, *pfp_shwr_assn, pfpCol.size()-1, shwIndex.begin(), shwIndex.end()))
802  {
803  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate shower with PFParticle";
804  } // exception
805  } // valid shwIndex
806  } // pfp -> Shower
807  // PFParticle cosmic tag
808  if(tca::tcc.modes[tca::kTagCosmics]) {
809  std::vector<float> tempPt1, tempPt2;
810  tempPt1.push_back(-999);
811  tempPt1.push_back(-999);
812  tempPt1.push_back(-999);
813  tempPt2.push_back(-999);
814  tempPt2.push_back(-999);
815  tempPt2.push_back(-999);
816  ctCol.emplace_back(tempPt1, tempPt2, pfp.CosmicScore, anab::CosmicTagID_t::kNotTagged);
817  if (!util::CreateAssn(*this, evt, pfpCol, ctCol, *pfp_cos_assn, ctCol.size()-1, ctCol.size())){
818  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate CosmicTag with PFParticle";
819  }
820  } // cosmic tag
821  } // ipfp
822  } // isl
823 
824  // add the hits that weren't used in any slice to hitCol unless this is a
825  // special debugging mode and would be a waste of time
826  if(!slices.empty() && tca::tcc.recoSlice == 0) {
827  auto slcHandle = evt.getValidHandle<std::vector<recob::Slice>>(fSliceModuleLabel);
828  art::FindManyP<recob::Hit> hitFromSlc(slcHandle, evt, fSliceModuleLabel);
829  for(unsigned int allHitsIndex = 0; allHitsIndex < nInputHits; ++allHitsIndex) {
830  if(newIndex[allHitsIndex] != UINT_MAX) continue;
831  std::vector<unsigned int> oneHit(1, allHitsIndex);
832  fTCAlg->MergeTPHits(oneHit, hitCol, newIndex);
833  // find out which slice it is in
834  bool gotit = false;
835  for(size_t isl = 0; isl < slices.size(); ++isl) {
836  auto& hit_in_slc = hitFromSlc.at(isl);
837  for(auto& hit : hit_in_slc) {
838  if(hit.key() != allHitsIndex) continue;
839  gotit = true;
840  // Slice -> Hit assn
841  if(!util::CreateAssn(*this, evt, hitCol, slices[isl], *slc_hit_assn))
842  {
843  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate old Hit with Slice";
844  } // exception
845  break;
846  } // hit
847  if(gotit) break;
848  } // isl
849  } // allHitsIndex
850  } // slices exist
851  else {
852  // no recob::Slices. Just copy the unused hits
853  for(unsigned int allHitsIndex = 0; allHitsIndex < nInputHits; ++allHitsIndex) {
854  if(newIndex[allHitsIndex] != UINT_MAX) continue;
855  std::vector<unsigned int> oneHit(1, allHitsIndex);
856  fTCAlg->MergeTPHits(oneHit, hitCol, newIndex);
857  } // allHitsIndex
858  } // recob::Slices
859  } // input hits exist
860 
861  // www: find spacepoint from hits (inputHits) through SpacePoint->Hit assns, then create association between spacepoint and trajcluster hits (here, hits in hitCol)
862  if (nInputHits > 0) {
863  // www: expecting to find spacepoint from hits (inputHits): SpacePoint->Hit assns
864  if (fSpacePointModuleLabel != "NA") {
865  art::FindManyP<recob::SpacePoint> spFromHit (inputHits, evt, fSpacePointModuleLabel);
866  // www: using sp from hit
867  for (unsigned int allHitsIndex = 0; allHitsIndex < nInputHits; ++allHitsIndex) {
868  if (newIndex[allHitsIndex] == UINT_MAX) continue; // skip hits not used in slice (not TrajCluster hits)
869  auto & sp_from_hit = spFromHit.at(allHitsIndex);
870  for (auto& sp : sp_from_hit) {
871  // SpacePoint -> Hit assn
872  if(!util::CreateAssn(*this, evt, hitCol, sp, *sp_hit_assn, newIndex[allHitsIndex])) {
873  throw art::Exception(art::errors::ProductRegistrationFailure)<<"Failed to associate new Hit with SpacePoint";
874  } // exception
875  } // sp
876  } // allHitsIndex
877  } // fSpacePointModuleLabel != "NA"
878  } // nInputHits > 0
879 
880  // clear the alg data structures
881  fTCAlg->ClearResults();
882 
883  // convert vectors to unique_ptrs
884  std::unique_ptr<std::vector<recob::Hit> > hcol(new std::vector<recob::Hit>(std::move(hitCol)));
885  std::unique_ptr<std::vector<recob::Cluster> > ccol(new std::vector<recob::Cluster>(std::move(clsCol)));
886  std::unique_ptr<std::vector<recob::EndPoint2D> > v2col(new std::vector<recob::EndPoint2D>(std::move(vx2Col)));
887  std::unique_ptr<std::vector<recob::Vertex> > v3col(new std::vector<recob::Vertex>(std::move(vx3Col)));
888  std::unique_ptr<std::vector<recob::PFParticle> > pcol(new std::vector<recob::PFParticle>(std::move(pfpCol)));
889  std::unique_ptr<std::vector<recob::Seed> > sdcol(new std::vector<recob::Seed>(std::move(sedCol)));
890  std::unique_ptr<std::vector<recob::Shower> > scol(new std::vector<recob::Shower>(std::move(shwCol)));
891  std::unique_ptr<std::vector<anab::CosmicTag>> ctgcol(new std::vector<anab::CosmicTag>(std::move(ctCol)));
892 
893  // move the cluster collection and the associations into the event:
894  if(fHitModuleLabel != "NA") {
896  shcol.use_hits(std::move(hcol));
897  shcol.put_into(evt);
898  } else {
900  shcol.use_hits(std::move(hcol));
901  shcol.put_into(evt);
902  }
903  evt.put(std::move(ccol));
904  evt.put(std::move(cls_hit_assn));
905  evt.put(std::move(v2col));
906  evt.put(std::move(v3col));
907  evt.put(std::move(scol));
908  evt.put(std::move(sdcol));
909  evt.put(std::move(shwr_hit_assn));
910  evt.put(std::move(cls_vx2_assn));
911  evt.put(std::move(cls_vx3_assn));
912  evt.put(std::move(pcol));
913  evt.put(std::move(pfp_cls_assn));
914  evt.put(std::move(pfp_shwr_assn));
915  evt.put(std::move(pfp_vx3_assn));
916  evt.put(std::move(pfp_sed_assn));
917  evt.put(std::move(slc_cls_assn));
918  evt.put(std::move(slc_pfp_assn));
919  evt.put(std::move(slc_hit_assn));
920  evt.put(std::move(ctgcol));
921  evt.put(std::move(pfp_cos_assn));
922  evt.put(std::move(sp_hit_assn)); // www: association between sp and hit (trjaclust)
923  } // TrajCluster::produce()
Expect tracks entering from the front face. Don&#39;t create neutrino PFParticles.
Definition: DataStructs.h:448
void set_start_point_err(const TVector3 &xyz_e)
Definition: Shower.h:138
void set_dedx_err(const std::vector< double > &q)
Definition: Shower.h:140
void set_direction_err(const TVector3 &dir_e)
Definition: Shower.h:136
const key_type & TrackId(const size_type) const
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
TCConfig tcc
Definition: DataStructs.cxx:6
list_type::const_iterator const_iterator
Definition: ParticleList.h:132
simb::Origin_t Origin() const
Definition: MCTruth.h:71
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
enum simb::_ev_origin Origin_t
event origin types
void set_total_energy(const std::vector< double > &q)
Definition: Shower.h:129
art::InputTag fSliceModuleLabel
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:130
void set_total_MIPenergy_err(const std::vector< double > &q)
Definition: Shower.h:132
Float_t tmp
Definition: plot.C:37
std::vector< float > matchTruth
Match to MC truth.
Definition: DataStructs.h:477
bool isRealData() const
Definition: Event.h:83
bool SortHits(HitLoc const &h1, HitLoc const &h2)
void set_total_energy_err(const std::vector< double > &q)
Definition: Shower.h:130
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
Float_t Z
Definition: plot.C:39
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
void set_id(const int id)
Definition: Shower.h:128
unsigned int Hit
set to the hit index in evt.allHits if a Plane:Wire:Tick match is found
Definition: DebugStruct.h:25
int Cryostat
Select Cryostat.
Definition: DebugStruct.h:19
art::InputTag fHitModuleLabel
void set_direction(const TVector3 &dir)
Definition: Shower.h:135
bool dbgStp
debug stepping using debug.Cryostat, debug.TPC, etc
Definition: DataStructs.h:508
int Wire
Select hit Wire for debugging.
Definition: DebugStruct.h:23
std::vector< float > testBeamCuts
Definition: DataStructs.h:481
float unitsPerTick
scale factor from Tick to WSE equivalent units
Definition: DataStructs.h:488
DebugStuff debug
Definition: DebugStruct.cxx:4
bool CreateAssnD(PRODUCER const &prod, art::Event &evt, art::Assns< T, U, D > &assn, size_t first_index, size_t second_index, typename art::Assns< T, U, D >::data_t &&data)
Creates a single one-to-one association with associated data.
void set_length(const double &l)
Definition: Shower.h:141
int Plane
Select plane.
Definition: DebugStruct.h:21
void set_open_angle(const double &a)
Definition: Shower.h:142
iterator begin()
Definition: ParticleList.h:305
A class handling a collection of hits and its associations.
Definition: HitCreator.h:865
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.
EventNumber_t event() const
Definition: Event.h:67
const geo::GeometryCore * geom
Definition: DataStructs.h:493
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
Description of geometry of one entire detector.
void set_total_best_plane(const int q)
Definition: Shower.h:133
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
std::unique_ptr< tca::TrajClusterAlg > fTCAlg
void set_total_MIPenergy(const std::vector< double > &q)
Definition: Shower.h:131
std::vector< TCSlice > slices
Definition: DataStructs.cxx:10
Detector simulation of raw signals on wires.
art::InputTag fSpacePointModuleLabel
void PrintAll(std::string someText, const std::vector< simb::MCParticle * > &mcpList)
Definition: Utils.cxx:4774
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
int Tick
Select hit PeakTime for debugging (< 0 for vertex finding)
Definition: DebugStruct.h:24
int TPC
Select TPC.
Definition: DebugStruct.h:20
TDirectory * dir
Definition: macro.C:5
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
geo::PlaneID DecodeCTP(CTP_t CTP)
Int_t ipart
Definition: Style.C:10
CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
Definition: DataStructs.h:45
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
void set_start_point(const TVector3 &xyz)
Definition: Shower.h:137
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:464
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:203
short recoSlice
only reconstruct the slice with ID (0 = all)
Definition: DataStructs.h:506
std::string const & label() const noexcept
Definition: InputTag.h:55
master switch for turning on debug mode
Definition: DataStructs.h:449
tag cosmic rays
Definition: DataStructs.h:455
art::InputTag fHitTruthModuleLabel
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:230
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
const art::Ptr< simb::MCTruth > & TrackIdToMCTruth_P(int const &id)
void set_dedx(const std::vector< double > &q)
Definition: Shower.h:139
void cluster::TrajCluster::reconfigure ( fhicl::ParameterSet const &  pset)

Definition at line 125 of file TrajCluster_module.cc.

References fDoRawDigitAssns, fDoWireAssns, fHitModuleLabel, fHitTruthModuleLabel, fSliceModuleLabel, fSpacePointModuleLabel, fTCAlg, fhicl::ParameterSet::get(), and fhicl::ParameterSet::has_key().

Referenced by TrajCluster().

126  {
127  // this trick avoids double configuration on construction
128  if (fTCAlg)
129  fTCAlg->reconfigure(pset.get< fhicl::ParameterSet >("TrajClusterAlg"));
130  else {
131  fTCAlg.reset(new tca::TrajClusterAlg(pset.get< fhicl::ParameterSet >("TrajClusterAlg")));
132  }
133 
134 
135  fHitModuleLabel = "NA";
136  if(pset.has_key("HitModuleLabel")) fHitModuleLabel = pset.get<art::InputTag>("HitModuleLabel");
137  fSliceModuleLabel = "NA";
138  if(pset.has_key("SliceModuleLabel")) fSliceModuleLabel = pset.get<art::InputTag>("SliceModuleLabel");
139  fHitTruthModuleLabel = "NA";
140  if(pset.has_key("HitTruthModuleLabel")) fHitTruthModuleLabel = pset.get<art::InputTag>("HitTruthModuleLabel");
141  fSpacePointModuleLabel = "NA";
142  if(pset.has_key("SpacePointModuleLabel")) fSpacePointModuleLabel = pset.get<art::InputTag>("SpacePointModuleLabel");
143  fDoWireAssns = pset.get<bool>("DoWireAssns",true);
144  fDoRawDigitAssns = pset.get<bool>("DoRawDigitAssns",true);
145 
146  } // TrajCluster::reconfigure()
art::InputTag fSliceModuleLabel
art::InputTag fHitModuleLabel
std::unique_ptr< tca::TrajClusterAlg > fTCAlg
art::InputTag fSpacePointModuleLabel
art::InputTag fHitTruthModuleLabel
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 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

Member Data Documentation

bool cluster::TrajCluster::fDoRawDigitAssns
private

Definition at line 71 of file TrajCluster_module.cc.

Referenced by produce(), reconfigure(), and TrajCluster().

bool cluster::TrajCluster::fDoWireAssns
private

Definition at line 70 of file TrajCluster_module.cc.

Referenced by produce(), reconfigure(), and TrajCluster().

art::InputTag cluster::TrajCluster::fHitModuleLabel
private

Definition at line 65 of file TrajCluster_module.cc.

Referenced by produce(), and reconfigure().

art::InputTag cluster::TrajCluster::fHitTruthModuleLabel
private

Definition at line 67 of file TrajCluster_module.cc.

Referenced by produce(), and reconfigure().

art::InputTag cluster::TrajCluster::fSliceModuleLabel
private

Definition at line 66 of file TrajCluster_module.cc.

Referenced by produce(), and reconfigure().

art::InputTag cluster::TrajCluster::fSpacePointModuleLabel
private

Definition at line 68 of file TrajCluster_module.cc.

Referenced by produce(), and reconfigure().

std::unique_ptr<tca::TrajClusterAlg> cluster::TrajCluster::fTCAlg
private

Definition at line 61 of file TrajCluster_module.cc.

Referenced by beginJob(), endJob(), produce(), and reconfigure().

TTree* cluster::TrajCluster::showertree
private

Definition at line 62 of file TrajCluster_module.cc.

Referenced by beginJob().


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