CMS 3D CMS Logo

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