CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/Calibration/HcalCalibAlgos/src/hcalCalibUtils.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <fstream>
00003 #include <algorithm>
00004 #include <numeric>
00005 
00006 #include "TString.h"
00007 #include "Calibration/HcalCalibAlgos/interface/hcalCalibUtils.h"
00008 
00009 using namespace std;
00010 
00011 void sumDepths(vector<TCell> &selectCells) {
00012     
00013   // Assignes teh sum of the energy in cells with the same iEta, iPhi to the cell with depth=1.
00014   // All cells with depth>1 are removed form the container. If
00015   // the cell at depth=1 is not present: create it and follow the procedure. 
00016     
00017   if (selectCells.size()==0) return;
00018 
00019   vector<TCell> selectCellsDepth1;
00020   vector<TCell> selectCellsHighDepth;
00021     
00022   //
00023   // NB: Here we add depth 3 for iEta==16 in *HE* to the value in the barrel
00024   // this approach is reflected in several of the following loops: make sure
00025   // to check when making changes.
00026   //
00027   // In some documents it is described as having depth 1, the mapping in CMSSW uses depth 3.
00028     
00029   for (vector<TCell>::iterator i_it = selectCells.begin(); i_it != selectCells.end(); ++i_it) {
00030     if (HcalDetId(i_it->id()).depth()==1) {
00031       selectCellsDepth1.push_back(*i_it);
00032     }
00033     else {
00034       selectCellsHighDepth.push_back(*i_it);
00035     }
00036   }
00037     
00038     
00039     
00040   // case where depth 1 has zero energy, but higher depths with same (iEta, iPhi) have energy.
00041   // For iEta<15 there is one depth -> selectCellsHighDepth is empty and we do not get in the loop.
00042   for (vector<TCell>::iterator i_it2 = selectCellsHighDepth.begin(); i_it2 != selectCellsHighDepth.end(); ++i_it2) {
00043 
00044 
00045     // protect against corrupt data      
00046     if (HcalDetId(i_it2->id()).ietaAbs()<15 && HcalDetId(i_it2->id()).depth()>1) {
00047       cout << "ERROR!!! there are no HB cells with depth>1 for iEta<15!\n"
00048            << "Check the input data..." << endl;
00049       cout << "HCalDetId: "  <<  HcalDetId(i_it2->id()) << endl;
00050       return;
00051     }
00052 
00053 
00054     bool foundDepthOne = false;
00055     for (vector<TCell>::iterator i_it = selectCellsDepth1.begin(); i_it != selectCellsDepth1.end(); ++i_it) {
00056       if (HcalDetId(i_it->id()).ieta()==HcalDetId(i_it2->id()).ieta() && 
00057           HcalDetId(i_it->id()).iphi()==HcalDetId(i_it2->id()).iphi())
00058         foundDepthOne = true;
00059       continue;
00060     }
00061     if (!foundDepthOne) { // create entry for depth 1 with 0 energy
00062         
00063       UInt_t newId;
00064       if (abs(HcalDetId(i_it2->id()).ieta())==16)
00065         newId = HcalDetId(HcalBarrel, HcalDetId(i_it2->id()).ieta(), HcalDetId(i_it2->id()).iphi(), 1);
00066       else
00067         newId = HcalDetId(HcalDetId(i_it2->id()).subdet(), HcalDetId(i_it2->id()).ieta(), HcalDetId(i_it2->id()).iphi(), 1);
00068         
00069       selectCellsDepth1.push_back(TCell(newId, 0.0));
00071     }
00072   }
00073     
00074   for (vector<TCell>::iterator i_it = selectCellsDepth1.begin(); i_it != selectCellsDepth1.end(); ++i_it) {
00075     for (vector<TCell>::iterator i_it2 = selectCellsHighDepth.begin(); i_it2 != selectCellsHighDepth.end(); ++i_it2) {
00076       if (HcalDetId(i_it->id()).ieta()==HcalDetId(i_it2->id()).ieta() && 
00077           HcalDetId(i_it->id()).iphi()==HcalDetId(i_it2->id()).iphi()) {
00078         i_it->SetE(i_it->e()+i_it2->e());
00079         i_it2->SetE(0.0); // paranoid, aren't we...
00080       }
00081     }
00082   }
00083     
00084   // replace the original vectors with the new ones
00085   selectCells = selectCellsDepth1;
00086     
00087   return;
00088 }
00089 
00090 
00091 void combinePhi(vector<TCell> &selectCells) {
00092   
00093   // Map: NxN -> N cluster
00094   // Comine the targetE of cells with the same iEta
00095 
00096   if (selectCells.size()==0) return;
00097     
00098   // new container for the TCells
00099   // dummy cell id created with iEta; iPhi=1; depth
00100   // if combinePhi() is run after combining depths, depth=1
00101   vector<TCell> combinedCells;
00102     
00103   map<UInt_t, vector<Float_t> > etaSliceE; // keyed by id of cell with iEta and **iPhi=1**
00104     
00105   // map the cells to the eta ring
00106   vector<TCell>::iterator i_it = selectCells.begin();
00107   for (; i_it != selectCells.end(); ++i_it) {
00108     DetId id = HcalDetId(i_it->id());
00109     UInt_t thisKey = HcalDetId(HcalDetId(id).subdet(), HcalDetId(id).ieta(), 1, HcalDetId(id).depth() );
00110     etaSliceE[thisKey].push_back(i_it->e());
00111   }
00112     
00113   map<UInt_t, vector<Float_t> >::iterator m_it = etaSliceE.begin();
00114   for (; m_it != etaSliceE.end(); ++m_it) {
00115     combinedCells.push_back(TCell(m_it->first, accumulate(m_it->second.begin(), m_it->second.end(), 0.0) ) );
00116   }
00117     
00118   // replace the original TCell vector with the new one
00119   selectCells = combinedCells;
00120     
00121 }
00122 
00123 
00124 void combinePhi(vector<TCell> &selectCells, vector<TCell> &combinedCells) {
00125   
00126   // Map: NxN -> N cluster
00127   // Comine the targetE of cells with the same iEta
00128 
00129   if (selectCells.size()==0) return;
00130     
00131   map<UInt_t, vector<Float_t> > etaSliceE; // keyed by id of cell with iEta and **iPhi=1**
00132     
00133   // map the cells to the eta ring
00134   vector<TCell>::iterator i_it = selectCells.begin();
00135   for (; i_it != selectCells.end(); ++i_it) {
00136     DetId id = HcalDetId(i_it->id());
00137     UInt_t thisKey = HcalDetId(HcalDetId(id).subdet(), HcalDetId(id).ieta(), 1, HcalDetId(id).depth() );
00138     etaSliceE[thisKey].push_back(i_it->e());
00139   }
00140     
00141   map<UInt_t, vector<Float_t> >::iterator m_it = etaSliceE.begin();
00142   for (; m_it != etaSliceE.end(); ++m_it) {
00143     combinedCells.push_back(TCell(m_it->first, accumulate(m_it->second.begin(), m_it->second.end(), 0.0) ) );
00144   }
00145         
00146 }
00147 
00148 
00149 
00150 void getIEtaIPhiForHighestE(vector<TCell>& selectCells, Int_t& iEtaMostE, UInt_t& iPhiMostE) {
00151   
00152   
00153   vector<TCell> summedDepthsCells = selectCells;
00154 
00155   sumDepths(summedDepthsCells);  
00156   vector<TCell>::iterator  highCell = summedDepthsCells.begin();
00157    
00158   // sum depths locally to get highest energy tower
00159  
00160   Float_t highE = -999;
00161     
00162   for (vector<TCell>::iterator it=summedDepthsCells.begin(); it!=summedDepthsCells.end(); ++it) {
00163     if (highE < it->e()) {
00164       highCell = it;
00165       highE = it->e();
00166     }
00167   }
00168 
00169   iEtaMostE = HcalDetId(highCell->id()).ieta();
00170   iPhiMostE = HcalDetId(highCell->id()).iphi();
00171 
00172   return;
00173 }
00174 
00175 
00176 //
00177 // Remove RecHits outside the 3x3 cluster and replace the  vector that will
00178 // be used in the minimization. Acts on "event" level.
00179 // This can not be done for iEta>20 due to segmentation => in principle the result should be restricted
00180 // to iEta<20. Attempted to minimize affect at the boundary without a sharp jump.
00181 
00182 void filterCells3x3(vector<TCell>& selectCells, Int_t iEtaMaxE, UInt_t iPhiMaxE) {
00183     
00184   vector<TCell> filteredCells;
00185     
00186   Int_t dEta, dPhi;
00187     
00188   for (vector<TCell>::iterator it=selectCells.begin(); it!=selectCells.end(); ++it) {
00189 
00190     Bool_t passDEta = false;
00191     Bool_t passDPhi = false;
00192 
00193     dEta = HcalDetId(it->id()).ieta() - iEtaMaxE;
00194     dPhi = HcalDetId(it->id()).iphi() - iPhiMaxE;
00195 
00196     if (dPhi >  36) dPhi -= 72;
00197     if (dPhi < -36) dPhi += 72; 
00198 
00199     if (abs(dEta)<=1 || (iEtaMaxE * HcalDetId(it->id()).ieta() == -1)) passDEta = true;
00200 
00201     if (abs(iEtaMaxE)<=20) {
00202 
00203       if (abs(HcalDetId(it->id()).ieta())<=20) {
00204         if (abs(dPhi)<=1) passDPhi = true;
00205       }
00206       else {
00207         // iPhi is labelled by odd numbers
00208         if (iPhiMaxE%2==0){
00209           if (abs(dPhi)<=1) passDPhi = true;
00210         }
00211         else {
00212           if (dPhi== -2 || dPhi==0) passDPhi = true;
00213         }
00214       }
00215 
00216     } // if hottest cell with iEta<=20
00217   
00218     else {      
00219       if (abs(HcalDetId(it->id()).ieta())<=20) {
00220         if (abs(dPhi)<=1 || dPhi==2)  passDPhi = true;
00221       }
00222       else {
00223         if (abs(dPhi)<=2) passDPhi = true;
00224       }
00225     } // if hottest cell with iEta>20
00226                  
00227     if (passDEta && passDPhi) filteredCells.push_back(*it);
00228   }
00229     
00230   selectCells = filteredCells;
00231 
00232   return;
00233 }
00234               
00235 //
00236 // Remove RecHits outside the 5x5 cluster and replace the  vector that will
00237 // be used in the minimization. Acts on "event" level
00238 // In principle the ntuple should be produced with 5x5 already precelected
00239 //
00240 // Size for iEta>20 is 3x3, but the segmentation changes by x2 in phi.
00241 // There is some bias in the selection of towers near the boundary
00242 
00243 void filterCells5x5(vector<TCell>& selectCells, Int_t iEtaMaxE, UInt_t iPhiMaxE) {
00244     
00245   vector<TCell> filteredCells;
00246     
00247   Int_t dEta, dPhi;
00248     
00249   for (vector<TCell>::iterator it=selectCells.begin(); it!=selectCells.end(); ++it) {
00250  
00251     dEta = HcalDetId(it->id()).ieta() - iEtaMaxE;
00252     dPhi = HcalDetId(it->id()).iphi() - iPhiMaxE;
00253   
00254     if (dPhi >  36) dPhi -= 72;
00255     if (dPhi < -36) dPhi += 72; 
00256 
00257     bool passDPhi = (abs(dPhi)<3);
00258 
00259     bool passDEta = (abs(dEta)<3 || (iEtaMaxE * HcalDetId(it->id()).ieta() == -2) );  
00260     // includes  +/- eta boundary 
00261 
00262     if (passDPhi && passDEta) filteredCells.push_back(*it);
00263 
00264   }
00265     
00266   selectCells = filteredCells;
00267 
00268   return;
00269 }
00270               
00271 
00272 
00273 
00274 // this is for the problematic layer near the HB/HE boundary
00275 // sum depths 1,2 in towers 15,16
00276 
00277 void sumSmallDepths(vector<TCell> &selectCells) {
00278        
00279   if (selectCells.size()==0) return;
00280     
00281   vector<TCell> newCells; // holds unaffected cells to which the modified ones are added
00282   vector<TCell> manipulatedCells; // the ones that are combined
00283     
00284   for (vector<TCell>::iterator i_it = selectCells.begin(); i_it != selectCells.end(); ++i_it) {
00285 
00286     if ( (HcalDetId(i_it->id()).ietaAbs()==15 && HcalDetId(i_it->id()).depth()<=2) ||
00287          (HcalDetId(i_it->id()).ietaAbs()==16 && HcalDetId(i_it->id()).depth()<=2)) {
00288       manipulatedCells.push_back(*i_it);
00289     }
00290     else {
00291       newCells.push_back(*i_it);
00292     }
00293 
00294   }
00295 
00296   // if the list is empty there is nothing to manipulate
00297   // leave the original vector unchanged
00298 
00299   if (manipulatedCells.size()<1) {
00300     newCells.clear();    
00301     return;
00302   }
00303 
00304 
00305   // See what cells are needed to hold the combined information:
00306   // Make holders for depth=1 for each (iEta,iPhi) 
00307   // if a cell with these values is present in "manupulatedCells"  
00308   vector<UInt_t> dummyIds; // to keep track of kreated cells 
00309   vector<TCell> createdCells; // cells that need to be added or they exists;
00310 
00311   for (vector<TCell>::iterator i_it = manipulatedCells.begin(); i_it!=manipulatedCells.end(); ++i_it) {
00312     UInt_t dummyId = HcalDetId(HcalDetId(i_it->id()).subdet(), HcalDetId(i_it->id()).ieta(), HcalDetId(i_it->id()).iphi(), 1);
00313     if (find(dummyIds.begin(), dummyIds.end(), dummyId)==dummyIds.end()) {
00314       dummyIds.push_back(dummyId);
00315       createdCells.push_back(TCell(dummyId, 0.0));
00316     }
00317   }
00318 
00319   for (vector<TCell>::iterator i_it = createdCells.begin(); i_it!=createdCells.end(); ++i_it) {
00320     for (vector<TCell>::iterator i_it2 = manipulatedCells.begin(); i_it2!=manipulatedCells.end(); ++i_it2) {
00321       if (HcalDetId(i_it->id()).ieta()==HcalDetId(i_it2->id()).ieta() && 
00322           HcalDetId(i_it->id()).iphi()==HcalDetId(i_it2->id()).iphi() &&
00323           HcalDetId(i_it2->id()).depth()<=2) {
00324         i_it->SetE(i_it->e()+i_it2->e()); 
00325       }  
00326     }
00327   }
00328     
00329   for (vector<TCell>::iterator i_it = createdCells.begin(); i_it!=createdCells.end(); ++i_it) {
00330     newCells.push_back(*i_it);
00331   }
00332   
00333     
00334   // replace the original vectors with the new ones
00335   selectCells = newCells;
00336     
00337   return;
00338 }
00339 
00340 
00341 void filterCellsInCone(std::vector<TCell>& selectCells, const GlobalPoint hitPositionHcal, 
00342                        Float_t maxConeDist, const CaloGeometry* theCaloGeometry) {
00343 
00344   vector<TCell> filteredCells;
00345       
00346   for (vector<TCell>::iterator it=selectCells.begin(); it!=selectCells.end(); ++it) {
00347 
00348     const GlobalPoint recHitPoint = theCaloGeometry->getPosition(it->id());
00349 
00350     if (getDistInPlaneSimple(hitPositionHcal, recHitPoint)<= maxConeDist) 
00351       filteredCells.push_back(*it);
00352   }
00353 
00354   selectCells = filteredCells;
00355 
00356   return;
00357 }
00358 
00359 
00360 // From Jim H. => keep till the code is included centrally
00361 double getDistInPlaneSimple(const GlobalPoint caloPoint, const GlobalPoint rechitPoint) {
00362   
00363   // Simplified version of getDistInPlane
00364   // Assume track direction is origin -> point of hcal intersection
00365   
00366   const GlobalVector caloIntersectVector(caloPoint.x(), 
00367                                          caloPoint.y(), 
00368                                          caloPoint.z());
00369 
00370   const GlobalVector caloIntersectUnitVector = caloIntersectVector.unit();
00371   
00372   const GlobalVector rechitVector(rechitPoint.x(),
00373                                   rechitPoint.y(),
00374                                   rechitPoint.z());
00375 
00376   const GlobalVector rechitUnitVector = rechitVector.unit();
00377 
00378   double dotprod = caloIntersectUnitVector.dot(rechitUnitVector);
00379   double rechitdist = caloIntersectVector.mag()/dotprod;
00380   
00381   
00382   const GlobalVector effectiveRechitVector = rechitdist*rechitUnitVector;
00383   const GlobalPoint effectiveRechitPoint(effectiveRechitVector.x(),
00384                                          effectiveRechitVector.y(),
00385                                          effectiveRechitVector.z());
00386   
00387   
00388   GlobalVector distance_vector = effectiveRechitPoint-caloPoint;
00389   
00390   if (dotprod > 0.)
00391     {
00392       return distance_vector.mag();
00393     }
00394   else
00395     {
00396       return 999999.;
00397     
00398     }
00399 
00400     
00401 }
00402