#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::numeric_limits; #include "TObject.h" #include "TVector3.h" #include "TRandom.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 "DrcPhoton.h" #include "DrcOptReflAbs.h" #include "DrcSurfAbs.h" #include "DrcOptMatAbs.h" #include "DrcOptDev.h" #include "DrcOptVol.h" #include "DrcUtil.h" //---------------------------------------------------------------------- DrcOptVol::DrcOptVol() { m_optMat = 0; } //---------------------------------------------------------------------- DrcOptVol::~DrcOptVol() { delete m_optMat; } //---------------------------------------------------------------------- DrcOptVol* DrcOptVol::clone() const { return new DrcOptVol(*this); } //---------------------------------------------------------------------- void DrcOptVol::copy(const DrcOptVol& d) { if (!(&(d.optMaterial()))) { cerr<<" *** DrcOptVol::copy: optMaterial undefined."<=1) cout<<" DrcOptVol::DrcOptVol" <<"(const DrcOptVol&) name,copy: " <=1) cout<<" DrcOptVol::operator=" <<"(const DrcOptVol&) name,copy: " <((*this)) = d; // assignment of base class part. copy(d); } return *this; } //---------------------------------------------------------------------- void DrcOptVol::setOptMaterial(const DrcOptMatAbs& mat) { if (&mat) { delete m_optMat; m_optMat = mat.clone(); } } //---------------------------------------------------------------------- void DrcOptVol::propagate(DrcPhoton& ph) { static const double eps = 1.0e-9; if (verbosity()>=4) cout<<" DrcOptVol::propagate"<=4) ph.print(); list::const_iterator isurf; while (ph.fate() == Drc::PhotFlying) {// while ph.setDevice(this); //--------------- // search the closest surface which is not the surface where the photon is // right now. DrcSurfAbs* surf_closest=0; double path_length_min = numeric_limits::max(); for(isurf=m_listSurf.begin(); isurf != m_listSurf.end(); ++isurf) { if (verbosity()>=4) cout<<" check "<<(*isurf)->name() <<" (surface coupling = " <<(*isurf)->coupled()<<")"<surfaceHit(ph,pos_new,path_length)) { if (verbosity()>=4) cout<<" hit for "<<(*isurf)->name()<=4) cout<<" path_length "<eps) { path_length_min = path_length; surf_closest = (*isurf); } } else { if (verbosity()>=4) cout<<" no hit "<<(*isurf)->name()<=4) cout<<" no hit with any surface ->edge hit->lost"<=4) cout<<" closest "<name()<surfaceHit(ph,pos_new,path_length)) {// hit surf_closest if (verbosity()>=4) { XYZPoint pos_old(ph.position()); cout<<" hit, set pos from "<=4) cout<<" surface coupling = " <coupled() <<" for " <name()<coupled()) {// if surf_closest coupled list::const_iterator idev_coupled; list::const_iterator isurf_coupled; for (idev_coupled = (surf_closest->coupledDeviceList()).begin(), isurf_coupled = (surf_closest->coupledSurfaceList()).begin(); idev_coupled != (surf_closest->coupledDeviceList()).end(); ++idev_coupled, ++isurf_coupled) { if (verbosity()>=4) cout<<" coupling to dev,copy,surf= " <<(*idev_coupled)->name()<<"," <<(*idev_coupled)->copyNumber()<<"," <<(*isurf_coupled)->name()<isFlat()) { ph1.setPosition(ph.position()-ph.direction()*0.1); if (verbosity()>=4) cout<<" bring back from " <surfaceHit(ph1,pos_new,path_length); if (verbosity()>=4) cout<<" hit="<name()<reflectivity())) // Reflectivity defined { // check reflectivity XYZVector norm = surf_closest->normal(ph.position()); Drc::Reflectivity refl = Drc::ReflReflected; refl = surf_closest->reflectivity().reflectivity(ph,norm); if (refl == Drc::ReflAbsorbed) { if (verbosity()>=4) cout<<" DrcOptMirror::propagate: mirror absorbed"<=4) cout<<" Photon lost"<optMaterial()); if (verbosity()>=4) cout<<" opt_mat="<refIndex(ph.wavelength()); bool iref = refract(ph, surf_closest->normal(ph.position()), n2); if (verbosity()>=4) cout<<" refract in new volume flag = " <=4) cout<<" go into new volume " <<(*idev_coupled)->name()<propagate(ph); } else { break; // coupled surface loop, since phot. is reflected. } } else // screen or mirror... { // do not bring photons inside flat objects // ph.setPosition(ph.position()+2*eps*ph.direction()); (*idev_coupled)->propagate(ph); } if (ph.fate() != Drc::PhotFlying) break; } } } //---------- else {// uncoupled surfaces XYZVector norm = surf_closest->normal(ph.position()); if (&(surf_closest->reflectivity())) // Reflectivity defined { ph.setDevice(this); Drc::Reflectivity refl = Drc::ReflReflected; refl = surf_closest->reflectivity().reflectivity(ph,norm); if (refl == Drc::ReflAbsorbed) { if (verbosity()>=4) cout<<" DrcOptMirror::propagate: mirror absorbed"<=4) cout<<" Photon lost"<=4) cout<<" Photon lost"<0) ? normal : -normal; // // sin(alpha1) n2 // ----------- = -- (Snellius) // sin(alpha2) n1 // // alpaha1, alpha2 > 0 if (verbosity()>=4) cout<<" norm=" <=4) cout<<" dir1=" <=4) cout<<" norm*dir="< 1) // reflect photon { refract_flag = false; ph.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 = "<< dir2.X()<<" "<< dir2.Y()<<" "<< dir2.Z()<=4) { cout<<" refraction, brought it inside to " <