CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EcalRecHitWorkerRecover.cc
Go to the documentation of this file.
2 
14 
17 
19 
21 
22 //$Id: EcalRecHitWorkerRecover.cc,v 1.36 2012/03/01 14:32:39 vieri Exp $
23 
26 {
28  // isolated channel recovery
29  singleRecoveryMethod_ = ps.getParameter<std::string>("singleChannelRecoveryMethod");
30  singleRecoveryThreshold_ = ps.getParameter<double>("singleChannelRecoveryThreshold");
31  killDeadChannels_ = ps.getParameter<bool>("killDeadChannels");
32  recoverEBIsolatedChannels_ = ps.getParameter<bool>("recoverEBIsolatedChannels");
33  recoverEEIsolatedChannels_ = ps.getParameter<bool>("recoverEEIsolatedChannels");
34  recoverEBVFE_ = ps.getParameter<bool>("recoverEBVFE");
35  recoverEEVFE_ = ps.getParameter<bool>("recoverEEVFE");
36  recoverEBFE_ = ps.getParameter<bool>("recoverEBFE");
37  recoverEEFE_ = ps.getParameter<bool>("recoverEEFE");
38 
39  dbStatusToBeExcludedEE_ = ps.getParameter<std::vector<int> >("dbStatusToBeExcludedEE");
40  dbStatusToBeExcludedEB_ = ps.getParameter<std::vector<int> >("dbStatusToBeExcludedEB");
41 
42  tpDigiCollection_ = ps.getParameter<edm::InputTag>("triggerPrimitiveDigiCollection");
43  logWarningEtThreshold_EB_FE_ = ps.getParameter<double>("logWarningEtThreshold_EB_FE");
44  logWarningEtThreshold_EE_FE_ = ps.getParameter<double>("logWarningEtThreshold_EE_FE");
45 }
46 
47 
49 {
50 
51  es.get<EcalLaserDbRecord>().get(laser);
54  es.get<EcalMappingRcd>().get(pEcalMapping_);
56  // geometry...
57  es.get<EcalBarrelGeometryRecord>().get("EcalBarrel",pEBGeom_);
58  es.get<EcalEndcapGeometryRecord>().get("EcalEndcap",pEEGeom_);
64  es.get<IdealGeometryRecord>().get(ttMap_);
65  recoveredDetIds_EB_.clear();
66  recoveredDetIds_EE_.clear();
68 }
69 
70 
71 bool
73  const EcalUncalibratedRecHit& uncalibRH,
75 {
76  DetId detId=uncalibRH.id();
77  uint32_t flags = (0xF & uncalibRH.flags());
78 
79  // get laser coefficient
80  //float lasercalib = laser->getLaserCorrection( detId, evt.time());
81 
82  // killDeadChannels_ = true, means explicitely kill dead channels even if the recovered energies are computed in the code
83  // if you don't want to store the recovered energies in the rechit you can produce LogWarnings if logWarningEtThreshold_EB(EE)_FE>0
84  // logWarningEtThreshold_EB(EE)_FE_<0 will not compute the recovered energies at all (faster)
85 
86  if ( killDeadChannels_ ) {
91  ) {
92  EcalRecHit hit( detId, 0., 0., EcalRecHit::kDead );
94  insertRecHit( hit, result); // insert trivial rechit with kDead flag
95  return true;
96  }
97  if ( flags == EcalRecHitWorkerRecover::EB_FE && !recoverEBFE_) {
98  EcalTrigTowerDetId ttDetId( ((EBDetId)detId).tower() );
99  std::vector<DetId> vid = ttMap_->constituentsOf( ttDetId );
100  for ( std::vector<DetId>::const_iterator dit = vid.begin(); dit != vid.end(); ++dit ) {
101  EcalRecHit hit( (*dit), 0., 0., EcalRecHit::kDead );
102  hit.setFlag( EcalRecHit::kDead ) ;
103  insertRecHit( hit, result ); // insert trivial rechit with kDead flag
104  }
105  if(logWarningEtThreshold_EB_FE_<0)return true; // if you don't want log warning just return true
106  }
107  if ( flags == EcalRecHitWorkerRecover::EE_FE && !recoverEEFE_) {
108  EEDetId id( detId );
109  EcalScDetId sc( 1+(id.ix()-1)/5, 1+(id.iy()-1)/5, id.zside() );
110  std::vector<DetId> eeC;
111  for(int dx=1; dx<=5; ++dx){
112  for(int dy=1; dy<=5; ++dy){
113  int ix = (sc.ix()-1)*5 + dx;
114  int iy = (sc.iy()-1)*5 + dy;
115  int iz = sc.zside();
116  if(EEDetId::validDetId(ix, iy, iz)){
117  eeC.push_back(EEDetId(ix, iy, iz));
118  }
119  }
120  }
121  for ( size_t i = 0; i < eeC.size(); ++i ) {
122  EcalRecHit hit( eeC[i], 0., 0., EcalRecHit::kDead );
123  hit.setFlag( EcalRecHit::kDead ) ;
124  insertRecHit( hit, result ); // insert trivial rechit with kDead flag
125  }
126  if(logWarningEtThreshold_EE_FE_<0) return true; // if you don't want log warning just return true
127  }
128  }
129 
130  if ( flags == EcalRecHitWorkerRecover::EB_single ) {
131  // recover as single dead channel
132  const EcalRecHitCollection * hit_collection = &result;
133  EcalDeadChannelRecoveryAlgos deadChannelCorrector(caloTopology_.product());
134 
135  // channel recovery
136  EcalRecHit hit = deadChannelCorrector.correct( detId, hit_collection, singleRecoveryMethod_, singleRecoveryThreshold_ );
137  if ( hit.energy() != 0 ) {
138  hit.setFlag( EcalRecHit::kNeighboursRecovered ) ;
139  } else {
140  // recovery failed
141  hit.setFlag( EcalRecHit::kDead ) ;
142  }
143  insertRecHit( hit, result );
144  } else if ( flags == EcalRecHitWorkerRecover::EB_VFE ) {
145  // recover as dead VFE
146  EcalRecHit hit( detId, 0., 0.);
147  hit.setFlag( EcalRecHit::kDead ) ;
148  // recovery not implemented
149  insertRecHit( hit, result );
150  } else if ( flags == EcalRecHitWorkerRecover::EB_FE ) {
151  // recover as dead TT
152 
153  EcalTrigTowerDetId ttDetId( ((EBDetId)detId).tower() );
155  evt.getByLabel(tpDigiCollection_, pTPDigis);
156  const EcalTrigPrimDigiCollection * tpDigis = 0;
157  if ( pTPDigis.isValid() ) {
158  tpDigis = pTPDigis.product();
159  } else {
160  edm::LogError("EcalRecHitWorkerRecover") << "Can't get the product " << tpDigiCollection_.instance()
161  << " with label " << tpDigiCollection_.label();
162  return false;
163  }
164  EcalTrigPrimDigiCollection::const_iterator tp = tpDigis->find( ttDetId );
165  // recover the whole trigger tower
166  if ( tp != tpDigis->end() ) {
167  //std::vector<DetId> vid = ecalMapping_->dccTowerConstituents( ecalMapping_->DCCid( ttDetId ), ecalMapping_->iTT( ttDetId ) );
168  std::vector<DetId> vid = ttMap_->constituentsOf( ttDetId );
169  float tpEt = ecalScale_.getTPGInGeV( tp->compressedEt(), tp->id() );
170  float tpEtThreshEB = logWarningEtThreshold_EB_FE_;
171  if(tpEt>tpEtThreshEB){
172  edm::LogWarning("EnergyInDeadEB_FE")<<"TP energy in the dead TT = "<<tpEt<<" at "<<ttDetId;
173  }
174  if ( !killDeadChannels_ || recoverEBFE_ ) {
175  // democratic energy sharing
176 
177  for ( std::vector<DetId>::const_iterator dit = vid.begin(); dit != vid.end(); ++dit ) {
178  if (alreadyInserted(*dit)) continue;
179  float theta = ebGeom_->getGeometry(*dit)->getPosition().theta();
180  float tpEt = ecalScale_.getTPGInGeV( tp->compressedEt(), tp->id() );
182  EcalRecHit hit( *dit, tpEt /((float)vid.size()) / sin(theta), 0.);
184  if ( tp->compressedEt() == 0xFF ) hit.setFlag( EcalRecHit::kTPSaturated );
185  if ( tp->sFGVB() ) hit.setFlag( EcalRecHit::kL1SpikeFlag );
186  insertRecHit( hit, result );
187  }
188  }
189  } else {
190  // tp not found => recovery failed
191  std::vector<DetId> vid = ttMap_->constituentsOf( ttDetId );
192  for ( std::vector<DetId>::const_iterator dit = vid.begin(); dit != vid.end(); ++dit ) {
193  if (alreadyInserted(*dit)) continue;
194  EcalRecHit hit( *dit,0., 0. );
195  hit.setFlag( EcalRecHit::kDead ) ;
196  insertRecHit( hit, result );
197  }
198  }
199  }
200  } else if ( flags == EcalRecHitWorkerRecover::EE_FE ) {
201  // Structure for recovery:
202  // ** SC --> EEDetId constituents (eeC) --> associated Trigger Towers (aTT) --> EEDetId constituents (aTTC)
203  // ** energy for a SC EEDetId = [ sum_aTT(energy) - sum_aTTC(energy) ] / N_eeC
204  // .. i.e. the total energy of the TTs covering the SC minus
205  // .. the energy of the recHits in the TTs but not in the SC
206  //std::vector<DetId> vid = ecalMapping_->dccTowerConstituents( ecalMapping_->DCCid( ttDetId ), ecalMapping_->iTT( ttDetId ) );
207  // due to lack of implementation of the EcalTrigTowerDetId ix,iy methods in EE we compute Et recovered energies (in EB we compute E)
208 
209  EEDetId eeId( detId );
210  EcalScDetId sc( (eeId.ix()-1)/5+1, (eeId.iy()-1)/5+1, eeId.zside() );
211  std::set<DetId> eeC;
212  for(int dx=1; dx<=5; ++dx){
213  for(int dy=1; dy<=5; ++dy){
214  int ix = (sc.ix()-1)*5 + dx;
215  int iy = (sc.iy()-1)*5 + dy;
216  int iz = sc.zside();
217  if(EEDetId::validDetId(ix, iy, iz)){
218  EEDetId id(ix, iy, iz);
220  eeC.insert(id);
221  } // check status
222  }
223  }
224  }
225 
227  evt.getByLabel(tpDigiCollection_, pTPDigis);
228  const EcalTrigPrimDigiCollection * tpDigis = 0;
229  if ( pTPDigis.isValid() ) {
230  tpDigis = pTPDigis.product();
231  } else {
232  edm::LogError("EcalRecHitWorkerRecover") << "Can't get the product " << tpDigiCollection_.instance()
233  << " with label " << tpDigiCollection_.label();
234  return false;
235  }
236  // associated trigger towers
237  std::set<EcalTrigTowerDetId> aTT;
238  for ( std::set<DetId>::const_iterator it = eeC.begin(); it!=eeC.end(); ++it ) {
239  aTT.insert( ttMap_->towerOf( *it ) );
240  }
241  // associated trigger towers: total energy
242  float totE = 0;
243  // associated trigger towers: EEDetId constituents
244  std::set<DetId> aTTC;
245  bool atLeastOneTPSaturated = false;
246  for ( std::set<EcalTrigTowerDetId>::const_iterator it = aTT.begin(); it != aTT.end(); ++it ) {
247  // add the energy of this trigger tower
248  EcalTrigPrimDigiCollection::const_iterator itTP = tpDigis->find( *it );
249  if ( itTP != tpDigis->end() ) {
250 
251  std::vector<DetId> v = ttMap_->constituentsOf( *it );
252 
253  // from the constituents, remove dead channels
254  std::vector<DetId>::iterator ttcons = v.begin();
255  while (ttcons != v.end()){
257  ttcons=v.erase(ttcons);
258  } else {
259  ++ttcons;
260  }
261  }// while
262 
263  if ( itTP->compressedEt() == 0xFF ){ // In the case of a saturated trigger tower, a fraction
264  atLeastOneTPSaturated = true; //of the saturated energy is put in: number of xtals in dead region/total xtals in TT *63.75
265 
266  //Alternative recovery algorithm that I will now investigate.
267  //Estimate energy sums the energy in the working channels, then decides how much energy
268  //to put here depending on that. Duncan 20101203
269 
270  totE += estimateEnergy(itTP->id().ietaAbs(), &result, eeC, v);
271 
272  /*
273  These commented out lines use
274  64GeV*fraction of the TT overlapping the dead FE
275 
276  int count = 0;
277  for (std::vector<DetId>::const_iterator idsit = v.begin(); idsit != v.end(); ++ idsit){
278  std::set<DetId>::const_iterator itFind = eeC.find(*idsit);
279  if (itFind != eeC.end())
280  ++count;
281  }
282  //std::cout << count << ", " << v.size() << std::endl;
283  totE+=((float)count/(float)v.size())* ((it->ietaAbs()>26)?2*ecalScale_.getTPGInGeV( itTP->compressedEt(), itTP->id() ):ecalScale_.getTPGInGeV( itTP->compressedEt(), itTP->id() ));*/
284  }
285  else {totE += ((it->ietaAbs()>26)?2:1)*ecalScale_.getTPGInGeV( itTP->compressedEt(), itTP->id() );}
286 
287 
288  // get the trigger tower constituents
289 
290  if (itTP->compressedEt() == 0){ // If there's no energy in TT, the constituents are removed from the recovery.
291  for (size_t i = 0 ; i < v.size(); ++i)
292  eeC.erase(v[i]);
293  }
294  else if (itTP->compressedEt()!=0xFF){ //If it's saturated the energy has already been determined, so we do not want to subtract any channels
295  for ( size_t j = 0; j < v.size(); ++j ) {
296  aTTC.insert( v[j] );
297  }
298  }
299 
300  }
301  }
302  // remove crystals of dead SC
303  // (this step is not needed if sure that SC crystals are not
304  // in the recHit collection)
305 
306  for ( std::set<DetId>::const_iterator it = eeC.begin(); it != eeC.end(); ++it ) {
307  aTTC.erase(*it);
308  }
309  // compute the total energy for the dead SC
310  const EcalRecHitCollection * hits = &result;
311  for ( std::set<DetId>::const_iterator it = aTTC.begin(); it != aTTC.end(); ++it ) {
312  EcalRecHitCollection::const_iterator jt = hits->find( *it );
313  if ( jt != hits->end() ) {
314  float energy = jt->energy(); // Correct conversion to Et
315  float eta = geo_->getPosition(jt->id()).eta();
316  float pf = 1.0/cosh(eta);
317  //float theta = eeGeom_->getGeometry( *it )->getPosition().theta();
318  // use Et instead of E, consistent with the Et estimation of the associated TT
319  totE -= energy*pf;
320  }
321  }
322 
323 
324  float scEt = totE;
325  float scEtThreshEE = logWarningEtThreshold_EE_FE_;
326  if(scEt>scEtThreshEE){
327  edm::LogWarning("EnergyInDeadEE_FE")<<"TP energy in the dead TT = "<<scEt<<" at "<<sc;
328  }
329 
330  // assign the energy to the SC crystals
331  if ( !killDeadChannels_ || recoverEEFE_ ) { // if eeC is empty, i.e. there are no hits
332  // in the tower, nothing is returned. No negative values from noise.
333  for ( std::set<DetId>::const_iterator it = eeC.begin(); it != eeC.end(); ++it ) {
334 
335  float eta = geo_->getPosition(*it).eta(); //Convert back to E from Et for the recovered hits
336  float pf = 1.0/cosh(eta);
337  EcalRecHit hit( *it, totE / ((float)eeC.size()*pf), 0);
338 
339  if (atLeastOneTPSaturated) hit.setFlag(EcalRecHit::kTPSaturated );
341  insertRecHit( hit, result );
342 
343  }// for
344  }// if
345  }
346  return true;
347 }
348 
349 float EcalRecHitWorkerRecover::estimateEnergy(int ieta, EcalRecHitCollection* hits, std::set<DetId> sId, std::vector<DetId> vId ) {
350 
351  float xtalE=0;
352  int count = 0;
353  for (std::vector<DetId>::const_iterator vIdit = vId.begin(); vIdit != vId.end(); ++ vIdit){
354  std::set<DetId>::const_iterator sIdit = sId.find(*vIdit);
355  if (sIdit==sId.end()){
356  float energy = hits->find(*vIdit)->energy();
357  float eta = geo_->getPosition(*vIdit).eta();
358  float pf = 1.0/cosh(eta);
359  xtalE += energy*pf;
360  count++;
361  }
362  }
363 
364  if (count==0) { // If there are no overlapping crystals return saturated value.
365 
366  double etsat = tpgscale_.getTPGInGeV(0xFF,
367  ttMap_->towerOf(*vId.begin())); // get saturation value for the first
368  // constituent, for the others it's the same
369 
370  return etsat/cosh(ieta)*(ieta>26?2:1); // account for duplicated TT in EE for ieta>26
371  }
372  else return xtalE*((vId.size()/(float)count) - 1)*(ieta>26?2:1);
373 
374 
375 }
376 
377 
379 {
380  // skip already inserted DetId's and raise a log warning
381  if ( alreadyInserted( hit.id() ) ) {
382  edm::LogWarning("EcalRecHitWorkerRecover") << "DetId already recovered! Skipping...";
383  return;
384  }
385  EcalRecHitCollection::iterator it = collection.find( hit.id() );
386  if ( it == collection.end() ) {
387  // insert the hit in the collection
388  collection.push_back( hit );
389  } else {
390  // overwrite existing recHit
391  *it = hit;
392  }
393  if ( hit.id().subdetId() == EcalBarrel ) {
394  recoveredDetIds_EB_.insert( hit.id() );
395  } else if ( hit.id().subdetId() == EcalEndcap ) {
396  recoveredDetIds_EE_.insert( hit.id() );
397  } else {
398  edm::LogError("EcalRecHitWorkerRecover::InvalidDetId") << "Invalid DetId " << hit.id().rawId();
399  }
400 }
401 
402 
404 {
405  bool res = false;
406  if ( id.subdetId() == EcalBarrel ) {
407  res = ( recoveredDetIds_EB_.find( id ) != recoveredDetIds_EB_.end() );
408  } else if ( id.subdetId() == EcalEndcap ) {
409  res = ( recoveredDetIds_EE_.find( id ) != recoveredDetIds_EE_.end() );
410  } else {
411  edm::LogError("EcalRecHitWorkerRecover::InvalidDetId") << "Invalid DetId " << id.rawId();
412  }
413  return res;
414 }
415 
416 // In the future, this will be used to calibrate the TT energy. There is a dependance on
417 // eta at lower energies that can be corrected for here after more validation.
418 float EcalRecHitWorkerRecover::recCheckCalib(float eTT, int ieta){
419 
420  return eTT;
421 
422 }
423 
424 // return false is the channel has status in the list of statusestoexclude
425 // true otherwise (channel ok)
427  const std::vector<int>& statusestoexclude){
428 
429 
430  if (!chStatus_.isValid())
431  edm::LogError("ObjectNotFound") << "Channel Status not set";
432 
433 
434  EcalChannelStatus::const_iterator chIt = chStatus_->find( id );
435  uint16_t dbStatus = 0;
436  if ( chIt != chStatus_->end() ) {
437  dbStatus = chIt->getStatusCode();
438  } else {
439  edm::LogError("ObjectNotFound") << "No channel status found for xtal "
440  << id.rawId()
441  << "! something wrong with EcalChannelStatus in your DB? ";
442  }
443 
444  for (std::vector<int>::const_iterator status = statusestoexclude.begin();
445  status!= statusestoexclude.end(); ++status){
446 
447  if ( *status == dbStatus) return false;
448 
449  }
450 
451  return true;
452 }
453 
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
int ix() const
Definition: EEDetId.h:71
bool alreadyInserted(const DetId &id)
void setEventSetup(const edm::EventSetup &evtSetup)
Definition: EcalTPGScale.cc:19
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
std::vector< T >::const_iterator const_iterator
Geom::Theta< T > theta() const
std::vector< int > dbStatusToBeExcludedEE_
void push_back(T const &t)
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
void setFlag(int flag)
set the flags (from Flags or ESFlags)
Definition: EcalRecHit.h:98
edm::ESHandle< CaloTopology > caloTopology_
double getTPGInGeV(const EcalTriggerPrimitiveDigi &tpDigi)
Definition: EcalTPGScale.cc:24
T eta() const
const GlobalPoint & getPosition() const
Returns the position of reference for this cell.
float recCheckCalib(float energy, int ieta)
static bool validDetId(int crystal_ix, int crystal_iy, int iz)
Definition: EEDetId.cc:562
const CaloSubdetectorGeometry * eeGeom_
virtual const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
Geom::Theta< T > theta() const
Definition: PV3DBase.h:74
void insertRecHit(const EcalRecHit &hit, EcalRecHitCollection &collection)
uint32_t rawId() const
get the raw id
Definition: DetId.h:45
int ix() const
Definition: EcalScDetId.h:72
edm::ESHandle< CaloSubdetectorGeometry > pEEGeom_
edm::ESHandle< EcalTrigTowerConstituentsMap > ttMap_
tuple result
Definition: query.py:137
EcalRecHitWorkerRecover(const edm::ParameterSet &)
int zside() const
Definition: EEDetId.h:65
int j
Definition: DBlmapReader.cc:9
const GlobalPoint & getPosition(const DetId &id) const
Get the position of a given detector id.
Definition: CaloGeometry.cc:68
int iy() const
Definition: EEDetId.h:77
edm::ESHandle< CaloSubdetectorGeometry > pEBGeom_
bool isValid() const
Definition: HandleBase.h:76
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:39
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:356
int iy() const
Definition: EcalScDetId.h:78
const CaloSubdetectorGeometry * ebGeom_
std::vector< EcalRecHit >::iterator iterator
const_iterator end() const
float estimateEnergy(int ieta, EcalRecHitCollection *hits, std::set< DetId > sId, std::vector< DetId > vId)
Definition: DetId.h:20
DetId id() const
get the id
Definition: EcalRecHit.h:76
const T & get() const
Definition: EventSetup.h:55
std::vector< Item >::const_iterator const_iterator
std::set< DetId > recoveredDetIds_EE_
T const * product() const
Definition: ESHandle.h:62
int zside() const
Definition: EcalScDetId.h:66
EcalRecHitSimpleAlgo * rechitMaker_
T const * product() const
Definition: Handle.h:74
std::string const & label() const
Definition: InputTag.h:25
void set(const edm::EventSetup &es)
T eta() const
Definition: PV3DBase.h:75
iterator find(key_type k)
edm::ESHandle< CaloGeometry > caloGeometry_
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::vector< int > dbStatusToBeExcludedEB_
tuple status
Definition: ntuplemaker.py:245
edm::ESHandle< EcalChannelStatus > chStatus_
edm::ESHandle< EcalLaserDbService > laser
std::string const & instance() const
Definition: InputTag.h:26
mathSSE::Vec4< T > v
const EcalElectronicsMapping * ecalMapping_
edm::ESHandle< EcalElectronicsMapping > pEcalMapping_
bool run(const edm::Event &evt, const EcalUncalibratedRecHit &uncalibRH, EcalRecHitCollection &result)
bool checkChannelStatus(const DetId &id, const std::vector< int > &statusestoexclude)
std::set< DetId > recoveredDetIds_EB_