CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoTBCalo/EcalTBAnalysisCoreTools/src/TBPositionCalc.cc

Go to the documentation of this file.
00001 #include "RecoTBCalo/EcalTBAnalysisCoreTools/interface/TBPositionCalc.h"
00002 
00003 using namespace std;
00004 
00005 TBPositionCalc::TBPositionCalc(const std::map<std::string,double>& providedParameters, std::string const & fullMapName, const CaloSubdetectorGeometry *passedGeometry ) 
00006 {
00007   // barrel geometry initialization
00008   if(passedGeometry == NULL)
00009     throw(std::runtime_error("\n\n TBPositionCalc: wrong initialization.\n\n"));
00010   theGeometry_ = passedGeometry;
00011   
00012   // parameters initialization
00013   param_LogWeighted_ = providedParameters.find("LogWeighted")->second;
00014   param_X0_ = providedParameters.find("X0")->second;
00015   param_T0_ = providedParameters.find("T0")->second; 
00016   param_W0_ = providedParameters.find("W0")->second;
00017 
00018   theTestMap = new EcalTBCrystalMap(fullMapName);
00019 }
00020 
00021 TBPositionCalc::~TBPositionCalc()
00022 {
00023   if (theTestMap) delete theTestMap;
00024 }
00025 
00026 CLHEP::Hep3Vector TBPositionCalc::CalculateTBPos(const std::vector<EBDetId>& upassedDetIds, int myCrystal, EcalRecHitCollection const *passedRecHitsMap) {
00027   
00028   std::vector<EBDetId> passedDetIds = upassedDetIds;
00029   // throw an error if the cluster was not initialized properly  
00030   if(passedRecHitsMap == NULL)
00031     throw(std::runtime_error("\n\n TBPositionCalc::CalculateTBPos called uninitialized.\n\n"));
00032   
00033   // check DetIds are nonzero
00034   std::vector<EBDetId> validDetIds;
00035   std::vector<EBDetId>::const_iterator iter;
00036   for (iter = passedDetIds.begin(); iter != passedDetIds.end(); iter++) {
00037     if (((*iter) != DetId(0)) 
00038         && (passedRecHitsMap->find(*iter) != passedRecHitsMap->end()))
00039       validDetIds.push_back(*iter);
00040   }
00041   passedDetIds.clear();
00042   passedDetIds = validDetIds;
00043   
00044   // computing the position in the cms frame
00045   CLHEP::Hep3Vector cmsPos = CalculateCMSPos(passedDetIds, myCrystal, passedRecHitsMap);
00046 
00047   // computing the rotation matrix (from CMS to TB)
00048   CLHEP::HepRotation *CMStoTB = new CLHEP::HepRotation();
00049   computeRotation(myCrystal, (*CMStoTB));
00050 
00051   // moving to testbeam frame
00052   CLHEP::Hep3Vector tbPos = (*CMStoTB)*cmsPos;
00053   delete CMStoTB;
00054 
00055   return tbPos;
00056 } 
00057 
00058 
00059 CLHEP::Hep3Vector TBPositionCalc::CalculateCMSPos(const std::vector<EBDetId>& passedDetIds, int myCrystal, EcalRecHitCollection const *passedRecHitsMap) {
00060   
00061   // Calculate the total energy
00062   double thisEne = 0;
00063   double eTot = 0;
00064   EBDetId myId;
00065   std::vector<EBDetId>::const_iterator myIt;
00066   for (myIt = passedDetIds.begin(); myIt !=  passedDetIds.end(); myIt++) {
00067     myId = (*myIt);
00068     EcalRecHitCollection::const_iterator itt = passedRecHitsMap->find(myId);
00069     thisEne = itt->energy();
00070     eTot += thisEne;
00071   }
00072 
00073   // Calculate shower depth
00074   float depth = 0.;
00075   if(eTot<=0.) {
00076     edm::LogError("NegativeClusterEnergy") << "cluster with negative energy: " << eTot << ", setting depth to 0.";
00077   } else {
00078     depth = param_X0_ * (param_T0_ + log(eTot));
00079   }
00080 
00081   // Get position of the central crystal from shower depth 
00082   EBDetId maxId_ = EBDetId(1, myCrystal, EBDetId::SMCRYSTALMODE);
00083   const CaloCellGeometry* center_cell = theGeometry_ -> getGeometry(maxId_);
00084   GlobalPoint center_pos = 
00085     (dynamic_cast<const TruncatedPyramid*>(center_cell))->getPosition(depth);
00086 
00087   // Loop over the hits collection
00088   double weight        = 0;
00089   double total_weight  = 0;
00090   double cluster_theta = 0;
00091   double cluster_phi   = 0;
00092   std::vector<EBDetId>::const_iterator myIt2;
00093   for (myIt2 = passedDetIds.begin(); myIt2 != passedDetIds.end(); myIt2++) {
00094 
00095     // getting weights
00096     myId = (*myIt2);
00097     EcalRecHitCollection::const_iterator itj = passedRecHitsMap->find(myId);
00098     double ener = itj->energy();
00099 
00100     if (param_LogWeighted_) {
00101       if(eTot<=0.) { weight = 0.; } 
00102       else { weight = std::max(0., param_W0_ + log( fabs(ener)/eTot) ); }
00103     } else {
00104       weight = ener/eTot;
00105     }
00106     total_weight += weight;
00107 
00108     // weighted position of this detId
00109     const CaloCellGeometry* jth_cell = theGeometry_->getGeometry(myId);
00110     GlobalPoint jth_pos = dynamic_cast<const TruncatedPyramid*>(jth_cell)->getPosition(depth);    
00111     cluster_theta += weight*jth_pos.theta();
00112     cluster_phi   += weight*jth_pos.phi();
00113   }
00114   
00115   // normalizing
00116   cluster_theta /= total_weight;
00117   cluster_phi /= total_weight;
00118   if (cluster_phi > M_PI) { cluster_phi -= 2.*M_PI; }
00119   if (cluster_phi < -M_PI){ cluster_phi += 2.*M_PI; }
00120 
00121   // position in the cms frame
00122   double radius = sqrt(center_pos.x()*center_pos.x() + center_pos.y()*center_pos.y() + center_pos.z()*center_pos.z());
00123   double xpos = radius*cos(cluster_phi)*sin(cluster_theta);
00124   double ypos = radius*sin(cluster_phi)*sin(cluster_theta); 
00125   double zpos = radius*cos(cluster_theta);
00126 
00127   return CLHEP::Hep3Vector(xpos, ypos, zpos);
00128 }
00129 
00130 // rotation matrix to move from the CMS reference frame to the test beam one  
00131 void TBPositionCalc::computeRotation(int MyCrystal, CLHEP::HepRotation &CMStoTB){
00132   
00133   // taking eta/phi of the crystal
00134 
00135   double myEta   = 999.;
00136   double myPhi   = 999.;
00137   double myTheta = 999.;
00138   theTestMap->findCrystalAngles(MyCrystal, myEta, myPhi);
00139   myTheta = 2.0*atan(exp(-myEta));
00140 
00141   // matrix
00142   CLHEP::HepRotation * fromCMStoTB = new CLHEP::HepRotation();
00143   double angle1 = 90.*deg - myPhi;
00144   CLHEP::HepRotationZ * r1 = new CLHEP::HepRotationZ(angle1);
00145   double angle2 = myTheta;
00146   CLHEP::HepRotationX * r2 = new CLHEP::HepRotationX(angle2);
00147   double angle3 = 90.*deg;
00148   CLHEP::HepRotationZ * r3 = new CLHEP::HepRotationZ(angle3);
00149   (*fromCMStoTB) *= (*r3);
00150   (*fromCMStoTB) *= (*r2);
00151   (*fromCMStoTB) *= (*r1);
00152   
00153   CMStoTB = (*fromCMStoTB);
00154 
00155   delete fromCMStoTB;
00156   delete r1;
00157   delete r2;
00158   delete r3;
00159 }
00160 
00161