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.};
845 std::cout <<
"\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
846 <<
" 2D wire position " << p0->
w <<
" [cm] corresponds to negative wire number." << std::endl
847 <<
" Forcing it to wire=0..." << std::endl
848 <<
"\033[93mWarning ends...\033[00m"<<std::endl;
852 std::cout <<
"\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
853 <<
" 2D wire position " << p0->
w <<
" [cm] exceeds max wire number " << (
geom->
Nwires(p0->
plane)-1) <<std::endl
854 <<
" Forcing it to the max wire number..." << std::endl
855 <<
"\033[93mWarning ends...\033[00m"<<std::endl;
859 std::cout <<
"\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
860 <<
" 2D wire position " << p1->
w <<
" [cm] corresponds to negative wire number." << std::endl
861 <<
" Forcing it to wire=0..." << std::endl
862 <<
"\033[93mWarning ends...\033[00m"<<std::endl;
866 std::cout <<
"\033[93mWarning\033[00m \033[95m<<GeometryUtilities::GetYZ>>\033[00m" << std::endl
867 <<
" 2D wire position " << p1->
w <<
" [cm] exceeds max wire number " << (
geom->
Nwires(p0->
plane)-1) <<std::endl
868 <<
" Forcing it to the max wire number..." << std::endl
869 <<
"\033[93mWarning ends...\033[00m"<<std::endl;
893 const double origin[3] = {0.};
894 Double_t pos[3]={0.};
916 const double origin[3] = {0.};
986 double xyznew[3]={(*xyz)[0],(*xyz)[1],(*xyz)[2]};
996 const double origin[3] = {0.};
1014 Double_t theta)
const 1016 Double_t dirs[3] = {0.};
1021 Double_t wirePitch = 0.;
1022 Double_t angleToVert = 0.;
1029 Double_t cosgamma = TMath::Abs(TMath::Sin(angleToVert)*dirs[1] +
1030 TMath::Cos(angleToVert)*dirs[2]);
1036 if(cosgamma < 1.
e-5)
1038 {std::cout <<
" returning 100" << std::endl;
1044 return wirePitch/cosgamma;
1051 Double_t *dirs)
const 1053 theta*=(TMath::Pi()/180);
1054 phi*=(TMath::Pi()/180);
1055 dirs[0]=TMath::Cos(theta)*TMath::Sin(phi);
1056 dirs[1]=TMath::Sin(theta);
1057 dirs[2]=TMath::Cos(theta)*TMath::Cos(phi);
1063 std::vector <const util::PxHit*> &hitlistlocal,
1065 Double_t& linearlimit,
1067 Double_t& lineslopetest)
1070 SelectLocalHitlist(hitlist, hitlistlocal, startHit, linearlimit, ortlimit, lineslopetest, testHit);
1080 std::vector <const util::PxHit*> &hitlistlocal,
1082 Double_t& linearlimit,
1084 Double_t& lineslopetest,
1088 hitlistlocal.clear();
1089 std::vector< unsigned int > hitlistlocal_index;
1091 hitlistlocal_index.clear();
1097 for(
size_t i=0; i<hitlistlocal_index.size(); ++i) {
1099 hitlistlocal.push_back((
const util::PxHit*)(&(hitlist.at(hitlistlocal_index.at(i)))));
1100 timesum += hitlist.at(hitlistlocal_index.at(i)).t;
1101 wiresum += hitlist.at(hitlistlocal_index.at(i)).
w;
1108 if(hitlistlocal.size())
1110 averageHit.
w = wiresum/(double)hitlistlocal.size();
1111 averageHit.
t = timesum/((double) hitlistlocal.size());
1117 std::vector <unsigned int> &hitlistlocal_index,
1119 Double_t& linearlimit,
1121 Double_t& lineslopetest)
1124 hitlistlocal_index.clear();
1125 double locintercept=startHit.
t - startHit.
w * lineslopetest;
1128 for(
size_t i=0; i<hitlist.size(); ++i) {
1140 if(lindist<linearlimit && ortdist<ortlimit){
1141 hitlistlocal_index.push_back(i);
1160 std::vector <const util::PxHit*> &hitlistlocal)
1162 if(!(hitlist.size())) {
1167 hitlistlocal.clear();
1168 unsigned char plane = (*hitlist.begin()).plane;
1171 std::map<double,const util::PxHit*> hitmap;
1173 for(
auto const &h : hitlist){
1175 hitmap.insert(std::pair<double,const util::PxHit*>(h.charge,&h));
1180 std::vector<const util::PxHit*> ordered_hits;
1181 ordered_hits.reserve(hitlist.size());
1182 for(
auto hiter = hitmap.rbegin();
1183 qintegral < qtotal*0.95 && hiter != hitmap.rend();
1186 qintegral += (*hiter).first;
1187 ordered_hits.push_back((*hiter).second);
1192 std::vector<size_t> hit_index(8,0);
1193 std::vector<double> hit_distance(8,1e9);
1197 std::vector<util::PxPoint> edges(4,
PxPoint(plane,0,0));
1201 for(
size_t index = 0; index<ordered_hits.size(); ++index) {
1203 if(ordered_hits.at(index)->t < 0 ||
1204 ordered_hits.at(index)->w < 0 ||
1205 ordered_hits.at(index)->t > time_max ||
1206 ordered_hits.at(index)->w > wire_max ) {
1208 throw UtilException(Form(
"Invalid wire/time (%g,%g) ... range is (0=>%g,0=>%g)",
1209 ordered_hits.at(index)->w,
1210 ordered_hits.at(index)->t,
1220 dist = ordered_hits.at(index)->t;
1221 if(dist < hit_distance.at(1)) {
1222 hit_distance.at(1) = dist;
1223 hit_index.at(1) = index;
1224 edges.at(0).t = ordered_hits.at(index)->t;
1225 edges.at(1).t = ordered_hits.at(index)->t;
1229 dist = wire_max - ordered_hits.at(index)->w;
1230 if(dist < hit_distance.at(3)) {
1231 hit_distance.at(3) = dist;
1232 hit_index.at(3) = index;
1233 edges.at(1).w = ordered_hits.at(index)->w;
1234 edges.at(2).w = ordered_hits.at(index)->w;
1238 dist = time_max - ordered_hits.at(index)->t;
1239 if(dist < hit_distance.at(5)) {
1240 hit_distance.at(5) = dist;
1241 hit_index.at(5) = index;
1242 edges.at(2).t = ordered_hits.at(index)->t;
1243 edges.at(3).t = ordered_hits.at(index)->t;
1247 dist = ordered_hits.at(index)->w;
1248 if(dist < hit_distance.at(7)) {
1249 hit_distance.at(7) = dist;
1250 hit_index.at(7) = index;
1251 edges.at(0).w = ordered_hits.at(index)->w;
1252 edges.at(3).w = ordered_hits.at(index)->w;
1264 for(
size_t index = 0; index<ordered_hits.size(); ++index) {
1268 dist = pow((ordered_hits.at(index)->t - edges.at(0).t),2) + pow((ordered_hits.at(index)->w - edges.at(0).w),2);
1269 if(dist < hit_distance.at(0)) {
1270 hit_distance.at(0) = dist;
1271 hit_index.at(0) = index;
1275 dist = pow((ordered_hits.at(index)->t - edges.at(1).t),2) + pow((ordered_hits.at(index)->w - edges.at(1).w),2);
1276 if(dist < hit_distance.at(2)) {
1277 hit_distance.at(2) = dist;
1278 hit_index.at(2) = index;
1282 dist = pow((ordered_hits.at(index)->t - edges.at(2).t),2) + pow((ordered_hits.at(index)->w - edges.at(2).w),2);
1283 if(dist < hit_distance.at(4)) {
1284 hit_distance.at(4) = dist;
1285 hit_index.at(4) = index;
1289 dist = pow((ordered_hits.at(index)->t - edges.at(3).t),2) + pow((ordered_hits.at(index)->w - edges.at(3).w),2);
1290 if(dist < hit_distance.at(6)) {
1291 hit_distance.at(6) = dist;
1292 hit_index.at(6) = index;
1298 std::set<size_t> unique_index;
1299 std::vector<size_t> candidate_polygon;
1300 candidate_polygon.reserve(9);
1302 for(
auto &index : hit_index) {
1304 if(unique_index.find(index) == unique_index.end()) {
1307 unique_index.insert(index);
1308 candidate_polygon.push_back(index);
1311 for (
auto &index: hit_index){
1312 candidate_polygon.push_back(index);
1316 if(unique_index.size()>8)
throw UtilException(
"Size of the polygon > 8!");
1319 candidate_polygon =
PolyOverlap( ordered_hits, candidate_polygon);
1321 hitlistlocal.clear();
1322 for(
unsigned int i=0; i<(candidate_polygon.size()-1); i++){
1323 hitlistlocal.push_back((
const util::PxHit*)(ordered_hits.at(candidate_polygon.at(i))));
1326 if(unique_index.size()>8)
throw UtilException(
"Size of the polygon > 8!");
1331 std::vector<size_t> candidate_polygon) {
1334 for (
unsigned int i=0; i<(candidate_polygon.size()-1); i++){
1335 double Ax = ordered_hits.at(candidate_polygon.at(i))->
w;
1336 double Ay = ordered_hits.at(candidate_polygon.at(i))->t;
1337 double Bx = ordered_hits.at(candidate_polygon.at(i+1))->
w;
1338 double By = ordered_hits.at(candidate_polygon.at(i+1))->t;
1341 for (
unsigned int j=i+2; j<(candidate_polygon.size()-1); j++){
1343 if ( candidate_polygon.at(i) == candidate_polygon.at(j+1) )
1346 double Cx = ordered_hits.at(candidate_polygon.at(j))->
w;
1347 double Cy = ordered_hits.at(candidate_polygon.at(j))->t;
1348 double Dx = ordered_hits.at(candidate_polygon.at(j+1))->
w;
1349 double Dy = ordered_hits.at(candidate_polygon.at(j+1))->t;
1351 if ( (
Clockwise(Ax,Ay,Cx,Cy,Dx,Dy) !=
Clockwise(Bx,By,Cx,Cy,Dx,Dy))
1352 and (
Clockwise(Ax,Ay,Bx,By,Cx,Cy) !=
Clockwise(Ax,Ay,Bx,By,Dx,Dy)) ){
1353 size_t tmp = candidate_polygon.at(i+1);
1354 candidate_polygon.at(i+1) = candidate_polygon.at(j);
1355 candidate_polygon.at(j) =
tmp;
1357 candidate_polygon.at(candidate_polygon.size()-1) = candidate_polygon.at(0);
1359 return PolyOverlap( ordered_hits, candidate_polygon);
1365 return candidate_polygon;
1369 return (Cy-Ay)*(Bx-Ax) > (By-Ay)*(Cx-Ax);
1411 unsigned int wirein,
1412 double timein)
const 1422 unsigned int wirein,
1423 double timein)
const 1425 double min_length_from_start=99999;
1430 unsigned int ret_ind=0;
1432 for(
unsigned int ii=0; ii<hitlist.size();ii++){
1440 if(dist_mod<min_length_from_start){
1443 nearHit=(hitlist[ii]);
1444 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