LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
quad Namespace Reference

Classes

class  EvalVtx
 
class  HeatMap
 
struct  Line2D
 
struct  Pt2D
 
class  QuadVtx
 

Functions

recob::Vertex GetFirstVertex (const std::string &label, const art::Event &evt)
 
recob::Vertex GetVtxByAssns (const std::string &label, const art::Event &evt)
 
bool IntersectsCircle (float m, float c, float z0, float x0, float R, float &z1, float &z2)
 
void LinesFromPoints (const std::vector< Pt2D > &pts, std::vector< Line2D > &lines, float z0=0, float x0=0, float R=-1)
 
bool CloseAngles (float ma, float mb)
 
void MapFromLines (const std::vector< Line2D > &lines, HeatMap &hm)
 
recob::tracking::Point_t FindPeak3D (const std::vector< HeatMap > &hs, const std::vector< recob::tracking::Vector_t > &dirs) noexcept
 
void GetPts2D (const detinfo::DetectorPropertiesData &detProp, const std::vector< recob::Hit > &hits, std::vector< std::vector< Pt2D >> &pts, std::vector< recob::tracking::Vector_t > &dirs, const geo::GeometryCore *geom)
 

Function Documentation

bool quad::CloseAngles ( float  ma,
float  mb 
)
inline

Definition at line 176 of file QuadVtx_module.cc.

References geo::vect::dot().

Referenced by MapFromLines().

177  {
178  const float cosCrit = cos(10 * M_PI / 180.);
179  const float dot = 1 + ma * mb; // (1, ma)*(1, mb)
180  return cet::square(dot) > (1 + cet::square(ma)) * (1 + cet::square(mb)) * cet::square(cosCrit);
181  }
constexpr auto dot(Vector const &a, OtherVector const &b)
Return cross product of two vectors.
recob::tracking::Point_t quad::FindPeak3D ( const std::vector< HeatMap > &  hs,
const std::vector< recob::tracking::Vector_t > &  dirs 
)
noexcept

Definition at line 245 of file QuadVtx_module.cc.

References h1, h2, r, quad::Pt2D::view, y, and quad::Pt2D::z.

Referenced by quad::QuadVtx::FindVtx().

247  {
248  assert(hs.size() == 3);
249  assert(dirs.size() == 3);
250 
251  const int Nx = hs[0].Nx;
252 
253  TMatrixD M(2, 2);
254  M(0, 0) = dirs[0].Y();
255  M(0, 1) = dirs[0].Z();
256  M(1, 0) = dirs[1].Y();
257  M(1, 1) = dirs[1].Z();
258 
259  // Singular, and stupid setup of exceptions means we can't test any other way
260  if (M(0, 0) * M(1, 1) - M(1, 0) * M(0, 1) == 0) return {};
261 
262  M.Invert();
263 
264  float bestscore = -1;
266 
267  // Accumulate some statistics up front that will enable us to optimize
268  std::vector<float> colMax[3];
269  for (int view = 0; view < 3; ++view) {
270  colMax[view].resize(hs[view].Nz);
271  for (int iz = 0; iz < hs[view].Nz; ++iz) {
272  colMax[view][iz] = *std::max_element(&hs[view].map[Nx * iz], &hs[view].map[Nx * (iz + 1)]);
273  }
274  }
275 
276  for (int iz = 0; iz < hs[0].Nz; ++iz) {
277  const float z = hs[0].ZBinCenter(iz);
278  const float bonus = 1; // works badly... exp((hs[0].maxz-z)/1000.);
279 
280  for (int iu = 0; iu < hs[1].Nz; ++iu) {
281  const float u = hs[1].ZBinCenter(iu);
282  // r.Dot(d0) = z && r.Dot(d1) = u
283  TVectorD p(2);
284  p(0) = z;
285  p(1) = u;
286  const TVectorD r = M * p;
287  const float v = r[0] * dirs[2].Y() + r[1] * dirs[2].Z();
288  const int iv = hs[2].ZToBin(v);
289  if (iv < 0 || iv >= hs[2].Nz) continue;
290  const double y = r(0);
291 
292  // Even if the maxes were all at the same x we couldn't beat the record
293  if (colMax[0][iz] + colMax[1][iu] + colMax[2][iv] < bestscore) continue;
294 
295  const float* h0 = &hs[0].map[Nx * iz];
296  const float* h1 = &hs[1].map[Nx * iu];
297  const float* h2 = &hs[2].map[Nx * iv];
298 
299  int bestix = -1;
300  for (int ix = 1; ix < Nx - 1; ++ix) {
301  const float score = bonus * (h0[ix] + h1[ix] + h2[ix]);
302 
303  if (score > bestscore) {
304  bestscore = score;
305  bestix = ix;
306  }
307  } // end for dx
308 
309  if (bestix != -1) { bestr.SetXYZ(hs[0].XBinCenter(bestix), y, z); }
310  } // end for u
311  } // end for z
312 
313  return bestr;
314  }
TRandom r
Definition: spectrum.C:23
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:276
TH1F * h2
Definition: plot.C:44
TH1F * h1
Definition: plot.C:41
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space. See recob::tracking::Coord_t for more detai...
Definition: TrackingTypes.h:27
recob::Vertex quad::GetFirstVertex ( const std::string &  label,
const art::Event evt 
)

