20 #include "TLorentzVector.h" 33 for (UInt_t ip = 0; ip <
fNPlanes; ip++)
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)
151 phis = asin(ln / TMath::Sqrt(ln * ln + nn * nn));
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();
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.;
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.;
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);
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 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.};
642 std::cout <<
"\033[93mWarning\033[00m " 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;
652 std::cout <<
"\033[93mWarning\033[00m " 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;
662 std::cout <<
"\033[93mWarning\033[00m " 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;
672 std::cout <<
"\033[93mWarning\033[00m " 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));
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;
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;
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;
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;
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;
std::vector< Double_t > vertangle
detinfo::DetectorClocksData const & fClocks
Namespace for general, non-LArSoft-specific utilities.
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
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.
WireGeo const & Wire(unsigned int iwire) const
Double_t Get2Dangle(Double_t deltawire, Double_t deltatime) const
constexpr T sum_of_squares(T x, T y)
double Temperature() const
In kelvin.
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
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double ThetaZ() const
Returns angle of wire with respect to z axis in the Y-Z plane in radians.
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.
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
Double_t PitchInView(UInt_t plane, Double_t phi, Double_t theta) const
double Efield(unsigned int planegap=0) const
kV/cm
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
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.
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
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
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
Description of geometry of one entire detector.
Detector simulation of raw signals on wires.
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)
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)
Access the description of detector geometry.
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.
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.
QTextStream & endl(QTextStream &s)
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