//----------------------- // This Class's Header -- //----------------------- #include "CalorObjects/Pes2dCluster.hh" //----------------- // C/C++ Headers -- //----------------- #include #include //------------------------------- // Collaborating Class Headers -- //------------------------------- #include "CalorGeometry/PesGeometry.hh" #include "ErrorLogger_i/gERRLOG.hh" #include "TBuffer.h" #include "AbsEnv/AbsEnv.hh" // SET THE VERSION NUMBER : // bht 2 August updating the version number to include _energyV and _energyU // as part of the streamed data const Version_t Pes2dCluster::_VERSION = 2; // Default constructor : Pes2dCluster::Pes2dCluster() : _pesCluster0L(),_pesCluster1L(), _globalX(0.),_globalY(0.),_globalZ(0.), _globalErrX(0.),_globalErrY(0.) { _energyU = 0.; _energyV = 0.; #ifndef __CINT__ _vertex = Hep3Vector(0,0,0); #endif } // Copy constructor : Pes2dCluster::Pes2dCluster(const Pes2dCluster& oldPes) { _pesCluster0L = oldPes._pesCluster0L; _pesCluster1L = oldPes._pesCluster1L; _globalX = oldPes._globalX; _globalY = oldPes._globalY; _globalZ = oldPes._globalZ; _globalErrX = oldPes._globalErrX; _globalErrY = oldPes._globalErrY; _energyU = oldPes._energyU; _energyV = oldPes._energyV; _vertex = oldPes._vertex; } void Pes2dCluster::intersectPesClusters(Hep3Vector vertex) { // bool bMonte = AbsEnv::instance()->monteFlag(); // const PesCluster& pesCluster0 = _pesCluster0L.operator*(); const PesCluster& pesCluster1 = _pesCluster1L.operator*(); float octant = pesCluster0.octant(); float centroid0 = pesCluster0.centroidCM(); float centroid1 = pesCluster1.centroidCM(); _globalZ = (pesCluster0.clusterZ()+pesCluster1.clusterZ())/2.; _vertex = vertex; PesGeometry pesGeometry(centroid0, centroid1, _globalZ, octant, vertex); _globalX = pesGeometry.x(); _globalY = pesGeometry.y(); _globalZ = pesGeometry.z(); _globalErrX = 0; _globalErrY = 0; float _localR = sqrt(pow(_globalX,2) + pow(_globalY,2)); // we will only save the u and v layer energy. note that in the west (==0), // layer 0 is the u layer, while in the east, layer 1 is in the u layer. if (side() == 0) { if ( bMonte ) { setEnergy(pesCluster0.energy()*1.0, pesCluster1.energy()*1.0, _localR); } else { setEnergy(pesCluster0.energy(), pesCluster1.energy(), _localR); } _energy0 = _energyU; _energy1 = _energyV; } else { if ( bMonte ) { setEnergy(pesCluster1.energy()*1.0, pesCluster0.energy()*1.0, _localR); } else { setEnergy(pesCluster1.energy(), pesCluster0.energy(), _localR); } _energy0 = _energyV; _energy1 = _energyU; } } unsigned int Pes2dCluster::quality() const { unsigned int dead0,swap0,edge0,lowC0; unsigned int dead1,swap1,edge1,lowC1; unsigned int quality; // layer 0 quality quality = pesCluster0().quality(); dead0 = quality & 0xf; swap0 = (quality >> 4) & 0xf; edge0 = (quality >> 8) & 0xf; lowC0 = (quality >> 12) & 0xf; // layer 1 quality quality = pesCluster1().quality(); dead1 = quality & 0xf; swap1 = (quality >> 4) & 0xf; edge1 = (quality >> 8) & 0xf; lowC1 = (quality >> 12) & 0xf; // cut off overruns (highly unlikely, but just in case) int dead = dead0 + dead1; if (dead > 15 || dead < 0) dead = 15; int swap = swap0 + swap1; if (swap > 15 || swap < 0) swap = 15; int edge = edge0 + edge1; if (edge > 15 || edge < 0) edge = 15; int lowC = lowC0 + lowC1; if (lowC > 15 || lowC < 0) lowC = 15; // 2d cluster quality quality = ( (dead & 0xf) | ((swap << 4) & 0xf0) | ((edge << 8) & 0xf00) | ((lowC << 12) & 0xf000) ); return quality; } void Pes2dCluster::print(std::ostream& os) const { os << " Pes2dCluster : " << "\n" ; os << " X-position = " << _globalX << " +/- " << _globalErrX << "\n"; os << " Y-position = " << _globalY << " +/- " << _globalErrY << "\n"; os << " Z-position = " << _globalZ << "\n"; os << " u-Energy = "<<_energyU <monteFlag(); // // 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 // I = I_0 * exp(-x/lambda) // 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. //129.0 is the distance, in cm, to the edge of the chamber. float attenuation = 341.0;//attenuation in cm. float position ; position = (129.0 - localR ) / cos(M_PI/8.); // std::cout<<"localR "<> version; if (version == 1) { _pesCluster0L.Streamer(iobuffer); _pesCluster1L.Streamer(iobuffer); iobuffer >> _globalX >> _globalY >> _globalZ >> _globalErrX >> _globalErrY ; } else if (version == 2) { _pesCluster0L.Streamer(iobuffer); _pesCluster1L.Streamer(iobuffer); iobuffer >> _globalX >> _globalY >> _globalZ >> _globalErrX >> _globalErrY >> _energyU >> _energyV; if (side() == 0) { _energy0 = _energyU; _energy1 = _energyV; } else { _energy0 = _energyV; _energy1 = _energyU; } } else { ERRLOG( ELerror, "Unsupported Pes2dCluster version" ) << "@SUB=Pes2dCluster::Streamer()" << "Pes2dCluster cannot be read" << endmsg; } } //----------------------------------------------------------------------------- // Write object to buffer //----------------------------------------------------------------------------- else if (iobuffer.IsWriting()) { ShowerMaxCluster::Streamer(iobuffer); iobuffer << class_version(); _pesCluster0L.Streamer(iobuffer); _pesCluster1L.Streamer(iobuffer); iobuffer << _globalX << _globalY << _globalZ << _globalErrX << _globalErrY << _energyU << _energyV ; } //----------------------------------------------------------------------------- // Unanticipated action //----------------------------------------------------------------------------- else { ERRLOG( ELerror, "Pes2dCluster::Streamer()") << "@SUB=Pes2dCluster::Streamer" << "NOTHING DONE." << endmsg; } } bool Pes2dCluster::postread(EventRecord* p) { /* bool baseread = ShowerMaxCluster::postread(p); bool postreadL0 = _pesCluster0L.restore(p); bool postreadL1 = _pesCluster1L.restore(p); return (baseread && postreadL0 && postreadL1);*/ // changed since valuevector does this for us now , i.e. we no longer need // to do our own postreading. 5.mar 2002 Benn Tannenbaum return true; } bool Pes2dCluster::prewrite(EventRecord* p) { bool basewrite = ShowerMaxCluster::prewrite(p); return (basewrite); } /* return the global eta*/ float Pes2dCluster::plug2dClusterEta() const { PesGeometry pesGeometry(_globalX, _globalY, _globalZ); return pesGeometry.eta(); } float Pes2dCluster::plug2dClusterEtaErr() const { return sqrt(_globalErrX*_globalErrX + _globalErrY*_globalErrY); } /* return the global phi*/ float Pes2dCluster::plug2dClusterPhi() const { PesGeometry pesGeometry(_globalX, _globalY, _globalZ); return pesGeometry.phi(); } float Pes2dCluster::plug2dClusterPhiErr() const { return sqrt(_globalErrX*_globalErrX + _globalErrY*_globalErrY); }