All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StubBuilder.cxx
Go to the documentation of this file.
1 #include "StubBuilder.h"
3 
4 // Helper functions
5 bool HitOnTrack(const art::Ptr<recob::Hit> &hit,
6  const art::Ptr<recob::Track> &trk,
7  const std::vector<art::Ptr<recob::Hit>> &trk_hits,
8  const std::vector<const recob::TrackHitMeta *> &trk_thms) {
9 
10  if (!trk) return false; // no track: hit can't be on a track
11 
12  for (unsigned i = 0; i < trk_hits.size(); i++) {
13  // Found the hit on the track!
14  if (hit == trk_hits[i]) {
15  // Is the hit part of the track Calo?
16  if (trk->HasValidPoint(trk_thms[i]->Index())) {
17  return true;
18  }
19  break;
20  }
21  }
22  return false;
23 }
24 
26  const std::vector<art::Ptr<recob::Hit>> &hits,
27  const std::vector<art::Ptr<recob::PFParticle>> &pfps,
28  const std::vector<std::vector<art::Ptr<recob::Hit>>> &pfp_hits) {
29 
30  std::vector<unsigned> pfp_nhit(pfps.size(), 0);
31 
32  for (const art::Ptr<recob::Hit> h: hits) {
33  for (unsigned i_pfp = 0; i_pfp < pfps.size(); i_pfp++) {
34  const std::vector<art::Ptr<recob::Hit>> &thispfpHits = pfp_hits[i_pfp];
35  bool found = false;
36  for (const art::Ptr<recob::Hit> &pfp_h: thispfpHits) {
37  if (h == pfp_h) {
38  found = true;
39  pfp_nhit[i_pfp] ++;
40  break;
41  }
42  }
43  if (found) break;
44  }
45  }
46 
47  // Look to see if more than half of the hits on the stub match to a single
48  // PFParticle
49  for (unsigned i_pfp = 0; i_pfp < pfps.size(); i_pfp++) {
50  if (pfp_nhit[i_pfp] >= hits.size() / 2) return i_pfp;
51  }
52 
53  return -1;
54 }
55 
56 std::vector<art::Ptr<recob::Hit>> CollectHits(
57  const std::vector<art::Ptr<recob::Hit>> &hits,
58  const sbn::VertexHit &vhit,
59  const recob::Hit &vhit_hit,
60  const geo::GeometryCore *geo,
61  const detinfo::DetectorPropertiesData &dprop) {
62 
63  // project the vertex onto the wireplane
64  float vert_wf = vhit.vtxw;
65  float vert_x = vhit.vtxx;
66 
67  // get the vertex hit-coordinates
68  int hit_w = vhit_hit.WireID().Wire;
69  float hit_x = dprop.ConvertTicksToX(vhit_hit.PeakTime(), vhit_hit.WireID());
70  geo::PlaneID vhit_plane = vhit_hit.WireID();
71 
72  // get the line-segment slope / intercept
73  float slope = (hit_x - vert_x) / (hit_w - vert_wf);
74  float intercept = hit_x - slope * hit_w;
75 
76  // check for "bad" (infinite) slope
77  //
78  // In this case, only hits overlapping with the vertex hit should be
79  // included in the returned list
80  bool badslope = abs(hit_w - vert_wf) < 1e-5;
81  if (badslope) {
82  std::vector<art::Ptr<recob::Hit>> ret;
83  for (art::Ptr<recob::Hit> h: hits) {
84  int this_hit_w = h->WireID().Wire;
85  geo::PlaneID this_hit_plane = h->WireID();
86  if (this_hit_plane == vhit_plane && // check plane
87  this_hit_w == hit_w /* check wire */) {
88  float h_time_lo = h->PeakTime() - h->RMS();
89  float h_time_hi = h->PeakTime() + h->RMS();
90 
91  if (h_time_lo < vhit_hit.PeakTime() && h_time_hi > vhit_hit.PeakTime()) {
92  ret.push_back(h);
93  }
94  }
95  }
96  return ret;
97  }
98 
99  // Include wires one after the hit and one before the vtx
100  int vert_w = (int)((hit_w > vert_wf) ? std::floor(vert_wf) : std::ceil(vert_wf));
101  hit_w = hit_w + ((hit_w > vert_wf) ? 1 : -1);
102 
103  // get all the hits that overlap between these two points
104  std::vector<art::Ptr<recob::Hit>> ret;
105  for (art::Ptr<recob::Hit> h: hits) {
106  int this_hit_w = h->WireID().Wire;
107  geo::PlaneID this_hit_plane = h->WireID();
108  if (this_hit_plane == vhit_plane && // check plane
109  ((this_hit_w <= hit_w && this_hit_w >= vert_w) || // check overlap
110  (this_hit_w >= hit_w && this_hit_w <= vert_w))) {
111  float this_proj_x = slope * this_hit_w + intercept;
112 
113  float h_time_lo = h->PeakTime() - h->RMS();
114  float h_x_A = dprop.ConvertTicksToX(h_time_lo, h->WireID());
115  float h_time_hi = h->PeakTime() + h->RMS();
116  float h_x_B = dprop.ConvertTicksToX(h_time_hi, h->WireID());
117 
118  if ((h_x_A >= this_proj_x && h_x_B <= this_proj_x) ||
119  (h_x_A <= this_proj_x && h_x_B >= this_proj_x)) {
120  ret.push_back(h);
121  }
122  }
123  }
124 
125  return ret;
126 }
127 
128 
129 void sbn::StubBuilder::Setup(const art::Event &e, const art::InputTag &pfplabel, const art::InputTag &trklabel) {
130  // Clear out old data
131  fSlicePFPHits.clear();
132  fSlicePFPs.clear();
133  fSliceHits.clear();
134  fSliceTrkHits.clear();
135  fSliceTrkTHMs.clear();
136  fSliceTrks.clear();
137 
138  // Build the map of the slice key to the hits
139  art::Handle<std::vector<recob::Slice>> slice_handle;
140  e.getByLabel(pfplabel, slice_handle);
141 
142  std::vector<art::Ptr<recob::Slice>> slices;
143  art::fill_ptr_vector(slices, slice_handle);
144 
145  art::FindManyP<recob::PFParticle> slicePFPs(slices, e, pfplabel);
146  art::FindManyP<recob::Hit> sliceHits(slices, e, pfplabel);
147 
148  for (unsigned i_slc = 0; i_slc < slices.size(); i_slc++) {
149  const std::vector<art::Ptr<recob::PFParticle>> thisSlicePFPs = slicePFPs.at(i_slc);
150  art::FindManyP<recob::Cluster> pfparticleClusters(thisSlicePFPs, e, pfplabel);
151 
152  std::vector<art::Ptr<recob::Track>> thisSliceTracks;
153  std::vector<std::vector<art::Ptr<recob::Hit>>> thisSlicePFPHits;
154  std::vector<std::vector<art::Ptr<recob::Hit>>> thisSliceTrkHits;
155  std::vector<std::vector<const recob::TrackHitMeta *>> thisSliceTrkTHMs;
156 
157  art::FindManyP<recob::Track> pfparticleTracks(thisSlicePFPs, e, trklabel);
158  for (unsigned i_slc_pfp = 0; i_slc_pfp < thisSlicePFPs.size(); i_slc_pfp++) {
159  thisSlicePFPHits.emplace_back();
160  const std::vector<art::Ptr<recob::Cluster>> &thisPFPClusters = pfparticleClusters.at(i_slc_pfp);
161  art::FindManyP<recob::Hit> clusterHits(thisPFPClusters, e, pfplabel);
162  for (unsigned i_clus = 0; i_clus < thisPFPClusters.size(); i_clus++) {
163  thisSlicePFPHits.back().insert(thisSlicePFPHits.back().end(), clusterHits.at(i_clus).begin(), clusterHits.at(i_clus).end());
164  }
165 
166  art::FindManyP<recob::Hit, recob::TrackHitMeta> FMthisTrackHits(pfparticleTracks.at(i_slc_pfp), e, trklabel);
167  if (pfparticleTracks.at(i_slc_pfp).size()) {
168  const std::vector<art::Ptr<recob::Hit>> &thisTrackHits = FMthisTrackHits.at(0);
169  const std::vector<const recob::TrackHitMeta *> &thisTrackTHMs = FMthisTrackHits.data(0);
170  thisSliceTrkHits.push_back(thisTrackHits);
171  thisSliceTrkTHMs.push_back(thisTrackTHMs);
172  thisSliceTracks.push_back(pfparticleTracks.at(i_slc_pfp).at(0));
173  }
174  else {
175  thisSliceTrkHits.emplace_back();
176  thisSliceTrkTHMs.emplace_back();
177  thisSliceTracks.emplace_back(); // nullptr
178  }
179 
180  }
181 
182  std::size_t const sliceKey = slices[i_slc].key();
183 
184  fSlicePFPHits[sliceKey] = thisSlicePFPHits;
185  fSliceTrkHits[sliceKey] = thisSliceTrkHits;
186  fSliceTrkTHMs[sliceKey] = thisSliceTrkTHMs;
187  fSliceTrks[sliceKey] = thisSliceTracks;
188  fSlicePFPs[sliceKey] = thisSlicePFPs;
189  fSliceHits[sliceKey] = sliceHits.at(i_slc);
190  }
191 }
192 
193 double sbn::StubBuilder::Normalize(double dQdx, const art::Event &e, const recob::Hit &h, const geo::Point_t &location, const geo::Vector_t &direction, double t0) {
194 
195  double ret = dQdx;
196 
197  // Normtools configured -- use those
198  if (fNormTools.size()) {
199  for (auto const &nt: fNormTools) {
200  ret = nt->Normalize(ret, e, h, location, direction, t0);
201  }
202  }
203  // Otherwise, fix using configured electron lifetime
204  else {
205  auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
206  auto const dprop =
207  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, clock_data);
208 
209  ret = ret * fCaloAlg.LifetimeCorrection(clock_data, dprop, h.PeakTime(), 0.);
210  }
211 
212  return ret;
213 }
214 
215 sbn::Stub sbn::StubBuilder::FromVertexHit(const art::Ptr<recob::Slice> &slice,
216  const sbn::VertexHit &vhit,
217  const recob::Hit &vhit_hit,
218  const geo::GeometryCore *geo,
219  const spacecharge::SpaceCharge *sce,
220  const detinfo::DetectorClocksData &dclock,
221  const detinfo::DetectorPropertiesData &dprop,
222  const art::Event &e,
223  std::vector<art::Ptr<recob::Hit>> &stub_hits,
224  art::Ptr<recob::PFParticle> &stub_pfp) {
225  // look up stuff
226  const std::vector<art::Ptr<recob::Hit>> &hits = fSliceHits.at(slice.key());
227  const std::vector<art::Ptr<recob::PFParticle>> &pfps = fSlicePFPs.at(slice.key());
228  const std::vector<art::Ptr<recob::Track>> &trks = fSliceTrks.at(slice.key());
229  const std::vector<std::vector<art::Ptr<recob::Hit>>> &pfp_hits = fSlicePFPHits.at(slice.key());
230  const std::vector<std::vector<art::Ptr<recob::Hit>>> &trk_hits = fSliceTrkHits.at(slice.key());
231  const std::vector<std::vector<const recob::TrackHitMeta *>> &trk_thms = fSliceTrkTHMs.at(slice.key());
232 
233  stub_hits = CollectHits(hits, vhit, vhit_hit, geo, dprop);
234 
235  // Sort hits along the vtx -> end direction
236  float vertex_w = vhit.vtxw;
237  int stubdir = vertex_w <= vhit_hit.WireID().Wire ? 1 : -1;
238  std::sort(stub_hits.begin(), stub_hits.end(),
239  [stubdir](auto const &lhs, auto const &rhs) {
240  return lhs->WireID().Wire * stubdir < rhs->WireID().Wire * stubdir;});
241 
242  // Find which pfparticle to group this VertexStub with
243  int pfp_ind = FindPFPInd(stub_hits, pfps, pfp_hits);
244  art::Ptr<recob::PFParticle> null; // nullptr
245  stub_pfp = (pfp_ind >= 0) ? pfps[pfp_ind] : null;
246 
247  sbn::Stub stub;
248 
249  // Save all the charges
250  stub.hits.emplace_back();
251  for (unsigned i_hit = 0; i_hit < stub_hits.size(); i_hit++) {
252  const recob::Hit &hit = *stub_hits[i_hit];
253 
254  sbn::StubHit stubhit;
255 
256  stubhit.charge = fCaloAlg.ElectronsFromADCArea(Normalize(hit.Integral(), e, hit,
257  vhit.vtxXYZ /* close enuff to hit */,
258  geo::Vector_t() /* no direction available */,
259  0. /* TODO: add T0*/),
260  hit.WireID().Plane);
261  stubhit.ontrack = (pfp_ind >= 0) ? HitOnTrack(stub_hits[i_hit], trks[pfp_ind], trk_hits[pfp_ind], trk_thms[pfp_ind]) : false;
262  stubhit.wire = hit.WireID().Wire;
263 
264  stub.hits.back().push_back(stubhit);
265  }
266 
267  // See if we can compute a track pitch
268  if (pfp_ind >= 0 && trks[pfp_ind]) {
269  stub.trkpitch.push_back(sbn::GetPitch(geo, sce, trks[pfp_ind]->Start(), trks[pfp_ind]->StartDirection(), geo->View(vhit_hit.WireID()), vhit_hit.WireID(), true, fPositionsAreSCECorrected));
270  }
271  else {
272  stub.trkpitch.push_back(-1.);
273  }
274 
275  stub.vtx = vhit.vtxXYZ;
276  stub.end = vhit.spXYZ;
277  stub.pitch.push_back(vhit.charge / vhit.dqdx);
278  stub.plane.push_back(vhit.wire);
279  stub.hit_w.push_back(vhit.wire.Wire);
280  stub.vtx_w.push_back(vertex_w);
281 
282  // Save the EField at the start and end point
283  stub.efield_vtx = sbn::GetEfield(dprop, sce, vhit.vtxXYZ, vhit_hit.WireID(), false);
284  stub.efield_end = sbn::GetEfield(dprop, sce, vhit.spXYZ, vhit_hit.WireID(), false);
285 
286  return stub;
287 }
288 
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
float dqdx
charge/pitch [#elec/cm]
Definition: VertexHit.h:20
double Normalize(double dQdx, const art::Event &e, const recob::Hit &h, const geo::Point_t &location, const geo::Vector_t &direction, double t0)
std::map< unsigned, std::vector< art::Ptr< recob::PFParticle > > > fSlicePFPs
Definition: StubBuilder.h:70
std::map< unsigned, std::vector< std::vector< art::Ptr< recob::Hit > > > > fSliceTrkHits
Definition: StubBuilder.h:73
geo::Point_t spXYZ
3D location of the SpacePoint associated with this hit. Space charge corrected. [cm] ...
Definition: VertexHit.h:17
std::vector< geo::PlaneID > plane
The plane ID.
Definition: Stub.h:25
void Setup(const art::Event &e, const art::InputTag &pfplabel, const art::InputTag &trklabel)
geo::WireID WireID() const
Definition: Hit.h:233
geo::WireID wire
Wire that the hit is on.
Definition: VertexHit.h:11
float charge
Calibrated and corrected for electron lifetime [#elec].
Definition: Stub.h:11
std::vector< std::vector< StubHit > > hits
Hits on each plane. Ordered vtx-&gt;end.
Definition: Stub.h:32
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
geo::Point_t end
End of Stub. Space charge corrected. [cm].
Definition: Stub.h:19
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
process_name hit
Definition: cheaterreco.fcl:51
geo::Point_t vtx
Interaction Vertex / Start of Stub. Space charge corrected. [cm].
Definition: Stub.h:18
float charge
Calibrated and lifetime-corrected charge on the hit [#elec].
Definition: VertexHit.h:12
std::vector< float > vtx_w
Wire coordinate of the vertex on this plane.
Definition: Stub.h:29
while getopts h
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
short wire
The wire this hit is on.
Definition: Stub.h:12
T abs(T value)
std::map< unsigned, std::vector< std::vector< art::Ptr< recob::Hit > > > > fSlicePFPHits
Definition: StubBuilder.h:72
std::vector< art::Ptr< recob::Hit > > CollectHits(const std::vector< art::Ptr< recob::Hit >> &hits, const sbn::VertexHit &vhit, const recob::Hit &vhit_hit, const geo::GeometryCore *geo, const detinfo::DetectorPropertiesData &dprop)
Definition: StubBuilder.cxx:56
std::vector< short > hit_w
Wire of the end point hit on this plane.
Definition: Stub.h:30
double GetPitch(const geo::GeometryCore *geo, const spacecharge::SpaceCharge *sce, geo::Point_t loc, geo::Vector_t dir, geo::View_t view, geo::TPCID tpc, bool correct_sce, bool track_is_sce_corrected, float xsign=1.)
Computes the track-pitch on a plane given an input direction and location.
Description of geometry of one entire detector.
float vtxx
X-Position of the vertex associated with this hit as seen by wire-planes. Not space charge corrected...
Definition: VertexHit.h:15
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
float efield_end
The E-Field at the stub end point.
Definition: Stub.h:21
float efield_vtx
The E-Field at the reconstructed vertex.
Definition: Stub.h:22
bool HitOnTrack(const art::Ptr< recob::Hit > &hit, const art::Ptr< recob::Track > &trk, const std::vector< art::Ptr< recob::Hit >> &trk_hits, const std::vector< const recob::TrackHitMeta * > &trk_thms)
Definition: StubBuilder.cxx:5
std::vector< TCSlice > slices
Definition: DataStructs.cxx:13
std::map< unsigned, std::vector< std::vector< const recob::TrackHitMeta * > > > fSliceTrkTHMs
Definition: StubBuilder.h:74
double ConvertTicksToX(double ticks, int p, int t, int c) const
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
Contains all timing reference information for the detector.
sbn::Stub FromVertexHit(const art::Ptr< recob::Slice > &slice, const sbn::VertexHit &vhit, const recob::Hit &vhit_hit, const geo::GeometryCore *geo, const spacecharge::SpaceCharge *sce, const detinfo::DetectorClocksData &dclock, const detinfo::DetectorPropertiesData &dprop, const art::Event &e, std::vector< art::Ptr< recob::Hit >> &stub_hits, art::Ptr< recob::PFParticle > &stub_pfp)
std::map< unsigned, std::vector< art::Ptr< recob::Hit > > > fSliceHits
Definition: StubBuilder.h:69
do i e
double GetEfield(const detinfo::DetectorPropertiesData &dprop, const spacecharge::SpaceCharge *sce, geo::Point_t loc, geo::TPCID TPC, bool correct_loc_sce, float xsign=1.)
Get the E-Field in the presence of space charge.
int FindPFPInd(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< art::Ptr< recob::PFParticle >> &pfps, const std::vector< std::vector< art::Ptr< recob::Hit >>> &pfp_hits)
Definition: StubBuilder.cxx:25
std::vector< float > trkpitch
Pitch of the matched track on each wire [cm].
Definition: Stub.h:28
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
Definition: Stub.h:16
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
std::vector< float > pitch
Pitch of stub on each wire [cm].
Definition: Stub.h:27
bool ontrack
Whether the hit is also on a track.
Definition: Stub.h:13
std::map< unsigned, std::vector< art::Ptr< recob::Track > > > fSliceTrks
Definition: StubBuilder.h:71
geo::Point_t vtxXYZ
3D location of the Vertex associated with this hit. Space charge corrected. [cm]
Definition: VertexHit.h:18
float vtxw
Wire of the vertex associated with this hit. Not space charge corrected. [cm].
Definition: VertexHit.h:14