11 #include "cetlib/pow.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
20 #include "TLorentzVector.h"
31 fNPlanes =
fGeom.Nplanes();
32 vertangle.resize(fNPlanes);
33 for (UInt_t ip = 0; ip < fNPlanes; ip++)
34 vertangle[ip] =
fGeom.Plane(ip).Wire(0).ThetaZ(
false) - TMath::Pi() / 2.;
36 fWirePitch =
fGeom.WirePitch();
40 fWiretoCm = fWirePitch;
41 fTimetoCm = fTimeTick * fDriftVelocity;
42 fWireTimetoCmCm = fTimetoCm / fWirePitch;
58 Double_t& theta)
const
61 Double_t ln(0), mn(0), nn(0);
62 Double_t phis(0), thetan(0);
67 UInt_t Cplane = 0, Iplane = 1;
71 Double_t angleC, angleI, slopeC, slopeI, omegaC, omegaI;
77 if (omega0 == 0 || omega1 == 0) {
86 Double_t alt_backwards = 0;
88 if (fabs(omega0) > (TMath::Pi() / 2.0) || fabs(omega1) > (TMath::Pi() / 2.0)) {
126 slopeC = tan(omegaC);
127 slopeI = tan(omegaI);
135 if (omegaC < TMath::Pi() && omegaC > 0)
141 mn = (ln / (2 * sin(angleI))) * ((cos(angleI) / (slopeC * cos(angleC))) - (1 / slopeI) +
142 nfact * (cos(angleI) / (cos(angleC) * slopeC) - 1 / slopeI));
144 nn = (ln / (2 * cos(angleC))) *
145 ((1 / slopeC) + (1 / slopeI) + nfact * ((1 / slopeC) - (1 / slopeI)));
148 if (fabs(omegaC) > 0.01)
153 if (fabs(slopeC + slopeI) < 0.001)
155 else if (fabs(omegaI) > 0.01 && (omegaI / fabs(omegaI) == -omegaC / fabs(omegaC)) &&
156 (fabs(omegaC) < 1 * TMath::Pi() / 180 ||
157 fabs(omegaC) > 179 * TMath::Pi() / 180))
158 phis = (fabs(omegaC) > TMath::Pi() / 2) ? TMath::Pi() : 0;
160 if (nn < 0 && phis > 0 &&
164 phis = (TMath::Pi()) - phis;
165 else if (nn < 0 && phis < 0 && !(!alt_backwards && fabs(phis) < TMath::Pi() / 4))
166 phis = (-TMath::Pi()) - phis;
168 phi = phis * 180 / TMath::Pi();
176 thetan = -asin(mn / std::hypot(ln, mn, nn));
177 theta = thetan * 180 / TMath::Pi();
193 Double_t splane, lplane;
196 if (dw0 == 0 && dw1 == 0)
return -1;
215 Double_t tantheta = top /
bottom;
228 Double_t pitch = -1.;
231 mf::LogError(Form(
"Warning : no Pitch foreseen for view %d",
fGeom.
Plane(iplane).
View()));
236 Double_t
pi = TMath::Pi();
237 Double_t fTheta = pi / 2 - theta;
238 Double_t fPhi = -(phi + pi / 2);
243 Double_t angleToVert =
246 TMath::Abs(TMath::Sin(angleToVert) * TMath::Cos(fTheta) +
247 TMath::Cos(angleToVert) * TMath::Sin(fTheta) * TMath::Sin(fPhi));
249 if (cosgamma > 0) pitch = wirePitch / cosgamma;
265 Double_t pitch = -1.;
268 mf::LogError(Form(
"Warning : no Pitch foreseen for view %d",
fGeom.
Plane(iplane).
View()));
273 Double_t fTheta = theta;
279 Double_t angleToVert =
282 TMath::Abs(TMath::Sin(angleToVert) * TMath::Cos(fTheta) +
283 TMath::Cos(angleToVert) * TMath::Sin(fTheta) * TMath::Sin(fPhi));
285 if (cosgamma > 0) pitch = wirePitch / cosgamma;
301 Double_t timestart)
const
316 return Get2Dslope(endpoint->
w - startpoint->
w, endpoint->
t - startpoint->
t);
338 Double_t timestart)
const
353 return Get2Dangle(endpoint->
w - startpoint->
w, endpoint->
t - startpoint->
t);
366 BC = ((Double_t)dwire);
367 AC = ((Double_t)dtime);
368 omega = std::asin(AC / std::hypot(AC, BC));
372 omega = TMath::Pi() -
std::abs(omega);
375 omega = -TMath::Pi() +
std::abs(omega);
390 TVector3 dummyvector(cos(theta * TMath::Pi() / 180.) * sin(phi * TMath::Pi() / 180.),
391 sin(theta * TMath::Pi() / 180.),
392 cos(theta * TMath::Pi() / 180.) * cos(phi * TMath::Pi() / 180.));
409 TVector3
end = start + dir_vector;
414 (
fGeom.
DetHalfHeight() * sin(fabs(alpha)) + start[2] * cos(alpha) - start[1] * sin(alpha)),
419 (
fGeom.
DetHalfHeight() * sin(fabs(alpha)) + end[2] * cos(alpha) - end[1] * sin(alpha)),
435 Double_t time2)
const
444 return std::hypot(point1->
w - point2->
w, point1->
t - point2->
t);
454 Double_t radangle = TMath::Pi() * angle / 180;
455 if (std::cos(radangle) == 0)
return 9999;
477 Double_t& timeout)
const
479 Double_t invslope = 0;
481 if (slope) { invslope = -1. / slope; }
483 Double_t ort_intercept = time1 - invslope * (Double_t)wire1;
485 if ((slope - invslope) != 0)
486 wireout = (ort_intercept - intercept) / (slope - invslope);
489 timeout = slope * wireout + intercept;
505 double intercept = startpoint->
t - slope * startpoint->
w;
522 if (slope) { invslope = -1. / slope; }
524 double ort_intercept = point1->
t - invslope * point1->
w;
526 if ((slope - invslope) != 0)
527 pointout.
w = (ort_intercept - intercept) / (slope - invslope);
529 pointout.
w = point1->
w;
531 pointout.
t = slope * pointout.
w + intercept;
547 Double_t& timeout)
const
549 Double_t intercept = timestart - slope * (Double_t)wirestart;
551 return GetPointOnLine(slope, intercept, wire1, time1, wireout, timeout);
561 Double_t ort_intercept,
563 Double_t& timeout)
const
565 Double_t invslope = 0;
567 if (slope) { invslope = -1. / slope; }
571 wireout = (ort_intercept - intercept) / (slope - invslope);
572 timeout = slope * wireout + intercept;
587 double ort_intercept,
590 Double_t invslope = 0;
592 if (slope) invslope = -1. / slope;
594 pointonline.
w = (ort_intercept - intercept) / (slope - invslope);
595 pointonline.
t = slope * pointonline.
w + intercept;
605 for (UInt_t i = 0; i <
fNPlanes; ++i) {
606 if (i == p0->
plane || i == p1->
plane)
continue;
615 const double origin[3] = {0.};
616 Double_t pos[3] = {0.};
643 "\033[95m<<GeometryUtilities::GetYZ>>\033[00m"
645 <<
" 2D wire position " << p0->
w <<
" [cm] corresponds to negative wire number."
647 <<
" Forcing it to wire=0..." << std::endl
648 <<
"\033[93mWarning ends...\033[00m" << std::endl;
653 "\033[95m<<GeometryUtilities::GetYZ>>\033[00m"
655 <<
" 2D wire position " << p0->
w <<
" [cm] exceeds max wire number "
657 <<
" Forcing it to the max wire number..." << std::endl
658 <<
"\033[93mWarning ends...\033[00m" << std::endl;
663 "\033[95m<<GeometryUtilities::GetYZ>>\033[00m"
665 <<
" 2D wire position " << p1->
w <<
" [cm] corresponds to negative wire number."
667 <<
" Forcing it to wire=0..." << std::endl
668 <<
"\033[93mWarning ends...\033[00m" << std::endl;
673 "\033[95m<<GeometryUtilities::GetYZ>>\033[00m"
675 <<
" 2D wire position " << p1->
w <<
" [cm] exceeds max wire number "
677 <<
" Forcing it to the max wire number..." << std::endl
678 <<
"\033[93mWarning ends...\033[00m" << std::endl;
697 const double origin[3] = {0.};
698 Double_t pos[3] = {0.};
719 const double origin[3] = {0.};
749 Double_t pos[3]{0., xyz[1], xyz[2]};
767 Double_t pos[3]{0., xyz[1], xyz[2]};
782 double xyznew[3] = {(*xyz)[0], (*xyz)[1], (*xyz)[2]};
791 const double origin[3] = {0.};
805 Double_t dirs[3] = {0.};
810 Double_t wirePitch = 0.;
811 Double_t angleToVert = 0.;
820 TMath::Abs(TMath::Sin(angleToVert) * dirs[1] + TMath::Cos(angleToVert) * dirs[2]);
822 if (cosgamma < 1.
e-5)
825 std::cout <<
" returning 100" << std::endl;
829 return wirePitch / cosgamma;
836 theta *= (TMath::Pi() / 180);
837 phi *= (TMath::Pi() / 180);
838 dirs[0] = TMath::Cos(theta) * TMath::Sin(phi);
839 dirs[1] = TMath::Sin(theta);
840 dirs[2] = TMath::Cos(theta) * TMath::Cos(phi);
845 std::vector<const util::PxHit*>& hitlistlocal,
847 Double_t& linearlimit,
849 Double_t& lineslopetest)
const
853 hitlist, hitlistlocal, startHit, linearlimit, ortlimit, lineslopetest, testHit);
862 std::vector<const util::PxHit*>& hitlistlocal,
864 Double_t& linearlimit,
866 Double_t& lineslopetest,
870 hitlistlocal.clear();
871 std::vector<unsigned int> hitlistlocal_index;
873 hitlistlocal_index.clear();
876 hitlist, hitlistlocal_index, startHit, linearlimit, ortlimit, lineslopetest);
880 for (
size_t i = 0; i < hitlistlocal_index.size(); ++i) {
882 hitlistlocal.push_back((
const util::PxHit*)(&(hitlist.at(hitlistlocal_index.at(i)))));
883 timesum += hitlist.at(hitlistlocal_index.at(i)).t;
884 wiresum += hitlist.at(hitlistlocal_index.at(i)).
w;
888 if (hitlistlocal.size()) {
889 averageHit.
w = wiresum / (double)hitlistlocal.size();
890 averageHit.
t = timesum / ((double)hitlistlocal.size());
896 std::vector<unsigned int>& hitlistlocal_index,
898 Double_t& linearlimit,
900 Double_t& lineslopetest)
const
903 hitlistlocal_index.clear();
904 double locintercept = startHit.
t - startHit.
w * lineslopetest;
906 for (
size_t i = 0; i < hitlist.size(); ++i) {
919 if (lindist < linearlimit && ortdist < ortlimit) { hitlistlocal_index.push_back(i); }
928 std::vector<util::PxHit const*>& hitlistlocal)
const
932 hitlistlocal.clear();
933 unsigned char plane = hitlist.front().plane;
936 std::map<double, const util::PxHit*> hitmap;
938 for (
auto const&
h : hitlist) {
939 hitmap.try_emplace(
h.charge, &
h);
942 double qintegral = 0;
943 std::vector<const util::PxHit*> ordered_hits;
944 ordered_hits.reserve(hitlist.size());
945 for (
auto hiter = hitmap.rbegin(); qintegral < qtotal * 0.95 && hiter != hitmap.rend();
948 qintegral += (*hiter).first;
949 ordered_hits.push_back((*hiter).second);
953 std::vector<size_t> hit_index(8, 0);
954 std::vector<double> hit_distance(8, 1e9);
958 std::vector<util::PxPoint> edges(4,
PxPoint(plane, 0, 0));
962 for (
size_t index = 0; index < ordered_hits.size(); ++index) {
964 if (ordered_hits.at(index)->t < 0 || ordered_hits.at(index)->w < 0 ||
965 ordered_hits.at(index)->t > time_max || ordered_hits.at(index)->w > wire_max) {
967 throw UtilException(Form(
"Invalid wire/time (%g,%g) ... range is (0=>%g,0=>%g)",
968 ordered_hits.at(index)->w,
969 ordered_hits.at(index)->t,
977 dist = ordered_hits.at(index)->t;
978 if (dist < hit_distance.at(1)) {
979 hit_distance.at(1) =
dist;
980 hit_index.at(1) = index;
981 edges.at(0).t = ordered_hits.at(index)->t;
982 edges.at(1).t = ordered_hits.at(index)->t;
986 dist = wire_max - ordered_hits.at(index)->w;
987 if (dist < hit_distance.at(3)) {
988 hit_distance.at(3) =
dist;
989 hit_index.at(3) = index;
990 edges.at(1).w = ordered_hits.at(index)->w;
991 edges.at(2).w = ordered_hits.at(index)->w;
995 dist = time_max - ordered_hits.at(index)->t;
996 if (dist < hit_distance.at(5)) {
997 hit_distance.at(5) =
dist;
998 hit_index.at(5) = index;
999 edges.at(2).t = ordered_hits.at(index)->t;
1000 edges.at(3).t = ordered_hits.at(index)->t;
1004 dist = ordered_hits.at(index)->w;
1005 if (dist < hit_distance.at(7)) {
1006 hit_distance.at(7) =
dist;
1007 hit_index.at(7) = index;
1008 edges.at(0).w = ordered_hits.at(index)->w;
1009 edges.at(3).w = ordered_hits.at(index)->w;
1012 for (
size_t index = 0; index < ordered_hits.size(); ++index) {
1016 dist = cet::sum_of_squares(ordered_hits.at(index)->t - edges.at(0).t,
1017 ordered_hits.at(index)->w - edges.at(0).w);
1018 if (dist < hit_distance.at(0)) {
1019 hit_distance.at(0) =
dist;
1020 hit_index.at(0) = index;
1024 dist = cet::sum_of_squares(ordered_hits.at(index)->t - edges.at(1).t,
1025 ordered_hits.at(index)->w - edges.at(1).w);
1026 if (dist < hit_distance.at(2)) {
1027 hit_distance.at(2) =
dist;
1028 hit_index.at(2) = index;
1032 dist = cet::sum_of_squares(ordered_hits.at(index)->t - edges.at(2).t,
1033 ordered_hits.at(index)->w - edges.at(2).w);
1034 if (dist < hit_distance.at(4)) {
1035 hit_distance.at(4) =
dist;
1036 hit_index.at(4) = index;
1040 dist = cet::sum_of_squares(ordered_hits.at(index)->t - edges.at(3).t,
1041 ordered_hits.at(index)->w - edges.at(3).w);
1042 if (dist < hit_distance.at(6)) {
1043 hit_distance.at(6) =
dist;
1044 hit_index.at(6) = index;
1050 std::set<size_t> unique_index;
1051 std::vector<size_t> candidate_polygon;
1052 candidate_polygon.reserve(9);
1053 for (
auto& index : hit_index) {
1054 if (unique_index.find(index) == unique_index.end()) {
1055 unique_index.insert(index);
1056 candidate_polygon.push_back(index);
1059 for (
auto& index : hit_index) {
1060 candidate_polygon.push_back(index);
1064 if (unique_index.size() > 8)
throw UtilException(
"Size of the polygon > 8!");
1067 candidate_polygon =
PolyOverlap(ordered_hits, candidate_polygon);
1069 hitlistlocal.clear();
1070 for (
unsigned int i = 0; i < (candidate_polygon.size() - 1); i++) {
1071 hitlistlocal.push_back((
const util::PxHit*)(ordered_hits.at(candidate_polygon.at(i))));
1074 if (unique_index.size() > 8)
throw UtilException(
"Size of the polygon > 8!");
1079 std::vector<size_t> candidate_polygon)
const
1082 for (
unsigned int i = 0; i < (candidate_polygon.size() - 1); i++) {
1083 double Ax = ordered_hits.at(candidate_polygon.at(i))->
w;
1084 double Ay = ordered_hits.at(candidate_polygon.at(i))->t;
1085 double Bx = ordered_hits.at(candidate_polygon.at(i + 1))->
w;
1086 double By = ordered_hits.at(candidate_polygon.at(i + 1))->t;
1089 for (
unsigned int j = i + 2; j < (candidate_polygon.size() - 1); j++) {
1091 if (candidate_polygon.at(i) == candidate_polygon.at(j + 1))
1094 double Cx = ordered_hits.at(candidate_polygon.at(j))->
w;
1095 double Cy = ordered_hits.at(candidate_polygon.at(j))->t;
1096 double Dx = ordered_hits.at(candidate_polygon.at(j + 1))->
w;
1097 double Dy = ordered_hits.at(candidate_polygon.at(j + 1))->t;
1099 if ((
Clockwise(Ax, Ay, Cx, Cy, Dx, Dy) !=
Clockwise(Bx, By, Cx, Cy, Dx, Dy))
and
1100 (
Clockwise(Ax, Ay, Bx, By, Cx, Cy) !=
Clockwise(Ax, Ay, Bx, By, Dx, Dy))) {
1101 size_t tmp = candidate_polygon.at(i + 1);
1102 candidate_polygon.at(i + 1) = candidate_polygon.at(j);
1103 candidate_polygon.at(j) = tmp;
1105 candidate_polygon.at(candidate_polygon.size() - 1) = candidate_polygon.at(0);
1107 return PolyOverlap(ordered_hits, candidate_polygon);
1112 return candidate_polygon;
1121 double const Cy)
const
1123 return (Cy - Ay) * (Bx - Ax) > (By - Ay) * (Cx - Ax);
1128 unsigned int const wirein,
1129 double const timein)
const
1136 unsigned int const wirein,
1137 double const timein)
const
1139 double min_length_from_start = 99999;
1140 unsigned int ret_ind = 0;
1142 for (
unsigned int ii = 0; ii < hitlist.size(); ii++) {
1145 if (dist_mod < min_length_from_start) {
1146 min_length_from_start = dist_mod;
process_name opflash particleana ie ie ie z
std::vector< Double_t > vertangle
detinfo::DetectorClocksData const & fClocks
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
Double_t Get2DDistance(Double_t wire1, Double_t time1, Double_t wire2, Double_t time2) const
process_name opflash particleana ie x
std::vector< size_t > PolyOverlap(std::vector< const util::PxHit * > ordered_hits, std::vector< size_t > candidate_polygon) const
Class def header for exception classes used in GeometryUtilities.
Double_t Get2Dangle(Double_t deltawire, Double_t deltatime) const
bool ChannelsIntersect(raw::ChannelID_t c1, raw::ChannelID_t c2, double &y, double &z) const
Returns an intersection point of two channels.
util::PxHit FindClosestHit(std::vector< util::PxHit > const &hitlist, unsigned int wirein, double timein) const
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
Double_t PitchInView(UInt_t plane, Double_t phi, Double_t theta) const
detinfo::DetectorPropertiesData const & fDetProp
3-dimensional objects, potentially hits, clusters, prongs, etc.
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Double_t Get2DPitchDistance(Double_t angle, Double_t inwire, Double_t wire) const
Access the description of detector geometry.
View_t View() const
Which coordinate does this plane measure.
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
process_name opflash particleana ie ie y
geo::WireID::WireID_t NearestWire(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the index of wire closest to position in the specified TPC.
geo::GeometryCore const & fGeom
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
unsigned int NumberTimeSamples() const
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
Double_t Get3DSpecialCaseTheta(Int_t iplane0, Int_t iplane1, Double_t dw0, Double_t dw1) const
Double_t GetTimeTicks(Double_t x, Int_t plane) const
void SelectLocalHitlistIndex(const std::vector< util::PxHit > &hitlist, std::vector< unsigned int > &hitlistlocal_index, util::PxPoint &startHit, Double_t &linearlimit, Double_t &ortlimit, Double_t &lineslopetest) const
Description of geometry of one entire detector.
Encapsulate the geometry of a wire.
Int_t GetPointOnLine(Double_t slope, Double_t intercept, Double_t wire1, Double_t time1, Double_t &wireout, Double_t &timeout) const
bool Clockwise(double Ax, double Ay, double Bx, double By, double Cx, double Cy) const
Double_t Get2DPitchDistanceWSlope(Double_t slope, Double_t inwire, Double_t wire) const
Int_t GetYZ(const PxPoint *p0, const PxPoint *p1, Double_t *yz) const
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
Encapsulate the construction of a single detector plane.
Contains all timing reference information for the detector.
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
Var Sqrt(const Var &v)
Use to take sqrt of a var.
double Get2DangleFrom3D(unsigned int plane, double phi, double theta) const
GeometryUtilities(geo::GeometryCore const &geom, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &propData)
Int_t GetProjectedPoint(const PxPoint *p0, const PxPoint *p1, PxPoint &pN) const
void GetDirectionCosines(Double_t phi, Double_t theta, Double_t *dirs) const
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
PxPoint Get2DPointProjection(Double_t *xyz, Int_t plane) const
int trigger_offset(DetectorClocksData const &data)
finds tracks best matching by angle
constexpr double kINVALID_DOUBLE
unsigned int FindClosestHitIndex(std::vector< util::PxHit > const &hitlist, unsigned int wirein, double timein) const
PxPoint Get2DPointProjectionCM(std::vector< double > xyz, int plane) const
Double_t CalculatePitch(UInt_t iplane0, Double_t phi, Double_t theta) const
void SelectPolygonHitList(const std::vector< util::PxHit > &hitlist, std::vector< const util::PxHit * > &hitlistlocal) const
Int_t GetPointOnLineWSlopes(Double_t slope, Double_t intercept, Double_t ort_intercept, Double_t &wireout, Double_t &timeout) const
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
Double_t Get2Dslope(Double_t deltawire, Double_t deltatime) const
Int_t GetXYZ(const PxPoint *p0, const PxPoint *p1, Double_t *xyz) const
Int_t Get3DaxisN(Int_t iplane0, Int_t iplane1, Double_t omega0, Double_t omega1, Double_t &phi, Double_t &theta) const
void LocalToWorld(const double *plane, double *world) const
Transform point from local plane frame to world frame.
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
physics associatedGroupsWithLeft p1
BEGIN_PROLOG could also be cout
constexpr Point origin()
Returns a origin position with a point of the specified type.
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
void SelectLocalHitlist(const std::vector< util::PxHit > &hitlist, std::vector< const util::PxHit * > &hitlistlocal, util::PxPoint &startHit, Double_t &linearlimit, Double_t &ortlimit, Double_t &lineslopetest) const
Double_t CalculatePitchPolar(UInt_t iplane0, Double_t phi, Double_t theta) const