00001 #include "RecoParticleFlow/PFClusterProducer/interface/PFRecHitProducerHCAL.h"
00002
00003 #include <memory>
00004
00005 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00006
00007 #include "DataFormats/HcalRecHit/interface/HBHERecHit.h"
00008 #include "DataFormats/HcalRecHit/interface/HcalRecHitCollections.h"
00009 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
00010
00011 #include "DataFormats/DetId/interface/DetId.h"
00012
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 #include "FWCore/Framework/interface/ESHandle.h"
00015 #include "FWCore/Framework/interface/EventSetup.h"
00016
00017
00018 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00019 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00020 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00021 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00022 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00023
00024 #include "Geometry/CaloTopology/interface/HcalTopology.h"
00025 #include "RecoCaloTools/Navigation/interface/CaloNavigator.h"
00026
00027 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00028
00029 #include "Geometry/CaloTopology/interface/CaloTowerTopology.h"
00030 #include "RecoCaloTools/Navigation/interface/CaloTowerNavigator.h"
00031
00032
00033 using namespace std;
00034 using namespace edm;
00035
00036 PFRecHitProducerHCAL::PFRecHitProducerHCAL(const edm::ParameterSet& iConfig)
00037 : PFRecHitProducer( iConfig )
00038 {
00039
00040
00041
00042
00043
00044
00045 inputTagHcalRecHitsHBHE_ =
00046 iConfig.getParameter<InputTag>("hcalRecHitsHBHE");
00047
00048
00049 inputTagCaloTowers_ =
00050 iConfig.getParameter<InputTag>("caloTowers");
00051
00052 thresh_HF_ =
00053 iConfig.getParameter<double>("thresh_HF");
00054 }
00055
00056
00057
00058 PFRecHitProducerHCAL::~PFRecHitProducerHCAL() {}
00059
00060
00061
00062 void PFRecHitProducerHCAL::createRecHits(vector<reco::PFRecHit>& rechits,
00063 edm::Event& iEvent,
00064 const edm::EventSetup& iSetup ) {
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 map<unsigned, unsigned > idSortedRecHits;
00075 typedef map<unsigned, unsigned >::iterator IDH;
00076
00077
00078 edm::ESHandle<CaloGeometry> geoHandle;
00079 iSetup.get<CaloGeometryRecord>().get(geoHandle);
00080
00081
00082 const CaloSubdetectorGeometry *hcalBarrelGeometry =
00083 geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalBarrel);
00084
00085
00086 const CaloSubdetectorGeometry *hcalEndcapGeometry =
00087 geoHandle->getSubdetectorGeometry(DetId::Hcal, HcalEndcap);
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 if( !(inputTagCaloTowers_ == InputTag()) ) {
00103
00104 edm::Handle<CaloTowerCollection> caloTowers;
00105 CaloTowerTopology caloTowerTopology;
00106 const CaloSubdetectorGeometry *caloTowerGeometry = 0;
00107
00108
00109
00110 bool found = iEvent.getByLabel(inputTagCaloTowers_,
00111 caloTowers);
00112
00113 if(!found) {
00114 ostringstream err;
00115 err<<"could not find rechits "<<inputTagCaloTowers_;
00116 LogError("PFRecHitProducerHCAL")<<err.str()<<endl;
00117
00118 throw cms::Exception( "MissingProduct", err.str());
00119 }
00120 else {
00121 assert( caloTowers.isValid() );
00122
00123
00124 typedef CaloTowerCollection::const_iterator ICT;
00125
00126 for(ICT ict=caloTowers->begin(); ict!=caloTowers->end();ict++) {
00127
00128 const CaloTower& ct = (*ict);
00129
00130
00131 if(!caloTowerGeometry)
00132 caloTowerGeometry = geoHandle->getSubdetectorGeometry(ct.id());
00133
00134
00135 double energy = ct.hadEnergy()+ct.emEnergy();
00136
00137 if( energy < 1e-9 ) continue;
00138
00139
00140
00141
00142
00143 assert( ct.constituentsSize() );
00144 const HcalDetId& detid = ct.constituent(0);
00145
00146 reco::PFRecHit* pfrh = 0;
00147
00148 switch( detid.subdet() ) {
00149 case HcalBarrel:
00150 {
00151 if(energy < thresh_Barrel_ ) continue;
00152 pfrh = createHcalRecHit( detid,
00153 energy,
00154 PFLayer::HCAL_BARREL1,
00155 hcalBarrelGeometry,
00156 ct.id().rawId() );
00157 }
00158 break;
00159 case HcalEndcap:
00160 {
00161 if(energy < thresh_Endcap_ ) continue;
00162 pfrh = createHcalRecHit( detid,
00163 energy,
00164 PFLayer::HCAL_ENDCAP,
00165 hcalEndcapGeometry,
00166 ct.id().rawId() );
00167 }
00168 break;
00169 case HcalForward:
00170 {
00171 if(energy < thresh_HF_ ) continue;
00172 pfrh = createHcalRecHit( detid,
00173 energy,
00174 PFLayer::HCAL_HF,
00175 hcalEndcapGeometry,
00176 ct.id().rawId() );
00177 }
00178 break;
00179 default:
00180 LogError("PFRecHitProducerHCAL")
00181 <<"CaloTower constituent: unknown layer : "
00182 <<detid.subdet()<<endl;
00183 }
00184
00185 if(pfrh) {
00186 rechits.push_back( *pfrh );
00187 delete pfrh;
00188 idSortedRecHits.insert( make_pair(ct.id().rawId(),
00189 rechits.size()-1 ) );
00190 }
00191 }
00192
00193
00194
00195
00196 for(unsigned i=0; i<rechits.size(); i++ ) {
00197
00198 findRecHitNeighboursCT( rechits[i],
00199 idSortedRecHits,
00200 caloTowerTopology);
00201
00202 }
00203 }
00204 }
00205 else if( !(inputTagHcalRecHitsHBHE_ == InputTag()) ) {
00206
00207
00208
00209
00210 HcalTopology hcalTopology;
00211
00212
00213
00214 edm::Handle<HBHERecHitCollection> hcalHandle;
00215
00216
00217 bool found = iEvent.getByLabel(inputTagHcalRecHitsHBHE_,
00218 hcalHandle );
00219
00220 if(!found) {
00221 ostringstream err;
00222 err<<"could not find rechits "<<inputTagHcalRecHitsHBHE_;
00223 LogError("PFRecHitProducerHCAL")<<err.str()<<endl;
00224
00225 throw cms::Exception( "MissingProduct", err.str());
00226 }
00227 else {
00228 assert( hcalHandle.isValid() );
00229
00230 const edm::Handle<HBHERecHitCollection>& handle = hcalHandle;
00231 for(unsigned irechit=0; irechit<handle->size(); irechit++) {
00232 const HBHERecHit& hit = (*handle)[irechit];
00233
00234 double energy = hit.energy();
00235
00236 reco::PFRecHit* pfrh = 0;
00237
00238
00239 const HcalDetId& detid = hit.detid();
00240 switch( detid.subdet() ) {
00241 case HcalBarrel:
00242 {
00243 if(energy < thresh_Barrel_ ) continue;
00244 pfrh = createHcalRecHit( detid,
00245 energy,
00246 PFLayer::HCAL_BARREL1,
00247 hcalBarrelGeometry );
00248 }
00249 break;
00250 case HcalEndcap:
00251 {
00252 if(energy < thresh_Endcap_ ) continue;
00253 pfrh = createHcalRecHit( detid,
00254 energy,
00255 PFLayer::HCAL_ENDCAP,
00256 hcalEndcapGeometry );
00257 }
00258 break;
00259 case HcalForward:
00260 {
00261 if(energy < thresh_HF_ ) continue;
00262 pfrh = createHcalRecHit( detid,
00263 energy,
00264 PFLayer::HCAL_HF,
00265 hcalEndcapGeometry );
00266 }
00267 break;
00268 default:
00269 LogError("PFRecHitProducerHCAL")
00270 <<"HCAL rechit: unknown layer : "<<detid.subdet()<<endl;
00271 continue;
00272 }
00273
00274 if(pfrh) {
00275 rechits.push_back( *pfrh );
00276 delete pfrh;
00277 idSortedRecHits.insert( make_pair(detid.rawId(),
00278 rechits.size()-1 ) );
00279 }
00280 }
00281
00282
00283
00284 for(unsigned i=0; i<rechits.size(); i++ ) {
00285
00286 findRecHitNeighbours( rechits[i], idSortedRecHits,
00287 hcalTopology,
00288 *hcalBarrelGeometry,
00289 hcalTopology,
00290 *hcalEndcapGeometry);
00291 }
00292 }
00293 }
00294 }
00295
00296
00297
00298
00299
00300
00301 reco::PFRecHit*
00302 PFRecHitProducerHCAL::createHcalRecHit( const DetId& detid,
00303 double energy,
00304 PFLayer::Layer layer,
00305 const CaloSubdetectorGeometry* geom,
00306 unsigned newDetId ) {
00307
00308 const CaloCellGeometry *thisCell = geom->getGeometry(detid);
00309 if(!thisCell) {
00310 edm::LogError("PFRecHitProducerHCAL")
00311 <<"warning detid "<<detid.rawId()<<" not found in layer "
00312 <<layer<<endl;
00313 return 0;
00314 }
00315
00316 const GlobalPoint& position = thisCell->getPosition();
00317
00318
00319 unsigned id = detid;
00320 if(newDetId) id = newDetId;
00321 reco::PFRecHit *rh =
00322 new reco::PFRecHit( id, layer, energy,
00323 position.x(), position.y(), position.z(),
00324 0,0,0 );
00325
00326
00327
00328
00329
00330 const CaloCellGeometry::CornersVec& corners = thisCell->getCorners();
00331
00332 assert( corners.size() == 8 );
00333
00334 rh->setNECorner( corners[0].x(), corners[0].y(), corners[0].z() );
00335 rh->setSECorner( corners[1].x(), corners[1].y(), corners[1].z() );
00336 rh->setSWCorner( corners[2].x(), corners[2].y(), corners[2].z() );
00337 rh->setNWCorner( corners[3].x(), corners[3].y(), corners[3].z() );
00338
00339 return rh;
00340 }
00341
00342
00343
00344
00345 void
00346 PFRecHitProducerHCAL::findRecHitNeighbours
00347 ( reco::PFRecHit& rh,
00348 const map<unsigned,unsigned >& sortedHits,
00349 const CaloSubdetectorTopology& barrelTopology,
00350 const CaloSubdetectorGeometry& barrelGeometry,
00351 const CaloSubdetectorTopology& endcapTopology,
00352 const CaloSubdetectorGeometry& endcapGeometry ) {
00353
00354
00355 if( rh.layer() == PFLayer::HCAL_HF )
00356 return;
00357
00358 DetId detid( rh.detId() );
00359
00360 const CaloSubdetectorTopology* topology = 0;
00361 const CaloSubdetectorGeometry* geometry = 0;
00362 const CaloSubdetectorGeometry* othergeometry = 0;
00363
00364 switch( rh.layer() ) {
00365 case PFLayer::ECAL_ENDCAP:
00366 topology = &endcapTopology;
00367 geometry = &endcapGeometry;
00368 break;
00369 case PFLayer::ECAL_BARREL:
00370 topology = &barrelTopology;
00371 geometry = &barrelGeometry;
00372 break;
00373 case PFLayer::HCAL_ENDCAP:
00374 topology = &endcapTopology;
00375 geometry = &endcapGeometry;
00376 othergeometry = &barrelGeometry;
00377 break;
00378 case PFLayer::HCAL_BARREL1:
00379 topology = &barrelTopology;
00380 geometry = &barrelGeometry;
00381 othergeometry = &endcapGeometry;
00382 break;
00383 case PFLayer::PS1:
00384 case PFLayer::PS2:
00385 topology = &barrelTopology;
00386 geometry = &barrelGeometry;
00387 othergeometry = &endcapGeometry;
00388 break;
00389 default:
00390 assert(0);
00391 }
00392
00393 assert( topology && geometry );
00394
00395 CaloNavigator<DetId> navigator(detid, topology);
00396
00397 DetId north = navigator.north();
00398
00399 DetId northeast(0);
00400 if( north != DetId(0) ) {
00401 northeast = navigator.east();
00402 }
00403 navigator.home();
00404
00405
00406 DetId south = navigator.south();
00407
00408
00409
00410 DetId southwest(0);
00411 if( south != DetId(0) ) {
00412 southwest = navigator.west();
00413 }
00414 navigator.home();
00415
00416
00417 DetId east = navigator.east();
00418 DetId southeast;
00419 if( east != DetId(0) ) {
00420 southeast = navigator.south();
00421 }
00422 navigator.home();
00423 DetId west = navigator.west();
00424 DetId northwest;
00425 if( west != DetId(0) ) {
00426 northwest = navigator.north();
00427 }
00428 navigator.home();
00429
00430 IDH i = sortedHits.find( north.rawId() );
00431 if(i != sortedHits.end() )
00432 rh.add4Neighbour( i->second );
00433
00434 i = sortedHits.find( northeast.rawId() );
00435 if(i != sortedHits.end() )
00436 rh.add8Neighbour( i->second );
00437
00438 i = sortedHits.find( south.rawId() );
00439 if(i != sortedHits.end() )
00440 rh.add4Neighbour( i->second );
00441
00442 i = sortedHits.find( southwest.rawId() );
00443 if(i != sortedHits.end() )
00444 rh.add8Neighbour( i->second );
00445
00446 i = sortedHits.find( east.rawId() );
00447 if(i != sortedHits.end() )
00448 rh.add4Neighbour( i->second );
00449
00450 i = sortedHits.find( southeast.rawId() );
00451 if(i != sortedHits.end() )
00452 rh.add8Neighbour( i->second );
00453
00454 i = sortedHits.find( west.rawId() );
00455 if(i != sortedHits.end() )
00456 rh.add4Neighbour( i->second );
00457
00458 i = sortedHits.find( northwest.rawId() );
00459 if(i != sortedHits.end() )
00460 rh.add8Neighbour( i->second );
00461
00462
00463 }
00464
00465
00466 void
00467 PFRecHitProducerHCAL::findRecHitNeighboursCT
00468 ( reco::PFRecHit& rh,
00469 const map<unsigned, unsigned >& sortedHits,
00470 const CaloSubdetectorTopology& topology ) {
00471
00472 if( rh.layer() == PFLayer::HCAL_HF )
00473 return;
00474
00475 CaloTowerDetId ctDetId( rh.detId() );
00476
00477
00478 vector<DetId> northids = topology.north(ctDetId);
00479 vector<DetId> westids = topology.west(ctDetId);
00480 vector<DetId> southids = topology.south(ctDetId);
00481 vector<DetId> eastids = topology.east(ctDetId);
00482
00483
00484 CaloTowerDetId badId;
00485
00486
00487 CaloTowerDetId north;
00488 CaloTowerDetId northwest;
00489 CaloTowerDetId west;
00490 CaloTowerDetId southwest;
00491 CaloTowerDetId south;
00492 CaloTowerDetId southeast;
00493 CaloTowerDetId east;
00494 CaloTowerDetId northeast;
00495
00496
00497 string err("PFRecHitProducerHCAL::findRecHitNeighboursCT : incorrect number of neighbours ");
00498 char n[20];
00499
00500 switch( northids.size() ) {
00501 case 0:
00502 break;
00503 case 1:
00504 north = northids[0];
00505 break;
00506 default:
00507 sprintf(n, "north: %d", northids.size() );
00508 err += n;
00509 throw( err );
00510 }
00511
00512 switch( southids.size() ) {
00513 case 0:
00514 break;
00515 case 1:
00516 south = southids[0];
00517 break;
00518 default:
00519 sprintf(n, "south %d", southids.size() );
00520 err += n;
00521 throw( err );
00522 }
00523
00524
00525
00526
00527 switch( eastids.size() ) {
00528 case 0:
00529 break;
00530 case 1:
00531 east = eastids[0];
00532 northeast = getNorth(east, topology);
00533 southeast = getSouth(east, topology);
00534 break;
00535 case 2:
00536
00537 east = eastids[0];
00538 northeast = getNorth(east, topology );
00539 southeast = getSouth(eastids[1], topology);
00540 break;
00541 default:
00542 sprintf(n, "%d", eastids.size() );
00543 err += n;
00544 throw( err );
00545 }
00546
00547
00548 switch( westids.size() ) {
00549 case 0:
00550 break;
00551 case 1:
00552 west = westids[0];
00553 northwest = getNorth(west, topology);
00554 southwest = getSouth(west, topology);
00555 break;
00556 case 2:
00557
00558 west = westids[0];
00559 northwest = getNorth(west, topology );
00560 southwest = getSouth(westids[1], topology );
00561 break;
00562 default:
00563 sprintf(n, "%d", westids.size() );
00564 err += n;
00565 throw( err );
00566 }
00567
00568
00569
00570
00571
00572
00573 IDH i = sortedHits.find( north.rawId() );
00574 if(i != sortedHits.end() )
00575 rh.add4Neighbour( i->second );
00576
00577 i = sortedHits.find( northeast.rawId() );
00578 if(i != sortedHits.end() )
00579 rh.add8Neighbour( i->second );
00580
00581 i = sortedHits.find( south.rawId() );
00582 if(i != sortedHits.end() )
00583 rh.add4Neighbour( i->second );
00584
00585 i = sortedHits.find( southwest.rawId() );
00586 if(i != sortedHits.end() )
00587 rh.add8Neighbour( i->second );
00588
00589 i = sortedHits.find( east.rawId() );
00590 if(i != sortedHits.end() )
00591 rh.add4Neighbour( i->second );
00592
00593 i = sortedHits.find( southeast.rawId() );
00594 if(i != sortedHits.end() )
00595 rh.add8Neighbour( i->second );
00596
00597 i = sortedHits.find( west.rawId() );
00598 if(i != sortedHits.end() )
00599 rh.add4Neighbour( i->second );
00600
00601 i = sortedHits.find( northwest.rawId() );
00602 if(i != sortedHits.end() )
00603 rh.add8Neighbour( i->second );
00604 }
00605
00606
00607
00608 DetId PFRecHitProducerHCAL::getSouth(const DetId& id,
00609 const CaloSubdetectorTopology& topology) {
00610
00611 DetId south;
00612 vector<DetId> sids = topology.south(id);
00613 if(sids.size() == 1)
00614 south = sids[0];
00615
00616 return south;
00617 }
00618
00619
00620
00621 DetId PFRecHitProducerHCAL::getNorth(const DetId& id,
00622 const CaloSubdetectorTopology& topology) {
00623
00624 DetId north;
00625 vector<DetId> nids = topology.north(id);
00626 if(nids.size() == 1)
00627 north = nids[0];
00628
00629 return north;
00630 }
00631
00632