16 #include "art_root_io/TFileService.h" 37 Pt2D(
double _x,
double _z,
int _view,
double _energy)
55 :
m((b.
x - a.
x) / (b.
z - a.
z))
83 const std::vector<recob::Hit>& hits,
99 , fHitLabel(pset.
get<
std::
string>("HitLabel"))
100 , fSavePlots(pset.
get<
bool>("SavePlots"))
102 produces<std::vector<recob::Vertex>>();
122 const float B = 2 * m *
c;
127 if (desc < 0)
return false;
131 z1 = (-B -
desc) / (2 * A);
132 z2 = (-B +
desc) / (2 * A);
144 std::vector<Line2D>&
lines,
149 constexpr
size_t kMaxLines = 10 * 1000 * 1000;
151 const size_t product = (pts.size() * (pts.size() - 1)) / 2;
152 const int stride = product / kMaxLines + 1;
154 lines.reserve(
std::min(product, kMaxLines));
156 for (
int offset = 0; offset < stride; ++offset) {
157 for (
unsigned int i = 0; i < pts.size(); ++i) {
158 for (
unsigned int j = i + offset + 1; j < pts.size(); j += stride) {
159 const Line2D l(pts[i], pts[j]);
161 if (isinf(l.
m) || isnan(l.
m) || isinf(l.
c) || isnan(l.
c))
continue;
170 if (lines.size() == kMaxLines)
goto end;
177 lines.shrink_to_fit();
179 mf::LogInfo() <<
"Made " << lines.size() <<
" lines using stride " << stride
180 <<
" to fit under cap of " << kMaxLines <<
std::endl;
183 std::sort(lines.begin(), lines.end());
190 const float cosCrit = cos(10 *
M_PI / 180.);
191 const float dot = 1 + ma *
mb;
200 constexpr
size_t kMaxPts = 10 * 1000 * 1000;
203 unsigned int jmax = 0;
206 for (
unsigned int i = 0; i + 1 < lines.size(); ++i) {
210 while (j0 < lines.size() &&
CloseAngles(a.
m, lines[j0].m))
213 while (jmax < lines.size() && !
CloseAngles(a.
m, lines[jmax].m))
219 const size_t product = (lines.size() * (lines.size() - 1)) / 2;
220 const int stride = npts / kMaxPts + 1;
229 for (
unsigned int i = 0; i + 1 < lines.size(); ++i) {
233 while (j0 < lines.size() &&
CloseAngles(a.
m, lines[j0].m))
236 while (jmax < lines.size() && !
CloseAngles(a.
m, lines[jmax].m))
239 for (
unsigned int j = j0; j < jmax; j += stride) {
243 const float z = (b.
c - a.
c) / (a.
m - b.
m);
244 const float x = a.
m * z + a.
c;
247 if ((z < a.minz || z > a.
maxz) && (z < b.
minz || z > b.
maxz)) {
248 const int iz = hm.
ZToBin(z);
249 const int ix = hm.
XToBin(x);
250 if (iz >= 0 && iz < hm.Nz && ix >= 0 && ix < hm.
Nx) { hm.
map[iz * hm.
Nx + ix] += stride; }
259 FindPeak3D(
const std::vector<HeatMap>&
hs,
const std::vector<TVector3>& dirs) noexcept
261 assert(
hs.size() == 3);
262 assert(dirs.size() == 3);
264 const int Nx =
hs[0].Nx;
267 M(0, 0) = dirs[0].Y();
268 M(0, 1) = dirs[0].Z();
269 M(1, 0) = dirs[1].Y();
270 M(1, 1) = dirs[1].Z();
273 if (M(0, 0) * M(1, 1) - M(1, 0) * M(0, 1) == 0)
return TVector3(0, 0, 0);
277 float bestscore = -1;
281 std::vector<float> colMax[3];
284 for (
int iz = 0; iz <
hs[
view].Nz; ++iz) {
285 colMax[
view][iz] = *std::max_element(&
hs[
view].map[Nx * iz], &
hs[
view].map[Nx * (iz + 1)]);
289 for (
int iz = 0; iz <
hs[0].Nz; ++iz) {
290 const float z =
hs[0].ZBinCenter(iz);
291 const float bonus = 1;
293 for (
int iu = 0; iu <
hs[1].Nz; ++iu) {
294 const float u =
hs[1].ZBinCenter(iu);
299 const TVectorD
r = M *
p;
300 const float v = r[0] * dirs[2].Y() + r[1] * dirs[2].Z();
301 const int iv =
hs[2].ZToBin(v);
302 if (iv < 0 || iv >=
hs[2].Nz)
continue;
303 const double y =
r(0);
306 if (colMax[0][iz] + colMax[1][iu] + colMax[2][iv] < bestscore)
continue;
309 const float* __restrict__ h0 = &
hs[0].map[Nx * iz];
310 const float* __restrict__
h1 = &
hs[1].map[Nx * iu];
311 const float* __restrict__
h2 = &
hs[2].map[Nx * iv];
314 for (
int ix = 1; ix < Nx - 1; ++ix) {
315 const float score = bonus * (h0[ix] + h1[ix] + h2[ix]);
317 if (score > bestscore) {
323 if (bestix != -1) { bestr = TVector3(
hs[0].XBinCenter(bestix), y, z); }
333 const std::vector<recob::Hit>& hits,
335 std::vector<TVector3>& dirs,
340 TVector3 dirZ(0, 0, 1);
354 pts[0].emplace_back(xpos, r0.z(), 0,
energy);
359 TVector3 perp = (r1 - r0).Unit();
360 perp = TVector3(0, -perp.z(), perp.y());
362 if (perp.z() < 0) perp *= -1;
367 if (dirU.Mag2() == 0) { dirU = perp; }
368 else if (dirV.Mag2() == 0 && fabs(dirU.Dot(perp)) < 0.99) {
374 if (fabs(dirU.Dot(perp)) > 0.99) { pts[1].emplace_back(xpos, r0.Dot(dirU), 1,
energy); }
376 pts[2].emplace_back(xpos, r0.Dot(dirV), 2,
energy);
380 dirs = {dirZ, dirU, dirV};
382 std::default_random_engine
gen;
393 const std::vector<recob::Hit>& hits,
397 if (hits.empty())
return false;
399 std::vector<std::vector<Pt2D>> pts;
400 std::vector<TVector3> dirs;
402 GetPts2D(detProp, hits, pts, dirs, geom);
406 double minz[3] = {+1e9, +1e9, +1e9};
407 double maxz[3] = {-1e9, -1e9, -1e9};
427 std::vector<float>
zs;
428 zs.reserve(pts[0].
size());
429 for (
const Pt2D&
p : pts[0])
431 auto mid = zs.begin() + zs.size() / 4;
432 if (mid != zs.end()) {
433 std::nth_element(zs.begin(), mid, zs.end());
437 std::vector<HeatMap> hms;
442 std::vector<Line2D>
lines;
445 if (lines.empty())
return false;
448 hms.emplace_back(maxz[view] - minz[view], minz[view], maxz[view], maxx - minx, minx, maxx);
454 std::vector<HeatMap> hms_zoom;
457 const double x0 = vtx.X();
458 const double z0 = vtx.Dot(dirs[
view]);
460 std::vector<Line2D>
lines;
463 if (lines.empty())
return false;
466 hms_zoom.emplace_back(50, z0 - 2.5, z0 + 2.5, 50, x0 - 2.5, x0 + 2.5);
474 art::TFileDirectory evt_dir =
480 TGraph* gpts = view_dir.makeAndRegister<TGraph>(
"hits",
"");
482 gpts->SetPoint(gpts->GetN(),
p.z,
p.x);
484 view_dir.makeAndRegister<TH2F>(
"hmap",
"", *hms[
view].AsTH2());
486 view_dir.makeAndRegister<TH2F>(
"hmap_zoom",
"", *hms_zoom[
view].AsTH2());
488 const double x = vtx.X();
489 const double z = vtx.Dot(dirs[view]);
490 view_dir.makeAndRegister<TGraph>(
"vtx3d",
"", 1, &
z, &
x);
501 auto vtxcol = std::make_unique<std::vector<recob::Vertex>>();
509 if (FindVtx(detProp, *hits, vtx, evt.
event())) {
510 vtxcol->emplace_back(
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void GetPts2D(const detinfo::DetectorPropertiesData &detProp, const std::vector< recob::Hit > &hits, std::vector< std::vector< Pt2D >> &pts, std::vector< TVector3 > &dirs, const geo::GeometryCore *geom)
int XToBin(double x) const
EventNumber_t event() const
TVector3 FindPeak3D(const std::vector< HeatMap > &hs, const std::vector< TVector3 > &dirs) noexcept
def mkdir(path, mode=0o777)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
tracking::SMatrixSym33 SMatrixSym33
int ZToBin(double z) const
virtual const provider_type * provider() const override
Planes which measure Z direction.
art framework interface to geometry description
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
tracking::Point_t Point_t
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
bool FindVtx(const detinfo::DetectorPropertiesData &detProp, const std::vector< recob::Hit > &hits, TVector3 &vtx, int evt) const
Pt2D(double _x, double _z, int _view, double _energy)
#define DEFINE_ART_MODULE(klass)
void MapFromLines(const std::vector< Line2D > &lines, HeatMap &hm)
static constexpr double mb
bool IntersectsCircle(float m, float c, float z0, float x0, float R, float &z1, float &z2)
bool operator<(const Pt2D &p) const
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
static int max(int a, int b)
Description of geometry of one entire detector.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
Detector simulation of raw signals on wires.
double ConvertTicksToX(double ticks, int p, int t, int c) const
Declaration of signal hit object.
bool CloseAngles(float ma, float mb)
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
void LinesFromPoints(const std::vector< Pt2D > &pts, std::vector< Line2D > &lines, float z0=0, float x0=0, float R=-1)
void WireEndPoints(geo::WireID const &wireid, double *xyzStart, double *xyzEnd) const
Fills two arrays with the coordinates of the wire end points.
static constexpr double zs
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
2D representation of charge deposited in the TDC/wire plane
auto const & get(AssnsNode< L, R, D > const &r)
const geo::GeometryCore * geom
list hs
New: trying to fill every bin.
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
QTextStream & endl(QTextStream &s)
void produce(art::Event &evt) override
Line2D(const Pt2D &a, const Pt2D &b)