All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IndirectHitParticleAssns_tool.cc
Go to the documentation of this file.
2 
4 
5 #include "nusimdata/SimulationBase/MCParticle.h"
6 
7 #include "art/Framework/Principal/Event.h"
8 #include "art/Framework/Principal/Handle.h"
9 #include "art/Utilities/ToolMacros.h"
10 #include "canvas/Persistency/Common/Ptr.h"
11 #include "canvas/Utilities/InputTag.h"
12 #include "messagefacility/MessageLogger/MessageLogger.h"
13 #include "fhiclcpp/ParameterSet.h"
14 
15 namespace t0
16 {
17 ////////////////////////////////////////////////////////////////////////
18 //
19 // Class: IndirectHitParticleAssns
20 // Module Type: art tool
21 // File: IndirectHitParticleAssns.h
22 //
23 // This provides MC truth information by using output
24 // reco Hit <--> MCParticle associations
25 //
26 // Configuration parameters:
27 //
28 // TruncMeanFraction - the fraction of waveform bins to discard when
29 //
30 // Created by Tracy Usher (usher@slac.stanford.edu) on November 21, 2017
31 //
32 ////////////////////////////////////////////////////////////////////////
33 
35 {
36 public:
37  /**
38  * @brief Constructor
39  *
40  * @param pset
41  */
42  explicit IndirectHitParticleAssns(fhicl::ParameterSet const & pset);
43 
44  // provide for initialization
45  void reconfigure(fhicl::ParameterSet const & pset) override;
46 
47  /**
48  * @brief This rebuilds the internal maps
49  */
50  void CreateHitParticleAssociations(art::Event&, HitParticleAssociations*) override;
51 
52 private:
53 
54  std::vector<art::InputTag> fHitModuleLabelVec;
55  art::InputTag fMCParticleModuleLabel;
56  art::InputTag fHitPartAssnsModuleLabel;
57 
58 };
59 
60 //----------------------------------------------------------------------------
61 /// Constructor.
62 ///
63 /// Arguments:
64 ///
65 /// pset - Fcl parameters.
66 ///
67 IndirectHitParticleAssns::IndirectHitParticleAssns(fhicl::ParameterSet const & pset)
68 {
69  reconfigure(pset);
70 
71  // Report.
72  mf::LogInfo("IndirectHitParticleAssns") << "Configured\n";
73 }
74 
75 //----------------------------------------------------------------------------
76 /// Reconfigure method.
77 ///
78 /// Arguments:
79 ///
80 /// pset - Fcl parameter set.
81 ///
82 void IndirectHitParticleAssns::reconfigure(fhicl::ParameterSet const & pset)
83 {
84  fHitPartAssnsModuleLabel = pset.get<art::InputTag >("HitPartAssnsLabel");
85  fMCParticleModuleLabel = pset.get<art::InputTag >("MCParticleModuleLabel");
86  fHitModuleLabelVec = pset.get<std::vector<art::InputTag>>("HitModuleLabelVec");
87 }
88 
89 //----------------------------------------------------------------------------
90 /// Rebuild method -> rebuild the basic maps to get truth information
91 ///
92 /// Arguments:
93 ///
94 /// event - the art event used to extract all information
95 ///
97 {
98  // This function handles the "indirect" creation of hit<-->MCParticle associations by trying to
99  // use the previously created Hit<-->MCParticle associations
100  // Its pretty much a brute force approach here... but time is short!
101  //
102  // First step is to recover the preexisting associations
103 
104  // Get a handle for the associations...
105  auto partHitAssnsHandle = evt.getValidHandle< HitParticleAssociations >(fHitPartAssnsModuleLabel);
106  auto mcParticleHandle = evt.getValidHandle< std::vector<simb::MCParticle> >(fMCParticleModuleLabel);
107 
108  if (!partHitAssnsHandle.isValid() || !mcParticleHandle.isValid())
109  {
110  throw cet::exception("IndirectHitParticleAssns") << "===>> NO MCParticle <--> Hit associations found for run/subrun/event: " << evt.run() << "/" << evt.subRun() << "/" << evt.id().event();
111  }
112 
113  // Loop over input hit collections
114  for(const auto& inputTag : fHitModuleLabelVec)
115  {
116  // Look up the hits we want to process as well, since if they are not there then no point in proceeding
117  art::Handle< std::vector<recob::Hit> > hitListHandle;
118  evt.getByLabel(inputTag,hitListHandle);
119 
120  if(!hitListHandle.isValid()){
121  mf::LogInfo("IndirectHitParticleAssns") << "===>> NO Hit collection found to process for run/subrun/event: " << evt.run() << "/" << evt.subRun() << "/" << evt.id().event() << "\n";
122  continue;
123  }
124 
125  // Go through the associations and build out our (hopefully sparse) data structure
126  using ParticleDataPair = std::pair<size_t, const anab::BackTrackerHitMatchingData*>;
127  using MCParticleDataSet = std::set<ParticleDataPair>;
128  using TickToPartDataMap = std::unordered_map<raw::TDCtick_t, MCParticleDataSet>;
129  using ChannelToTickPartDataMap = std::unordered_map<raw::ChannelID_t, TickToPartDataMap>;
130 
131  ChannelToTickPartDataMap chanToTickPartDataMap;
132 
133  // Build out the maps between hits/particles
134  for(HitParticleAssociations::const_iterator partHitItr = partHitAssnsHandle->begin(); partHitItr != partHitAssnsHandle->end(); ++partHitItr)
135  {
136  const art::Ptr<simb::MCParticle>& mcParticle = partHitItr->first;
137  const art::Ptr<recob::Hit>& recoHit = partHitItr->second;
138  const anab::BackTrackerHitMatchingData* data = &partHitAssnsHandle->data(partHitItr);
139 
140  TickToPartDataMap& tickToPartDataMap = chanToTickPartDataMap[recoHit->Channel()];
141 
142  for(raw::TDCtick_t tick = recoHit->PeakTimeMinusRMS(); tick <= recoHit->PeakTimePlusRMS(); tick++)
143  {
144  tickToPartDataMap[tick].insert(ParticleDataPair(mcParticle.key(),data));
145  }
146  }
147 
148  // Armed with the map, process the hit list
149  for(size_t hitIdx = 0; hitIdx < hitListHandle->size(); hitIdx++)
150  {
151  art::Ptr<recob::Hit> hit(hitListHandle,hitIdx);
152 
153  TickToPartDataMap& tickToPartDataMap = chanToTickPartDataMap[hit->Channel()];
154 
155  if (tickToPartDataMap.empty())
156  {
157  mf::LogInfo("IndirectHitParticleAssns") << "No channel information found for hit " << hit << "\n";
158  continue;
159  }
160 
161  // Keep track of results
162  MCParticleDataSet particleDataSet;
163 
164  // Go through the ticks in this hit and recover associations
165  for(raw::TDCtick_t tick = hit->PeakTimeMinusRMS(); tick <= hit->PeakTimePlusRMS(); tick++)
166  {
167  TickToPartDataMap::iterator hitInfoItr = tickToPartDataMap.find(tick);
168 
169  if (hitInfoItr != tickToPartDataMap.end())
170  {
171  for(const auto& partData : hitInfoItr->second) particleDataSet.insert(partData);
172  }
173  }
174 
175  // Now create new associations for the hit in question
176  for(const auto& partData : particleDataSet)
177  hitPartAssns->addSingle(art::Ptr<simb::MCParticle>(mcParticleHandle, partData.first), hit, *partData.second);
178  }
179  }
180 
181  return;
182 }
183 
184 //----------------------------------------------------------------------------
185 
186 DEFINE_ART_CLASS_TOOL(IndirectHitParticleAssns)
187 }
art::Assns< simb::MCParticle, recob::Hit, anab::BackTrackerHitMatchingData > HitParticleAssociations
void CreateHitParticleAssociations(art::Event &, HitParticleAssociations *) override
This rebuilds the internal maps.
Declaration of signal hit object.
process_name hit
Definition: cheaterreco.fcl:51
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:25
void reconfigure(fhicl::ParameterSet const &pset) override
std::vector< art::InputTag > fHitModuleLabelVec
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
IndirectHitParticleAssns(fhicl::ParameterSet const &pset)
Constructor.
TCEvent evt
Definition: DataStructs.cxx:8