#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 "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 "PndDrcPhoton.h" #include "PndDrcOptReflAbs.h" #include "PndDrcSurfAbs.h" #include "PndDrcSurfPolyFlat.h" #include "PndDrcSurfPolyAsphere.h" #include "PndDrcOptMatAbs.h" #include "PndDrcOptDev.h" #include "PndDrcUtil.h" //---------------------------------------------------------------------- PndDrcSurfPolyAsphere::PndDrcSurfPolyAsphere() { m_radius = -999; m_checked = false; m_conConst = 0; // sphere } //---------------------------------------------------------------------- PndDrcSurfPolyAsphere* PndDrcSurfPolyAsphere::clone() const { return new PndDrcSurfPolyAsphere(*this); } //---------------------------------------------------------------------- void PndDrcSurfPolyAsphere::copy(const PndDrcSurfPolyAsphere& s) { m_radius = s.m_radius; m_conConst = s.m_conConst; m_checked = s.m_checked; m_trans = s.m_trans; m_transInv = s.m_transInv; } //---------------------------------------------------------------------- PndDrcSurfPolyAsphere::PndDrcSurfPolyAsphere(const PndDrcSurfPolyAsphere& s) : PndDrcSurfPolyFlat(s) { if (s.m_verbosity>=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 (!m_checked) m_checked = check();// check dimensions // transform point back, where sphere was defined. XYZPoint p1(m_transInv(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(m_radius*m_radius - (1.0+m_conConst)*h2); dzdh = (2*h * (m_radius+root) + (1.0+m_conConst)*h/root * h2)/((m_radius+root)*(m_radius+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 = m_trans(pc); return -pc.Unit(); } //---------------------------------------------------------------------- bool PndDrcSurfPolyAsphere::surfaceHit(PndDrcPhoton& ph, XYZPoint& pos_new, double& path_length) const { const double eps = 0.001; if (m_verbosity>=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 (m_verbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<=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 (m_verbosity>=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 (m_verbosity>=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2 =" <eps && lambda2>eps) { // 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"<=4) { cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit hit1 lambda_1=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit hit2 lambda_1=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit " <<"no hits for both lambdas"<eps && lambda2<=eps) { lambda = lambda1; } else if (lambda1<=eps && lambda2>eps) { 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=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit" <<" calc. point not on surface," <<" wrong lambda"<=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit lambda_1,2=" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit " <<"no hits for both lambdas"<eps && lambda2<=eps) { lambda = lambda1; } else if (lambda1<=eps && lambda2>eps) { 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"<=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit: lambda -> hit" <=4) cout<<" PndDrcSurfPolyAsphere::surfaceHit " <(m_p.size()-1) || i<0) { cerr<<" *** PndDrcSurfPolyAsphere::limitingPoint: index out of range, i="<SetPoint("<<(icnt++)<<"," <SetPoint("<<(icnt++)<<"," <SetLineColor("<Draw();"<=3) cout<<" PndDrcSurfCyl::addTransform() name="<