// ---------------------------------------------------- // This file belongs to the ray tracing framework // for the use with Cherenkov detectors // // created 2007 //----------------------------------------------------- #include "PndDrcEffiAbs.h" #include "PndDrcSurfPolySphere.h" #include "PndDrcPhoton.h" //#include "PndDrcOptReflAbs.h" //#include "PndDrcSurfAbs.h" //#include "PndDrcSurfPolyFlat.h" //#include "PndDrcOptMatAbs.h" //#include "PndDrcOptDev.h" // //#include "TVector3.h" //#include "TRotation.h" //#include "TRandom.h" //#include "TMatrixD.h" //#include "TVectorD.h" //#include "TDecompSVD.h" // //#include "Math/Vector3D.h" //using ROOT::Math::XYZVector; // //#include "Math/Point3D.h" //using ROOT::Math::XYZPoint; // //#include "Math/Transform3D.h" //using ROOT::Math::Transform3D; // //#include "Math/RotationX.h" //using ROOT::Math::RotationX; //#include "Math/RotationY.h" //using ROOT::Math::RotationY; //#include "Math/RotationZ.h" //using ROOT::Math::RotationZ; //#include "Math/Rotation3D.h" //using ROOT::Math::Rotation3D; // #include using std::cout; using std::cerr; //using std::cin; using std::endl; // //#include //using std::valarray; // //#include //using std::fstream; // //#include //using std::string; // //#include //using std::list; // //#include //using std::vector; #include "TPolyLine3D.h" //---------------------------------------------------------------------- PndDrcSurfPolySphere::PndDrcSurfPolySphere() { fRadius = -999; fChecked = false; } //---------------------------------------------------------------------- PndDrcSurfPolySphere* PndDrcSurfPolySphere::Clone() const { return new PndDrcSurfPolySphere(*this); } //---------------------------------------------------------------------- void PndDrcSurfPolySphere::Copy(const PndDrcSurfPolySphere& s) { fRadius = s.fRadius; fChecked = s.fChecked; fTrans = s.fTrans; fTransInv = s.fTransInv; } //---------------------------------------------------------------------- PndDrcSurfPolySphere::PndDrcSurfPolySphere(const PndDrcSurfPolySphere& s) : PndDrcSurfPolyFlat(s) { if (s.fVerbosity>=1) cout<<" PndDrcSurfPolySphere::PndDrcSurfPolySphere" <<"(const PndDrcSurfPolySphere&) name,copy: " <=1) cout<<" PndDrcSurfPolySphere::operator=" <<"(const PndDrcSurfPolySphere&) name,copy: " <((*this)) = s; // assignment of base class part. Copy(s); } return *this; } //---------------------------------------------------------------------- XYZVector PndDrcSurfPolySphere::Normal(const XYZPoint& point) const { if (!fChecked) fChecked = Check1();// check dimensions // transform point back, where sphere was defined. XYZPoint point0(fTransInv*point); // normal vector points from origin (0,0,0) to point of surface. XYZVector pn(point0); // transform back return fTrans(pn).Unit();//p1.Unit(); } //---------------------------------------------------------------------- bool PndDrcSurfPolySphere::SurfaceHit(PndDrcPhoton& ph, XYZPoint& pos_new, double& path_length) const { if (!fChecked) fChecked = Check1();// check dimensions // transform back in sphere definitions space XYZPoint pos(fTransInv*ph.Position()); XYZVector dir(fTransInv*ph.Direction()); //if (/*pos.Z()<0 && */ dir.Z()<0) return false; // wrong direction### // check if the photon hits the full sphere // double costh = sqrt((dir.X()*dir.X()+dir.Y()*dir.Y())/dir.Mag2()); // double theta = fabs(acos(costh)); // if (tan(theta)* -dir.Z() >= fRadius) return false; // angle too steep // compute hit position // // line : x = pos + lambda*dir // // sphere: x^2 = r^2 // // pos^2 + lambda^2*dir^2 + 2 pos lambda dir = r^2 // // // lambda^2 + lambda*2*pos*dir + pos^2-r^2 = 0; // // lambda12 = -pos*dir + sqrt((pos*dir)^2 - (pos^2-r^2) // // the other (-) solution is the wrong one. // // path_length = lambda since dir is normalized double posdir = pos.Dot(dir); double diff = pos.Mag2() - fRadius*fRadius; double root2 = posdir*posdir - diff; if (fVerbosity>=4) cout<<" PndDrcSurfPolySphere::surfaceHit root2="<=4) cout<<" PndDrcSurfPolySphere::surfaceHit lambda_1,2=" <kEps && lambda2>kEps) { // check both lambdas XYZPoint pos_new1 = pos + lambda1*dir; XYZPoint pos_check(pos_new1); bool hit1 = (pos_new1.Z()>0); pos_check.SetZ(0); if (hit1) hit1 = WithinSurface(pos_check); XYZPoint pos_new2 = pos + lambda2*dir; pos_check = pos_new2; bool hit2 = (pos_new2.Z()>0); pos_check.SetZ(0); if (hit2) hit2 = WithinSurface(pos_check); if (hit1 && hit2) { // take closest double lambda = (lambda1EffiFlag(ph.Wavelength(), ph.Direction().Dot(Normal(pos_new)))) { ph.SetFate(Drc::kPhotMeasured); if (fPixelCorr) ph.SetPosition(fPixelPoint); } else { ph.SetFate(Drc::kPhotAbsorbed); } } //if (fPixel) ph.SetFate(Drc::kPhotMeasured); return true; } else if (hit1) { pos_new = pos + lambda1*dir; path_length = lambda1; pos_new = fTrans * pos_new; if (fPixel){ if (fEffiCathode ->EffiFlag(ph.Wavelength(), ph.Direction().Dot(Normal(pos_new)))) { ph.SetFate(Drc::kPhotMeasured); if (fPixelCorr) ph.SetPosition(fPixelPoint); } else { ph.SetFate(Drc::kPhotAbsorbed); } } //if (fPixel) ph.SetFate(Drc::kPhotMeasured); return true; } else if (hit2) { pos_new = pos + lambda2*dir; path_length = lambda2; pos_new = fTrans * pos_new; if (fPixel){ if (fEffiCathode ->EffiFlag(ph.Wavelength(), ph.Direction().Dot(Normal(pos_new)))) { ph.SetFate(Drc::kPhotMeasured); if (fPixelCorr) ph.SetPosition(fPixelPoint); } else { ph.SetFate(Drc::kPhotAbsorbed); } } //if (fPixel) ph.SetFate(Drc::kPhotMeasured); return true; } else { return false; } } else if (lambda1>kEps && lambda2<=kEps) { path_length = lambda1; } else if (lambda1<=kEps && lambda2>kEps) { path_length = lambda2; } else { //cout<<" not taken"<=4) cout<<" PndDrcSurfPolySphere::surfaceHit pos_new_z=" <EffiFlag(ph.Wavelength(), ph.Direction().Dot(Normal(pos_new)))) { ph.SetFate(Drc::kPhotMeasured); if (fPixelCorr) ph.SetPosition(fPixelPoint); } else { ph.SetFate(Drc::kPhotAbsorbed); } } //if (fPixel) ph.SetFate(Drc::kPhotMeasured); return true; } if (fVerbosity>=4) cout<<" PndDrcSurfPolySphere::surfaceHit false"<(isize-1) || i<0) { cerr<<" *** PndDrcSurfPolySphere::limitingPoint: index out of range, i="<=3) cout<<" PndDrcSurfPolySphere::addTransform() name="<SetPoint("<SetPoint( icnt, fP1.X(), fP1.Y(), fP1.Z() ); // for an opened canvas icnt++; } } fP1 = fP[0]*frac; double x2y2 = fP1.X()*fP1.X()+fP1.Y()*fP1.Y(); fP1.SetZ(sqrt(fRadius*fRadius - x2y2)); fP1 = fTrans(fP1); //fP1.Transform(fRot); //fP1 += fShift; stream<<" l->SetPoint("<SetLineColor("<Draw();"<SetPoint( icnt, fP1.X(), fP1.Y(), fP1.Z()); l->SetLineColor(fPrintColor); l->Draw(); icnt++; } } //---------------------------------------------------------------------- void PndDrcSurfPolySphere::Print() const { cout<<" Coordinates of PndDrcSurfPolySphere "<((*this)).Print(); cout<<" r = "<