LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
IndirectHitParticleAssns_tool.cc
Go to the documentation of this file.
1 
3 
10 
13 
14 #include <cmath>
15 #include <algorithm>
16 
17 namespace t0
18 {
20 //
21 // Class: IndirectHitParticleAssns
22 // Module Type: art tool
23 // File: IndirectHitParticleAssns.h
24 //
25 // This provides MC truth information by using output
26 // reco Hit <--> MCParticle associations
27 //
28 // Configuration parameters:
29 //
30 // TruncMeanFraction - the fraction of waveform bins to discard when
31 //
32 // Created by Tracy Usher (usher@slac.stanford.edu) on November 21, 2017
33 //
35 
37 {
38 public:
44  explicit IndirectHitParticleAssns(fhicl::ParameterSet const & pset);
45 
50 
51  // provide for initialization
52  void reconfigure(fhicl::ParameterSet const & pset) override;
53 
58 
59 private:
60 
64 
65 };
66 
67 //----------------------------------------------------------------------------
75 {
76  reconfigure(pset);
77 
78  // Report.
79  mf::LogInfo("IndirectHitParticleAssns") << "Configured\n";
80 }
81 
82 //----------------------------------------------------------------------------
85 {}
86 
87 //----------------------------------------------------------------------------
95 {
96  fHitPartAssnsModuleLabel = pset.get<art::InputTag>("HitPartAssnsLabel");
97  fMCParticleModuleLabel = pset.get<art::InputTag>("MCParticleModuleLabel");
98  fHitModuleLabel = pset.get<art::InputTag>("HitModuleLabel");
99 }
100 
101 //----------------------------------------------------------------------------
109 {
110  // This function handles the "indirect" creation of hit<-->MCParticle associations by trying to
111  // use the previously created Hit<-->MCParticle associations
112  // Its pretty much a brute force approach here... but time is short!
113  //
114  // First step is to recover the preexisting associations
115 
116  // Get a handle for the associations...
117  auto partHitAssnsHandle = evt.getValidHandle< HitParticleAssociations >(fHitPartAssnsModuleLabel);
118  auto mcParticleHandle = evt.getValidHandle< std::vector<simb::MCParticle> >(fMCParticleModuleLabel);
119 
120  if (!partHitAssnsHandle.isValid() || !mcParticleHandle.isValid())
121  {
122  throw cet::exception("IndirectHitParticleAssns") << "===>> NO MCParticle <--> Hit associations found for run/subrun/event: " << evt.run() << "/" << evt.subRun() << "/" << evt.id().event();
123  }
124 
125  // Look up the hits we want to process as well, since if they are not there then no point in proceeding
126  art::Handle< std::vector<recob::Hit> > hitListHandle;
127  evt.getByLabel(fHitModuleLabel,hitListHandle);
128 
129  if(!hitListHandle.isValid()){
130  throw cet::exception("IndirectHitParticleAssns") << "===>> NO Hit collection found to process for run/subrun/event: " << evt.run() << "/" << evt.subRun() << "/" << evt.id().event();
131  }
132 
133  // Go through the associations and build out our (hopefully sparse) data structure
134  using ParticleDataPair = std::pair<size_t, const anab::BackTrackerHitMatchingData*>;
135  using MCParticleDataSet = std::set<ParticleDataPair>;
136  using TickToPartDataMap = std::unordered_map<raw::TDCtick_t, MCParticleDataSet>;
137  using ChannelToTickPartDataMap = std::unordered_map<raw::ChannelID_t, TickToPartDataMap>;
138 
139  ChannelToTickPartDataMap chanToTickPartDataMap;
140 
141  // Build out the maps between hits/particles
142  for(HitParticleAssociations::const_iterator partHitItr = partHitAssnsHandle->begin(); partHitItr != partHitAssnsHandle->end(); ++partHitItr)
143  {
144  const art::Ptr<simb::MCParticle>& mcParticle = partHitItr->first;
145  const art::Ptr<recob::Hit>& recoHit = partHitItr->second;
146  const anab::BackTrackerHitMatchingData* data = &partHitAssnsHandle->data(partHitItr);
147 
148  TickToPartDataMap& tickToPartDataMap = chanToTickPartDataMap[recoHit->Channel()];
149 
150  for(raw::TDCtick_t tick = recoHit->PeakTimeMinusRMS(); tick <= recoHit->PeakTimePlusRMS(); tick++)
151  {
152  tickToPartDataMap[tick].insert(ParticleDataPair(mcParticle.key(),data));
153  }
154  }
155 
156  // Armed with the map, process the hit list
157  for(size_t hitIdx = 0; hitIdx < hitListHandle->size(); hitIdx++)
158  {
159  art::Ptr<recob::Hit> hit(hitListHandle,hitIdx);
160 
161  TickToPartDataMap& tickToPartDataMap = chanToTickPartDataMap[hit->Channel()];
162 
163  if (tickToPartDataMap.empty())
164  {
165  mf::LogInfo("IndirectHitParticleAssns") << "No channel information found for hit " << hit << "\n";
166  continue;
167  }
168 
169  // Keep track of results
170  MCParticleDataSet particleDataSet;
171 
172  // Go through the ticks in this hit and recover associations
173  for(raw::TDCtick_t tick = hit->PeakTimeMinusRMS(); tick <= hit->PeakTimePlusRMS(); tick++)
174  {
175  TickToPartDataMap::iterator hitInfoItr = tickToPartDataMap.find(tick);
176 
177  if (hitInfoItr != tickToPartDataMap.end())
178  {
179  for(const auto& partData : hitInfoItr->second) particleDataSet.insert(partData);
180  }
181  }
182 
183  // Now create new associations for the hit in question
184  for(const auto& partData : particleDataSet)
185  hitPartAssns->addSingle(art::Ptr<simb::MCParticle>(mcParticleHandle, partData.first), hit, *partData.second);
186  }
187 
188  return;
189 }
190 
191 //----------------------------------------------------------------------------
192 
194 }
key_type key() const
Definition: Ptr.h:356
code to link reconstructed objects back to the MC truth information
SubRunNumber_t subRun() const
Definition: Event.h:72
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:45
intermediate_table::iterator iterator
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void CreateHitParticleAssociations(art::Event &, HitParticleAssociations *) override
This rebuilds the internal maps.
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:24
void reconfigure(fhicl::ParameterSet const &pset) override
bool isValid() const
Definition: Handle.h:190
T get(std::string const &key) const
Definition: ParameterSet.h:231
float PeakTimeMinusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:240
Detector simulation of raw signals on wires.
IndirectHitParticleAssns(fhicl::ParameterSet const &pset)
Constructor.
Utility object to perform functions of association.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:489
EventNumber_t event() const
Definition: EventID.h:117
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:237
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
RunNumber_t run() const
Definition: Event.h:77
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:231
Definition: fwd.h:25
typename art::const_AssnsIter< L, R, D, Direction::Forward > const_iterator
Definition: Assns.h:217
EventID id() const
Definition: Event.h:56
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33