All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HitAnaAlg.cxx
Go to the documentation of this file.
1 /*!
2  * Title: HitAnaModule
3  * Author: wketchum@lanl.gov
4  * Inputs: recob::Wire (calibrated), recob::Hit, Assns<recob::Wire, recob::Hit>
5  * Outputs: validation histograms
6  *
7  * Description:
8  * This module is intended to be yet another hit analyzer module. Its intention is
9  * (1) to compare hit-finding modules against each other, and eventually
10  * (2) to compare those to truth
11  */
12 
13 #include "HitAnaAlg.h"
15 
16 #include <functional>
17 #include <unordered_map>
18 
19 #include "TTree.h"
20 
22 {
24 }
25 
26 void
28 {
29  wireDataTree = wdt;
30  SetupWireDataTree();
31 }
32 
33 void
34 hit::HitAnaAlg::SetHitDataTree(std::vector<TTree*>& trees)
35 {
36 
37  hitDataTree.clear();
38  hitData.clear();
39 
40  hitDataTree.reserve(trees.size());
41  // This is particularly important: to establish the hitData memory -- all before
42  // individually making the tree->Branch() calls, specifying those addresses.
43  hitData.reserve(trees.size());
44 
45  // Construct the local attribute data container
46  for (auto const& t : trees) {
47  hitDataTree.push_back(t);
48  hitData.push_back(new recob::Hit);
49  }
50 
51  for (size_t i = 0; i < hitData.size(); ++i)
52  hitDataTree[i]->Branch(hitDataTree[i]->GetName(), "recob::Hit", &(hitData[i]));
53 }
54 
55 void
57 {
58  wireDataTree->Branch("event", &wireData.event, "event/i");
59  wireDataTree->Branch("run", &wireData.run, "run/i");
60  wireDataTree->Branch("channel", &wireData.channel, "channel/i");
61  wireDataTree->Branch("plane", &wireData.plane, "plane/i");
62  wireDataTree->Branch("roi_index", &wireData.range_index, "roi_index/i");
63  wireDataTree->Branch("roi_start", &wireData.range_start, "roi_start/i");
64  wireDataTree->Branch("roi_size", &wireData.range_size, "roi_size/i");
65  wireDataTree->Branch("roi_charge", &wireData.integrated_charge, "roi_charge/F");
66  wireDataTree->Branch("roi_peak_charge", &wireData.peak_charge, "roi_peak_charge/F");
67  wireDataTree->Branch("roi_peak_time", &wireData.peak_time, "roi_peak_time/F");
68  wireDataTree->Branch("nHitModules", &wireData.NHitModules, "nHitModules/I");
69  wireDataTree->Branch("HitModuleLabels", &wireData.HitModuleLabels);
70  wireDataTree->Branch("NHits", &wireData.NHits);
71  wireDataTree->Branch("Hits_IntegratedCharge", &wireData.Hits_IntegratedCharge);
72  wireDataTree->Branch("Hits_AverageCharge", &wireData.Hits_AverageCharge);
73  wireDataTree->Branch("Hits_PeakCharge", &wireData.Hits_PeakCharge);
74  wireDataTree->Branch("Hits_Peak", &wireData.Hits_PeakTime);
75  wireDataTree->Branch("Hits_wAverageCharge", &wireData.Hits_wAverageCharge);
76  wireDataTree->Branch("Hits_wAverageTime", &wireData.Hits_wAverageTime);
77  wireDataTree->Branch("Hits_MeanMultiplicity", &wireData.Hits_MeanMultiplicity);
78 
79  wireDataTree->Branch("NMCHits", &wireData.NMCHits);
80  wireDataTree->Branch("MCHits_IntegratedCharge", &wireData.MCHits_IntegratedCharge);
81  wireDataTree->Branch("MCHits_AverageCharge", &wireData.MCHits_AverageCharge);
82  wireDataTree->Branch("MCHits_PeakCharge", &wireData.MCHits_PeakCharge);
83  wireDataTree->Branch("MCHits_Peak", &wireData.MCHits_PeakTime);
84  wireDataTree->Branch("MCHits_wAverageCharge", &wireData.MCHits_wAverageCharge);
85  wireDataTree->Branch("MCHits_wAverageTime", &wireData.MCHits_wAverageTime);
86 }
87 
88 void
90 {
91  HitModuleLabels.clear();
92  HitProcessingQueue.clear();
93  wireData.NHitModules = 0;
94 }
95 
96 void
97 hit::HitAnaAlg::LoadHitAssocPair(std::vector<recob::Hit> const& HitVector,
98  std::vector<std::vector<int>> const& AssocVector,
99  std::string const& HitModuleLabel)
100 {
101 
102  HitProcessingQueue.push_back(std::make_pair(std::cref(HitVector), std::cref(AssocVector)));
103  HitModuleLabels.push_back(HitModuleLabel);
104 
105  if (HitProcessingQueue.size() != HitModuleLabels.size()) throw hitanaalgexception;
106 }
107 
108 void
109 hit::HitAnaAlg::AnalyzeWires(std::vector<recob::Wire> const& WireVector,
110  std::vector<sim::MCHitCollection> const& MCHitCollectionVector,
111  std::vector<std::vector<int>> const& AssocVector,
112  detinfo::DetectorClocksData const& clock_data,
113  unsigned int event,
114  unsigned int run)
115 {
116 
117  InitWireData(event, run);
118  for (size_t iwire = 0; iwire < WireVector.size(); iwire++)
119  FillWireInfo(WireVector[iwire], iwire, MCHitCollectionVector, AssocVector[iwire], clock_data);
120 }
121 
122 void
123 hit::HitAnaAlg::InitWireData(unsigned int event, unsigned int run)
124 {
125 
126  wireData.event = event;
127  wireData.run = run;
128  wireData.NHitModules = HitModuleLabels.size();
129  wireData.HitModuleLabels = HitModuleLabels;
130 }
131 
132 void
134 {
135  wireData.NMCHits = 0;
136  wireData.MCHits_IntegratedCharge = 0;
137  wireData.MCHits_AverageCharge = 0;
138  wireData.MCHits_PeakCharge = -999;
139  wireData.MCHits_PeakTime = 0;
140  wireData.MCHits_wAverageCharge = 0;
141  wireData.MCHits_wAverageTime = 0;
142 
143  wireData.NHits.assign(wireData.NHitModules, 0);
144  wireData.Hits_IntegratedCharge.assign(wireData.NHitModules, 0);
145  wireData.Hits_AverageCharge.assign(wireData.NHitModules, 0);
146  wireData.Hits_PeakCharge.assign(wireData.NHitModules, -999);
147  wireData.Hits_PeakTime.assign(wireData.NHitModules, 0);
148  wireData.Hits_wAverageCharge.assign(wireData.NHitModules, 0);
149  wireData.Hits_wAverageTime.assign(wireData.NHitModules, 0);
150  wireData.Hits_MeanMultiplicity.assign(wireData.NHitModules, 0);
151  wireData.Hits.clear();
152  wireData.Hits.resize(wireData.NHitModules);
153 }
154 
155 void
157  int WireIndex,
158  std::vector<sim::MCHitCollection> const& MCHitCollectionVector,
159  std::vector<int> const& thisAssocVector,
160  detinfo::DetectorClocksData const& clock_data)
161 {
162 
163  wireData.channel = wire.Channel();
164  wireData.plane = wire.View();
165  unsigned int range_index = 0;
166 
167  for (auto const& range : wire.SignalROI().get_ranges()) {
168 
169  wireData.range_index = range_index;
170  wireData.range_start = range.begin_index();
171  wireData.range_size = range.size();
172 
173  ClearWireDataHitInfo();
174 
175  ProcessROI(range, WireIndex, MCHitCollectionVector, thisAssocVector, clock_data);
176  range_index++;
177 
178  } //end loop over roi ranges
179 }
180 
181 void
183  float& charge_sum,
184  float& charge_peak,
185  float& charge_peak_time)
186 {
187 
188  charge_sum = 0;
189  charge_peak = -999;
190  unsigned int counter = range.begin_index();
191 
192  for (auto const& value : range) {
193  charge_sum += value;
194  if (value > charge_peak) {
195  charge_peak = value;
196  charge_peak_time = (float)counter;
197  }
198  counter++;
199  }
200 }
201 
202 void
204  int WireIndex,
205  std::vector<sim::MCHitCollection> const& MCHitCollectionVector,
206  std::vector<int> const& thisAssocVector,
207  detinfo::DetectorClocksData const& clock_data)
208 {
209 
210  ROIInfo(range, wireData.integrated_charge, wireData.peak_charge, wireData.peak_time);
211 
212  //std::cout << "----------------------------------------------------------------" << std::endl;
213  //std::cout << "WireIndex = " << WireIndex << std::endl;
214  //std::cout << "\tRange begin: " << range.begin_index() << std::endl;
215  //std::cout << "\tRange end: " << range.begin_index()+range.size() << std::endl;
216 
217  for (size_t iter = 0; iter < HitProcessingQueue.size(); iter++)
218  FindAndStoreHitsInRange(HitProcessingQueue[iter].first,
219  HitProcessingQueue[iter].second.at(WireIndex),
220  iter,
221  range.begin_index(),
222  range.begin_index() + range.size());
223 
224  FindAndStoreMCHitsInRange(MCHitCollectionVector,
225  thisAssocVector,
226  range.begin_index(),
227  range.begin_index() + range.size(),
228  clock_data);
229 
230  wireDataTree->Fill();
231 }
232 
233 void
234 hit::HitAnaAlg::FindAndStoreHitsInRange(std::vector<recob::Hit> const& HitVector,
235  std::vector<int> const& HitsOnWire,
236  size_t hitmodule_iter,
237  size_t begin_wire_tdc,
238  size_t end_wire_tdc)
239 {
240 
241  wireData.Hits_PeakCharge[hitmodule_iter] = -999;
242 
243  for (auto const& hit_index : HitsOnWire) {
244  recob::Hit const& thishit = HitVector.at(hit_index);
245 
246  //check if this hit is on this ROI
247  if (thishit.PeakTimeMinusRMS() < begin_wire_tdc || thishit.PeakTimePlusRMS() > end_wire_tdc)
248  continue;
249 
250  FillHitInfo(thishit, wireData.Hits[hitmodule_iter]);
251  wireData.NHits[hitmodule_iter]++;
252  wireData.Hits_IntegratedCharge[hitmodule_iter] += thishit.Integral();
253 
254  if (thishit.PeakAmplitude() > wireData.Hits_PeakCharge[hitmodule_iter]) {
255  wireData.Hits_PeakCharge[hitmodule_iter] = thishit.PeakAmplitude();
256  wireData.Hits_PeakTime[hitmodule_iter] = thishit.PeakTime();
257  }
258 
259  wireData.Hits_wAverageCharge[hitmodule_iter] += thishit.Integral() * thishit.Integral();
260  wireData.Hits_wAverageTime[hitmodule_iter] += thishit.Integral() * thishit.PeakTime();
261  wireData.Hits_MeanMultiplicity[hitmodule_iter] += thishit.Multiplicity();
262 
263  *(hitData.at(hitmodule_iter)) = thishit;
264  (hitDataTree.at(hitmodule_iter))->Fill();
265  }
266 
267  wireData.Hits_AverageCharge[hitmodule_iter] =
268  wireData.Hits_IntegratedCharge[hitmodule_iter] / wireData.NHits[hitmodule_iter];
269  wireData.Hits_wAverageCharge[hitmodule_iter] =
270  wireData.Hits_wAverageCharge[hitmodule_iter] / wireData.Hits_IntegratedCharge[hitmodule_iter];
271  wireData.Hits_wAverageTime[hitmodule_iter] =
272  wireData.Hits_wAverageTime[hitmodule_iter] / wireData.Hits_IntegratedCharge[hitmodule_iter];
273 
274  wireData.Hits_MeanMultiplicity[hitmodule_iter] /= wireData.NHits[hitmodule_iter];
275 }
276 
277 void
279  std::vector<sim::MCHitCollection> const& MCHitCollectionVector,
280  std::vector<int> const& HitsOnWire,
281  size_t begin_wire_tdc,
282  size_t end_wire_tdc,
283  detinfo::DetectorClocksData const& clock_data)
284 {
285 
286  wireData.MCHits_PeakCharge = -999;
287 
288  for (auto const& hit_index : HitsOnWire) {
289  sim::MCHitCollection const& thismchitcol = MCHitCollectionVector.at(hit_index);
290 
291  //let's have a map to keep track of the number of total particles
292  std::unordered_map<int, unsigned int> nmchits_per_trackID_map;
293  for (auto const& thishit : thismchitcol) {
294 
295  //std::cout << "\t************************************************************" << std::endl;
296  //std::cout << "\t\tMCHit begin: " << ts->TPCTDC2Tick( thishit.PeakTime()-thishit.PeakWidth() ) << std::endl;
297  //std::cout << "\t\tMCHit end: " << ts->TPCTDC2Tick( thishit.PeakTime()+thishit.PeakWidth() ) << std::endl;
298 
299  //check if this hit is on this ROI
300  if (clock_data.TPCTDC2Tick(thishit.PeakTime() - thishit.PeakWidth()) < begin_wire_tdc ||
301  clock_data.TPCTDC2Tick(thishit.PeakTime() + thishit.PeakWidth()) > end_wire_tdc)
302  continue;
303 
304  nmchits_per_trackID_map[thishit.PartTrackId()] += 1;
305  wireData.MCHits_IntegratedCharge += thishit.Charge();
306 
307  if (thishit.Charge(true) > wireData.MCHits_PeakCharge) {
308  wireData.MCHits_PeakCharge = thishit.Charge(true);
309  wireData.MCHits_PeakTime = clock_data.TPCTDC2Tick(thishit.PeakTime());
310  }
311 
312  wireData.MCHits_wAverageCharge += thishit.Charge() * thishit.Charge();
313  wireData.MCHits_wAverageTime += thishit.Charge() * clock_data.TPCTDC2Tick(thishit.PeakTime());
314  }
315 
316  wireData.NMCHits = nmchits_per_trackID_map.size();
317 
318  wireData.MCHits_AverageCharge = wireData.MCHits_IntegratedCharge / wireData.NMCHits;
319  wireData.MCHits_wAverageCharge =
320  wireData.MCHits_wAverageCharge / wireData.MCHits_IntegratedCharge;
321  wireData.MCHits_wAverageTime = wireData.MCHits_wAverageTime / wireData.MCHits_IntegratedCharge;
322  }
323 }
324 
325 void
326 hit::HitAnaAlg::FillHitInfo(recob::Hit const& hit, std::vector<HitInfo>& HitInfoVector)
327 {
328  HitInfoVector.emplace_back(hit.PeakTime(),
329  hit.SigmaPeakTime(),
330  hit.RMS(),
331  hit.StartTick(),
332  hit.EndTick(),
333  hit.Integral(),
334  hit.SigmaIntegral(),
335  hit.PeakAmplitude(),
336  hit.SigmaPeakAmplitude(),
337  hit.GoodnessOfFit());
338 }
void SetupWireDataTree()
Definition: HitAnaAlg.cxx:56
void LoadHitAssocPair(std::vector< recob::Hit > const &, std::vector< std::vector< int >> const &, std::string const &)
Definition: HitAnaAlg.cxx:97
void SetHitDataTree(std::vector< TTree * > &trees)
Definition: HitAnaAlg.cxx:34
void ProcessROI(lar::sparse_vector< float >::datarange_t const &, int, std::vector< sim::MCHitCollection > const &, std::vector< int > const &, detinfo::DetectorClocksData const &)
Definition: HitAnaAlg.cxx:203
WireROIInfo wireData
Definition: HitAnaAlg.h:165
void FillHitInfo(recob::Hit const &, std::vector< HitInfo > &)
Definition: HitAnaAlg.cxx:326
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:220
hit::HitAnaAlgException hitanaalgexception
std::pair< double, bool > Branch(double hnl_mass, double ue4, double um4, double rand)
void ClearWireDataHitInfo()
Definition: HitAnaAlg.cxx:133
float SigmaPeakAmplitude() const
Uncertainty on estimated amplitude of the hit at its peak, in ADC units.
Definition: Hit.h:222
float SigmaIntegral() const
Definition: Hit.h:225
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
size_type begin_index() const
Returns the first absolute index included in the range.
process_name hit
Definition: cheaterreco.fcl:51
float GoodnessOfFit() const
Degrees of freedom in the determination of the hit signal shape (-1 by default)
Definition: Hit.h:228
short int Multiplicity() const
How many hits could this one be shared with.
Definition: Hit.h:226
double TPCTDC2Tick(double const tdc) const
Given electronics clock count [tdc] returns TPC time-tick.
pure virtual base interface for detector clocks
std::array< float, 2 > HitVector(const recob::Hit &hit, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
void SetWireDataTree(TTree *)
Definition: HitAnaAlg.cxx:27
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
Definition: Hit.h:221
process_name is maximum options services RecoDrawingOptions rawDigitFilterTPC3 services RecoDrawingOptions decon1DroiTPC3 services RecoDrawingOptions HitModuleLabels
geo::View_t View() const
Returns the view the channel belongs to.
Definition: Wire.h:230
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:285
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
Definition: Wire.h:231
const RegionsOfInterest_t & SignalROI() const
Returns the list of regions of interest.
Definition: Wire.h:228
void AnalyzeWires(std::vector< recob::Wire > const &, std::vector< sim::MCHitCollection > const &, std::vector< std::vector< int >> const &, detinfo::DetectorClocksData const &, unsigned int, unsigned int)
Definition: HitAnaAlg.cxx:109
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
Definition: Hit.h:216
float PeakTimeMinusRMS(float sigmas=+1.) const
Definition: Hit.h:239
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
Definition: Hit.h:217
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
size_type size() const
Returns the size of the range.
void InitWireData(unsigned int, unsigned int)
Definition: HitAnaAlg.cxx:123
Contains all timing reference information for the detector.
std::vector< art::Ptr< recob::Wire > > WireVector
Class holding the regions of interest of signal from a channel.
Definition: Wire.h:118
Range class, with range and data.
temporary value
float SigmaPeakTime() const
Uncertainty for the signal peak, in tick units.
Definition: Hit.h:219
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
float PeakTimePlusRMS(float sigmas=+1.) const
Returns a time sigmas RMS away from the peak time.
Definition: Hit.h:236
void FindAndStoreHitsInRange(std::vector< recob::Hit > const &, std::vector< int > const &, size_t, size_t, size_t)
Definition: HitAnaAlg.cxx:234
void ClearHitModules()
Definition: HitAnaAlg.cxx:89
void ROIInfo(lar::sparse_vector< float >::datarange_t const &, float &, float &, float &)
Definition: HitAnaAlg.cxx:182
void FindAndStoreMCHitsInRange(std::vector< sim::MCHitCollection > const &, std::vector< int > const &, size_t, size_t, detinfo::DetectorClocksData const &)
Definition: HitAnaAlg.cxx:278
void FillWireInfo(recob::Wire const &, int, std::vector< sim::MCHitCollection > const &, std::vector< int > const &, detinfo::DetectorClocksData const &)
Definition: HitAnaAlg.cxx:156