Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:18:21

0001 /* Copyright 2008-2010, Technische Universitaet Muenchen,
0002    Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch
0003 
0004    This file is part of GENFIT.
0005 
0006    GENFIT is free software: you can redistribute it and/or modify
0007    it under the terms of the GNU Lesser General Public License as published
0008    by the Free Software Foundation, either version 3 of the License, or
0009    (at your option) any later version.
0010 
0011    GENFIT is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014    GNU Lesser General Public License for more details.
0015 
0016    You should have received a copy of the GNU Lesser General Public License
0017    along with GENFIT.  If not, see <http://www.gnu.org/licenses/>.
0018 */
0019 
0020 #include "DetPlane.h"
0021 #include "IO.h"
0022 
0023 #include <cassert>
0024 #include <cmath>
0025 #include <TMath.h>
0026 #include <TClass.h>
0027 #include <TBuffer.h>
0028 
0029 namespace genfit {
0030 
0031 
0032 DetPlane::DetPlane(AbsFinitePlane* finite)
0033   :finitePlane_(finite)
0034 {
0035   // default constructor
0036   o_.SetXYZ(0.,0.,0.);
0037   u_.SetXYZ(1.,0.,0.);
0038   v_.SetXYZ(0.,1.,0.);
0039   // sane() not needed here
0040 }
0041 
0042 
0043 DetPlane::DetPlane(const TVector3& o,
0044                        const TVector3& u,
0045                        const TVector3& v,
0046                        AbsFinitePlane* finite)
0047   :o_(o), u_(u), v_(v), finitePlane_(finite)
0048 {
0049   sane();
0050 }
0051 
0052 DetPlane::DetPlane(const TVector3& o,
0053                        const TVector3& n,
0054                        AbsFinitePlane* finite)
0055   :o_(o), finitePlane_(finite)
0056 {
0057   setNormal(n);
0058 }
0059 
0060 
0061 DetPlane::~DetPlane(){
0062   ;
0063 }
0064 
0065 
0066 DetPlane::DetPlane(const DetPlane& rhs) :
0067   TObject(rhs),
0068   o_(rhs.o_),
0069   u_(rhs.u_),
0070   v_(rhs.v_)
0071 {
0072   if(rhs.finitePlane_)
0073     finitePlane_.reset(rhs.finitePlane_->clone());
0074   else finitePlane_.reset();
0075 }
0076 
0077 
0078 DetPlane& DetPlane::operator=(DetPlane other) {
0079   swap(other);
0080   return *this;
0081 }
0082 
0083 
0084 void DetPlane::swap(DetPlane& other) {
0085   // by swapping the members of two classes,
0086   // the two classes are effectively swapped
0087   std::swap(this->o_, other.o_);
0088   std::swap(this->u_, other.u_);
0089   std::swap(this->v_, other.v_);
0090   this->finitePlane_.swap(other.finitePlane_);
0091 }
0092 
0093 
0094 void DetPlane::set(const TVector3& o,
0095                 const TVector3& u,
0096                 const TVector3& v)
0097 {
0098   o_ = o;
0099   u_ = u;
0100   v_ = v;
0101   sane();
0102 }
0103 
0104 
0105 void DetPlane::setO(const TVector3& o)
0106 {
0107   o_ = o;
0108 }
0109 
0110 void DetPlane::setO(double X,double Y,double Z)
0111 {
0112   o_.SetXYZ(X,Y,Z);
0113 }
0114 
0115 void DetPlane::setU(const TVector3& u)
0116 {
0117   u_ = u;
0118   sane(); // sets v_ perpendicular to u_
0119 }
0120 
0121 void DetPlane::setU(double X,double Y,double Z)
0122 {
0123   u_.SetXYZ(X,Y,Z);
0124   sane(); // sets v_ perpendicular to u_
0125 }
0126 
0127 void DetPlane::setV(const TVector3& v)
0128 {
0129   v_ = v;
0130   u_ = getNormal().Cross(v_);
0131   u_ *= -1.;
0132   sane();
0133 }
0134 
0135 void DetPlane::setV(double X,double Y,double Z)
0136 {
0137   v_.SetXYZ(X,Y,Z);
0138   u_ = getNormal().Cross(v_);
0139   u_ *= -1.;
0140   sane();
0141 }
0142 
0143 void DetPlane::setUV(const TVector3& u,const TVector3& v)
0144 {
0145   u_ = u;
0146   v_ = v;
0147   sane();
0148 }
0149 
0150 void DetPlane::setON(const TVector3& o,const TVector3& n){
0151   o_ = o;
0152   setNormal(n);
0153 }
0154 
0155 
0156 TVector3 DetPlane::getNormal() const
0157 {
0158   return u_.Cross(v_);
0159 }
0160 
0161 void DetPlane::setNormal(double X,double Y,double Z){
0162   setNormal( TVector3(X,Y,Z) );
0163 }
0164 
0165 void DetPlane::setNormal(const TVector3& n){
0166   u_ = n.Orthogonal();
0167   v_ = n.Cross(u_);
0168   u_.SetMag(1.);
0169   v_.SetMag(1.);
0170 }
0171 
0172 void DetPlane::setNormal(const double& theta, const double& phi){
0173   setNormal( TVector3(TMath::Sin(theta)*TMath::Cos(phi),TMath::Sin(theta)*TMath::Sin(phi),TMath::Cos(theta)) );
0174 }
0175 
0176 
0177 TVector2 DetPlane::project(const TVector3& x)const
0178 {
0179   return TVector2(u_*x, v_*x);
0180 }
0181 
0182 
0183 TVector2 DetPlane::LabToPlane(const TVector3& x)const
0184 {
0185   return project(x-o_);
0186 }
0187 
0188 
0189 TVector3 DetPlane::toLab(const TVector2& x)const
0190 {
0191   TVector3 d(o_);
0192   d += x.X()*u_;
0193   d += x.Y()*v_;
0194   return d;
0195 }
0196 
0197 
0198 TVector3 DetPlane::dist(const TVector3& x)const
0199 {
0200   return toLab(LabToPlane(x)) - x;
0201 }
0202 
0203 
0204 void DetPlane::sane(){
0205   assert(u_!=v_);
0206 
0207   // ensure unit vectors
0208   u_.SetMag(1.);
0209   v_.SetMag(1.);
0210 
0211   // check if already orthogonal
0212   if (u_.Dot(v_) < 1.E-5) return;
0213 
0214   // ensure orthogonal system
0215   v_ = getNormal().Cross(u_);
0216 }
0217 
0218 
0219 void DetPlane::Print(const Option_t* option) const
0220 {
0221   printOut<<"DetPlane: "
0222      <<"O("<<o_.X()<<", "<<o_.Y()<<", "<<o_.Z()<<") "
0223      <<"u("<<u_.X()<<", "<<u_.Y()<<", "<<u_.Z()<<") "
0224      <<"v("<<v_.X()<<", "<<v_.Y()<<", "<<v_.Z()<<") "
0225      <<"n("<<getNormal().X()<<", "<<getNormal().Y()<<", "<<getNormal().Z()<<") "
0226        <<std::endl;
0227   if(finitePlane_ != nullptr) {
0228     finitePlane_->Print(option);
0229   }
0230 
0231 }
0232 
0233 
0234 /*
0235   I could write pages of comments about correct equality checking for
0236   floating point numbers, but: When two planes are as close as 10E-5 cm
0237   in all nine numbers that define the plane, this will be enough for all
0238   practical purposes
0239  */
0240 bool operator== (const DetPlane& lhs, const DetPlane& rhs){
0241   if (&lhs == &rhs)
0242     return true;
0243   static const double detplaneEpsilon = 1.E-5;
0244   if(
0245      fabs( (lhs.o_.X()-rhs.o_.X()) ) > detplaneEpsilon  ||
0246      fabs( (lhs.o_.Y()-rhs.o_.Y()) ) > detplaneEpsilon  ||
0247      fabs( (lhs.o_.Z()-rhs.o_.Z()) ) > detplaneEpsilon
0248      ) return false;
0249   else if(
0250     fabs( (lhs.u_.X()-rhs.u_.X()) ) > detplaneEpsilon  ||
0251     fabs( (lhs.u_.Y()-rhs.u_.Y()) ) > detplaneEpsilon  ||
0252     fabs( (lhs.u_.Z()-rhs.u_.Z()) ) > detplaneEpsilon
0253     ) return false;
0254   else if(
0255     fabs( (lhs.v_.X()-rhs.v_.X()) ) > detplaneEpsilon  ||
0256     fabs( (lhs.v_.Y()-rhs.v_.Y()) ) > detplaneEpsilon  ||
0257     fabs( (lhs.v_.Z()-rhs.v_.Z()) ) > detplaneEpsilon
0258     ) return false;
0259   return true;
0260 }
0261 
0262 bool operator!= (const DetPlane& lhs, const DetPlane& rhs){
0263   return !(lhs==rhs);
0264 }
0265 
0266 
0267 double DetPlane::distance(const TVector3& point) const {
0268   // |(point - o_)*(u_ x v_)|
0269   return fabs( (point.X()-o_.X()) * (u_.Y()*v_.Z() - u_.Z()*v_.Y()) +
0270                (point.Y()-o_.Y()) * (u_.Z()*v_.X() - u_.X()*v_.Z()) +
0271                (point.Z()-o_.Z()) * (u_.X()*v_.Y() - u_.Y()*v_.X()));
0272 }
0273 
0274 double DetPlane::distance(double x, double y, double z) const {
0275   // |(point - o_)*(u_ x v_)|
0276   return fabs( (x-o_.X()) * (u_.Y()*v_.Z() - u_.Z()*v_.Y()) +
0277                (y-o_.Y()) * (u_.Z()*v_.X() - u_.X()*v_.Z()) +
0278                (z-o_.Z()) * (u_.X()*v_.Y() - u_.Y()*v_.X()));
0279 }
0280 
0281 
0282 TVector2 DetPlane::straightLineToPlane (const TVector3& point, const TVector3& dir) const {
0283   TVector3 dirNorm(dir.Unit());
0284   TVector3 normal = getNormal();
0285   double dirTimesN = dirNorm*normal;
0286   if(fabs(dirTimesN)<1.E-6){//straight line is parallel to plane, so return infinity
0287     return TVector2(1.E100,1.E100);
0288   }
0289   double t = 1./dirTimesN * ((o_-point)*normal);
0290   return project(point - o_ + t * dirNorm);
0291 }
0292 
0293 
0294 //! gives u,v coordinates of the intersection point of a straight line with plane
0295 void DetPlane::straightLineToPlane(const double& posX, const double& posY, const double& posZ,
0296                                    const double& dirX, const double& dirY, const double& dirZ,
0297                                    double& u, double& v) const {
0298 
0299   TVector3 W = getNormal();
0300   double dirTimesN = dirX*W.X() + dirY*W.Y() + dirZ*W.Z();
0301   if(fabs(dirTimesN)<1.E-6){//straight line is parallel to plane, so return infinity
0302     u = 1.E100;
0303     v = 1.E100;
0304     return;
0305   }
0306   double t = 1./dirTimesN * ((o_.X()-posX)*W.X() +
0307                              (o_.Y()-posY)*W.Y() +
0308                              (o_.Z()-posZ)*W.Z());
0309 
0310   double posOnPlaneX = posX-o_.X() + t*dirX;
0311   double posOnPlaneY = posY-o_.Y() + t*dirY;
0312   double posOnPlaneZ = posZ-o_.Z() + t*dirZ;
0313 
0314   u = u_.X()*posOnPlaneX + u_.Y()*posOnPlaneY + u_.Z()*posOnPlaneZ;
0315   v = v_.X()*posOnPlaneX + v_.Y()*posOnPlaneY + v_.Z()*posOnPlaneZ;
0316 }
0317 
0318 
0319 void DetPlane::rotate(double angle) {
0320   TVector3 normal = getNormal();
0321   u_.Rotate(angle, normal);
0322   v_.Rotate(angle, normal);
0323 
0324   sane();
0325 }
0326 
0327 
0328 void DetPlane::reset() {
0329   o_.SetXYZ(0.,0.,0.);
0330   u_.SetXYZ(1.,0.,0.);
0331   v_.SetXYZ(0.,1.,0.);
0332   finitePlane_.reset();
0333 }
0334 
0335 
0336 void DetPlane::Streamer(TBuffer &R__b)
0337 {
0338    // Stream an object of class genfit::DetPlane.
0339    // This is modified from the streamer generated by ROOT in order to 
0340    // account for the scoped_ptr.
0341    //This works around a msvc bug and should be harmless on other platforms
0342    typedef ::genfit::DetPlane thisClass;
0343    UInt_t R__s, R__c;
0344    if (R__b.IsReading()) {
0345       Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
0346       //TObject::Streamer(R__b);
0347       o_.Streamer(R__b);
0348       u_.Streamer(R__b);
0349       v_.Streamer(R__b);
0350       finitePlane_.reset();
0351       char flag;
0352       R__b >> flag;
0353       if (flag) {
0354     // Read AbsFinitePlane with correct overload ... see comment
0355     // in writing code.
0356     TClass* cl = TClass::Load(R__b);
0357         AbsFinitePlane *p = (AbsFinitePlane*)(cl->New());
0358         cl->Streamer(p, R__b);
0359         finitePlane_.reset(p);
0360       }
0361       R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
0362    } else {
0363       R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
0364       //TObject::Streamer(R__b);
0365       o_.Streamer(R__b);
0366       u_.Streamer(R__b);
0367       v_.Streamer(R__b);
0368       if (finitePlane_) {
0369         R__b << (char)1;
0370 
0371     // finitPlane_ is a scoped_ptr, but a shared plane may be
0372     // written several times in different places (e.g. it may also
0373     // be stored in the measurement class).  Since we have no way
0374     // of knowing in which other places the same plane is written
0375     // (it may even be in another track!), we cannot synchronize
0376     // these writes and have to duplicate the SharedPlanePtr's
0377     // instead.  ROOT caches which pointers were written and read
0378     // if one uses 'R__b << p' or equivalent.  This can lead to
0379     // trouble have no way of synchronizing two reads to
0380     // shared_ptr's pointing to the same memory location.  But
0381     // even if we break the link between the two shared_ptr's,
0382     // ROOT will still try to outsmart us, and it will notice that
0383     // the finitePlane_ was the same during writing.  This will
0384     // lead to the same address being attached to two different
0385     // scoped_ptrs in reading.  Highly undesirable.  Since we
0386     // cannot know whether other parts of code implicitly or
0387     // explicitly rely on TBuffer's caching, we cannot just
0388     // disable this caching via R__b.ResetMap() (it's not
0389     // documented in any elucidating manner anyway).
0390     // 
0391     // Therefore, we have to write and read the AbsFinitePlane*
0392     // manually, bypassing ROOT's caching.  In order to do this,
0393     // we need the information on the actual type, because
0394     // otherwise we couldn't read it back reliably.  Finally, the
0395     // _working_ means of reading and writing class information
0396     // are TClass::Store and TClass::Load, again barely
0397     // documented, but if one tries any of the other ways that
0398     // suggest themselves, weird breakage will occur.
0399     finitePlane_->IsA()->Store(R__b);
0400         finitePlane_->Streamer(R__b);
0401       } else {
0402         R__b << (char)0;
0403       }
0404       R__b.SetByteCount(R__c, kTRUE);
0405    }
0406 }
0407 } /* End of namespace genfit */