// ---------------------------------------------------- // This file belongs to the ray tracing framework // for the use with Cherenkov detectors // // created 2007 //----------------------------------------------------- #include "PndDrcSurfAbs.h" #include "PndDrcOptDevManager.h" #include "PndDrcPhoton.h" #include "PndDrcOptMatAbs.h" #include "PndDrcOptDev.h" #include #include using std::cout; //using std::cerr; //using std::cin; using std::endl; #include using namespace TMath; #include //---------------------------------------------------------------------- PndDrcPhoton::PndDrcPhoton() { fParticleIDnumber = 0; fLambda = 0; fPosition = XYZPoint(0,0,0); fPositionOld = XYZPoint(0,0,0); fDirection = XYZPoint(0,0,0); fOriginDirection = XYZPoint(0,0,0); fFate = Drc::kPhotFlying; fReflections = 0; fVerbosity = 0; fThetaC = 0; fPhiC = 0; fTime = 0; fDev = 0; fReflectionLimit = 1000; fPrintFlag = true; } //---------------------------------------------------------------------- void PndDrcPhoton::Copy(const PndDrcPhoton& ph) { fParticleIDnumber = ph.fParticleIDnumber; fLambda = ph.fLambda; fPosition = ph.fPosition; fPositionOld = ph.fPositionOld; fPositionXlist = ph.fPositionXlist; fPositionYlist = ph.fPositionYlist; fPositionZlist = ph.fPositionZlist; fSurfaceList = ph.fSurfaceList; fDirection = ph.fDirection; fOriginDirection = ph.fOriginDirection; fFate = ph.fFate; fReflections = ph.fReflections; fVerbosity = ph.fVerbosity; fThetaC = ph.fThetaC; fPhiC = ph.fPhiC; fTime = ph.fTime; fDev = ph.fDev; fReflectionLimit = ph.fReflectionLimit; fPrintFlag = ph.fPrintFlag; } //---------------------------------------------------------------------- PndDrcPhoton::PndDrcPhoton(const PndDrcPhoton& ph) { if (ph.fVerbosity>=1) cout<<" PndDrcPhoton::PndDrcPhoton" <<"(const PndDrcPhoton&)"<=1) cout<<" PndDrcPhoton::operator=" <<"(const PndDrcPhoton&) "<OptMaterial()).RefIndex(fLambda); double dndl = (fDev->OptMaterial()).RefIndexDeriv(fLambda); double len = sqrt((pos-fPosition).Mag2()); // mm // double v_phase = 299.792/n; // mm/ns double n_group = n - fLambda*dndl; double v_group = 299.792/n_group; double time = len/v_group; fTime += time; // pos in mm time in ns } SetPosition(pos); if( fPrintFlag ) { fPositionXlist.push_back(pos.X()); fPositionYlist.push_back(pos.Y()); fPositionZlist.push_back(pos.Z()); } } //---------------------------------------------------------------------- bool PndDrcPhoton::Refract(XYZVector normal, double n1, double ex1, bool fresnelFlag, double n2, double ex2, double diffuseProb) { // cout << "VOLCHECK2: " << n1 << " " << ex1 << " " // << n2 << " " << ex2 << " flag: " << fresnelFlag << " " // << "diffuseProb: " << diffuseProb << endl; // fVerbosity =4; // cout << "******************** REFRACT ******************" << endl; static const double kEps = 1.0e-9; bool refract_flag; XYZVector dir1 = Direction(); // norm points outside. XYZVector norm = (dir1.Dot(normal)>0) ? normal : -normal; // // sin(alpha1) n2 // ----------- = -- (Snellius) // sin(alpha2) n1 // // alpaha1, alpha2 > 0 if (Verbosity()>=4) { cout<<" norm="<Uniform(0.0,1.0); refract_flag = false; if( random <= diffuseProb && diffuseProb > 0 ) Diffuse( normal ); else Reflect( norm ); //ph.setDirection(dir1 - 2*(norm.Dot(dir1)*norm)); // new direction ??? if (Verbosity()>=4) cout<<" reflection"<=4) cout<<" alpha1,n1,n2 = "<=4) cout<<" x,alpha2 = "<=4) { cout<<" dir2 before unit = "<=4) { cout<<" refraction, brought it inside to " <Uniform(0.0,1.0); double phi = gRandom->Uniform(0.0,2*Pi()); XYZVector newf( Cos(phi) * Sqrt(1 - costheta*costheta), Sin(phi) * Sqrt(1 - costheta*costheta), costheta); // rotation matrix double xx = Cos(angle) + rotAxis.X()*rotAxis.X() * (1-Cos(angle)); double yx = rotAxis.X()*rotAxis.Y() * (1-Cos(angle)) + rotAxis.Z() * Sin(angle); double zx = rotAxis.X()*rotAxis.Z() * (1-Cos(angle)) - rotAxis.Y() * Sin(angle); double xy = rotAxis.Y()*rotAxis.X() * (1-Cos(angle)) - rotAxis.Z() * Sin(angle); double yy = Cos(angle) + rotAxis.Y()*rotAxis.Y() * (1-Cos(angle)); double zy = rotAxis.Y()*rotAxis.Z() * (1-Cos(angle)) + rotAxis.X() * Sin(angle); double xz = rotAxis.Z()*rotAxis.X() * (1-Cos(angle)) + rotAxis.Y() * Sin(angle); double yz = rotAxis.Z()*rotAxis.Y() * (1-Cos(angle)) - rotAxis.X() * Sin(angle); double zz = Cos(angle) + rotAxis.Z()*rotAxis.Z() * (1-Cos(angle)); double newfX = xx * newf.X() + xy * newf.Y() +xz * newf.Z(); double newfY = yx * newf.X() + yy * newf.Y() +yz * newf.Z(); double newfZ = zx * newf.X() + zy * newf.Y() +zz * newf.Z(); fDirection.SetXYZ( -newfX, -newfY, -newfZ ); // negative for reflection direction fDirection = fDirection.Unit(); fReflections++; } //---------------------------------------------------------------------- bool PndDrcPhoton::Fresnel(XYZVector normal, double n1, double ex1, double n2, double ex2) { XYZVector dir1 = Direction(); // norm points outside. XYZVector norm = (dir1.Dot(normal)>0) ? normal : -normal; if (Verbosity()>=4) { cout<<"PndDrcPhoton::Fresnel" <=4) { cout << " Fresnel reflected: " << "refl. probability: " << reflProb << " random: " << random << " inci: " << (inci/TMath::Pi()*180) << endl; } return true; } else return false; } //---------------------------------------------------------------------- void PndDrcPhoton::SetFate(Drc::kPhotonFate fate) { fFate=fate; //if (fate==Drc::kPhotLost) cout<<" PndDrcPhoton::SetFate lost-------------------------------"< 740) return 50; // dark red else if (lambda> 625) return 2; // red else if (lambda> 590) return 42; // orange else if (lambda> 565) return 5; // yellow else if (lambda> 520) return 3; // green else if (lambda> 500) return 7; // cyan else if (lambda> 450) return 4; // blue else if (lambda> 430) return 9; // indigo else if (lambda> 380) return 39; // violet return 33; // blue grey } //---------------------------------------------------------------------- void PndDrcPhoton::Print(fstream& stream) const { if (fPrintFlag) { stream<<" TPolyLine3D *l = new TPolyLine3D(2);"<SetPoint("<<0<<"," <SetPoint("<<1<<"," <SetLineColor("<Draw();"<