#ifndef H_J_PHOTON_PATH #define H_J_PHOTON_PATH /** * \author mjongen */ // c++ standard library includes #include #include #include #include #include #include // root includes #include "TObject.h" #include "TH1F.h" #include "TRandom3.h" // JPP includes #include "JGeometry3D/JPolyline3D.hh" #include "JGeometry3D/JVersor3D.hh" #include "JIO/JSerialisable.hh" namespace JMARKOV {} namespace JPP { using namespace JMARKOV; } namespace JMARKOV { using namespace std ; using namespace JGEOMETRY3D ; using namespace JGEOMETRY2D ; /** A photon path. This is basically a JPolyline3D with at least two vertices and a weight. **/ class JPhotonPath : public JPolyline3D, public JIO::JSerialisable { public: /// default constructor JPhotonPath() : n(2), weight(1) { resize(n) ; } /// constructor to actually be used JPhotonPath( int _nscat ) : n(_nscat+2), weight(1) { resize(n) ; } /// get a string with the path vertex positions string getString() ; /// get the total path length double getLength() ; void addVertex() { JPosition3D pos(0,0,0) ; addVertex(pos) ; } void addVertex( JPosition3D& pos ) ; /// Returns whether the photon path intersects a sphere of radius r at position pos bool hitsSphere( const JPosition3D& pos, double r ) ; /// Returns the position where the photon hits a sphere of radius r at position pos. If the photon does not hit, it returns (0,0,0). JPosition3D getSphereHitPosition( const JPosition3D& pos, double r ) ; /// return all coordinates where the photon path has the given x std::vector getPointsWithX( double x ) ; /// return all coordinates where the photon path has the given y std::vector getPointsWithY( double y ) ; /// return all coordinates where the photon path has the given z std::vector getPointsWithZ( double z ) ; JIO::JReader& read(JIO::JReader& in ) { // read number of vertices and adjust size accordingly in >> n ; if( n>0 ) resize(n) ; // read vertices for( iterator it=begin() ; it!=end() ; ++it ) in >> *it ; // read weight in >> weight ; return in ; } JIO::JWriter& write(JIO::JWriter& out ) const { // write size out << (int)size() ; // write vertices for( const_iterator it=begin() ; it!=end() ; ++it ) out << *it ; //it->getX() << it->getY() << it->getZ() ; // write weight out << weight ; return out ; } int n ; // the number of vertices in the path double weight ; } ; double JPhotonPath::getLength() { iterator v1 = begin() ; iterator v2(v1) ; ++v2 ; double L = 0 ; for( ; v2!=end() ; ++v1,++v2 ) { // length of path segment L += (*v2-*v1).getLength() ; } return L ; } void JPhotonPath::addVertex( JPosition3D& pos ) { ++n ; push_back(pos) ; } std::vector JPhotonPath::getPointsWithX( double x ) { std::vector res ; // loop over the path segments for( unsigned int i=1 ; ix) != (v2.getX()>x) ) { double frac = (x-v1.getX())/(v2.getX()-v1.getX()) ; res.push_back( v1+frac*(v2-v1) ) ; } } return res ; } string JPhotonPath::getString() { ostringstream oss ; for( unsigned int i=0 ; i JPhotonPath::getPointsWithY( double y ) { std::vector res ; // loop over the path segments for( unsigned int i=1 ; iy) != (v2.getY()>y) ) { double frac = (y-v1.getY())/(v2.getY()-v1.getY()) ; res.push_back( v1+frac*(v2-v1) ) ; } } return res ; } std::vector JPhotonPath::getPointsWithZ( double z ) { std::vector res ; // loop over the path segments for( unsigned int i=1 ; iz) != (v2.getZ()>z) ) { double frac = (z-v1.getZ())/(v2.getZ()-v1.getZ()) ; res.push_back( v1+frac*(v2-v1) ) ; } } return res ; } bool JPhotonPath::hitsSphere( const JPosition3D& pos, double r ) { // loop over the path segments for( unsigned int i=1 ; i (r_to_center/radius)^2 if( 1-ct*ct > r*r/(r_to_center*r_to_center) ) { // definitely no hit in this segment // continue with the next one continue ; } // the segment can be parametrized as x1 + xi * dir_seg // where xi is in the range [0,Lseg] // there are two possible solutions for xi double D = sqrt( r_to_center*r_to_center*(ct*ct-1) + r*r ) ; double xi1 = -r_to_center*ct + D ; if( xi1>0 && xi10 && xi2 (r_to_center/radius)^2 if( 1-ct*ct > r*r/(r_to_center*r_to_center) ) { // definitely no hit in this segment // continue with the next one continue ; } // the segment can be parametrized as x1 + xi * dir_seg // where xi is in the range [0,Lseg] // there are two possible solutions for xi double D = sqrt( r_to_center*r_to_center*(ct*ct-1) + r*r ) ; // first xi double xi1 = -r_to_center*ct + D ; if( xi1<0 || xi1>Lseg ) { xi1 = 1.1*Lseg ; } // second xi double xi2 = -r_to_center*ct - D ; // if this is a xi within the segment if( xi2>0 && xi20 && xi1