#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 "PndDrcPhoton.h" #include "PndDrcOptReflAbs.h" #include "PndDrcSurfAbs.h" #include "PndDrcOptMatAbs.h" #include "PndDrcOptDev.h" #include "PndDrcOptVol.h" #include "PndDrcUtil.h" //---------------------------------------------------------------------- PndDrcOptVol::PndDrcOptVol() { m_optMat = 0; } //---------------------------------------------------------------------- PndDrcOptVol::~PndDrcOptVol() { delete m_optMat; } //---------------------------------------------------------------------- PndDrcOptVol* PndDrcOptVol::clone() const { return new PndDrcOptVol(*this); } //---------------------------------------------------------------------- void PndDrcOptVol::copy(const PndDrcOptVol& d) { if (!(&(d.optMaterial()))) { cerr<<" *** PndDrcOptVol::copy: optMaterial undefined."<=1) cout<<" PndDrcOptVol::PndDrcOptVol" <<"(const PndDrcOptVol&) name,copy: " <=1) cout<<" PndDrcOptVol::operator=" <<"(const PndDrcOptVol&) name,copy: " <((*this)) = d; // assignment of base class part. copy(d); } return *this; } //---------------------------------------------------------------------- void PndDrcOptVol::setOptMaterial(const PndDrcOptMatAbs& mat) { if (&mat) { delete m_optMat; m_optMat = mat.clone(); } } //---------------------------------------------------------------------- void PndDrcOptVol::propagate(PndDrcPhoton& ph) { static const double eps = 1.0e-9; if (verbosity()>=4) cout<<" PndDrcOptVol::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. PndDrcSurfAbs* 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<<" PndDrcOptMirror::propagate: mirror absorbed"<=4) cout<<" Photon lost"<optMaterial()); if (verbosity()>=4) cout<<" opt_mat="<refIndex(ph.wavelength()); bool iref = ph.refract(surf_closest->normal(ph.position()), n1,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<<" PndDrcOptMirror::propagate: mirror absorbed"<=4) cout<<" Photon lost"<=4) cout<<" Photon lost"<