IndirectHitParticleAssns_tool.cc
Go to the documentation of this file.
2 
6 
7 namespace t0
8 {
9 ////////////////////////////////////////////////////////////////////////
10 //
11 // Class: IndirectHitParticleAssns
12 // Module Type: art tool
13 // File: IndirectHitParticleAssns.h
14 //
15 // This provides MC truth information by using output
16 // reco Hit <--> MCParticle associations
17 //
18 // Configuration parameters:
19 //
20 // TruncMeanFraction - the fraction of waveform bins to discard when
21 //
22 // Created by Tracy Usher (usher@slac.stanford.edu) on November 21, 2017
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
27 {
28 public:
29  /**
30  * @brief Constructor
31  *
32  * @param pset
33  */
34  explicit IndirectHitParticleAssns(fhicl::ParameterSet const & pset);
35 
36  // provide for initialization
37  void reconfigure(fhicl::ParameterSet const & pset) override;
38 
39  /**
40  * @brief This rebuilds the internal maps
41  */
43 
44 private:
45 
46  std::vector<art::InputTag> fHitModuleLabelVec;
49 
50 };
51 
52 //----------------------------------------------------------------------------
53 /// Constructor.
54 ///
55 /// Arguments:
56 ///
57 /// pset - Fcl parameters.
58 ///
60 {
61  reconfigure(pset);
62 
63  // Report.
64  mf::LogInfo("IndirectHitParticleAssns") << "Configured\n";
65 }
66 
67 //----------------------------------------------------------------------------
68 /// Reconfigure method.
69 ///
70 /// Arguments:
71 ///
72 /// pset - Fcl parameter set.
73 ///
75 {
76  fHitPartAssnsModuleLabel = pset.get<art::InputTag >("HitPartAssnsLabel");
77  fMCParticleModuleLabel = pset.get<art::InputTag >("MCParticleModuleLabel");
78  fHitModuleLabelVec = pset.get<std::vector<art::InputTag>>("HitModuleLabelVec");
79 }
80 
81 //----------------------------------------------------------------------------
82 /// Rebuild method -> rebuild the basic maps to get truth information
83 ///
84 /// Arguments:
85 ///
86 /// event - the art event used to extract all information
87 ///
89 {
90  // This function handles the "indirect" creation of hit<-->MCParticle associations by trying to
91  // use the previously created Hit<-->MCParticle associations
92  // Its pretty much a brute force approach here... but time is short!
93  //
94  // First step is to recover the preexisting associations
95 
96  // Get a handle for the associations...
97  auto partHitAssnsHandle = evt.getValidHandle< HitParticleAssociations >(fHitPartAssnsModuleLabel);
98  auto mcParticleHandle = evt.getValidHandle< std::vector<simb::MCParticle> >(fMCParticleModuleLabel);
99 
100  if (!partHitAssnsHandle.isValid() || !mcParticleHandle.isValid())
101  {
102  throw cet::exception("IndirectHitParticleAssns") << "===>> NO MCParticle <--> Hit associations found for run/subrun/event: " << evt.run() << "/" << evt.subRun() << "/" << evt.id().event();
103  }
104 
105  // Loop over input hit collections
106  for(const auto& inputTag : fHitModuleLabelVec)
107  {
108  // Look up the hits we want to process as well, since if they are not there then no point in proceeding
109  art::Handle< std::vector<recob::Hit> > hitListHandle;
110  evt.getByLabel(inputTag,hitListHandle);
111 
112  if(!hitListHandle.isValid()){
113  mf::LogInfo("IndirectHitParticleAssns") << "===>> NO Hit collection found to process for run/subrun/event: " << evt.run() << "/" << evt.subRun() << "/" << evt.id().event() << "\n";
114  continue;
115  }
116 
117  // Go through the associations and build out our (hopefully sparse) data structure
118  using ParticleDataPair = std::pair<size_t, const anab::BackTrackerHitMatchingData*>;
119  using MCParticleDataSet = std::set<ParticleDataPair>;
120  using TickToPartDataMap = std::unordered_map<raw::TDCtick_t, MCParticleDataSet>;
121  using ChannelToTickPartDataMap = std::unordered_map<raw::ChannelID_t, TickToPartDataMap>;
122 
123  ChannelToTickPartDataMap chanToTickPartDataMap;
124 
125  // Build out the maps between hits/particles
126  for(HitParticleAssociations::const_iterator partHitItr = partHitAssnsHandle->begin(); partHitItr != partHitAssnsHandle->end(); ++partHitItr)
127  {
128  const art::Ptr<simb::MCParticle>& mcParticle = partHitItr->first;
129  const art::Ptr<recob::Hit>& recoHit = partHitItr->second;
130  const anab::BackTrackerHitMatchingData* data = &partHitAssnsHandle->data(partHitItr);
131 
132  TickToPartDataMap& tickToPartDataMap = chanToTickPartDataMap[recoHit->Channel()];
133 
134  for(raw::TDCtick_t tick = recoHit->PeakTimeMinusRMS(); tick <= recoHit->PeakTimePlusRMS(); tick++)
135  {
136  tickToPartDataMap[tick].insert(ParticleDataPair(mcParticle.key(),data));
137  }
138  }
139 
140  // Armed with the map, process the hit list
141  for(size_t hitIdx = 0; hitIdx < hitListHandle->size(); hitIdx++)
142  {
143  art::Ptr<recob::Hit> hit(hitListHandle,hitIdx);
144 
145  TickToPartDataMap& tickToPartDataMap = chanToTickPartDataMap[hit->Channel()];
146 
147  if (tickToPartDataMap.empty())
148  {
149  mf::LogInfo("IndirectHitParticleAssns") << "No channel information found for hit " << hit << "\n";
150  continue;
151  }
152 
153  // Keep track of results
154  MCParticleDataSet particleDataSet;
155 
156  // Go through the ticks in this hit and recover associations
157  for(raw::TDCtick_t tick = hit->PeakTimeMinusRMS(); tick <= hit->PeakTimePlusRMS(); tick++)
158  {
159  TickToPartDataMap::iterator hitInfoItr = tickToPartDataMap.find(tick);
160 
161  if (hitInfoItr != tickToPartDataMap.end())
162  {
163  for(const auto& partData : hitInfoItr->second) particleDataSet.insert(partData);
164  }
165  }
166 
167  // Now create new associations for the hit in question
168  for(const auto& partData : particleDataSet)
169  hitPartAssns->addSingle(art::Ptr<simb::MCParticle>(mcParticleHandle, partData.first), hit, *partData.second);
170  }
171  }
172 
173  return;
174 }
175 
176 //----------------------------------------------------------------------------
177 
179 }
code to link reconstructed objects back to the MC truth information
intermediate_table::iterator iterator
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
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:25
bool isValid() const noexcept
Definition: Handle.h:191
void reconfigure(fhicl::ParameterSet const &pset) override
std::vector< art::InputTag > fHitModuleLabelVec
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
key_type key() const noexcept
Definition: Ptr.h:216
T get(std::string const &key) const
Definition: ParameterSet.h:271
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
RunNumber_t run() const
Definition: DataViewImpl.cc:71
float PeakTimeMinusRMS(float sigmas=+1.) const
Definition: Hit.h:239
IndirectHitParticleAssns(fhicl::ParameterSet const &pset)
Constructor.
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:546
EventNumber_t event() const
Definition: EventID.h:116
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:236
TCEvent evt
Definition: DataStructs.cxx:7
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:230
typename art::const_AssnsIter< L, R, D, Direction::Forward > const_iterator
Definition: Assns.h:237
EventID id() const
Definition: Event.cc:34
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33