00001 #include "RecoParticleFlow/PFClusterProducer/plugins/PFRecHitProducerHO.h"
00002
00003 #include <memory>
00004
00005 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00006
00007 #include "DataFormats/HcalRecHit/interface/HORecHit.h"
00008 #include "DataFormats/HcalRecHit/interface/HcalRecHitCollections.h"
00009 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
00010
00011 #include "DataFormats/DetId/interface/DetId.h"
00012 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00013 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00014
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 #include "FWCore/Framework/interface/ESHandle.h"
00017 #include "FWCore/Framework/interface/EventSetup.h"
00018
00019 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00020 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00021 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00022 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00023 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00024
00025 #include "Geometry/CaloTopology/interface/HcalTopology.h"
00026 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00027
00028 #include "Geometry/CaloTopology/interface/CaloTowerTopology.h"
00029 #include "RecoCaloTools/Navigation/interface/CaloTowerNavigator.h"
00030
00031 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalCaloFlagLabels.h"
00032 #include "RecoCaloTools/Navigation/interface/CaloNavigator.h"
00033
00034
00035 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalCaloFlagLabels.h"
00036 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalSeverityLevelComputer.h"
00037 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalSeverityLevelComputerRcd.h"
00038 #include "CondFormats/HcalObjects/interface/HcalChannelQuality.h"
00039
00040 using namespace std;
00041 using namespace edm;
00042
00043 PFRecHitProducerHO::PFRecHitProducerHO(const edm::ParameterSet& iConfig)
00044 : PFRecHitProducer(iConfig) {
00045
00046
00047 inputTagHORecHits_ =
00048 iConfig.getParameter<InputTag>("recHitsHO");
00049
00050 HOMaxAllowedSev_ = iConfig.getParameter<int>("HOMaxAllowedSev");
00051 neighbourmapcalculated_ = false;
00052 }
00053
00054
00055
00056 PFRecHitProducerHO::~PFRecHitProducerHO() {}
00057
00058 void
00059 PFRecHitProducerHO::createRecHits(vector<reco::PFRecHit>& rechits,
00060 vector<reco::PFRecHit>& rechitsCleaned,
00061 edm::Event& iEvent,
00062 const edm::EventSetup& iSetup ) {
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 map<unsigned, unsigned > idSortedRecHits;
00073
00074
00075 edm::ESHandle<CaloGeometry> geoHandle;
00076 iSetup.get<CaloGeometryRecord>().get(geoHandle);
00077
00078
00079 const CaloSubdetectorGeometry *hcalBarrelGeometry =
00080 geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalOuter);
00081
00082
00083 HcalTopology hcalBarrelTopology;
00084
00085 if(!neighbourmapcalculated_)
00086 hoNeighbArray( *hcalBarrelGeometry,
00087 hcalBarrelTopology);
00088
00089
00090 edm::ESHandle<HcalSeverityLevelComputer> hcalSevLvlComputerHndl;
00091 iSetup.get<HcalSeverityLevelComputerRcd>().get(hcalSevLvlComputerHndl);
00092 const HcalSeverityLevelComputer* hcalSevLvlComputer = hcalSevLvlComputerHndl.product();
00093
00094
00095
00096
00097 edm::Handle<HORecHitCollection> rhcHandle;
00098
00099
00100 bool found = iEvent.getByLabel(inputTagHORecHits_,
00101 rhcHandle);
00102
00103 if(!found) {
00104
00105 ostringstream err;
00106 err<<"could not find rechits "<<inputTagHORecHits_;
00107 LogError("PFRecHitProducerHO")<<err.str()<<endl;
00108
00109 throw cms::Exception( "MissingProduct", err.str());
00110 }
00111 else {
00112 assert( rhcHandle.isValid() );
00113
00114
00115 for(unsigned i=0; i<rhcHandle->size(); i++) {
00116
00117 const HORecHit& erh = (*rhcHandle)[i];
00118 const HcalDetId& detid = (HcalDetId)erh.detid();
00119
00120 double energy = erh.energy();
00121
00122 double time = erh.time();
00123
00124 HcalSubdetector esd=(HcalSubdetector)detid.subdetId();
00125
00126 if (esd != 3) continue;
00127
00128 int hoeta=detid.ieta();
00129 if ( (abs(hoeta)<=4 && energy < thresh_Barrel_) ||
00130 (abs(hoeta)> 4 && energy < thresh_Endcap_) ) continue;
00131
00132
00133
00134 const HcalChannelStatus* theStatus = theHcalChStatus->getValues(detid);
00135 unsigned theStatusValue = theStatus->getValue();
00136
00137 int hitSeverity=hcalSevLvlComputer->getSeverityLevel(detid, erh.flags(),theStatusValue);
00138
00139
00140
00141 if (hitSeverity>HOMaxAllowedSev_)
00142 {
00143
00144 continue;
00145 }
00146
00147
00148
00149 reco::PFRecHit *pfrh = createHORecHit(detid, energy,
00150 PFLayer::HCAL_BARREL2,
00151 hcalBarrelGeometry);
00152
00153 if( !pfrh ) continue;
00154
00155 pfrh->setRescale(time);
00156
00157 rechits.push_back( *pfrh );
00158 delete pfrh;
00159 idSortedRecHits.insert( make_pair(detid.rawId(), rechits.size()-1 ) );
00160 }
00161 }
00162
00163
00164 for(unsigned i=0; i<rechits.size(); i++ ) {
00165 findRecHitNeighboursHO( rechits[i], idSortedRecHits );
00166 }
00167
00168 }
00169
00170
00171 reco::PFRecHit*
00172 PFRecHitProducerHO::createHORecHit( const DetId& detid,
00173 double energy,
00174 PFLayer::Layer layer,
00175 const CaloSubdetectorGeometry* geom ) {
00176
00177 math::XYZVector position;
00178 math::XYZVector axis;
00179
00180 const CaloCellGeometry *thisCell
00181 = geom->getGeometry(detid);
00182
00183
00184 if(!thisCell) {
00185 LogError("PFRecHitProducerHO")
00186 <<"warning detid "<<detid.rawId()
00187 <<" not found in geometry"<<endl;
00188 return 0;
00189 }
00190
00191 double sclel0l1r=0.946;
00192
00193 if (abs(thisCell->getPosition().z())>130) {
00194 position.SetCoordinates ( sclel0l1r*thisCell->getPosition().x(),
00195 sclel0l1r*thisCell->getPosition().y(),
00196 sclel0l1r*thisCell->getPosition().z() );
00197
00198 } else {
00199 position.SetCoordinates ( thisCell->getPosition().x(),
00200 thisCell->getPosition().y(),
00201 thisCell->getPosition().z() );
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 axis = math::XYZVector(0,0,0);
00222
00223
00224
00225
00226
00227
00228
00229
00230 reco::PFRecHit *rh
00231 = new reco::PFRecHit( detid.rawId(), layer,
00232 energy,
00233 position.x(), position.y(), position.z(),
00234 axis.x(), axis.y(), axis.z() );
00235
00236 const CaloCellGeometry::CornersVec& corners = thisCell->getCorners();
00237 assert( corners.size() == 8 );
00238
00239 if (abs(corners[0].z())>130.0) {
00240 rh->setNECorner( sclel0l1r*corners[0].x(), sclel0l1r*corners[0].y(), sclel0l1r*corners[0].z() );
00241 rh->setSECorner( sclel0l1r*corners[1].x(), sclel0l1r*corners[1].y(), sclel0l1r*corners[1].z() );
00242 rh->setSWCorner( sclel0l1r*corners[2].x(), sclel0l1r*corners[2].y(), sclel0l1r*corners[2].z() );
00243 rh->setNWCorner( sclel0l1r*corners[3].x(), sclel0l1r*corners[3].y(), sclel0l1r*corners[3].z() );
00244
00245 } else {
00246 rh->setNECorner( corners[0].x(), corners[0].y(), corners[0].z() );
00247 rh->setSECorner( corners[1].x(), corners[1].y(), corners[1].z() );
00248 rh->setSWCorner( corners[2].x(), corners[2].y(), corners[2].z() );
00249 rh->setNWCorner( corners[3].x(), corners[3].y(), corners[3].z() );
00250 }
00251
00252 return rh;
00253 }
00254
00255
00256 bool
00257 PFRecHitProducerHO::findHORecHitGeometry(const DetId& detid,
00258 const CaloSubdetectorGeometry* geom,
00259 math::XYZVector& position,
00260 math::XYZVector& axis ) {
00261
00262
00263 const CaloCellGeometry *thisCell
00264 = geom->getGeometry(detid);
00265
00266
00267 if(!thisCell) {
00268 LogError("PFRecHitProducerHO")
00269 <<"warning detid "<<detid.rawId()
00270 <<" not found in geometry"<<endl;
00271 return false;
00272 }
00273
00274 position.SetCoordinates ( thisCell->getPosition().x(),
00275 thisCell->getPosition().y(),
00276 thisCell->getPosition().z() );
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 axis = math::XYZVector(0,0,0);
00299 return true;
00300
00301
00302 }
00303
00304
00305
00306 void
00307 PFRecHitProducerHO::findRecHitNeighboursHO
00308 ( reco::PFRecHit& rh,
00309 const map<unsigned,unsigned >& sortedHits ) {
00310
00311 DetId center( rh.detId() );
00312
00313
00314 DetId north = move( center, NORTH );
00315 DetId northeast = move( center, NORTHEAST );
00316 DetId northwest = move( center, NORTHWEST );
00317 DetId south = move( center, SOUTH );
00318 DetId southeast = move( center, SOUTHEAST );
00319 DetId southwest = move( center, SOUTHWEST );
00320 DetId east = move( center, EAST );
00321 DetId west = move( center, WEST );
00322
00323 IDH i = sortedHits.find( north.rawId() );
00324 if(i != sortedHits.end() )
00325 rh.add4Neighbour( i->second );
00326
00327 i = sortedHits.find( northeast.rawId() );
00328 if(i != sortedHits.end() )
00329 rh.add8Neighbour( i->second );
00330
00331 i = sortedHits.find( south.rawId() );
00332 if(i != sortedHits.end() )
00333 rh.add4Neighbour( i->second );
00334
00335 i = sortedHits.find( southwest.rawId() );
00336 if(i != sortedHits.end() )
00337 rh.add8Neighbour( i->second );
00338
00339 i = sortedHits.find( east.rawId() );
00340 if(i != sortedHits.end() )
00341 rh.add4Neighbour( i->second );
00342
00343 i = sortedHits.find( southeast.rawId() );
00344 if(i != sortedHits.end() )
00345 rh.add8Neighbour( i->second );
00346
00347 i = sortedHits.find( west.rawId() );
00348 if(i != sortedHits.end() )
00349 rh.add4Neighbour( i->second );
00350
00351 i = sortedHits.find( northwest.rawId() );
00352 if(i != sortedHits.end() )
00353 rh.add8Neighbour( i->second );
00354 }
00355
00356
00357
00358 void
00359 PFRecHitProducerHO::hoNeighbArray(
00360 const CaloSubdetectorGeometry& barrelGeom,
00361 const CaloSubdetectorTopology& barrelTopo){
00362
00363 static const CaloDirection orderedDir[8]={SOUTHWEST,
00364 SOUTH,
00365 SOUTHEAST,
00366 WEST,
00367 EAST,
00368 NORTHWEST,
00369 NORTH,
00370 NORTHEAST};
00371
00372 const unsigned nbarrel = 2160;
00373
00374 neighboursHO_.resize(nbarrel);
00375
00376
00377
00378 const std::vector<DetId>& vec(barrelGeom.getValidDetIds(DetId::Hcal,
00379 HcalOuter));
00380 unsigned size=vec.size();
00381 for(unsigned ic=0; ic<size; ++ic)
00382 {
00383
00384 std::vector<DetId> neighbours(barrelTopo.getWindow(vec[ic],3,3));
00385 unsigned nneighbours=neighbours.size();
00386
00387 unsigned hashedindex=HcalDetId(vec[ic]).hashed_index()-5184;
00388
00389 if(hashedindex>=nbarrel)
00390 {
00391 LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
00392 }
00393
00394
00395
00396
00397
00398
00399
00400 if(nneighbours==9)
00401 {
00402 neighboursHO_[hashedindex].reserve(8);
00403 for(unsigned in=0;in<nneighbours;++in)
00404 {
00405
00406
00407 if(neighbours[in]!=vec[ic])
00408 {
00409 neighboursHO_[hashedindex].push_back(neighbours[in]);
00410
00411 }
00412 }
00413 }
00414 else
00415 {
00416 DetId central(vec[ic]);
00417 neighboursHO_[hashedindex].resize(8,DetId(0));
00418 for(unsigned idir=0;idir<8;++idir)
00419 {
00420 DetId testid=central;
00421 bool status=stdmove(testid,orderedDir[idir],
00422 barrelTopo, barrelGeom);
00423 if(status) neighboursHO_[hashedindex][idir]=testid;
00424 }
00425
00426 }
00427 }
00428
00429
00430 neighbourmapcalculated_ = true;
00431 }
00432
00433 bool
00434 PFRecHitProducerHO::stdsimplemove(DetId& cell,
00435 const CaloDirection& dir,
00436 const CaloSubdetectorTopology& barrelTopo,
00437 const CaloSubdetectorGeometry& barrelGeom)
00438 const {
00439
00440 std::vector<DetId> neighbours;
00441
00442
00443 if(cell.subdetId()==HcalOuter) {
00444 HcalDetId hoDetId = cell;
00445
00446 neighbours = barrelTopo.getNeighbours(hoDetId,dir);
00447
00448
00449 if(neighbours.size()>0 && !neighbours[0].null()) {
00450 cell = neighbours[0];
00451 return true;
00452 }
00453
00454
00455
00456
00457 }
00458
00459
00460 cell = DetId(0);
00461 return false;
00462 }
00463
00464
00465
00466 bool
00467 PFRecHitProducerHO::stdmove(DetId& cell,
00468 const CaloDirection& dir,
00469 const CaloSubdetectorTopology& barrelTopo,
00470 const CaloSubdetectorGeometry& barrelGeom)
00471
00472 const {
00473
00474
00475 bool result;
00476
00477 if(dir==NORTH) {
00478 result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
00479 return result;
00480 }
00481 else if(dir==SOUTH) {
00482 result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom);
00483 return result;
00484 }
00485 else if(dir==EAST) {
00486 result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
00487 return result;
00488 }
00489 else if(dir==WEST) {
00490 result = stdsimplemove(cell,WEST, barrelTopo, barrelGeom);
00491 return result;
00492 }
00493
00494
00495
00496 else if(dir==NORTHEAST)
00497 {
00498 result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
00499 if(result)
00500 return stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
00501 else
00502 {
00503 result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom);
00504 if(result)
00505 return stdsimplemove(cell,NORTH, barrelTopo, barrelGeom);
00506 else
00507 return false;
00508 }
00509 }
00510 else if(dir==NORTHWEST)
00511 {
00512 result = stdsimplemove(cell,NORTH, barrelTopo, barrelGeom );
00513 if(result)
00514 return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
00515 else
00516 {
00517 result = stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
00518 if(result)
00519 return stdsimplemove(cell,NORTH, barrelTopo, barrelGeom );
00520 else
00521 return false;
00522 }
00523 }
00524 else if(dir == SOUTHEAST)
00525 {
00526 result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
00527 if(result)
00528 return stdsimplemove(cell,EAST, barrelTopo, barrelGeom );
00529 else
00530 {
00531 result = stdsimplemove(cell,EAST, barrelTopo, barrelGeom );
00532 if(result)
00533 return stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
00534 else
00535 return false;
00536 }
00537 }
00538 else if(dir == SOUTHWEST)
00539 {
00540 result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
00541 if(result)
00542 return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
00543 else
00544 {
00545 result = stdsimplemove(cell,SOUTH, barrelTopo, barrelGeom );
00546 if(result)
00547 return stdsimplemove(cell,WEST, barrelTopo, barrelGeom );
00548 else
00549 return false;
00550 }
00551 }
00552 cell = DetId(0);
00553 return false;
00554 }
00555
00556 DetId PFRecHitProducerHO::move(DetId cell,
00557 const CaloDirection&dir ) const
00558 {
00559 DetId originalcell = cell;
00560 if(dir==NONE || cell==DetId(0)) return false;
00561
00562
00563
00564
00565 static const int calodirections[9]={-1,1,2,0,4,3,7,5,6};
00566
00567 assert(neighbourmapcalculated_);
00568
00569 DetId result = neighboursHO_[HcalDetId(originalcell).hashed_index()-5184][calodirections[dir]];
00570 return result;
00571 }
00572