22 inline T
sqr(T v) {
return v*v; }
25 inline T sum_sqr(T a, T b) {
return sqr(a) +
sqr(b); }
38 geom = lar::providerFrom<geo::Geometry>();
39 detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
86 Double_t &theta)
const 93 Double_t ln(0),mn(0),nn(0);
94 Double_t phis(0),thetan(0);
99 UInt_t Cplane=0,Iplane=1;
103 Double_t angleC,angleI,slopeC,slopeI,omegaC,omegaI;
109 if(omega0==0 || omega1==0){
119 Double_t alt_backwards=0;
128 if(fabs(omega0)>(TMath::Pi()/2.0) || fabs(omega1)>(TMath::Pi()/2.0) ) {
185 if(omegaC < TMath::Pi() && omegaC > 0 )
191 mn = (ln/(2*sin(angleI)))*((cos(angleI)/(slopeC*cos(angleC)))-(1/slopeI)
192 +nfact*( cos(angleI)/(cos(angleC)*slopeC)-1/slopeI ) );
194 nn = (ln/(2*cos(angleC)))*((1/slopeC)+(1/slopeI) +nfact*((1/slopeC)-(1/slopeI)));
205 if(fabs(omegaC)>0.01)
208 phis=asin(ln/TMath::Sqrt(ln*ln+nn*nn));
210 if(fabs(slopeC+slopeI) < 0.001)
212 else if( fabs(omegaI)>0.01 && (omegaI/fabs(omegaI) == -omegaC/fabs(omegaC) )
213 && ( fabs(omegaC) < 1*TMath::Pi()/180 || fabs(omegaC) > 179*TMath::Pi()/180 ) )
214 phis = (fabs(omegaC) > TMath::Pi()/2) ? TMath::Pi() : 0;
217 if(nn<0 && phis>0 && !(!alt_backwards && fabs(phis)<TMath::Pi()/4 ) )
218 phis=(TMath::Pi())-phis;
219 else if(nn<0 && phis<0 && !(!alt_backwards && fabs(phis)<TMath::Pi()/4 ) )
220 phis=(-TMath::Pi())-phis;
223 phi=phis*180/TMath::Pi();
250 thetan = -asin ( mn / (sqrt(pow(ln,2)+pow(mn,2)+pow(nn,2)) ) ) ;
251 theta=thetan*180/TMath::Pi();
284 Double_t splane,lplane;
307 Double_t tantheta=top/bottom;
318 Double_t theta)
const 321 Double_t pitch = -1.;
326 Form(
"Warning : no Pitch foreseen for view %d",
geom->
Plane(iplane).
View()));
331 Double_t
pi=TMath::Pi();
333 Double_t fTheta=pi/2-theta;
335 Double_t fPhi=-(phi+pi/2);
356 Double_t cosgamma = TMath::Abs(TMath::Sin(angleToVert)*TMath::Cos(fTheta)
357 +TMath::Cos(angleToVert)*TMath::Sin(fTheta)*TMath::Sin(fPhi));
359 if (cosgamma>0) pitch = wirePitch/cosgamma;
375 Double_t theta)
const 378 Double_t pitch = -1.;
383 Form(
"Warning : no Pitch foreseen for view %d",
geom->
Plane(iplane).
View()));
388 Double_t fTheta=theta;
408 Double_t cosgamma = TMath::Abs(TMath::Sin(angleToVert)*TMath::Cos(fTheta)
409 +TMath::Cos(angleToVert)*TMath::Sin(fTheta)*TMath::Sin(fPhi));
411 if (cosgamma>0) pitch = wirePitch/cosgamma;
429 Double_t timestart)
const 443 return Get2Dslope(endpoint->
w - startpoint->
w,endpoint->
t - startpoint->
t);
453 Double_t dtime)
const 470 Double_t timestart)
const 484 return Get2Dangle(endpoint->
w - startpoint->
w, endpoint->
t - startpoint->
t);
493 Double_t dtime)
const 500 BC = ((Double_t)dwire);
501 AC = ((Double_t)dtime);
502 omega = std::asin( AC/std::sqrt(pow(AC,2)+pow(BC,2)) );
506 omega= TMath::Pi()-std::abs(omega);
509 omega=-TMath::Pi()+std::abs(omega);
525 TVector3 dummyvector(cos(theta*TMath::Pi()/180.)*sin(phi*TMath::Pi()/180.) ,sin(theta*TMath::Pi()/180.) , cos(theta*TMath::Pi()/180.)*cos(phi*TMath::Pi()/180.));
544 TVector3
end=start+dir_vector;
570 Double_t time2)
const 581 return TMath::Sqrt(sum_sqr(point1->
w - point2->
w, point1->
t - point2->
t));
593 Double_t radangle = TMath::Pi()*angle/180;
594 if(std::cos(radangle)==0)
596 return std::abs((wire-inwire)/std::cos(radangle))*
fWiretoCm;
606 return std::abs(wire-inwire)*TMath::Sqrt(1+slope*slope)*
fWiretoCm;
622 Double_t &timeout)
const 631 Double_t ort_intercept=time1-invslope*(Double_t)wire1;
633 if((slope-invslope)!=0)
634 wireout=(ort_intercept - intercept)/(slope-invslope);
637 timeout=slope*wireout+intercept;
652 double intercept=startpoint->
t - slope * startpoint->
w;
677 double ort_intercept=point1->
t - invslope * point1->
w;
679 if((slope-invslope)!=0)
680 pointout.
w = (ort_intercept - intercept)/(slope-invslope);
682 pointout.
w = point1->
w;
684 pointout.
t = slope * pointout.
w + intercept;
699 Double_t &timeout)
const 701 Double_t intercept=timestart-slope*(Double_t)wirestart;
703 return GetPointOnLine(slope,intercept,wire1,time1,wireout,timeout);
712 Double_t ort_intercept,
714 Double_t &timeout)
const 725 wireout=(ort_intercept - intercept)/(slope-invslope);
726 timeout=slope*wireout+intercept;
742 double ort_intercept,
753 pointonline.
w = (ort_intercept - intercept)/(slope-invslope);
754 pointonline.
t = slope * pointonline.
w + intercept;
803 for(UInt_t i = 0; i <
fNPlanes; ++i){
813 const double origin[3] = {0.};
814 Double_t pos[3]={0.};
844 std::cout <<
"\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
845 <<
" 2D wire position " << p0->
w <<
" [cm] corresponds to negative wire number." << std::endl
846 <<
" Forcing it to wire=0..." << std::endl
847 <<
"\033[93mWarning ends...\033[00m"<<std::endl;
851 std::cout <<
"\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
852 <<
" 2D wire position " << p0->
w <<
" [cm] exceeds max wire number " << (
geom->
Nwires(p0->
plane)-1) <<std::endl
853 <<
" Forcing it to the max wire number..." << std::endl
854 <<
"\033[93mWarning ends...\033[00m"<<std::endl;
858 std::cout <<
"\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
859 <<
" 2D wire position " << p1->
w <<
" [cm] corresponds to negative wire number." << std::endl
860 <<
" Forcing it to wire=0..." << std::endl
861 <<
"\033[93mWarning ends...\033[00m"<<std::endl;
865 std::cout <<
"\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
866 <<
" 2D wire position " << p1->
w <<
" [cm] exceeds max wire number " << (
geom->
Nwires(p0->
plane)-1) <<std::endl
867 <<
" Forcing it to the max wire number..." << std::endl
868 <<
"\033[93mWarning ends...\033[00m"<<std::endl;
892 const double origin[3] = {0.};
893 Double_t pos[3]={0.};
915 const double origin[3] = {0.};
945 Double_t pos[3]{0., xyz[1], xyz[2]};
962 Double_t pos[3]{0., xyz[1], xyz[2]};
977 double xyznew[3]={(*xyz)[0],(*xyz)[1],(*xyz)[2]};
987 const double origin[3] = {0.};
1005 Double_t theta)
const 1007 Double_t dirs[3] = {0.};
1012 Double_t wirePitch = 0.;
1013 Double_t angleToVert = 0.;
1020 Double_t cosgamma = TMath::Abs(TMath::Sin(angleToVert)*dirs[1] +
1021 TMath::Cos(angleToVert)*dirs[2]);
1027 if(cosgamma < 1.
e-5)
1029 {std::cout <<
" returning 100" << std::endl;
1035 return wirePitch/cosgamma;
1042 Double_t *dirs)
const 1044 theta*=(TMath::Pi()/180);
1045 phi*=(TMath::Pi()/180);
1046 dirs[0]=TMath::Cos(theta)*TMath::Sin(phi);
1047 dirs[1]=TMath::Sin(theta);
1048 dirs[2]=TMath::Cos(theta)*TMath::Cos(phi);
1054 std::vector <const util::PxHit*> &hitlistlocal,
1056 Double_t& linearlimit,
1058 Double_t& lineslopetest)
1061 SelectLocalHitlist(hitlist, hitlistlocal, startHit, linearlimit, ortlimit, lineslopetest, testHit);
1071 std::vector <const util::PxHit*> &hitlistlocal,
1073 Double_t& linearlimit,
1075 Double_t& lineslopetest,
1079 hitlistlocal.clear();
1080 std::vector< unsigned int > hitlistlocal_index;
1082 hitlistlocal_index.clear();
1088 for(
size_t i=0; i<hitlistlocal_index.size(); ++i) {
1090 hitlistlocal.push_back((
const util::PxHit*)(&(hitlist.at(hitlistlocal_index.at(i)))));
1091 timesum += hitlist.at(hitlistlocal_index.at(i)).t;
1092 wiresum += hitlist.at(hitlistlocal_index.at(i)).
w;
1099 if(hitlistlocal.size())
1101 averageHit.
w = wiresum/(double)hitlistlocal.size();
1102 averageHit.
t = timesum/((double) hitlistlocal.size());
1108 std::vector <unsigned int> &hitlistlocal_index,
1110 Double_t& linearlimit,
1112 Double_t& lineslopetest)
1115 hitlistlocal_index.clear();
1116 double locintercept=startHit.
t - startHit.
w * lineslopetest;
1119 for(
size_t i=0; i<hitlist.size(); ++i) {
1131 if(lindist<linearlimit && ortdist<ortlimit){
1132 hitlistlocal_index.push_back(i);
1151 std::vector <const util::PxHit*> &hitlistlocal)
1153 if(!(hitlist.size())) {
1158 hitlistlocal.clear();
1159 unsigned char plane = (*hitlist.begin()).plane;
1162 std::map<double,const util::PxHit*> hitmap;
1164 for(
auto const &h : hitlist){
1166 hitmap.insert(std::pair<double,const util::PxHit*>(h.charge,&h));
1171 std::vector<const util::PxHit*> ordered_hits;
1172 ordered_hits.reserve(hitlist.size());
1173 for(
auto hiter = hitmap.rbegin();
1174 qintegral < qtotal*0.95 && hiter != hitmap.rend();
1177 qintegral += (*hiter).first;
1178 ordered_hits.push_back((*hiter).second);
1183 std::vector<size_t> hit_index(8,0);
1184 std::vector<double> hit_distance(8,1e9);
1188 std::vector<util::PxPoint> edges(4,
PxPoint(plane,0,0));
1192 for(
size_t index = 0; index<ordered_hits.size(); ++index) {
1194 if(ordered_hits.at(index)->t < 0 ||
1195 ordered_hits.at(index)->w < 0 ||
1196 ordered_hits.at(index)->t > time_max ||
1197 ordered_hits.at(index)->w > wire_max ) {
1199 throw UtilException(Form(
"Invalid wire/time (%g,%g) ... range is (0=>%g,0=>%g)",
1200 ordered_hits.at(index)->w,
1201 ordered_hits.at(index)->t,
1211 dist = ordered_hits.at(index)->t;
1212 if(dist < hit_distance.at(1)) {
1213 hit_distance.at(1) = dist;
1214 hit_index.at(1) = index;
1215 edges.at(0).t = ordered_hits.at(index)->t;
1216 edges.at(1).t = ordered_hits.at(index)->t;
1220 dist = wire_max - ordered_hits.at(index)->w;
1221 if(dist < hit_distance.at(3)) {
1222 hit_distance.at(3) = dist;
1223 hit_index.at(3) = index;
1224 edges.at(1).w = ordered_hits.at(index)->w;
1225 edges.at(2).w = ordered_hits.at(index)->w;
1229 dist = time_max - ordered_hits.at(index)->t;
1230 if(dist < hit_distance.at(5)) {
1231 hit_distance.at(5) = dist;
1232 hit_index.at(5) = index;
1233 edges.at(2).t = ordered_hits.at(index)->t;
1234 edges.at(3).t = ordered_hits.at(index)->t;
1238 dist = ordered_hits.at(index)->w;
1239 if(dist < hit_distance.at(7)) {
1240 hit_distance.at(7) = dist;
1241 hit_index.at(7) = index;
1242 edges.at(0).w = ordered_hits.at(index)->w;
1243 edges.at(3).w = ordered_hits.at(index)->w;
1255 for(
size_t index = 0; index<ordered_hits.size(); ++index) {
1259 dist = pow((ordered_hits.at(index)->t - edges.at(0).t),2) + pow((ordered_hits.at(index)->w - edges.at(0).w),2);
1260 if(dist < hit_distance.at(0)) {
1261 hit_distance.at(0) = dist;
1262 hit_index.at(0) = index;
1266 dist = pow((ordered_hits.at(index)->t - edges.at(1).t),2) + pow((ordered_hits.at(index)->w - edges.at(1).w),2);
1267 if(dist < hit_distance.at(2)) {
1268 hit_distance.at(2) = dist;
1269 hit_index.at(2) = index;
1273 dist = pow((ordered_hits.at(index)->t - edges.at(2).t),2) + pow((ordered_hits.at(index)->w - edges.at(2).w),2);
1274 if(dist < hit_distance.at(4)) {
1275 hit_distance.at(4) = dist;
1276 hit_index.at(4) = index;
1280 dist = pow((ordered_hits.at(index)->t - edges.at(3).t),2) + pow((ordered_hits.at(index)->w - edges.at(3).w),2);
1281 if(dist < hit_distance.at(6)) {
1282 hit_distance.at(6) = dist;
1283 hit_index.at(6) = index;
1289 std::set<size_t> unique_index;
1290 std::vector<size_t> candidate_polygon;
1291 candidate_polygon.reserve(9);
1293 for(
auto &index : hit_index) {
1295 if(unique_index.find(index) == unique_index.end()) {
1298 unique_index.insert(index);
1299 candidate_polygon.push_back(index);
1302 for (
auto &index: hit_index){
1303 candidate_polygon.push_back(index);
1307 if(unique_index.size()>8)
throw UtilException(
"Size of the polygon > 8!");
1310 candidate_polygon =
PolyOverlap( ordered_hits, candidate_polygon);
1312 hitlistlocal.clear();
1313 for(
unsigned int i=0; i<(candidate_polygon.size()-1); i++){
1314 hitlistlocal.push_back((
const util::PxHit*)(ordered_hits.at(candidate_polygon.at(i))));
1317 if(unique_index.size()>8)
throw UtilException(
"Size of the polygon > 8!");
1322 std::vector<size_t> candidate_polygon) {
1325 for (
unsigned int i=0; i<(candidate_polygon.size()-1); i++){
1326 double Ax = ordered_hits.at(candidate_polygon.at(i))->
w;
1327 double Ay = ordered_hits.at(candidate_polygon.at(i))->t;
1328 double Bx = ordered_hits.at(candidate_polygon.at(i+1))->
w;
1329 double By = ordered_hits.at(candidate_polygon.at(i+1))->t;
1332 for (
unsigned int j=i+2; j<(candidate_polygon.size()-1); j++){
1334 if ( candidate_polygon.at(i) == candidate_polygon.at(j+1) )
1337 double Cx = ordered_hits.at(candidate_polygon.at(j))->
w;
1338 double Cy = ordered_hits.at(candidate_polygon.at(j))->t;
1339 double Dx = ordered_hits.at(candidate_polygon.at(j+1))->
w;
1340 double Dy = ordered_hits.at(candidate_polygon.at(j+1))->t;
1342 if ( (
Clockwise(Ax,Ay,Cx,Cy,Dx,Dy) !=
Clockwise(Bx,By,Cx,Cy,Dx,Dy))
1343 and (
Clockwise(Ax,Ay,Bx,By,Cx,Cy) !=
Clockwise(Ax,Ay,Bx,By,Dx,Dy)) ){
1344 size_t tmp = candidate_polygon.at(i+1);
1345 candidate_polygon.at(i+1) = candidate_polygon.at(j);
1346 candidate_polygon.at(j) =
tmp;
1348 candidate_polygon.at(candidate_polygon.size()-1) = candidate_polygon.at(0);
1350 return PolyOverlap( ordered_hits, candidate_polygon);
1356 return candidate_polygon;
1360 return (Cy-Ay)*(Bx-Ax) > (By-Ay)*(Cx-Ax);
1402 unsigned int wirein,
1403 double timein)
const 1413 unsigned int wirein,
1414 double timein)
const 1416 double min_length_from_start=99999;
1421 unsigned int ret_ind=0;
1423 for(
unsigned int ii=0; ii<hitlist.size();ii++){
1431 if(dist_mod<min_length_from_start){
1434 nearHit=(hitlist[ii]);
1435 min_length_from_start=dist_mod;
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.
Encapsulate the construction of a single cyostat.
virtual int TriggerOffset() const =0
Double_t Get2DDistance(Double_t wire1, Double_t time1, Double_t wire2, Double_t time2) const
WireGeo const & Wire(unsigned int iwire) const
bool Clockwise(double Ax, double Ay, double Bx, double By, double Cx, double Cy)
Double_t Get2Dangle(Double_t deltawire, Double_t deltatime) const
static GeometryUtilities * _me
bool ChannelsIntersect(raw::ChannelID_t c1, raw::ChannelID_t c2, double &y, double &z) const
Returns an intersection point of two channels.
virtual double SamplingRate() const =0
Returns the period of the TPC readout electronics clock.
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.
Double_t PitchInView(UInt_t plane, Double_t phi, Double_t theta) const
3-dimensional objects, potentially hits, clusters, prongs, etc.
Double_t Get2DPitchDistance(Double_t angle, Double_t inwire, Double_t wire) const
const detinfo::DetectorProperties * detp
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.
virtual double Temperature() const =0
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::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
virtual unsigned int NumberTimeSamples() const =0
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)
~GeometryUtilities()
Default destructor.
std::vector< Double_t > vertangle
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
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)
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.
GeometryUtilities()
Default constructor = private for singleton.
const geo::GeometryCore * geom
Encapsulate the construction of a single detector plane.
util::PxHit FindClosestHit(std::vector< util::PxHit > hitlist, unsigned int wirein, double timein) const
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
double Get2DangleFrom3D(unsigned int plane, double phi, double theta) const
Int_t GetProjectedPoint(const PxPoint *p0, const PxPoint *p1, PxPoint &pN) const
void GetDirectionCosines(Double_t phi, Double_t theta, Double_t *dirs) const
const double kINVALID_DOUBLE
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
PxPoint Get2DPointProjection(Double_t *xyz, Int_t plane) const
std::vector< evd::details::RawDigitInfo_t >::const_iterator end(RawDigitCacheDataClass const &cache)
PxPoint Get2DPointProjectionCM(std::vector< double > xyz, int plane) const
Double_t CalculatePitch(UInt_t iplane0, Double_t phi, Double_t theta) const
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
Int_t GetPointOnLineWSlopes(Double_t slope, Double_t intercept, Double_t ort_intercept, Double_t &wireout, Double_t &timeout) const
std::vector< size_t > PolyOverlap(std::vector< const util::PxHit * > ordered_hits, std::vector< size_t > candidate_polygon)
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 SelectPolygonHitList(const std::vector< util::PxHit > &hitlist, std::vector< const util::PxHit * > &hitlistlocal)
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.
Encapsulate the construction of a single detector plane.
Double_t CalculatePitchPolar(UInt_t iplane0, Double_t phi, Double_t theta) const
unsigned int FindClosestHitIndex(std::vector< util::PxHit > hitlist, unsigned int wirein, double timein) const