/* Detector.h Detector Class (Sep 2008) To simulate detector effects */ class Detector{ public: Detector(); void ecalFast(Particle&, double =0.0, double =0.0, double =0.0, double =0.0); }; //------------------------------------------------------------------------------ // The constructor // Detector::Detector(){ } //------------------------------------------------------------------------------ // ecalFast // Simulates the effects of ECAL by smearing four-momenta of the photon // according to: following energy and spatial resolutions: // dE = R*SQRT(E) + k*E (energy resolution) // dThetaPhi = A/sqrt(E) + B (angular resolution) // where E is energy(in GeV). // // For ALEPH: R=0.18 and k=0.009; A = 2.5 mrad.GeV^0.5 and B = 0.25 mrad // For ATLAS: R=0.10 and k=0.007 // For CMS : R=0.04 and k=0.005 //------------------------------------------------------------------------------ void Detector::ecalFast(Particle& par, double R, double k, double A, double B){ // Get the four-momenta of the particle double pX = par.px; double pY = par.py; double pZ = par.pz; double E = par.E; double pAbs = par.pAbs; double pt = par.pt; // Determine the direction of the particle double cosPhi = pX/pt; double sinPhi = pY/pt; double cosTheta = pZ/pAbs; double sinTheta = sqrt(1.0-cosTheta*cosTheta); // Energy resolution in GeV double dE = R*sqrt(E) + k*E; // Modify the energy of the particle by applying a gaussian smearing // and evaluate the components of the space-momentum. (Do not modify the direction) E = Random::Gauss(E, dE); pAbs = sqrt(E*E-par.m*par.m); pX = pAbs*sinTheta*cosPhi; pY = pAbs*sinTheta*sinPhi; pZ = pAbs*cosTheta; // Now modify the direction of the momentum vector to simulate angular resolution if(fabs(A)>0.0 && fabs(B)>0.0){ // Spatial (angular) resolution in radians double dThetaPhi = (A/sqrt(E) + B)*1.0e-3; // transform momentum vector to a new coordinate system // whose y axis is directed in to vector p double theta = acos(pY/pAbs); double phi = atan(pZ/pX); if(pZ<0.0 && pX<0.0) phi += M_PI; if(pZ>0.0 && pX<0.0) phi += M_PI; double Spx = cos(theta)*cos(phi)*pX - sin(theta)*pY + cos(theta)*sin(phi)*pZ; double Spy = sin(theta)*cos(phi)*pX + cos(theta)*pY + sin(theta)*sin(phi)*pZ; double Spz =-sin(phi)*pX + cos(phi)*pZ; double Sp = sqrt(Spx*Spx + Spy*Spy + Spz*Spz); // smear (modify) the momentum vector in the new coordinate double alpha = 2.0*M_PI*Random::Flat(); double beta = Random::Gauss(0.0, dThetaPhi); // RMS value of smearing angle Spx = Sp*sin(beta)*cos(alpha); Spy = Sp*cos(beta); Spz = Sp*sin(beta)*sin(alpha); // inverse transform (back to original coordinate) pX = sin(theta)*cos(phi)*Spy + cos(theta)*cos(phi)*Spx - sin(phi)*Spz; pY = cos(theta)*Spy - sin(theta)*Spx; pZ = sin(theta)*sin(phi)*Spy + cos(theta)*sin(phi)*Spx + cos(phi)*Spz; } // Reset the four-momentum par.p4( pX, pY, pZ, E ); }