CMS 3D CMS Logo

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