00001
00002 #include "RecoEcal/EgammaClusterAlgos/interface/PFSuperClusterAlgo.h"
00003 #include "RecoParticleFlow/PFClusterTools/interface/PFClusterWidthAlgo.h"
00004 #include "RecoParticleFlow/PFClusterTools/interface/LinkByRecHit.h"
00005 #include "DataFormats/ParticleFlowReco/interface/PFLayer.h"
00006 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00007 #include "RecoEcal/EgammaCoreTools/interface/Mustache.h"
00008 #include "Math/GenVector/VectorUtil.h"
00009 #include "TFile.h"
00010 #include "TH2F.h"
00011 #include "TROOT.h"
00012 #include "TMath.h"
00013
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015
00016 #include <stdexcept>
00017 #include <string>
00018 #include <sstream>
00019
00020 using namespace std;
00021
00022 PFSuperClusterAlgo::PFSuperClusterAlgo()
00023
00024 {
00025
00026 }
00027
00028
00029 void PFSuperClusterAlgo::doClustering(const edm::Handle<reco::PFClusterCollection> & pfclustersHandle, std::auto_ptr< reco::BasicClusterCollection > & basicClusters_p, boost::shared_ptr<PFEnergyCalibration> thePFEnergyCalibration_, int detector){
00030
00031
00032
00033
00034
00035
00036
00037
00038 const reco::PFClusterCollection& pfclusters = *pfclustersHandle.product();
00039
00040 if (detector==0) {
00041 threshPFClusterSeed_ = threshPFClusterSeedBarrel_;
00042 threshPFCluster_ = threshPFClusterBarrel_;
00043 etawidthSuperCluster_ = etawidthSuperClusterBarrel_;
00044 phiwidthSuperCluster_ = phiwidthSuperClusterBarrel_;
00045 }
00046 if (detector==1) {
00047 threshPFClusterSeed_ = threshPFClusterSeedEndcap_;
00048 threshPFCluster_ = threshPFClusterEndcap_;
00049 etawidthSuperCluster_ = etawidthSuperClusterEndcap_;
00050 phiwidthSuperCluster_ = phiwidthSuperClusterEndcap_;
00051 }
00052
00053 if (verbose_) {
00054 if (detector==0) cout << "PFSuperClusterAlgo::doClustering in EB" << endl;
00055 if (detector==1) cout << "PFSuperClusterAlgo::doClustering in EE" << endl;
00056 }
00057
00058
00059 pfClusters_.clear();
00060 basicClusters_.clear();
00061
00062 basicClusterPtr_.clear();
00063
00064 scPFseedIndex_.clear();
00065 seedCandidateIndex_.clear();
00066 pfClusterIndex_.clear();
00067
00068 unsigned int nClusters = pfclusters.size();
00069 allPfClusterCalibratedEnergy_.resize(nClusters);
00070 allPfClusterCalibratedEnergy_.assign(nClusters, 0.0);
00071
00072 pfClusterCalibratedEnergy_.clear();
00073
00074 seedCandidateCollection.clear();
00075 pfClusterAboveThresholdCollection.clear();
00076
00077
00078 int layer;
00079 if (detector==0) layer = PFLayer::ECAL_BARREL;
00080 if (detector==1) layer = PFLayer::ECAL_ENDCAP;
00081
00082
00083 for (unsigned int i=0; i<pfclusters.size(); i++){
00084 const reco::PFCluster & myPFCluster = pfclusters[i];
00085 if (verbose_) cout << "PFCluster i="<<i<<" energy="<<myPFCluster.energy()<<endl;
00086
00087 if (myPFCluster.layer()==layer){
00088
00089 double PFClusterCalibratedEnergy = thePFEnergyCalibration_->energyEm(myPFCluster,0.0,0.0,applyCrackCorrections_);
00090
00091 allPfClusterCalibratedEnergy_[i]= PFClusterCalibratedEnergy;
00092
00093
00094 if (PFClusterCalibratedEnergy > threshPFClusterSeed_){
00095 const reco::PFClusterRef seedCandidate = reco::PFClusterRef(pfclustersHandle, i);
00096 seedCandidateCollection.push_back(seedCandidate);
00097 }
00098
00099
00100 if (PFClusterCalibratedEnergy > threshPFCluster_){
00101 const reco::PFClusterRef pfClusterAboveThreshold = reco::PFClusterRef(pfclustersHandle, i);
00102 pfClusterAboveThresholdCollection.push_back(pfClusterAboveThreshold);
00103 pfClusterIndex_.push_back(i);
00104 }
00105
00106 }
00107
00108 }
00109
00110
00111 sort(seedCandidateCollection.begin(), seedCandidateCollection.end(), less_magPF());
00112
00113 if (verbose_) cout << "After sorting"<<endl;
00114 for (unsigned int is=0; is<seedCandidateCollection.size(); is++) {
00115 if (verbose_) cout << "SeedPFCluster "<<is<< " energy="<<seedCandidateCollection[is]->energy()<<endl;
00116
00117 for (unsigned int i=0; i<pfclusters.size(); i++){
00118 if (seedCandidateCollection[is].key()==i) {
00119 seedCandidateIndex_.push_back(i);
00120 if (verbose_) cout << "seedCandidateIndex_[is]="<<seedCandidateIndex_[is]<<endl;
00121 }
00122 }
00123 }
00124
00125
00126
00127
00128 std::vector<int> isSeedUsed(seedCandidateCollection.size(),0);
00129
00130 std::vector<int> isPFclusterUsed(pfClusterAboveThresholdCollection.size(), 0);
00131
00132 std::vector<bool> isClusterized(pfclusters.size(), false);
00133
00134 nSuperClusters = 0;
00135
00136
00137 for (unsigned int is=0; is<seedCandidateCollection.size(); is++){
00138
00139 if (verbose_) cout << "is="<<is<<" seedCandidate Energy="<<seedCandidateCollection[is]->energy() <<" eta="<< seedCandidateCollection[is]->eta()<< " phi="<< seedCandidateCollection[is]->phi()<< endl;
00140
00141 if (isClusterized[seedCandidateIndex_[is]]==true) {
00142 if (verbose_) cout << "This seed cluster (energy="<<(*pfclustersHandle)[seedCandidateIndex_[is]].energy() <<") is already used, switching to next one" << endl;
00143 continue;
00144 }
00145 isSeedUsed[is]=0;
00146
00147 double seedEta = seedCandidateCollection[is]->eta();
00148 double seedPhi = seedCandidateCollection[is]->phi();
00149
00150 for (unsigned int j=0; j<pfClusterAboveThresholdCollection.size(); j++){
00151
00152 reco::PFClusterRef myPFClusterRef = pfClusterAboveThresholdCollection[j];
00153 const reco::PFCluster & myPFCluster (*myPFClusterRef);
00154 if (isPFclusterUsed[j]==1) {
00155 if (verbose_) cout << "This PFCluster (energy="<<myPFCluster.energy() <<") is already used" << endl;
00156 continue;
00157 }
00158
00159
00160 if (fabs(seedEta-myPFCluster.eta())<etawidthSuperCluster_
00161 && fabs(seedPhi-myPFCluster.phi())<phiwidthSuperCluster_
00162 ){
00163
00164 isSeedUsed[is]++;
00165 if (isSeedUsed[is]==1){
00166 pfClusters_.push_back(std::vector<const reco::PFCluster *>());
00167 basicClusters_.push_back(reco::BasicClusterCollection());
00168 pfClusterCalibratedEnergy_.push_back(std::vector<double>());
00169 }
00170
00171 isPFclusterUsed[j]=1;
00172
00173
00174 createBasicCluster(myPFClusterRef, basicClusters_[nSuperClusters], pfClusters_[nSuperClusters]);
00175
00176 double PFClusterCalibratedEnergy = allPfClusterCalibratedEnergy_[myPFClusterRef.key()];
00177
00178 pfClusterCalibratedEnergy_[nSuperClusters].push_back(PFClusterCalibratedEnergy);
00179
00180 if (myPFClusterRef==seedCandidateCollection[is]) {
00181 scPFseedIndex_.push_back(basicClusters_[nSuperClusters].size()-1);
00182 }
00183
00184 if (verbose_) cout << "Use PFCluster "<<j<<" eta="<< myPFCluster.eta()
00185 << "phi="<< myPFCluster.phi()
00186 <<" energy="<< myPFCluster.energy()
00187 <<" calibEnergy="<< pfClusterCalibratedEnergy_[nSuperClusters][basicClusters_[nSuperClusters].size()-1]<<endl;
00188
00189 isClusterized[pfClusterIndex_[j]] = true;
00190
00191 }
00192 }
00193
00194
00195
00196 if (isSeedUsed[is]>0) {
00197
00198 if (verbose_) cout << "New supercluster, number "<<nSuperClusters<<" having "<< basicClusters_[nSuperClusters].size()<< " basicclusters"<<endl;
00199 if (verbose_) for (unsigned int i=0; i<basicClusters_[nSuperClusters].size(); i++) cout << "BC "<<i<<" energy="<<basicClusters_[nSuperClusters][i].energy()<<endl;
00200
00201 basicClusters_p->insert(basicClusters_p->end(),basicClusters_[nSuperClusters].begin(), basicClusters_[nSuperClusters].end());
00202
00203 if (verbose_) cout << "basicClusters_p filled" << endl;
00204
00205 nSuperClusters++;
00206 }
00207
00208 }
00209
00210 if (verbose_) {
00211 if (detector==0) cout << "Leaving doClustering in EB (nothing more to clusterize)"<<endl;
00212 if (detector==1) cout << "Leaving doClustering in EE (nothing more to clusterize)"<<endl;
00213 }
00214
00215
00216 return;
00217 }
00218
00219
00220 void PFSuperClusterAlgo::createBasicCluster(const reco::PFClusterRef & myPFClusterRef,
00221 reco::BasicClusterCollection & basicClusters,
00222 std::vector<const reco::PFCluster *> & pfClusters) const
00223 {
00224
00225
00226
00227 if(myPFClusterRef.isNull()) return;
00228
00229 const reco::PFCluster & myPFCluster (*myPFClusterRef);
00230 pfClusters.push_back(&myPFCluster);
00231
00232
00233
00234 basicClusters.push_back(myPFCluster);
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 }
00246
00247 void PFSuperClusterAlgo::createBasicClusterPtrs(const edm::OrphanHandle<reco::BasicClusterCollection> & basicClustersHandle )
00248 {
00249 unsigned size=nSuperClusters;
00250 unsigned basicClusterCounter=0;
00251 basicClusterPtr_.resize(size);
00252
00253 for(unsigned is=0;is<size;++is)
00254 {
00255 unsigned nbc=basicClusters_[is].size();
00256 for(unsigned ibc=0;ibc<nbc;++ibc)
00257 {
00258 reco::CaloClusterPtr bcPtr(basicClustersHandle,basicClusterCounter);
00259 basicClusterPtr_[is].push_back(bcPtr);
00260 ++basicClusterCounter;
00261 }
00262 }
00263 }
00264
00265
00266 void PFSuperClusterAlgo::createSuperClusters(reco::SuperClusterCollection &superClusters, bool doEEwithES) const{
00267
00268 unsigned ns=nSuperClusters;
00269 for(unsigned is=0;is<ns;++is)
00270 {
00271
00272
00273 double sclusterE=0;
00274 double posX=0.;
00275 double posY=0.;
00276 double posZ=0.;
00277
00278 double correctedEnergy = 0;
00279 double correctedEnergyWithES = 0;
00280
00281 unsigned nbasics=basicClusters_[is].size();
00282 for(unsigned ibc=0;ibc<nbasics;++ibc)
00283 {
00284
00285 if (doMustacheCut_ && insideMust_[is][ibc] == 0) continue;
00286
00287 double BCenergy = basicClusters_[is][ibc].energy();
00288 sclusterE += BCenergy;
00289
00290
00291 correctedEnergy += pfClusterCalibratedEnergy_[is][ibc];
00292 if (doEEwithES) correctedEnergyWithES += pfClusterCalibratedEnergyWithES_[is][ibc];
00293
00294 posX += BCenergy * basicClusters_[is][ibc].position().X();
00295 posY += BCenergy * basicClusters_[is][ibc].position().Y();
00296 posZ += BCenergy * basicClusters_[is][ibc].position().Z();
00297 }
00298 posX /=sclusterE;
00299 posY /=sclusterE;
00300 posZ /=sclusterE;
00301
00302
00303
00304 PFClusterWidthAlgo pfwidth(pfClusters_[is]);
00305
00306
00307 double corrEnergy = correctedEnergy;
00308 if (doEEwithES) corrEnergy = correctedEnergyWithES;
00309 reco::SuperCluster mySuperCluster(corrEnergy,math::XYZPoint(posX,posY,posZ));
00310
00311 if (verbose_) {
00312 if (!doEEwithES) cout << "Supercluster "<<is<< " eta="<< mySuperCluster.eta() <<" phi="<< mySuperCluster.phi()<< " rawEnergy="<<sclusterE<<" correctedEnergy="<<correctedEnergy <<endl;
00313 if (doEEwithES) cout << "Supercluster "<<is<< " eta="<< mySuperCluster.eta() <<" phi="<< mySuperCluster.phi()<< " rawEnergy="<<sclusterE<<" correctedEnergy="<<correctedEnergy <<" correctedEnergyWithES="<<correctedEnergyWithES<<endl;
00314 }
00315
00316
00317 if(nbasics)
00318 {
00319 if (verbose_) std::cout << "Seed cluster energy=" << basicClusters_[is][scPFseedIndex_[is]].energy() << std::endl;
00320 mySuperCluster.setSeed(basicClusterPtr_[is][scPFseedIndex_[is]]);
00321 }
00322 else
00323 {
00324 mySuperCluster.setSeed(reco::CaloClusterPtr());
00325 }
00326
00327
00328
00329 for(unsigned ibc=0;ibc<nbasics;++ibc)
00330 {
00331 mySuperCluster.addCluster(basicClusterPtr_[is][ibc]);
00332
00333 const std::vector< std::pair<DetId, float> > & v1 = basicClusters_[is][ibc].hitsAndFractions();
00334 for( std::vector< std::pair<DetId, float> >::const_iterator diIt = v1.begin();
00335 diIt != v1.end();
00336 ++diIt ) {
00337 mySuperCluster.addHitAndFraction(diIt->first,diIt->second);
00338 }
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 if (doEEwithES) mySuperCluster.setPreshowerEnergy(correctedEnergyWithES-correctedEnergy);
00352 else mySuperCluster.setPreshowerEnergy(0.);
00353
00354
00355 mySuperCluster.setEtaWidth(pfwidth.pflowEtaWidth());
00356 mySuperCluster.setPhiWidth(pfwidth.pflowPhiWidth());
00357
00358 mySuperCluster.rawEnergy();
00359
00360 superClusters.push_back(mySuperCluster);
00361
00362 }
00363 }
00364
00365 void PFSuperClusterAlgo::storeSuperClusters(const edm::OrphanHandle<reco::BasicClusterCollection> & basicClustersHandle, std::auto_ptr< reco::SuperClusterCollection > & pfSuperClusters_p)
00366 {
00367
00368
00369 findClustersOutsideMustacheArea();
00370
00371
00372 createBasicClusterPtrs(basicClustersHandle);
00373 superClusters_.clear();
00374 createSuperClusters(superClusters_, false);
00375
00376 if (verbose_) cout << "Created "<<superClusters_.size()<< " pfSuperClusters"<<endl;
00377
00378
00379 pfSuperClusters_p->insert(pfSuperClusters_p->end(), superClusters_.begin(), superClusters_.end());
00380
00381 return;
00382 }
00383
00384 void PFSuperClusterAlgo::matchSCtoESclusters(const edm::Handle<reco::PFClusterCollection> & pfclustersHandle, std::auto_ptr< reco::SuperClusterCollection > & pfSuperClustersWithES_p, boost::shared_ptr<PFEnergyCalibration> thePFEnergyCalibration_, int detector)
00385 {
00386
00387 if (verbose_) cout << "matchSCtoESclusters" << endl;
00388
00389
00390 if (detector==0) return;
00391
00392 const reco::PFClusterCollection& pfclusters = *pfclustersHandle.product();
00393 std::vector<const reco::PFCluster*> pfESClusterAboveThresholdCollection;
00394 pfClusterCalibratedEnergyWithES_.clear();
00395
00396
00397
00398 typedef reco::PFClusterCollection::const_iterator PFCI;
00399 unsigned int i=0;
00400 for (PFCI cluster = pfclusters.begin(), cEnd = pfclusters.end(); cluster!=cEnd; ++cluster,++i){
00401
00402 if (cluster->layer()==PFLayer::PS1 || cluster->layer()==PFLayer::PS2){
00403
00404 if (verbose_) cout << "ES PFCluster i="<<i<<" energy="<<cluster->energy()<<endl;
00405
00406 if (cluster->energy()>threshPFClusterES_){
00407 pfESClusterAboveThresholdCollection.push_back(&*cluster);
00408 }
00409
00410 }
00411
00412 }
00413
00414 unsigned int nESaboveThreshold = pfESClusterAboveThresholdCollection.size();
00415
00416
00417
00418
00419 double dist = -1;
00420 double distmin = 1000;
00421 int iscsel = -1;
00422 int ibcsel = -1;
00423
00424 unsigned int nSCs = pfClusters_.size();
00425
00426
00427 unsigned int maxSize = 0;
00428 for (unsigned int isc=0; isc<nSCs; isc++) {
00429 unsigned int iscSize = pfClusters_[isc].size();
00430 if (maxSize < iscSize) maxSize = iscSize;
00431 }
00432
00433
00434 std::vector<double > SCBCtoESenergyPS1(nSCs*maxSize, 0);
00435 std::vector<double > SCBCtoESenergyPS2(nSCs*maxSize, 0);
00436
00437 std::vector<double> bcEtas(nSCs*maxSize,0);
00438 std::vector<double> bcPhis(nSCs*maxSize,0);
00439 for (unsigned int isc=0; isc<nSCs; isc++) {
00440 for (unsigned int ibc=0, nBCs = pfClusters_[isc].size(); ibc<nBCs; ibc++){
00441 unsigned int indBC = isc*maxSize + ibc;
00442 bcEtas[indBC] = pfClusters_[isc][ibc]->eta();
00443 bcPhis[indBC] = pfClusters_[isc][ibc]->phi();
00444 }
00445 }
00446 for (unsigned int ies=0; ies<nESaboveThreshold; ies++){
00447
00448 distmin = 1000;
00449 iscsel = -1;
00450 ibcsel = -1;
00451
00452 const reco::PFCluster* pfes(pfESClusterAboveThresholdCollection[ies]);
00453 double pfesEta = pfes->eta();
00454 double pfesPhi = pfes->phi();
00455 for (unsigned int isc=0; isc<nSCs; isc++){
00456 for (unsigned int ibc=0, nBCs = pfClusters_[isc].size(); ibc<nBCs; ibc++){
00457 unsigned int indBC = isc*maxSize + ibc;
00458 const reco::PFCluster* bcPtr = pfClusters_[isc][ibc];
00459
00460 if (bcPtr->layer()!=PFLayer::ECAL_ENDCAP) continue;
00461 double bcEta = bcEtas[indBC];
00462 double deta=fabs(bcEta-pfesEta);
00463 if (bcEta*pfesEta<0 || fabs(deta)>0.3) continue;
00464
00465 double bcPhi = bcPhis[indBC];
00466 double dphi= fabs(bcPhi-pfesPhi);
00467 if (dphi>TMath::Pi()) dphi-= TMath::TwoPi();
00468
00469 if (fabs(dphi)>0.6) continue;
00470
00471 dist = LinkByRecHit::testECALAndPSByRecHit( *(bcPtr), *(pfes), false);
00472
00473 if (dist!=-1){
00474 if (verbose_) cout << "isc="<<isc<<" ibc="<<ibc<< " ies="<<ies<< " ESenergy="<< pfes->energy()<<" dist="<<dist<<endl;
00475
00476 if (dist<distmin){
00477 distmin = dist;
00478 iscsel = isc;
00479 ibcsel = ibc;
00480 }
00481 }
00482
00483 }
00484 }
00485
00486
00487
00488 if (iscsel!=-1 && ibcsel!=-1){
00489 if (verbose_) cout << "Associate ESpfcluster ies="<<ies<<" to BC "<<ibcsel<<" in SC"<<iscsel<<endl;
00490 unsigned int indBCsel = iscsel*maxSize + ibcsel;
00491 if (pfes->layer()==PFLayer::PS1) {
00492 SCBCtoESenergyPS1[indBCsel]+=pfes->energy();
00493 }
00494 if (pfes->layer()==PFLayer::PS2) {
00495 SCBCtoESenergyPS2[indBCsel]+=pfes->energy();
00496 }
00497 }
00498
00499 }
00500
00501
00502
00503 for (unsigned int isc=0; isc<nSCs; isc++){
00504 pfClusterCalibratedEnergyWithES_.push_back(std::vector<double>());
00505 for (unsigned int ibc=0; ibc<pfClusters_[isc].size(); ibc++){
00506 const reco::PFCluster & myPFCluster (*(pfClusters_[isc][ibc]));
00507 if (myPFCluster.layer()!=PFLayer::ECAL_ENDCAP) continue;
00508
00509 unsigned int indBC = isc*maxSize + ibc;
00510 double PFClusterCalibratedEnergy =
00511 thePFEnergyCalibration_->energyEm(myPFCluster,SCBCtoESenergyPS1[indBC],SCBCtoESenergyPS2[indBC],applyCrackCorrections_);
00512 if (verbose_) cout << "isc="<<isc<<" ibc="<<ibc<<" EEenergy="<<myPFCluster.energy()
00513 <<" calibEnergyWithoutES="<< pfClusterCalibratedEnergy_[isc][ibc]
00514 << " calibEnergyWithES="<<PFClusterCalibratedEnergy <<endl;
00515 pfClusterCalibratedEnergyWithES_[isc].push_back(PFClusterCalibratedEnergy);
00516
00517 if (verbose_){
00518 cout << "isc="<<isc<<" ibc="<<ibc<<" EEenergy="<<myPFCluster.energy()
00519 <<" PS1energy="<< SCBCtoESenergyPS1[indBC]<<" PS2energy="<<SCBCtoESenergyPS2[indBC]
00520 <<" calibEnergyWithoutES="<< pfClusterCalibratedEnergy_[isc][ibc] << " calibEnergyWithES="<<PFClusterCalibratedEnergy <<endl;
00521 }
00522
00523 }
00524 }
00525
00526
00527
00528 if (verbose_) cout << "Store EE+preshower superclusters" << endl;
00529 superClusters_.clear();
00530
00531 createSuperClusters(superClusters_, true);
00532
00533 pfSuperClustersWithES_p->insert(pfSuperClustersWithES_p->end(), superClusters_.begin(), superClusters_.end());
00534
00535 return;
00536 }
00537
00538 void PFSuperClusterAlgo::findClustersOutsideMustacheArea(){
00539
00540
00541
00542 if (!doMustacheCut_) return;
00543
00544
00545
00546 insideMust_.clear();
00547
00548
00549 reco::Mustache PFSCMustache;
00550
00551
00552
00553 std::vector<unsigned int> insideMustList;
00554 std::vector<unsigned int> outsideMustList;
00555
00556 for (unsigned int isc=0; isc<basicClusters_.size(); isc++){
00557
00558
00559
00560 insideMust_.push_back(std::vector<unsigned int>());
00561
00562
00563 insideMustList.clear();
00564 outsideMustList.clear();
00565
00566
00567 PFSCMustache.MustacheClust(basicClusters_[isc],
00568 insideMustList,
00569 outsideMustList);
00570
00571 for (unsigned int ibc=0; ibc<basicClusters_[isc].size(); ibc++) insideMust_[isc].push_back(1);
00572
00573 for (unsigned int iclus=0; iclus<outsideMustList.size(); iclus++) {
00574 if (verbose_) cout << "isc="<<isc<<" outsideMustList[iclus]="<<outsideMustList[iclus]<<" outside mustache, energy="<< basicClusters_[isc][outsideMustList[iclus]]<<endl;
00575 insideMust_[isc][outsideMustList[iclus]] = 0;
00576 }
00577
00578 }
00579
00580
00581
00582 return;
00583 }