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