00001
00002
00003
00004
00005
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <memory>
00023
00024
00025
00026 #include "FWCore/Framework/interface/Frameworkfwd.h"
00027 #include "FWCore/Framework/interface/EDProducer.h"
00028
00029 #include "FWCore/Framework/interface/Event.h"
00030 #include "FWCore/Framework/interface/MakerMacros.h"
00031
00032 #include "FWCore/Framework/interface/ESHandle.h"
00033
00034 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00035
00036 #include "RecoHI/HiJetAlgos/plugins/ParticleTowerProducer.h"
00037
00038 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00039 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00040 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00041 #include "DataFormats/Math/interface/deltaR.h"
00042
00043 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00044 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00045 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00046 #include "Geometry/CaloTopology/interface/CaloTopology.h"
00047
00048 #include "TMath.h"
00049 #include "TRandom.h"
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 ParticleTowerProducer::ParticleTowerProducer(const edm::ParameterSet& iConfig):
00067 geo_(0)
00068 {
00069
00070 src_ = iConfig.getParameter<edm::InputTag>("src");
00071 useHF_ = iConfig.getUntrackedParameter<bool>("useHF");
00072
00073 produces<CaloTowerCollection>();
00074
00075
00076 random_ = new TRandom();
00077 PI = TMath::Pi();
00078
00079
00080
00081 }
00082
00083
00084 ParticleTowerProducer::~ParticleTowerProducer()
00085 {
00086
00087
00088
00089
00090 }
00091
00092
00093
00094
00095
00096
00097
00098 void
00099 ParticleTowerProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00100 {
00101 using namespace edm;
00102
00103 if(!geo_){
00104 edm::ESHandle<CaloGeometry> pG;
00105 iSetup.get<CaloGeometryRecord>().get(pG);
00106 geo_ = pG.product();
00107 }
00108
00109
00110 resetTowers(iEvent, iSetup);
00111
00112
00113 edm::Handle<reco::PFCandidateCollection> inputsHandle;
00114 iEvent.getByLabel(src_, inputsHandle);
00115
00116 for(reco::PFCandidateCollection::const_iterator ci = inputsHandle->begin(); ci!=inputsHandle->end(); ++ci) {
00117
00118 const reco::PFCandidate& particle = *ci;
00119
00120
00121
00122
00123 double eta = particle.eta();
00124
00125 if(!useHF_ && fabs(eta) > 3. ) continue;
00126
00127 int ieta = eta2ieta(eta);
00128 if(eta<0) ieta *= -1;
00129
00130 int iphi = phi2iphi(particle.phi(),ieta);
00131
00132 HcalSubdetector sd;
00133 if(abs(ieta)<=16) sd = HcalBarrel;
00134 else if(fabs(eta)< 3.) sd = HcalEndcap;
00135 else sd = HcalForward;
00136
00137 HcalDetId hid = HcalDetId(sd,ieta,iphi,1);
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 towers_[hid] += particle.et();
00160 }
00161
00162
00163 std::auto_ptr<CaloTowerCollection> prod(new CaloTowerCollection());
00164
00165 for ( std::map< DetId, double >::const_iterator iter = towers_.begin();
00166 iter != towers_.end(); ++iter ){
00167
00168 CaloTowerDetId newTowerId(iter->first.rawId());
00169 double et = iter->second;
00170
00171 if(et>0){
00172
00173 GlobalPoint pos =geo_->getGeometry(newTowerId)->getPosition();
00174
00175 if(!useHF_ && fabs(pos.eta()) > 3. ) continue;
00176
00177
00178
00179 reco::Particle::PolarLorentzVector p4(et,pos.eta(),pos.phi(),0.);
00180
00181 CaloTower newTower(newTowerId,et,0,0,0,0,p4,pos,pos);
00182 prod->push_back(newTower);
00183 }
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 iEvent.put(prod);
00205
00206
00207 }
00208
00209
00210 void
00211 ParticleTowerProducer::beginJob()
00212 {
00213
00214 const double etatow[42] = {0.000, 0.087, 0.174, 0.261, 0.348, 0.435, 0.522, 0.609, 0.696, 0.783, 0.870, 0.957, 1.044, 1.131, 1.218, 1.305, 1.392, 1.479, 1.566, 1.653, 1.740, 1.830, 1.930, 2.043, 2.172, 2.322, 2.500, 2.650, 2.853, 3.000, 3.139, 3.314, 3.489, 3.664, 3.839, 4.013, 4.191, 4.363, 4.538, 4.716, 4.889, 5.191};
00215
00216
00217 const double etacent[40] = {
00218 0.0435,
00219 0.1305,
00220 0.2175,
00221 0.3045,
00222 0.3915,
00223 0.4785,
00224 0.5655,
00225 0.6525,
00226 0.7395,
00227 0.8265,
00228 0.9135,
00229 1.0005,
00230 1.0875,
00231 1.1745,
00232 1.2615,
00233 1.3485,
00234 1.4355,
00235 1.5225,
00236 1.6095,
00237 1.6965,
00238 1.785 ,
00239 1.88 ,
00240 1.9865,
00241 2.1075,
00242 2.247 ,
00243 2.411 ,
00244 2.575 ,
00245 2.759 ,
00246 2.934 ,
00247 2.90138,
00248 3.04448,
00249 3.21932,
00250 3.39462,
00251 3.56966,
00252 3.74485,
00253 3.91956,
00254 4.09497,
00255 4.27007,
00256 4.44417,
00257 4.62046
00258 };
00259
00260
00261 etaedge[0] = 0.;
00262 for(int i=1;i<30;i++){
00263 etaedge[i] = (etacent[i-1]-etaedge[i-1])*2.0 + etaedge[i-1];
00264
00265 }
00266
00267 if(useHF_){
00268 for(int i=30;i<42;i++){
00269 etaedge[i]=etatow[i];
00270
00271 }
00272 }
00273 }
00274
00275
00276 void
00277 ParticleTowerProducer::endJob() {
00278 }
00279
00280
00281 void ParticleTowerProducer::resetTowers(edm::Event& iEvent,const edm::EventSetup& iSetup)
00282 {
00283
00284 std::vector<DetId> alldid = geo_->getValidDetIds();
00285
00286 for(std::vector<DetId>::const_iterator did=alldid.begin(); did != alldid.end(); did++){
00287 if( (*did).det() == DetId::Hcal ){
00288 HcalDetId hid = HcalDetId(*did);
00289 if( hid.depth() == 1 ) {
00290
00291 if(!useHF_){
00292 GlobalPoint pos =geo_->getGeometry(hid)->getPosition();
00293
00294 if(fabs(pos.eta())>3.) continue;
00295 }
00296 towers_[(*did)] = 0.;
00297 }
00298
00299 }
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 }
00319
00320
00321
00322
00323 DetId ParticleTowerProducer::getNearestTower(const reco::PFCandidate & in) const {
00324
00325 double eta = in.eta();
00326 double phi = in.phi();
00327
00328 double minDeltaR = 9999;
00329
00330 std::vector<DetId> alldid = geo_->getValidDetIds();
00331
00332 DetId returnId;
00333
00334
00335
00336 for(std::vector<DetId>::const_iterator did=alldid.begin(); did != alldid.end(); did++){
00337 if( (*did).det() == DetId::Hcal ){
00338
00339 HcalDetId hid(*did);
00340
00341
00342
00343 if( hid.depth() != 1 ) continue;
00344
00345 GlobalPoint pos =geo_->getGeometry(hid)->getPosition();
00346
00347 double hcalEta = pos.eta();
00348 double hcalPhi = pos.phi();
00349
00350
00351
00352
00353
00354 double deltaR = reco::deltaR(eta,phi,hcalEta,hcalPhi);
00355
00356
00357 double towersize = 0.087;
00358
00359 int ieta = (hid).ieta();
00360
00361 if(abs(ieta)>21){
00362 if(abs(ieta)>29) towersize=0.175;
00363 else{
00364 if(abs(ieta)==22) towersize=0.1;
00365 else if(abs(ieta)==23) towersize=0.113;
00366 else if(abs(ieta)==24) towersize=0.129;
00367 else if(abs(ieta)==25) towersize=0.16;
00368 else if(abs(ieta)==26) towersize=0.168;
00369 else if(abs(ieta)==27) towersize=0.15;
00370 else if(abs(ieta)==28) towersize=0.218;
00371 else if(abs(ieta)==29) towersize=0.132;
00372 }
00373 }
00374
00375 deltaR /= towersize;
00376
00377
00378 if(deltaR<minDeltaR){
00379 returnId = DetId(*did);
00380 minDeltaR = deltaR;
00381 }
00382
00383
00384 }
00385 }
00386
00387 return returnId;
00388
00389
00390 }
00391
00392
00393 DetId ParticleTowerProducer::getNearestTower(double eta, double phi) const {
00394
00395
00396
00397
00398 double minDeltaR = 9999;
00399
00400 std::vector<DetId> alldid = geo_->getValidDetIds();
00401
00402 DetId returnId;
00403
00404
00405
00406 for(std::vector<DetId>::const_iterator did=alldid.begin(); did != alldid.end(); did++){
00407 if( (*did).det() == DetId::Hcal ){
00408
00409 HcalDetId hid(*did);
00410
00411
00412
00413 if( hid.depth() != 1 ) continue;
00414
00415 GlobalPoint pos =geo_->getGeometry(hid)->getPosition();
00416
00417 double hcalEta = pos.eta();
00418 double hcalPhi = pos.phi();
00419
00420
00421
00422
00423
00424 double deltaR = reco::deltaR(eta,phi,hcalEta,hcalPhi);
00425
00426
00427 double towersize = 0.087;
00428
00429 int ieta = (hid).ieta();
00430
00431 if(abs(ieta)>21){
00432 if(abs(ieta)>29) towersize=0.175;
00433 else{
00434 if(abs(ieta)==22) towersize=0.1;
00435 else if(abs(ieta)==23) towersize=0.113;
00436 else if(abs(ieta)==24) towersize=0.129;
00437 else if(abs(ieta)==25) towersize=0.16;
00438 else if(abs(ieta)==26) towersize=0.168;
00439 else if(abs(ieta)==27) towersize=0.15;
00440 else if(abs(ieta)==28) towersize=0.218;
00441 else if(abs(ieta)==29) towersize=0.132;
00442 }
00443 }
00444
00445 deltaR /= towersize;
00446
00447
00448 if(deltaR<minDeltaR){
00449 returnId = DetId(*did);
00450 minDeltaR = deltaR;
00451 }
00452
00453
00454 }
00455 }
00456
00457 return returnId;
00458
00459
00460 }
00461
00462
00463
00464
00465
00466
00467 int ParticleTowerProducer::eta2ieta(double eta) const {
00468
00469 int size = 42;
00470 if(!useHF_) size = 30;
00471
00472 double x = fabs(eta);
00473 int curr = size / 2;
00474 int step = size / 4;
00475 int iter;
00476 int prevdir = 0;
00477 int actudir = 0;
00478
00479 for (iter = 0; iter < size ; iter++) {
00480
00481 if( curr >= size || curr < 1 )
00482 std::cout << " ParticleTowerProducer::eta2ieta - wrong current index = "
00483 << curr << " !!!" << std::endl;
00484
00485 if ((x <= etaedge[curr]) && (x > etaedge[curr-1])) break;
00486 prevdir = actudir;
00487 if(x > etaedge[curr]) {actudir = 1;}
00488 else {actudir = -1;}
00489 if(prevdir * actudir < 0) { if(step > 1) step /= 2;}
00490 curr += actudir * step;
00491 if(curr > size) curr = size;
00492 else { if(curr < 1) {curr = 1;}}
00493
00494
00495
00496
00497
00498
00499
00500 }
00501
00502
00503
00504
00505
00506
00507
00508 return curr;
00509 }
00510
00511 int ParticleTowerProducer::phi2iphi(double phi, int ieta) const {
00512
00513 if(phi<0) phi += 2.*PI;
00514 else if(phi> 2.*PI) phi -= 2.*PI;
00515
00516 int iphi = (int) TMath::Ceil(phi/2.0/PI*72.);
00517
00518 if(abs(ieta)>20){
00519 if(abs(ieta)<40) iphi -= (iphi+1)%2;
00520 else {
00521 iphi -= (iphi+1)%4;
00522 if(iphi==-1) iphi=71;
00523 }
00524 }
00525
00526 return iphi;
00527
00528 }
00529
00530
00531 DEFINE_FWK_MODULE(ParticleTowerProducer);