Definition at line 68 of file EvalVtx_module.cc.

References art::ProductRetriever::getValidHandle().

Referenced by quad::EvalVtx::analyze().

69  {
70  const auto& vtxs = *evt.getValidHandle<std::vector<recob::Vertex>>(label);
71 
72  if (vtxs.empty()) return recob::Vertex();
73 
74  return vtxs[0];
75  }
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
void quad::GetPts2D ( const detinfo::DetectorPropertiesData detProp,
const std::vector< recob::Hit > &  hits,
std::vector< std::vector< Pt2D >> &  pts,
std::vector< recob::tracking::Vector_t > &  dirs,
const geo::GeometryCore geom 
)

Definition at line 317 of file QuadVtx_module.cc.

References util::begin(), detinfo::DetectorPropertiesData::ConvertTicksToX(), util::end(), quad::Pt2D::energy, geo::kZ, quad::Pt2D::view, geo::GeometryCore::View(), and geo::GeometryCore::WireEndPoints().

Referenced by quad::QuadVtx::FindVtx().

322  {
323  pts.resize(3); // 3 views
324 
325  recob::tracking::Vector_t dirZ(0, 0, 1);
326  recob::tracking::Vector_t dirU, dirV;
327 
328  for (const recob::Hit& hit : hits) {
329  const geo::WireID wire = hit.WireID();
330 
331  const double xpos = detProp.ConvertTicksToX(hit.PeakTime(), wire);
332 
333  auto const r0 = geom->WireEndPoints(wire).start();
334  auto const r1 = geom->WireEndPoints(wire).end();
335 
336  const double energy = hit.Integral();
337 
338  if (geom->View(hit.Channel()) == geo::kZ) {
339  pts[0].emplace_back(xpos, r0.z(), 0, energy);
340  continue;
341  }
342 
343  // Compute the direction perpendicular to the wires
344  auto const unit = (r1 - r0).Unit();
345  recob::tracking::Vector_t perp{0, -unit.z(), unit.y()};
346  // We want to ultimately have a positive z component ion "perp"
347  if (perp.z() < 0) perp *= -1;
348 
349  // TODO check we never get a 4th view a-la the bug we had in the 3D version
350 
351  // The "U" direction is the first one we see
352  if (dirU.Mag2() == 0) { dirU = perp; }
353  else if (dirV.Mag2() == 0 && fabs(dirU.Dot(perp)) < 0.99) {
354  // If we still need a "V" and this direction differs from "U"
355  dirV = perp;
356  }
357 
358  // Hits belong to whichever view their perpendicular vector aligns with
359  if (fabs(dirU.Dot(perp)) > 0.99) { pts[1].emplace_back(xpos, r0.Dot(dirU), 1, energy); }
360  else {
361  pts[2].emplace_back(xpos, r0.Dot(dirV), 2, energy);
362  }
363  } // end for hits
364 
365  dirs = {dirZ, dirU, dirV};
366 
367  std::default_random_engine gen;
368 
369  // In case we need to sub-sample they should be shuffled
370  for (int view = 0; view < 3; ++view) {
371  std::shuffle(pts[view].begin(), pts[view].end(), gen);
372  }
373  }
Planes which measure Z direction.
Definition: geo_types.h:138
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
double energy
Definition: plottest35.C:25
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space. See recob::tracking::Coord_t for more details on the ...
Definition: TrackingTypes.h:31
Detector simulation of raw signals on wires.
double ConvertTicksToX(double ticks, int p, int t, int c) const
View_t View(PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
void WireEndPoints(WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
recob::Vertex quad::GetVtxByAssns ( const std::string &  label,
const art::Event evt 
)

Definition at line 78 of file EvalVtx_module.cc.

References util::abs(), and art::ProductRetriever::getByLabel().

Referenced by quad::EvalVtx::analyze().

79  {
81  evt.getByLabel(label, vtxs);
82 
83  if (vtxs->empty()) return recob::Vertex();
84 
86  evt.getByLabel(label, parts);
87 
88  art::FindManyP<recob::Vertex> fm(parts, evt, label);
89 
90  for (unsigned int i = 0; i < parts->size(); ++i) {
91  const int pdg = abs((*parts)[i].PdgCode());
92  if (pdg == 12 || pdg == 14 || pdg == 16) {
93  const std::vector<art::Ptr<recob::Vertex>>& vtxs = fm.at(i);
94  if (vtxs.size() == 1) return *vtxs[0];
95 
96  if (vtxs.empty()) { std::cout << "Warning: vertex list empty!" << std::endl; }
97  else {
98  std::cout << "Warning: " << vtxs.size() << " vertices for daughter?" << std::endl;
99  }
100  }
101  }
102 
103  return recob::Vertex();
104  }
constexpr auto abs(T v)
Returns the absolute value of the argument.
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
bool quad::IntersectsCircle ( float  m,
float  c,
float  z0,
float  x0,
float  R,
float &  z1,
float &  z2 
)

Definition at line 105 of file QuadVtx_module.cc.

Referenced by LinesFromPoints().

106  {
107  // Change to the frame where (z0, x0) = (0, 0)
108  c += m * z0 - x0;
109 
110  // z^2 + (m*z+c)^2 = R^2
111  const float A = 1 + cet::square(m);
112  const float B = 2 * m * c;
113  const float C = cet::square(c) - cet::square(R);
114 
115  double desc = cet::square(B) - 4 * A * C;
116 
117  if (desc < 0) return false;
118 
119  desc = sqrt(desc);
120 
121  z1 = (-B - desc) / (2 * A);
122  z2 = (-B + desc) / (2 * A);
123 
124  // Back to the original frame
125  z1 += z0;
126  z2 += z0;
127 
128  return true;
129  }
void quad::LinesFromPoints ( const std::vector< Pt2D > &  pts,
std::vector< Line2D > &  lines,
float  z0 = 0,
float  x0 = 0,
float  R = -1 
)

Definition at line 132 of file QuadVtx_module.cc.

References quad::Line2D::c, util::end(), IntersectsCircle(), quad::Line2D::m, quad::Line2D::maxz, and quad::Line2D::minz.

Referenced by quad::QuadVtx::FindVtx().

137  {
138  constexpr size_t kMaxLines = 10 * 1000 * 1000; // This is 150MB of lines...
139 
140  const size_t product = (pts.size() * (pts.size() - 1)) / 2;
141  const int stride = product / kMaxLines + 1;
142 
143  lines.reserve(std::min(product, kMaxLines));
144 
145  for (int offset = 0; offset < stride; ++offset) {
146  for (unsigned int i = 0; i < pts.size(); ++i) {
147  for (unsigned int j = i + offset + 1; j < pts.size(); j += stride) {
148  const Line2D l(pts[i], pts[j]);
149 
150  if (isinf(l.m) || isnan(l.m) || isinf(l.c) || isnan(l.c)) continue;
151 
152  if (R > 0) {
153  float z1, z2;
154  if (!IntersectsCircle(l.m, l.c, z0, x0, 2.5, z1, z2)) continue;
155  if (l.minz < z1 && l.minz < z2 && l.maxz > z1 && l.maxz > z2) continue;
156  }
157 
158  lines.push_back(std::move(l));
159  if (lines.size() == kMaxLines) goto end; // break out of 3 loops
160  }
161  }
162  }
163 
164  end:
165 
166  lines.shrink_to_fit();
167 
168  mf::LogInfo() << "Made " << lines.size() << " lines using stride " << stride
169  << " to fit under cap of " << kMaxLines << std::endl;
170 
171  // Lines are required to be sorted by gradient for a later optimization
172  std::sort(lines.begin(), lines.end());
173  }
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
bool IntersectsCircle(float m, float c, float z0, float x0, float R, float &z1, float &z2)
void quad::MapFromLines ( const std::vector< Line2D > &  lines,
HeatMap hm 
)

Definition at line 184 of file QuadVtx_module.cc.

References quad::Line2D::c, CloseAngles(), quad::Line2D::m, quad::HeatMap::map, quad::Line2D::maxz, quad::Line2D::minz, quad::HeatMap::Nx, quad::Pt2D::x, quad::HeatMap::XToBin(), quad::Pt2D::z, and quad::HeatMap::ZToBin().

Referenced by quad::QuadVtx::FindVtx().

185  {
186  // This maximum is driven by runtime
187  constexpr size_t kMaxPts = 10 * 1000 * 1000;
188 
189  unsigned int j0 = 0;
190  unsigned int jmax = 0;
191 
192  long npts = 0;
193  for (unsigned int i = 0; i + 1 < lines.size(); ++i) {
194  const Line2D a = lines[i];
195 
196  j0 = std::max(j0, i + 1);
197  while (j0 < lines.size() && CloseAngles(a.m, lines[j0].m))
198  ++j0;
199  jmax = std::max(jmax, j0);
200  while (jmax < lines.size() && !CloseAngles(a.m, lines[jmax].m))
201  ++jmax;
202 
203  npts += jmax - j0;
204  }
205 
206  const size_t product = (lines.size() * (lines.size() - 1)) / 2;
207  const int stride = npts / kMaxPts + 1;
208 
209  mf::LogInfo() << "Combining lines to points with stride " << stride << std::endl;
210 
211  mf::LogInfo() << npts << " cf " << product << " ie " << double(npts) / product << std::endl;
212 
213  j0 = 0;
214  jmax = 0;
215 
216  for (unsigned int i = 0; i + 1 < lines.size(); ++i) {
217  const Line2D a = lines[i];
218 
219  j0 = std::max(j0, i + 1);
220  while (j0 < lines.size() && CloseAngles(a.m, lines[j0].m))
221  ++j0;
222  jmax = std::max(jmax, j0);
223  while (jmax < lines.size() && !CloseAngles(a.m, lines[jmax].m))
224  ++jmax;
225 
226  for (unsigned int j = j0; j < jmax; j += stride) {
227  const Line2D& b = lines[j];
228 
229  // x = mA * z + cA = mB * z + cB
230  const float z = (b.c - a.c) / (a.m - b.m);
231  const float x = a.m * z + a.c;
232 
233  // No solutions within a line
234  if ((z < a.minz || z > a.maxz) && (z < b.minz || z > b.maxz)) {
235  const int iz = hm.ZToBin(z);
236  const int ix = hm.XToBin(x);
237  if (iz >= 0 && iz < hm.Nz && ix >= 0 && ix < hm.Nx) { hm.map[iz * hm.Nx + ix] += stride; }
238  }
239  } // end for i
240  }
241  }
Float_t x
Definition: compare.C:6
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Double_t z
Definition: plot.C:276
bool CloseAngles(float ma, float mb)