// ---------------------------------------------------- // This file belongs to the ray tracing framework // for the use with Cherenkov detectors // // created 2007 //----------------------------------------------------- #include "PndDrcEffiAbs.h" #include "PndDrcSurfPolyAsphere.h" #include "PndDrcPhoton.h" //#include "PndDrcOptReflAbs.h" //#include "PndDrcSurfAbs.h" //#include "PndDrcSurfPolyFlat.h" //#include "PndDrcOptMatAbs.h" //#include "PndDrcOptDev.h" //#include "PndDrcUtil.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/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 "Math/Transform3D.h" //using ROOT::Math::Transform3D; // #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 //using std::pair; #include "TPolyLine3D.h" //---------------------------------------------------------------------- PndDrcSurfPolyAsphere::PndDrcSurfPolyAsphere() { fRadius = -999; fChecked = false; fConConst = 0; // sphere } //---------------------------------------------------------------------- PndDrcSurfPolyAsphere* PndDrcSurfPolyAsphere::Clone() const { return new PndDrcSurfPolyAsphere(*this); } //---------------------------------------------------------------------- void PndDrcSurfPolyAsphere::Copy(const PndDrcSurfPolyAsphere& s) { fRadius = s.fRadius; fConConst = s.fConConst; fChecked = s.fChecked; fTrans = s.fTrans; fTransInv = s.fTransInv; } //---------------------------------------------------------------------- PndDrcSurfPolyAsphere::PndDrcSurfPolyAsphere(const PndDrcSurfPolyAsphere& s) : PndDrcSurfPolyFlat(s) { if (s.fVerbosity>=1) cout<<" PndDrcSurfPolyAsphere::PndDrcSurfPolyAsphere" <<"(const PndDrcSurfPolyAsphere&) name,copy: " <=1) cout<<" PndDrcSurfPolyAsphere::operator=" <<"(const PndDrcSurfPolyAsphere&) name,copy: " <((*this)) = s; // assignment of base class part. Copy(s); } return *this; } //---------------------------------------------------------------------- XYZVector PndDrcSurfPolyAsphere::Normal(const XYZPoint& point) const { if (!fChecked) fChecked = Check1();// check dimensions // transform point back, where sphere was defined. XYZPoint p1(fTransInv(point)); // p1 point on surface in unrotated and unshifted system double h2 = p1.X()*p1.X()+p1.Y()*p1.Y(); double h,root,dzdh,dhdx,dhdy; if (h2>1e-12) { h = sqrt(h2); root = sqrt(fRadius*fRadius - (1.0+fConConst)*h2); dzdh = (2*h * (fRadius+root) + (1.0+fConConst)*h/root * h2)/((fRadius+root)*(fRadius+root)); dhdx = p1.X()/h; dhdy = p1.Y()/h; } else { dhdx=0; // eg axis parallel beam throug zero dhdy=0; dzdh=0; } // real z is R-z dzdh *= -1; XYZVector pa(1,0,dzdh*dhdx); // vector along slope in x dir. XYZVector pb(0,1,dzdh*dhdy); // vector along slope in y dir. XYZVector pc(pa.Cross(pb)); pc = fTrans(pc); return -pc.Unit(); } //---------------------------------------------------------------------- bool PndDrcSurfPolyAsphere::SurfaceHit(PndDrcPhoton& ph, XYZPoint& pos_new, double& path_length) const { const double kEps = 0.001; if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit: test of " <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit: original photon: \n" <<" pos: "<=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit: transformed photon: \n" <<" pos: "<=4) { cout<<" PndDrcSurfPolyAsphere::surfaceHit: a ="<0) { pos_new = pos_new1; path_length = lambda; if (!OnSurface(pos_new)) { if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<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); if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit hit lambda=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit hit,lambda=" <0 long double p = a/h2; long double q = b/h2; long double root2 = p*p/4-q; if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit p,q,root2: " <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit root2<0"<0 long double lambda1 = -p/2 + sqrt(root2); long double lambda2 = -p/2 - sqrt(root2); if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2 =" <kEps && lambda2>kEps) { // check both solutions XYZPoint pos_check = pos + lambda1*dir; pos_check.SetZ(0); bool hit1 = WithinSurface(pos_check); pos_check = pos + lambda2*dir; pos_check.SetZ(0); bool hit2 = WithinSurface(pos_check); if (hit1 && hit2) { // take closest lambda = (lambda1=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<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); if (fVerbosity>=4) { cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <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); if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit hit1 lambda_1=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<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); if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit hit2 lambda_1=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit " <<"no hits for both lambdas"<kEps && lambda2<=kEps) { lambda = lambda1; } else if (lambda1<=kEps && lambda2>kEps) { lambda = lambda2; } else { //cout<<" both lambdas <0"<=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit " <<"both lambdas < 0 " <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda=" <=4) { cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <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); if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<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); if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<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); if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit " <<"no hits for both lambdas"<kEps && lambda2<=kEps) { lambda = lambda1; } else if (lambda1<=kEps && lambda2>kEps) { lambda = lambda2; } else { //cout<<" both lambdas <0"<=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit " <<"both lambdas < 0 " <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit:"<=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit pos_new before trans. =" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit zVal of pos_new =" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<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); if (fVerbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit: lambda -> hit" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit " <(fP.size()-1) || i<0) { cerr<<" *** PndDrcSurfPolyAsphere::limitingPoint: index out of range, i="<SetPoint("<SetPoint( icnt, fP1.X(), fP1.Y(), fP1.Z()); // for an opened canvas icnt++; } } fP1 = fP[0]*frac; fP1.SetZ(ZVal(fP1.X(),fP1.Y())); // fP1.Z()=0... fP1 = fTrans*fP1; stream<<" l->SetPoint("<SetLineColor("<Draw();"<SetPoint( icnt, fP1.X(), fP1.Y(), fP1.Z() ); l->SetLineColor(fPrintColor); l->Draw(); icnt++; } } //---------------------------------------------------------------------- void PndDrcSurfPolyAsphere::Print() const { cout<<" Coordinates of PndDrcSurfPolyAsphere "<((*this)).Print(); cout<<" r = "<