//////////////////////////////////////////////////////////////////////////////// /// \class RAT::LP::LightPath /// /// \brief A representation of a light path, with refractions. /// /// A LightPath object represents a path, regardless of how it was derived. /// It therefore doesn't include any geometry or geometry-dependent information. //////////////////////////////////////////////////////////////////////////////// #ifndef __RAT_LP_LightPath__ #define __RAT_LP_LightPath__ #include #include #include #include #include #include #include namespace RAT { namespace LP { class LightPath : public TObject { public: enum RegionType { Undefined, InnerAV, UpperInnerAV, LowerInnerAV, AV, Neck, Water, PMT }; /// Initialize properties of different regions. static void BeginOfRun(); /// Get refraction index for the given energy and region type. static Double_t GetRI(const RegionType regionType, const Double_t energy); /// Default constructor LightPath() : fEnergy(-999.0), fPoint(), fDirection(), fRegionType(), fFitter() { } /// Uniform straight line constructor LightPath(Double_t energy, const RAT::DU::Point3D& start, const RAT::DU::Point3D& stop, const RegionType startRegion, const RegionType stopRegion = Undefined) : fEnergy(energy), fPoint(), fDirection(), fRegionType(), fFitter() { TVector3 dir = stop.GetDirectionFrom(start); AddPoint(start, dir, startRegion); AddPoint(stop, dir, stopRegion == Undefined ? startRegion : stopRegion); } /// Returns true if this object contains a valid light path Bool_t IsValid() const { return fEnergy > 0.0; } /// Returns the name of the actual fitter used (which may have been delegated from the called fitter) const std::string GetFitter() const { return fFitter; } LightPath& SetFitter(const std::string name); Double_t GetEnergy() const { return fEnergy; } LightPath& SetEnergy(Double_t energy); /// Light path: a series of vertices, from 0 (start position). /// At each vertex, there is a location, direction into next region, /// and a region type for the next region. /// The last vertex will likely point "into" a PMT, /// with direction duplicated from previous vertex. /// Return number of vertices. /// /// @return Number of vertices, or <= 0 for invalid path. UInt_t GetPointCount() const { return fPoint.size(); } /// Return location of specified vertex. /// /// @return Point3D object of position, or origin of default coordinate system if invalid. /// (should this be something obviously wrong, like outside the cavern?) const RAT::DU::Point3D& GetPoint(UInt_t point) const { return fPoint.at(point); } /// Return direction from specified vertex. /// Note that the direction vector doesn't necessarily have unit length! /// /// @return Direction object (TVector3), or 0 vector if invalid light path. const TVector3& GetDirection(UInt_t initialPoint) const { return fDirection.at(initialPoint); } /// Return next region type following this vertex. /// /// @return The next region type, or Undefined if invalid light path. RegionType GetRegionType(UInt_t initialPoint) const { return fRegionType.at(initialPoint); } /// Derived outputs /// Return end position for this light path. const RAT::DU::Point3D& GetEndPos() const { return GetPoint(GetPointCount() - 1); } // actual end position /// Return direction into last vertex. const TVector3& GetIncidentVecOnPMT() const { return GetDirection(GetPointCount() - 1); } // or -2? /// Return direction from first vertex. const TVector3& GetInitialLightVec() const { return GetDirection(0); } /// Reset the light path to invalid state. /// /// @return reference to self. LightPath& Reset(); /// Clear points starting with identified point. /// /// @return reference to self. LightPath& ClearPoints(UInt_t point); /// Add a point to the end of this light path. /// /// @return reference to self. LightPath& AddPoint(const RAT::DU::Point3D& pos, const TVector3& dir, RegionType type); /// Change specified point, modifying previous and subsequent directions to match. /// Assume region is the same as before. /// /// @return reference to self. LightPath& SetPoint(UInt_t point, const RAT::DU::Point3D& pos); /// Change region type for a point along the path /// /// @return reference to self. LightPath& SetRegionType(UInt_t point, RegionType type); /// Insert a new point before the specified point, modifying directions to match. /// /// @return reference to self. LightPath& InsertPoint(UInt_t point, const RAT::DU::Point3D& pos, RegionType type); /// Delete the specified point /// /// @return reference to self. LightPath& DeletePoint(UInt_t point); /// Return total distance of light path, or < 0 if invalid. Double_t GetTotalDist() const; /// Return distance (mm) starting from specified vertex to next vertex, or < 0 if invalid. Double_t GetDist(UInt_t segment) const; // distance in specified segment /// Return distance (mm) summed over region type, or < 0 if invalid. Double_t GetDistByRegionType(RegionType regtype) const; // aggregate distance in a region type /// Return total time (in seconds) of light path, or < 0 if invalid. Double_t GetTotalTime() const; /// Calculate the cosine of the angle (theta) the light path makes with the bucket face. /// /// @param[in] pmtID The ID of the PMT for which cos(theta) is to be calculated. /// /// @return cos(theta), or something <= -999.0 for invalid path. Double_t GetCosThetaPMT(Int_t pmtID) const; private: static TGraph fInnerAVRI; static TGraph fUpperTargetRI; static TGraph fLowerTargetRI; static TGraph fAVRI; static TGraph fWaterRI; Double_t fEnergy; std::vector fPoint; std::vector fDirection; std::vector fRegionType; std::string fFitter; static void LoadRefractiveIndex(DBLinkPtr dbTable, TGraph& property); }; // class LightPath } // namespace LP } // namespace RAT #endif