/** \class Pes2dCluster \author Dave Waters Description: Class for 2-dimensional plug strip clusters - i.e. intersections of 2 1-dimensional clusters. The simple-minded intersection algorithm was copied and corrected from the class PlugClusterSeed in TrackingHL. This class derived from ShowerMaxCluster. Revision History: \date 15-Mar-2000 Dave Waters Initial creation. \date 10-May-2000 Bob Wagner Change return type of region() to Detector which is enumeration in CalConstants.hh \date 01-Jun-2000 Dave Waters Add version information. \date 18-Jan-2001 Benn Tannenbaum Added methods to return global eta & phi \date 14-May-2001 Benn Tannenbaum Rewrote intersection finding code \date 23 May 2001 Benn Tannenbaum Added code to correct the energy for attenuation through the green fiber. \date 2 August 2001 Benn Tannenbaum Added version 2 to the streamer. This now streams out the u and v energy. Bug fix! \date 1 October 2001 Benn Tannenbaum Changed from 1 and 2 layer ID to u and v layer ID, matching the hardware. \date 9 October 2001 Benn Tannenbaum Misunderstanding on my part. I was returning the sum of the u and v layer energy as the energy of the cluster. It should instead be just the u layer. I've changed the energy() method to do that, added an averageEnergy() method and also an et() method. \date 17 October 2001 Benn Tannenbaum To clear up a mistake and hopefully reduce some confusion, I am changing all the internal calculations to be with pesCluster0 and PesCluster1 to reflect the layer number from which they come. I will return quantities for both the 0/1 layer and for the U/V layer. Please see the notes for PlugStrip for details on what's really what. \date 8 April 2003 Alon Attal: Get Z position from PesGeometry which has is corrected for plug alignment. \todo At present, the code that calculates the energy correction due to attenuation in the green fiber uses a constant attenuation length. This will almost certainly change during the run and may vary from fiber to fiber. We have space in the database to allow for this to change on a strip to strip basis but I've not yet determined a good way to get this information from the strip to the cluster. \todo At present, the code that calculates the energy correction due to attenuation in the green fiber uses assumes all green fibers stop at the edge of the chamber. This is wrong, as the fibers extend somewhat past the edge of the chamber. Futhermore, different fibers are different lengths. I have have no idea what to do about this, but it must be dealt with. \date 06 Nov 2004 Brian Mohr: Include event vertex information (including beam line offset). \date 06 Nov 2004 Brian Mohr: Add tentative quality variable to indicate dead, cable swapped or edge strips. \date 14 Feb 2005 Brian Mohr: Removed quality as a class memeber. quality() accessor now derives its return value from accessors to the streamed 1d cluster quality */ #ifndef PES2DCLUSTER_HH_ #define PES2DCLUSTER_HH_ #include //--------------- // C++ Headers -- //--------------- #include "Edm/ConstHandle.hh" #include "CalorObjects/PesCluster.hh" #include "CalorObjects/PesClusterColl.hh" #include "CalorObjects/ShowerMaxCluster.hh" #include "Rtypes.h" #include "StorableContainers/ValueVectorLink.hh" #ifndef __CINT__ #include "CLHEP/Vector/ThreeVector.h" #endif //---------------------------------- // Forward Declaration of Classes -- //---------------------------------- class HepPoint3D; //***************************************************************************** // Class Declaration //***************************************************************************** class Pes2dCluster : public ShowerMaxCluster { //=========================================================================== // Minimal functions for good class definition //=========================================================================== public: Pes2dCluster(); // default constructor Pes2dCluster(const Pes2dCluster&); // copy constructor virtual ~Pes2dCluster(){} //=========================================================================== // Accessor functions required by base class //=========================================================================== virtual float clusterWidth() const; virtual Detector region() const; virtual float energy() const; virtual float localCoord() const; virtual float globalCoord() const; virtual int module() const; virtual int side() const; virtual int view() const; //=========================================================================== // Pes2dCluster specific accessor functions : //=========================================================================== const PesCluster& pesClusterU() const; const PesCluster& pesClusterV() const; const PesCluster& pesCluster0() const; const PesCluster& pesCluster1() const; /** Present the individual coordinates :*/ float plug2dClusterX() const; float plug2dClusterY() const; float plug2dClusterZ() const; /** return the global eta of this 2-d cluster*/ float plug2dClusterEta() const; float plug2dClusterEtaErr() const; /** return the global phi of this 2-d cluster*/ float plug2dClusterPhi() const; float plug2dClusterPhiErr() const; #ifndef __CINT__ /** Present the intersection point as a HepPoint3D :*/ HepPoint3D plug2dClusterLocation() const; #endif // !__CINT__ /** Errors on the intersect coordinates :*/ float plug2dClusterErrX() const; float plug2dClusterErrY() const; /** number of strips*/ int plug2dUstrips() const; int plug2dVstrips() const; int plug2d0strips() const; int plug2d1strips() const; /** energy on each layer*/ float plug2dUenergy() const; float plug2dVenergy() const; float plug2d0energy() const; float plug2d1energy() const; /** average energy: (u + 1.2 v)/2.2 */ float plug2dAverageEnergy() const; /** Transverse energy on the u layer*/ float plug2dEt() const; /** remaining location information*/ int plug2dOctant() const; /** quality word -- combines qualities of 1d clusters **/ unsigned int quality() const; #ifndef __CINT__ Hep3Vector vertex() const {return _vertex;} // vertex used in cluter location #endif //=========================================================================== // Set methods : //=========================================================================== void setPesCluster0(const ConstHandle& pesClusterCollCH, const PesClusterColl::const_iterator& ci); void setPesCluster1(const ConstHandle& pesClusterCollCH, const PesClusterColl::const_iterator& ci); //=========================================================================== // Additional functions required by base class //=========================================================================== #ifndef __CINT__ void intersectPesClusters(Hep3Vector vertex); #endif //=========================================================================== // Operator overloads //=========================================================================== Pes2dCluster& operator = (const Pes2dCluster&); bool operator == (const Pes2dCluster&) const; bool operator != (const Pes2dCluster&) const; virtual void print(std::ostream& = std::cout) const; //-------------------------------------------------------------------------- // Input/Output Requirements: // Child classes should call base class methods, // then treat own data members //-------------------------------------------------------------------------- virtual void Streamer(TBuffer& iobuffer) ; virtual bool postread(EventRecord* p_record) ; virtual bool prewrite(EventRecord* p_record) ; // VERSION INFORMATION : static Version_t class_version(){return _VERSION;} private: //=========================================================================== // Data members of class //=========================================================================== ValueVectorLink _pesCluster0L; ValueVectorLink _pesCluster1L; float _globalX,_globalY,_globalZ; float _globalErrX,_globalErrY; float _energyU, _energyV, _energy0, _energy1; #ifndef __CINT__ Hep3Vector _vertex; #endif float _theta() const; /** Need to correct for attenuation through the fiber. at present, I will use a constant attenuation length. This should be changed at some time in the future, as the attenuation length may change, and if may change differently for different fibers. I am using 3.41 meters. I'll use a little geometry to determine through how much fiber the signal passed. I know the distance from the beampipe to the centroid of the cluster. I know the distance from the beampipe to the outer edge of the chamber. Since the two layers are at 45 degrees, we get a triangle that has angles of 22.5, 67.5 and 90. Thus, the distance that the signal travels through the fiber is the distance from the edge of the chamber divided by cos(22.5). TaDa! The intensity of light in a fiber is given roughly by \f[I = I\_0 * \exp(-x/\lambda)\f] where I_0 is the original intensity, x is the position of the injection of the light and lambda is the attenuation length of the fiber. We have I and want to get I_0. This is only approximate, as it doesn't include the length of the fiber from edge of the chamber to the connector. Not sure what to do about that. */ void setEnergy(float energyU, float energyV, float localR); // EDM VERSION : static const Version_t _VERSION; }; //=========================================================================== // Inline functions //=========================================================================== inline std::ostream& operator << (std::ostream& os, const Pes2dCluster& inter) { inter.print(os); return os; } #include "CalorObjects/Pes2dCluster.icc" #endif // !PES2DCLUSTER_HH_