LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
TripletFinder.cxx
Go to the documentation of this file.
2 
4 
5 namespace reco3d
6 {
7  // -------------------------------------------------------------------------
9  const std::vector<art::Ptr<recob::Hit>>& uhits,
10  const std::vector<art::Ptr<recob::Hit>>& vhits,
11  const std::vector<raw::ChannelID_t>& xbad,
12  const std::vector<raw::ChannelID_t>& ubad,
13  const std::vector<raw::ChannelID_t>& vbad,
14  double distThresh, double distThreshDrift,
15  double xhitOffset)
16  : geom(art::ServiceHandle<geo::Geometry>()->provider()),
17  detprop(art::ServiceHandle<detinfo::DetectorPropertiesService>()->provider()),
18  fDistThresh(distThresh),
19  fDistThreshDrift(distThreshDrift),
20  fXHitOffset(xhitOffset)
21  {
22  FillHitMap(xhits, fX_by_tpc);
23  FillHitMap(uhits, fU_by_tpc);
24  FillHitMap(vhits, fV_by_tpc);
25 
26  FillBadMap(xbad, fXbad_by_tpc);
27  FillBadMap(ubad, fUbad_by_tpc);
28  FillBadMap(vbad, fVbad_by_tpc);
29  }
30 
31  // -------------------------------------------------------------------------
32  void TripletFinder::
34  std::map<geo::TPCID, std::vector<HitOrChan>>& out)
35  {
36  for(const art::Ptr<recob::Hit>& hit: hits){
37  for(geo::TPCID tpc: geom->ROPtoTPCs(geom->ChannelToROP(hit->Channel()))){
38  double xpos = 0;
39  for(geo::WireID wire: geom->ChannelToWire(hit->Channel())){
40  if(geo::TPCID(wire) == tpc){
41  xpos = detprop->ConvertTicksToX(hit->PeakTime(), wire);
42  if (geom->SignalType(wire) == geo::kCollection) xpos += fXHitOffset;
43  }
44  }
45 
46  out[tpc].emplace_back(hit.get(), xpos);
47  }
48  }
49  for(auto& it: out)
50  std::sort(it.second.begin(), it.second.end(),
51  [](auto a, auto b){return a.xpos < b.xpos;});
52  }
53 
54  // -------------------------------------------------------------------------
55  void TripletFinder::
56  FillBadMap(const std::vector<raw::ChannelID_t>& bads,
57  std::map<geo::TPCID, std::vector<raw::ChannelID_t>>& out)
58  {
59  for(raw::ChannelID_t chan: bads){
60  for(geo::TPCID tpc: geom->ROPtoTPCs(geom->ChannelToROP(chan))){
61  out[tpc].push_back(chan);
62  }
63  }
64  }
65 
66  // -------------------------------------------------------------------------
68  {
69  public:
71  : geom(art::ServiceHandle<geo::Geometry>()->provider()),
72  fTPC(tpc)
73  {
74  }
75 
78  {
79  const auto key = std::make_pair(a, b);
80 
81  auto it = fMap.find(key);
82  if(it != fMap.end()){
83  pt = fPtMap[key];
84  return it->second;
85  }
86 
87  const bool res = ISect(a, b, pt);
88  fMap.insert({key, res});
89  fPtMap.insert({key, pt});
90  return res;
91  }
92 
93  protected:
96  {
97  for(geo::WireID awire: geom->ChannelToWire(chanA)){
98  if(geo::TPCID(awire) != fTPC) continue;
99  for(geo::WireID bwire: geom->ChannelToWire(chanB)){
100  if(geo::TPCID(bwire) != fTPC) continue;
101 
102  if(geom->WireIDsIntersect(awire, bwire, pt)) return true;
103  }
104  }
105 
106  return false;
107  }
108 
110 
111  std::map<std::pair<raw::ChannelID_t, raw::ChannelID_t>, bool> fMap;
112  std::map<std::pair<raw::ChannelID_t, raw::ChannelID_t>, geo::WireIDIntersection> fPtMap;
113 
115  };
116 
117  // -------------------------------------------------------------------------
118  bool TripletFinder::CloseDrift(double xa, double xb) const
119  {
120  return fabs(xa-xb) < fDistThreshDrift;
121  }
122 
123  // -------------------------------------------------------------------------
125  geo::WireIDIntersection rb) const
126  {
127  const TVector3 pa(ra.y, ra.z, 0);
128  const TVector3 pb(rb.y, rb.z, 0);
129 
130  return (pa-pb).Mag() < fDistThresh;
131  }
132 
133  bool LessThanXHit(const ChannelDoublet& a, const ChannelDoublet& b)
134  {
135  // Make sure the bad hits get sorted too
136  if(a.a.hit == 0 && b.a.hit == 0) return a.a.chan < b.a.chan;
137  // But mostly just order the real hits (in some arbitrary order)
138  return a.a.hit < b.a.hit;
139  }
140 
141  bool SameXHit(const ChannelDoublet& a, const ChannelDoublet& b)
142  {
143  if(a.a.hit == 0 && b.a.hit == 0) return a.a.chan == b.a.chan;
144  return a.a.hit == b.a.hit;
145  }
146 
147  // -------------------------------------------------------------------------
148  std::vector<HitTriplet> TripletFinder::Triplets()
149  {
150  std::vector<HitTriplet> ret;
151 
152  for(const auto& it: fX_by_tpc){
153  const geo::TPCID& tpc = it.first;
154 
155  std::vector<ChannelDoublet> xus = DoubletsXU(tpc);
156  std::vector<ChannelDoublet> xvs = DoubletsXV(tpc);
157 
158  // Cache to prevent repeating the same questions
159  IntersectionCache isectUV(tpc);
160 
161  // For the efficient looping below to work we need to sort the doublet
162  // lists so the X hits occur in the same order.
163  std::sort(xus.begin(), xus.end(), LessThanXHit);
164  std::sort(xvs.begin(), xvs.end(), LessThanXHit);
165 
166  auto xvit_begin = xvs.begin();
167 
168  int nxuv = 0;
169  for(const ChannelDoublet& xu: xus){
170  const HitOrChan& x = xu.a;
171  const HitOrChan& u = xu.b;
172 
173  // Catch up until we're looking at the same X hit in XV
174  while(xvit_begin != xvs.end() && LessThanXHit(*xvit_begin, xu)) ++xvit_begin;
175 
176  // Loop through all those matching hits
177  for(auto xvit = xvit_begin; xvit != xvs.end() && SameXHit(*xvit, xu); ++xvit){
178  const HitOrChan& v = xvit->b;
179 
180  // Only allow one bad channel per triplet
181  if(!x.hit && !u.hit) continue;
182  if(!x.hit && !v.hit) continue;
183  if(!u.hit && !v.hit) continue;
184 
185  if(u.hit && v.hit && !CloseDrift(u.xpos, v.xpos)) continue;
186 
188  if(!isectUV(u.chan, v.chan, ptUV)) continue;
189 
190  if(!CloseSpace(xu.pt, xvit->pt) ||
191  !CloseSpace(xu.pt, ptUV) ||
192  !CloseSpace(xvit->pt, ptUV)) continue;
193 
194  double xavg = 0;
195  int nx = 0;
196  if(x.hit){xavg += x.xpos; ++nx;}
197  if(u.hit){xavg += u.xpos; ++nx;}
198  if(v.hit){xavg += v.xpos; ++nx;}
199  xavg /= nx;
200 
201  const XYZ pt{xavg,
202  (xu.pt.y + xvit->pt.y + ptUV.y)/3,
203  (xu.pt.z + xvit->pt.z + ptUV.z)/3};
204 
205  ret.emplace_back(HitTriplet{x.hit, u.hit, v.hit, pt});
206  ++nxuv;
207  } // end for xv
208  } // end for xu
209 
210  std::cout << tpc << " " << xus.size() << " XUs and " << xvs.size() << " XVs -> " << nxuv << " XUVs" << std::endl;
211 
212  } // end for tpc
213 
214  std::cout << ret.size() << " XUVs total" << std::endl;
215 
216  return ret;
217  }
218 
219  // -------------------------------------------------------------------------
220  std::vector<HitTriplet> TripletFinder::TripletsTwoView()
221  {
222  std::vector<HitTriplet> ret;
223 
224  for(const auto& it: fX_by_tpc){
225  const geo::TPCID& tpc = it.first;
226 
227  std::vector<ChannelDoublet> xus = DoubletsXU(tpc);
228 
229  for(const ChannelDoublet& xu: xus){
230  const HitOrChan& x = xu.a;
231  const HitOrChan& u = xu.b;
232 
233  double xavg = x.xpos;
234  int nx = 1;
235  if(u.hit){xavg += u.xpos; ++nx;}
236  xavg /= nx;
237 
238  const XYZ pt{xavg, xu.pt.y, xu.pt.z};
239 
240  ret.emplace_back(HitTriplet{x.hit, u.hit, 0, pt});
241  } // end for xu
242  } // end for tpc
243 
244  std::cout << ret.size() << " XUs total" << std::endl;
245 
246  return ret;
247  }
248 
249  // -------------------------------------------------------------------------
250  std::vector<ChannelDoublet> TripletFinder::DoubletsXU(geo::TPCID tpc)
251  {
252  std::vector<ChannelDoublet> ret = DoubletHelper(tpc, fX_by_tpc[tpc], fU_by_tpc[tpc], fUbad_by_tpc[tpc]);
253 
254  // Find X(bad)+U(good) doublets, have to flip them for the final result
255  for(auto it: DoubletHelper(tpc, fU_by_tpc[tpc], {}, fXbad_by_tpc[tpc])){
256  ret.push_back({it.b, it.a, it.pt});
257  }
258 
259  return ret;
260  }
261 
262  // -------------------------------------------------------------------------
263  std::vector<ChannelDoublet> TripletFinder::DoubletsXV(geo::TPCID tpc)
264  {
265  std::vector<ChannelDoublet> ret = DoubletHelper(tpc, fX_by_tpc[tpc], fV_by_tpc[tpc], fVbad_by_tpc[tpc]);
266 
267  // Find X(bad)+V(good) doublets, have to flip them for the final result
268  for(auto it: DoubletHelper(tpc, fV_by_tpc[tpc], {}, fXbad_by_tpc[tpc])){
269  ret.push_back({it.b, it.a, it.pt});
270  }
271 
272  return ret;
273  }
274 
275  // -------------------------------------------------------------------------
276  std::vector<ChannelDoublet> TripletFinder::
278  const std::vector<HitOrChan>& ahits,
279  const std::vector<HitOrChan>& bhits,
280  const std::vector<raw::ChannelID_t>& bbads) const
281  {
282  std::vector<ChannelDoublet> ret;
283 
284  IntersectionCache isect(tpc);
285 
286  auto b_begin = bhits.begin();
287 
288  for(const HitOrChan& a: ahits){
289  // Bad channels are easy because there's no timing constraint
290  for(raw::ChannelID_t b: bbads){
292  if(isect(a.chan, b, pt)){
293  ret.emplace_back(a, b, pt);
294  }
295  }
296 
297  while(b_begin != bhits.end() &&
298  b_begin->xpos < a.xpos &&
299  !CloseDrift(b_begin->xpos, a.xpos)) ++b_begin;
300 
301  for(auto bit = b_begin; bit != bhits.end(); ++bit){
302  const HitOrChan& b = *bit;
303 
304  if(b.xpos > a.xpos && !CloseDrift(b.xpos, a.xpos)) break;
305 
307  if(!isect(a.chan, b.chan, pt)) continue;
308 
309  ret.emplace_back(a, b, pt);
310  } // end for b
311  } // end for a
312 
313  return ret;
314  }
315 }
Float_t x
Definition: compare.C:6
bool CloseSpace(geo::WireIDIntersection ra, geo::WireIDIntersection rb) const
std::vector< geo::TPCID > ROPtoTPCs(readout::ROPID const &ropid) const
Returns a list of ID of TPCs the specified ROP spans.
raw::ChannelID_t chan
Definition: TripletFinder.h:26
double z
z position of intersection
Definition: geo_types.h:494
TripletFinder(const std::vector< art::Ptr< recob::Hit >> &xhits, const std::vector< art::Ptr< recob::Hit >> &uhits, const std::vector< art::Ptr< recob::Hit >> &vhits, const std::vector< raw::ChannelID_t > &xbad, const std::vector< raw::ChannelID_t > &ubad, const std::vector< raw::ChannelID_t > &vbad, double distThresh, double distThreshDrift, double xhitOffset)
std::vector< ChannelDoublet > DoubletHelper(geo::TPCID tpc, const std::vector< HitOrChan > &ahits, const std::vector< HitOrChan > &bhits, const std::vector< raw::ChannelID_t > &bbads) const
IntersectionCache(geo::TPCID tpc)
std::map< std::pair< raw::ChannelID_t, raw::ChannelID_t >, geo::WireIDIntersection > fPtMap
std::map< geo::TPCID, std::vector< HitOrChan > > fX_by_tpc
Definition: TripletFinder.h:97
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
const geo::GeometryCore * geom
const detinfo::DetectorProperties * detprop
Definition: TripletFinder.h:71
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
std::map< std::pair< raw::ChannelID_t, raw::ChannelID_t >, bool > fMap
std::map< geo::TPCID, std::vector< HitOrChan > > fV_by_tpc
Definition: TripletFinder.h:99
std::map< geo::TPCID, std::vector< raw::ChannelID_t > > fXbad_by_tpc
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
void hits()
Definition: readHits.C:15
void FillHitMap(const std::vector< art::Ptr< recob::Hit >> &hits, std::map< geo::TPCID, std::vector< HitOrChan >> &out)
Helper for constructor.
std::map< geo::TPCID, std::vector< HitOrChan > > fU_by_tpc
Definition: TripletFinder.h:98
const geo::GeometryCore * geom
Definition: TripletFinder.h:70
TMarker * pt
Definition: egs.C:25
General LArSoft Utilities.
The data type to uniquely identify a TPC.
Definition: geo_types.h:195
Description of geometry of one entire detector.
bool SameXHit(const ChannelDoublet &a, const ChannelDoublet &b)
Detector simulation of raw signals on wires.
readout::ROPID ChannelToROP(raw::ChannelID_t channel) const
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
std::vector< HitTriplet > TripletsTwoView()
Only search for XU intersections.
const recob::Hit * hit
Definition: TripletFinder.h:27
std::vector< ChannelDoublet > DoubletsXV(geo::TPCID tpc)
std::vector< ChannelDoublet > DoubletsXU(geo::TPCID tpc)
double y
y position of intersection
Definition: geo_types.h:493
bool CloseDrift(double xa, double xb) const
std::vector< HitTriplet > Triplets()
bool LessThanXHit(const ChannelDoublet &a, const ChannelDoublet &b)
HLT enums.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:27
std::map< geo::TPCID, std::vector< raw::ChannelID_t > > fUbad_by_tpc
void FillBadMap(const std::vector< raw::ChannelID_t > &bads, std::map< geo::TPCID, std::vector< raw::ChannelID_t >> &out)
Helper for constructor.
bool operator()(raw::ChannelID_t a, raw::ChannelID_t b, geo::WireIDIntersection &pt)
Namespace collecting geometry-related classes utilities.
bool ISect(raw::ChannelID_t chanA, raw::ChannelID_t chanB, geo::WireIDIntersection &pt) const
std::map< geo::TPCID, std::vector< raw::ChannelID_t > > fVbad_by_tpc
Signal from collection planes.
Definition: geo_types.h:93