00001 #include "RecoParticleFlow/PFClusterProducer/interface/PFClusterAlgo.h"
00002 #include "DataFormats/ParticleFlowReco/interface/PFLayer.h"
00003 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00004 #include "Math/GenVector/VectorUtil.h"
00005 #include "TFile.h"
00006 #include "TH2F.h"
00007 #include "TROOT.h"
00008
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010
00011 #include <stdexcept>
00012 #include <string>
00013 #include <sstream>
00014
00015 using namespace std;
00016
00017 unsigned PFClusterAlgo::prodNum_ = 1;
00018
00019
00020
00021
00022 PFClusterAlgo::PFClusterAlgo() :
00023 pfClusters_( new vector<reco::PFCluster> ),
00024 pfRecHitsCleaned_( new vector<reco::PFRecHit> ),
00025 threshBarrel_(0.),
00026 threshPtBarrel_(0.),
00027 threshSeedBarrel_(0.2),
00028 threshPtSeedBarrel_(0.),
00029 threshEndcap_(0.),
00030 threshPtEndcap_(0.),
00031 threshSeedEndcap_(0.6),
00032 threshPtSeedEndcap_(0.),
00033 threshCleanBarrel_(1E5),
00034 minS4S1Barrel_(0.),
00035 threshDoubleSpikeBarrel_(1E9),
00036 minS6S2DoubleSpikeBarrel_(-1.),
00037 threshCleanEndcap_(1E5),
00038 minS4S1Endcap_(0.),
00039 threshDoubleSpikeEndcap_(1E9),
00040 minS6S2DoubleSpikeEndcap_(-1.),
00041 nNeighbours_(4),
00042 posCalcNCrystal_(-1),
00043 posCalcP1_(-1),
00044 showerSigma_(5),
00045 useCornerCells_(false),
00046 cleanRBXandHPDs_(false),
00047 debug_(false)
00048 {
00049 file_ = 0;
00050 hBNeighbour = 0;
00051 hENeighbour = 0;
00052 }
00053
00054 void
00055 PFClusterAlgo::write() {
00056
00057 if ( file_ ) {
00058 file_->Write();
00059 cout << "Benchmark output written to file " << file_->GetName() << endl;
00060 file_->Close();
00061 }
00062
00063 }
00064
00065
00066 void PFClusterAlgo::doClustering( const PFRecHitHandle& rechitsHandle ) {
00067 const reco::PFRecHitCollection& rechits = * rechitsHandle;
00068
00069
00070 rechitsHandle_ = rechitsHandle;
00071
00072
00073 mask_.clear();
00074 mask_.resize( rechits.size(), true );
00075
00076
00077 doClusteringWorker( rechits );
00078 }
00079
00080 void PFClusterAlgo::doClustering( const PFRecHitHandle& rechitsHandle, const std::vector<bool> & mask ) {
00081 const reco::PFRecHitCollection& rechits = * rechitsHandle;
00082
00083
00084 rechitsHandle_ = rechitsHandle;
00085
00086
00087 mask_.clear();
00088 if (mask.size() == rechits.size()) {
00089 mask_.insert( mask_.end(), mask.begin(), mask.end() );
00090 } else {
00091 edm::LogError("PClusterAlgo::doClustering") << "map size should be " << rechits.size() << ". Will be reinitialized.";
00092 mask_.resize( rechits.size(), true );
00093 }
00094
00095
00096 doClusteringWorker( rechits );
00097 }
00098
00099 void PFClusterAlgo::doClustering( const reco::PFRecHitCollection& rechits ) {
00100
00101 rechitsHandle_.clear();
00102
00103
00104 mask_.clear();
00105 mask_.resize( rechits.size(), true );
00106
00107
00108 doClusteringWorker( rechits );
00109 }
00110
00111 void PFClusterAlgo::doClustering( const reco::PFRecHitCollection& rechits, const std::vector<bool> & mask ) {
00112
00113 rechitsHandle_.clear();
00114
00115
00116 mask_.clear();
00117 if (mask.size() == rechits.size()) {
00118 mask_.insert( mask_.end(), mask.begin(), mask.end() );
00119 } else {
00120 edm::LogError("PClusterAlgo::doClustering") << "map size should be " << rechits.size() << ". Will be reinitialized.";
00121 mask_.resize( rechits.size(), true );
00122 }
00123
00124
00125 doClusteringWorker( rechits );
00126 }
00127
00128
00129 void PFClusterAlgo::doClusteringWorker( const reco::PFRecHitCollection& rechits ) {
00130
00131 if ( pfClusters_.get() )
00132 pfClusters_->clear();
00133 else
00134 pfClusters_.reset( new std::vector<reco::PFCluster> );
00135
00136 if ( pfRecHitsCleaned_.get() )
00137 pfRecHitsCleaned_->clear();
00138 else
00139 pfRecHitsCleaned_.reset( new std::vector<reco::PFRecHit> );
00140
00141 eRecHits_.clear();
00142 for ( unsigned i = 0; i < rechits.size(); i++ )
00143 eRecHits_.insert( make_pair( rechit(i, rechits).energy(), i) );
00144
00145 color_.clear();
00146 color_.resize( rechits.size(), 0 );
00147
00148 seedStates_.clear();
00149 seedStates_.resize( rechits.size(), UNKNOWN );
00150
00151 usedInTopo_.clear();
00152 usedInTopo_.resize( rechits.size(), false );
00153
00154 if ( cleanRBXandHPDs_ ) cleanRBXAndHPD( rechits);
00155
00156
00157 findSeeds( rechits );
00158
00159
00160 buildTopoClusters( rechits );
00161
00162
00163 for(unsigned i=0; i<topoClusters_.size(); i++) {
00164
00165 const std::vector< unsigned >& topocluster = topoClusters_[i];
00166 buildPFClusters( topocluster, rechits );
00167 }
00168 }
00169
00170
00171 double PFClusterAlgo::parameter( Parameter paramtype,
00172 PFLayer::Layer layer,
00173 unsigned iCoeff ) const {
00174
00175
00176 double value = 0;
00177
00178 switch( layer ) {
00179 case PFLayer::ECAL_BARREL:
00180 case PFLayer::HCAL_BARREL1:
00181 case PFLayer::HCAL_BARREL2:
00182
00183 switch(paramtype) {
00184 case THRESH:
00185 value = threshBarrel_;
00186 break;
00187 case SEED_THRESH:
00188 value = threshSeedBarrel_;
00189 break;
00190 case PT_THRESH:
00191 value = threshPtBarrel_;
00192 break;
00193 case SEED_PT_THRESH:
00194 value = threshPtSeedBarrel_;
00195 break;
00196 case CLEAN_THRESH:
00197 value = threshCleanBarrel_;
00198 break;
00199 case CLEAN_S4S1:
00200 value = minS4S1Barrel_[iCoeff];
00201 break;
00202 case DOUBLESPIKE_THRESH:
00203 value = threshDoubleSpikeBarrel_;
00204 break;
00205 case DOUBLESPIKE_S6S2:
00206 value = minS6S2DoubleSpikeBarrel_;
00207 break;
00208 default:
00209 cerr<<"PFClusterAlgo::parameter : unknown parameter type "
00210 <<paramtype<<endl;
00211 assert(0);
00212 }
00213 break;
00214 case PFLayer::ECAL_ENDCAP:
00215 case PFLayer::HCAL_ENDCAP:
00216 case PFLayer::PS1:
00217 case PFLayer::PS2:
00218 case PFLayer::HF_EM:
00219 case PFLayer::HF_HAD:
00220
00221 switch(paramtype) {
00222 case THRESH:
00223 value = threshEndcap_;
00224 break;
00225 case SEED_THRESH:
00226 value = threshSeedEndcap_;
00227 break;
00228 case PT_THRESH:
00229 value = threshPtEndcap_;
00230 break;
00231 case SEED_PT_THRESH:
00232 value = threshPtSeedEndcap_;
00233 break;
00234 case CLEAN_THRESH:
00235 value = threshCleanEndcap_;
00236 break;
00237 case CLEAN_S4S1:
00238 value = minS4S1Endcap_[iCoeff];
00239 break;
00240 case DOUBLESPIKE_THRESH:
00241 value = threshDoubleSpikeEndcap_;
00242 break;
00243 case DOUBLESPIKE_S6S2:
00244 value = minS6S2DoubleSpikeEndcap_;
00245 break;
00246 default:
00247 cerr<<"PFClusterAlgo::parameter : unknown parameter type "
00248 <<paramtype<<endl;
00249 assert(0);
00250 }
00251 break;
00252 default:
00253 cerr<<"PFClusterAlgo::parameter : unknown layer "<<layer<<endl;
00254 assert(0);
00255 break;
00256 }
00257
00258 return value;
00259 }
00260
00261
00262 void
00263 PFClusterAlgo::cleanRBXAndHPD( const reco::PFRecHitCollection& rechits ) {
00264
00265 std::map< int, std::vector<unsigned> > hpds;
00266 std::map< int, std::vector<unsigned> > rbxs;
00267
00268 for(EH ih = eRecHits_.begin(); ih != eRecHits_.end(); ih++ ) {
00269
00270 unsigned rhi = ih->second;
00271
00272 if(! masked(rhi) ) continue;
00273
00274 const reco::PFRecHit& rhit = rechit( rhi, rechits);
00275
00276 int layer = rhit.layer();
00277 if ( layer != PFLayer::HCAL_BARREL1 &&
00278 layer != PFLayer::HCAL_ENDCAP ) break;
00279 HcalDetId theHcalDetId = HcalDetId(rhit.detId());
00280 int ieta = theHcalDetId.ieta();
00281 int iphi = theHcalDetId.iphi();
00282 int ihpd = ieta < 0 ?
00283 ( layer == PFLayer::HCAL_ENDCAP ? -(iphi+1)/2-100 : -iphi ) :
00284 ( layer == PFLayer::HCAL_ENDCAP ? (iphi+1)/2+100 : iphi ) ;
00285 hpds[ihpd].push_back(rhi);
00286 int irbx = ieta < 0 ?
00287 ( layer == PFLayer::HCAL_ENDCAP ? -(iphi+5)/4 - 20 : -(iphi+5)/4 ) :
00288 ( layer == PFLayer::HCAL_ENDCAP ? (iphi+5)/4 + 20 : (iphi+5)/4 ) ;
00289 if ( irbx == 19 ) irbx = 1;
00290 else if ( irbx == -19 ) irbx = -1;
00291 else if ( irbx == 39 ) irbx = 21;
00292 else if ( irbx == -39 ) irbx = -21;
00293 rbxs[irbx].push_back(rhi);
00294 }
00295
00296
00297 for ( std::map<int, std::vector<unsigned> >::iterator itrbx = rbxs.begin();
00298 itrbx != rbxs.end(); ++itrbx ) {
00299 if ( ( abs(itrbx->first)<20 && itrbx->second.size() > 30 ) ||
00300 ( abs(itrbx->first)>20 && itrbx->second.size() > 30 ) ) {
00301 const std::vector<unsigned>& rhits = itrbx->second;
00302 double totalEta = 0.;
00303 double totalEtaW = 0.;
00304 double totalPhi = 0.;
00305 double totalPhiW = 0.;
00306 double totalEta2 = 1E-9;
00307 double totalEta2W = 1E-9;
00308 double totalPhi2 = 1E-9;
00309 double totalPhi2W = 1E-9;
00310 double totalEnergy = 0.;
00311 double totalEnergy2 = 1E-9;
00312 unsigned nSeeds = rhits.size();
00313 unsigned nSeeds0 = rhits.size();
00314 std::map< int,std::vector<unsigned> > theHPDs;
00315 std::multimap< double,unsigned > theEnergies;
00316 for ( unsigned jh=0; jh < rhits.size(); ++jh ) {
00317 const reco::PFRecHit& hit = rechit(rhits[jh], rechits);
00318
00319 unsigned nN = 0;
00320 bool isASeed = true;
00321 const vector<unsigned>& neighbours4 = *(& hit.neighbours4());
00322 for(unsigned in=0; in<neighbours4.size(); in++) {
00323 const reco::PFRecHit& neighbour = rechit( neighbours4[in], rechits );
00324
00325 if( neighbour.energy() > hit.energy() ) {
00326 --nSeeds;
00327 --nSeeds0;
00328 isASeed = false;
00329 break;
00330 } else {
00331 if ( neighbour.energy() > 0.4 ) ++nN;
00332 }
00333 }
00334 if ( isASeed && !nN ) --nSeeds0;
00335
00336 HcalDetId theHcalDetId = HcalDetId(hit.detId());
00337
00338 int iphi = theHcalDetId.iphi();
00339
00340 if ( hit.layer() == PFLayer::HCAL_BARREL1 )
00341 theHPDs[iphi].push_back(rhits[jh]);
00342 else
00343 theHPDs[(iphi-1)/2].push_back(rhits[jh]);
00344 theEnergies.insert(std::pair<double,unsigned>(hit.energy(),rhits[jh]));
00345 totalEnergy += hit.energy();
00346 totalPhi += fabs(hit.position().phi());
00347 totalPhiW += hit.energy()*fabs(hit.position().phi());
00348 totalEta += hit.position().eta();
00349 totalEtaW += hit.energy()*hit.position().eta();
00350 totalEnergy2 += hit.energy()*hit.energy();
00351 totalPhi2 += hit.position().phi()*hit.position().phi();
00352 totalPhi2W += hit.energy()*hit.position().phi()*hit.position().phi();
00353 totalEta2 += hit.position().eta()*hit.position().eta();
00354 totalEta2W += hit.energy()*hit.position().eta()*hit.position().eta();
00355 }
00356
00357 totalPhi /= rhits.size();
00358 totalEta /= rhits.size();
00359 totalPhiW /= totalEnergy;
00360 totalEtaW /= totalEnergy;
00361 totalPhi2 /= rhits.size();
00362 totalEta2 /= rhits.size();
00363 totalPhi2W /= totalEnergy;
00364 totalEta2W /= totalEnergy;
00365 totalPhi2 = std::sqrt(totalPhi2 - totalPhi*totalPhi);
00366 totalEta2 = std::sqrt(totalEta2 - totalEta*totalEta);
00367 totalPhi2W = std::sqrt(totalPhi2W - totalPhiW*totalPhiW);
00368 totalEta2W = std::sqrt(totalEta2W - totalEtaW*totalEtaW);
00369 totalEnergy /= rhits.size();
00370 totalEnergy2 /= rhits.size();
00371 totalEnergy2 = std::sqrt(totalEnergy2 - totalEnergy*totalEnergy);
00372
00373 if ( nSeeds0 > 6 ) {
00374 unsigned nHPD15 = 0;
00375 for ( std::map<int, std::vector<unsigned> >::iterator itHPD = theHPDs.begin();
00376 itHPD != theHPDs.end(); ++itHPD ) {
00377 int hpdN = itHPD->first;
00378 const std::vector<unsigned>& hpdHits = itHPD->second;
00379 if ( ( abs(hpdN) < 100 && hpdHits.size() > 14 ) ||
00380 ( abs(hpdN) > 100 && hpdHits.size() > 14 ) ) ++nHPD15;
00381 }
00382 if ( nHPD15 > 1 ) {
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 std::multimap<double, unsigned >::iterator ntEn = theEnergies.end();
00399 --ntEn;
00400 unsigned nn = 0;
00401 double threshold = 1.;
00402 for ( std::multimap<double, unsigned >::iterator itEn = theEnergies.begin();
00403 itEn != theEnergies.end(); ++itEn ) {
00404 ++nn;
00405 if ( nn < 5 ) {
00406 mask_[itEn->second] = false;
00407 } else if ( nn == 5 ) {
00408 threshold = itEn->first * 5.;
00409 mask_[itEn->second] = false;
00410 } else {
00411 if ( itEn->first < threshold ) mask_[itEn->second] = false;
00412 }
00413 if ( !masked(itEn->second) ) {
00414 reco::PFRecHit theCleanedHit(rechit(itEn->second, rechits));
00415
00416 pfRecHitsCleaned_->push_back(theCleanedHit);
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426 }
00427 }
00428 }
00429 }
00430 }
00431
00432
00433 std::map<int, std::vector<unsigned> >::iterator neighbour1;
00434 std::map<int, std::vector<unsigned> >::iterator neighbour2;
00435 std::map<int, std::vector<unsigned> >::iterator neighbour0;
00436 std::map<int, std::vector<unsigned> >::iterator neighbour3;
00437 unsigned size1 = 0;
00438 unsigned size2 = 0;
00439 for ( std::map<int, std::vector<unsigned> >::iterator ithpd = hpds.begin();
00440 ithpd != hpds.end(); ++ithpd ) {
00441
00442 const std::vector<unsigned>& rhits = ithpd->second;
00443 std::multimap< double,unsigned > theEnergies;
00444 double totalEnergy = 0.;
00445 double totalEnergy2 = 1E-9;
00446 for ( unsigned jh=0; jh < rhits.size(); ++jh ) {
00447 const reco::PFRecHit& hit = rechit(rhits[jh], rechits);
00448 totalEnergy += hit.energy();
00449 totalEnergy2 += hit.energy()*hit.energy();
00450 theEnergies.insert(std::pair<double,unsigned>(hit.energy(),rhits[jh]));
00451 }
00452 totalEnergy /= rhits.size();
00453 totalEnergy2 /= rhits.size();
00454 totalEnergy2 = std::sqrt(totalEnergy2 - totalEnergy*totalEnergy);
00455
00456 if ( ithpd->first == 1 ) neighbour1 = hpds.find(72);
00457 else if ( ithpd->first == -1 ) neighbour1 = hpds.find(-72);
00458 else if ( ithpd->first == 101 ) neighbour1 = hpds.find(136);
00459 else if ( ithpd->first == -101 ) neighbour1 = hpds.find(-136);
00460 else neighbour1 = ithpd->first > 0 ? hpds.find(ithpd->first-1) : hpds.find(ithpd->first+1) ;
00461
00462 if ( ithpd->first == 72 ) neighbour2 = hpds.find(1);
00463 else if ( ithpd->first == -72 ) neighbour2 = hpds.find(-1);
00464 else if ( ithpd->first == 136 ) neighbour2 = hpds.find(101);
00465 else if ( ithpd->first == -136 ) neighbour2 = hpds.find(-101);
00466 else neighbour2 = ithpd->first > 0 ? hpds.find(ithpd->first+1) : hpds.find(ithpd->first-1) ;
00467
00468 if ( neighbour1 != hpds.end() ) {
00469 if ( neighbour1->first == 1 ) neighbour0 = hpds.find(72);
00470 else if ( neighbour1->first == -1 ) neighbour0 = hpds.find(-72);
00471 else if ( neighbour1->first == 101 ) neighbour0 = hpds.find(136);
00472 else if ( neighbour1->first == -101 ) neighbour0 = hpds.find(-136);
00473 else neighbour0 = neighbour1->first > 0 ? hpds.find(neighbour1->first-1) : hpds.find(neighbour1->first+1) ;
00474 }
00475
00476 if ( neighbour2 != hpds.end() ) {
00477 if ( neighbour2->first == 72 ) neighbour3 = hpds.find(1);
00478 else if ( neighbour2->first == -72 ) neighbour3 = hpds.find(-1);
00479 else if ( neighbour2->first == 136 ) neighbour3 = hpds.find(101);
00480 else if ( neighbour2->first == -136 ) neighbour3 = hpds.find(-101);
00481 else neighbour3 = neighbour2->first > 0 ? hpds.find(neighbour2->first+1) : hpds.find(neighbour2->first-1) ;
00482 }
00483
00484 size1 = neighbour1 != hpds.end() ? neighbour1->second.size() : 0;
00485 size2 = neighbour2 != hpds.end() ? neighbour2->second.size() : 0;
00486
00487
00488 if ( size1 > 10 ) {
00489 if ( ( abs(neighbour1->first) > 100 && neighbour1->second.size() > 15 ) ||
00490 ( abs(neighbour1->first) < 100 && neighbour1->second.size() > 12 ) )
00491 size1 = neighbour0 != hpds.end() ? neighbour0->second.size() : 0;
00492 }
00493 if ( size2 > 10 ) {
00494 if ( ( abs(neighbour2->first) > 100 && neighbour2->second.size() > 15 ) ||
00495 ( abs(neighbour2->first) < 100 && neighbour2->second.size() > 12 ) )
00496 size2 = neighbour3 != hpds.end() ? neighbour3->second.size() : 0;
00497 }
00498
00499 if ( ( abs(ithpd->first) > 100 && ithpd->second.size() > 15 ) ||
00500 ( abs(ithpd->first) < 100 && ithpd->second.size() > 12 ) )
00501 if ( (float)(size1 + size2)/(float)ithpd->second.size() < 1.0 ) {
00502
00503
00504
00505
00506
00507
00508 std::multimap<double, unsigned >::iterator ntEn = theEnergies.end();
00509 --ntEn;
00510 unsigned nn = 0;
00511 double threshold = 1.;
00512 for ( std::multimap<double, unsigned >::iterator itEn = theEnergies.begin();
00513 itEn != theEnergies.end(); ++itEn ) {
00514 ++nn;
00515 if ( nn < 5 ) {
00516 mask_[itEn->second] = false;
00517 } else if ( nn == 5 ) {
00518 threshold = itEn->first * 2.5;
00519 mask_[itEn->second] = false;
00520 } else {
00521 if ( itEn->first < threshold ) mask_[itEn->second] = false;
00522 }
00523 if ( !masked(itEn->second) ) {
00524 reco::PFRecHit theCleanedHit(rechit(itEn->second, rechits));
00525
00526 pfRecHitsCleaned_->push_back(theCleanedHit);
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536 }
00537 }
00538 }
00539
00540 }
00541
00542
00543 void PFClusterAlgo::findSeeds( const reco::PFRecHitCollection& rechits ) {
00544
00545 seeds_.clear();
00546
00547
00548 #ifdef PFLOW_DEBUG
00549 if(debug_)
00550 cout<<"PFClusterAlgo::findSeeds : start"<<endl;
00551 #endif
00552
00553
00554
00555 const vector<unsigned> noNeighbours(0, static_cast<unsigned>(0));
00556
00557
00558 for(EH ih = eRecHits_.begin(); ih != eRecHits_.end(); ih++ ) {
00559
00560 unsigned rhi = ih->second;
00561
00562 if(! masked(rhi) ) continue;
00563
00564
00565 double rhenergy = ih->first;
00566 const reco::PFRecHit& wannaBeSeed = rechit(rhi, rechits);
00567
00568 if( seedStates_[rhi] == NO ) continue;
00569
00570
00571
00572 int layer = wannaBeSeed.layer();
00573 double seedThresh = parameter( SEED_THRESH,
00574 static_cast<PFLayer::Layer>(layer) );
00575 double seedPtThresh = parameter( SEED_PT_THRESH,
00576 static_cast<PFLayer::Layer>(layer) );
00577 double cleanThresh = parameter( CLEAN_THRESH,
00578 static_cast<PFLayer::Layer>(layer) );
00579 double minS4S1_a = parameter( CLEAN_S4S1,
00580 static_cast<PFLayer::Layer>(layer), 0 );
00581 double minS4S1_b = parameter( CLEAN_S4S1,
00582 static_cast<PFLayer::Layer>(layer), 1 );
00583 double doubleSpikeThresh = parameter( DOUBLESPIKE_THRESH,
00584 static_cast<PFLayer::Layer>(layer) );
00585 double doubleSpikeS6S2 = parameter( DOUBLESPIKE_S6S2,
00586 static_cast<PFLayer::Layer>(layer) );
00587
00588
00589 #ifdef PFLOW_DEBUG
00590 if(debug_)
00591 cout<<"layer:"<<layer<<" seedThresh:"<<seedThresh<<endl;
00592 #endif
00593
00594
00595 if( rhenergy < seedThresh || (seedPtThresh>0. && wannaBeSeed.pt2() < seedPtThresh*seedPtThresh )) {
00596 seedStates_[rhi] = NO;
00597 continue;
00598 }
00599
00600
00601
00602 const vector<unsigned>* nbp;
00603 double tighterE = 1.0;
00604 double tighterF = 1.0;
00605
00606 switch ( layer ) {
00607 case PFLayer::ECAL_BARREL:
00608 case PFLayer::ECAL_ENDCAP:
00609 case PFLayer::HCAL_BARREL1:
00610 case PFLayer::HCAL_BARREL2:
00611 case PFLayer::HCAL_ENDCAP:
00612 tighterE = 2.0;
00613 tighterF = 3.0;
00614 case PFLayer::HF_EM:
00615 case PFLayer::HF_HAD:
00616 if( nNeighbours_ == 4 ) {
00617 nbp = & wannaBeSeed.neighbours4();
00618 }
00619 else if( nNeighbours_ == 8 ) {
00620 nbp = & wannaBeSeed.neighbours8();
00621 }
00622 else if( nNeighbours_ == 0 ) {
00623 nbp = & noNeighbours;
00624
00625
00626 }
00627 else {
00628 cerr<<"you're not allowed to set n neighbours to "
00629 <<nNeighbours_<<endl;
00630 assert(0);
00631 }
00632 break;
00633 case PFLayer::PS1:
00634 case PFLayer::PS2:
00635 nbp = & wannaBeSeed.neighbours4();
00636 break;
00637
00638 default:
00639 cerr<<"CellsEF::PhotonSeeds : unknown layer "<<layer<<endl;
00640 assert(0);
00641 }
00642
00643 const vector<unsigned>& neighbours = *nbp;
00644
00645
00646
00647
00648 seedStates_[rhi] = YES;
00649 for(unsigned in=0; in<neighbours.size(); in++) {
00650
00651 unsigned rhj = neighbours[in];
00652
00653 if ( !masked(rhj) ) continue;
00654 const reco::PFRecHit& neighbour = rechit( rhj, rechits );
00655
00656
00657 if( neighbour.energy() > wannaBeSeed.energy() ) {
00658 seedStates_[rhi] = NO;
00659 break;
00660 }
00661 }
00662
00663
00664
00665 if ( file_ || wannaBeSeed.energy() > cleanThresh ) {
00666
00667 const vector<unsigned>& neighbours4 = *(& wannaBeSeed.neighbours4());
00668
00669 double surroundingEnergy = wannaBeSeed.energyUp();
00670 double neighbourEnergy = 0.;
00671 double layerEnergy = 0.;
00672 for(unsigned in4=0; in4<neighbours4.size(); in4++) {
00673 unsigned rhj = neighbours4[in4];
00674
00675 if ( !masked(rhj) ) continue;
00676 const reco::PFRecHit& neighbour = rechit( rhj, rechits );
00677 surroundingEnergy += neighbour.energy() + neighbour.energyUp();
00678 neighbourEnergy += neighbour.energy() + neighbour.energyUp();
00679 layerEnergy += neighbour.energy();
00680 }
00681
00682
00683
00684
00685 double fraction1 = surroundingEnergy/wannaBeSeed.energy();
00686
00687
00688
00689
00690
00691
00692
00693
00694 if ( file_ ) {
00695 if ( layer == PFLayer::ECAL_BARREL || layer == PFLayer::HCAL_BARREL1 ) {
00696
00697
00698
00699
00700
00701
00702
00703 hBNeighbour->Fill(1./wannaBeSeed.energy(), fraction1);
00704 } else if ( fabs(wannaBeSeed.position().eta()) < 5.0 ) {
00705 if ( layer == PFLayer::ECAL_ENDCAP || layer == PFLayer::HCAL_ENDCAP ) {
00706 if ( wannaBeSeed.energy() > 1000 ) {
00707 if ( fabs(wannaBeSeed.position().eta()) < 2.8 )
00708 hENeighbour->Fill(1./wannaBeSeed.energy(), fraction1);
00709 }
00710 } else {
00711 hENeighbour->Fill(1./wannaBeSeed.energy(), fraction1);
00712 }
00713 }
00714 }
00715
00716
00717 if ( wannaBeSeed.energy() > cleanThresh ) {
00718 double f1Cut = minS4S1_a * log10(wannaBeSeed.energy()) + minS4S1_b;
00719 if ( fraction1 < f1Cut ) {
00720
00721 double eta = wannaBeSeed.position().eta();
00722 double phi = wannaBeSeed.position().phi();
00723 std::pair<double,double> dcr = dCrack(phi,eta);
00724 double dcrmin = layer == PFLayer::ECAL_BARREL ? std::min(dcr.first, dcr.second) : dcr.second;
00725 eta = fabs(eta);
00726 if ( eta < 5.0 &&
00727 ( ( eta < 2.85 && dcrmin > 1. ) ||
00728 ( rhenergy > tighterE*cleanThresh &&
00729 fraction1 < f1Cut/tighterF ) )
00730 ) {
00731 seedStates_[rhi] = CLEAN;
00732 mask_[rhi] = false;
00733 reco::PFRecHit theCleanedHit(wannaBeSeed);
00734
00735 pfRecHitsCleaned_->push_back(theCleanedHit);
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 }
00747 }
00748 }
00749 }
00750
00751
00752 if ( mask_[rhi] && wannaBeSeed.energy() > doubleSpikeThresh ) {
00753
00754 double surroundingEnergyi = 0.;
00755 double enmax = -999.;
00756 unsigned mostEnergeticNeighbour = 0;
00757 const vector<unsigned>& neighbours4i = *(& wannaBeSeed.neighbours4());
00758 for(unsigned in4=0; in4<neighbours4i.size(); in4++) {
00759 unsigned rhj = neighbours4i[in4];
00760 if ( !masked(rhj) ) continue;
00761 const reco::PFRecHit& neighbouri = rechit( rhj, rechits );
00762 surroundingEnergyi += neighbouri.energy();
00763 if ( neighbouri.energy() > enmax ) {
00764 enmax = neighbouri.energy();
00765 mostEnergeticNeighbour = rhj;
00766 }
00767 }
00768
00769 if ( enmax > 0. ) {
00770 unsigned rhj = mostEnergeticNeighbour;
00771 const reco::PFRecHit& neighbouri = rechit( rhj, rechits );
00772 double surroundingEnergyj = 0.;
00773
00774
00775 const vector<unsigned>& neighbours4j = *(& neighbouri.neighbours4());
00776 for(unsigned jn4=0; jn4<neighbours4j.size(); jn4++) {
00777 unsigned rhk = neighbours4j[jn4];
00778 const reco::PFRecHit& neighbourj = rechit( rhk, rechits );
00779 surroundingEnergyj += neighbourj.energy();
00780 }
00781
00782 double surroundingEnergyFraction =
00783 (surroundingEnergyi+surroundingEnergyj) / (wannaBeSeed.energy()+neighbouri.energy()) - 1.;
00784 if ( surroundingEnergyFraction < doubleSpikeS6S2 ) {
00785 double eta = wannaBeSeed.position().eta();
00786 double phi = wannaBeSeed.position().phi();
00787 std::pair<double,double> dcr = dCrack(phi,eta);
00788 double dcrmin = layer == PFLayer::ECAL_BARREL ? std::min(dcr.first, dcr.second) : dcr.second;
00789 eta = fabs(eta);
00790 if ( ( eta < 5.0 && dcrmin > 1. ) ||
00791 ( wannaBeSeed.energy() > tighterE*doubleSpikeThresh &&
00792 surroundingEnergyFraction < doubleSpikeS6S2/tighterF ) ) {
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 seedStates_[rhi] = CLEAN;
00803 mask_[rhi] = false;
00804 reco::PFRecHit theCleanedSeed(wannaBeSeed);
00805 pfRecHitsCleaned_->push_back(theCleanedSeed);
00806
00807 seedStates_[rhj] = CLEAN;
00808 mask_[rhj] = false;
00809 reco::PFRecHit theCleanedNeighbour(wannaBeSeed);
00810 pfRecHitsCleaned_->push_back(neighbouri);
00811 }
00812 }
00813 } else {
00814
00815
00816
00817
00818 }
00819 }
00820
00821 if ( seedStates_[rhi] == YES ) {
00822
00823
00824 seeds_.push_back( rhi );
00825
00826
00827 paint(rhi, SEED);
00828
00829
00830 for(unsigned in=0; in<neighbours.size(); in++) {
00831 seedStates_[ neighbours[in] ] = NO;
00832 }
00833 }
00834 }
00835
00836 #ifdef PFLOW_DEBUG
00837 if(debug_)
00838 cout<<"PFClusterAlgo::findSeeds : done"<<endl;
00839 #endif
00840 }
00841
00842
00843
00844
00845 void PFClusterAlgo::buildTopoClusters( const reco::PFRecHitCollection& rechits ){
00846
00847 topoClusters_.clear();
00848
00849 #ifdef PFLOW_DEBUG
00850 if(debug_)
00851 cout<<"PFClusterAlgo::buildTopoClusters start"<<endl;
00852 #endif
00853
00854 for(unsigned is = 0; is<seeds_.size(); is++) {
00855
00856 unsigned rhi = seeds_[is];
00857
00858 if( !masked(rhi) ) continue;
00859
00860
00861
00862 if( usedInTopo_[rhi] ) {
00863 #ifdef PFLOW_DEBUG
00864 if(debug_)
00865 cout<<rhi<<" used"<<endl;
00866 #endif
00867 continue;
00868 }
00869
00870 vector< unsigned > topocluster;
00871 buildTopoCluster( topocluster, rhi, rechits );
00872
00873 if(topocluster.empty() ) continue;
00874
00875 topoClusters_.push_back( topocluster );
00876
00877 }
00878
00879 #ifdef PFLOW_DEBUG
00880 if(debug_)
00881 cout<<"PFClusterAlgo::buildTopoClusters done"<<endl;
00882 #endif
00883
00884 return;
00885 }
00886
00887
00888 void
00889 PFClusterAlgo::buildTopoCluster( vector< unsigned >& cluster,
00890 unsigned rhi,
00891 const reco::PFRecHitCollection& rechits ){
00892
00893
00894 #ifdef PFLOW_DEBUG
00895 if(debug_)
00896 cout<<"PFClusterAlgo::buildTopoCluster in"<<endl;
00897 #endif
00898
00899 const reco::PFRecHit& rh = rechit( rhi, rechits);
00900
00901 double e = rh.energy();
00902 int layer = rh.layer();
00903
00904 double thresh = parameter( THRESH,
00905 static_cast<PFLayer::Layer>(layer) );
00906 double ptThresh = parameter( PT_THRESH,
00907 static_cast<PFLayer::Layer>(layer) );
00908
00909
00910 if( e < thresh || (ptThresh > 0. && rh.pt2() < ptThresh*ptThresh) ) {
00911 #ifdef PFLOW_DEBUG
00912 if(debug_)
00913 cout<<"return : "<<e<<"<"<<thresh<<endl;
00914 #endif
00915 return;
00916 }
00917
00918
00919
00920 cluster.push_back( rhi );
00921
00922
00923 usedInTopo_[ rhi ] = true;
00924
00925
00926
00927
00928
00929 const std::vector< unsigned >& nbs
00930 = useCornerCells_ ? rh.neighbours8() : rh.neighbours4();
00931
00932 for(unsigned i=0; i<nbs.size(); i++) {
00933
00934
00935
00936
00937
00938
00939
00940
00941 if( usedInTopo_[ nbs[i] ] ) {
00942 #ifdef PFLOW_DEBUG
00943 if(debug_)
00944 cout<<rhi<<" used"<<endl;
00945 #endif
00946 continue;
00947 }
00948
00949 if( !masked(nbs[i]) ) continue;
00950 buildTopoCluster( cluster, nbs[i], rechits );
00951 }
00952 #ifdef PFLOW_DEBUG
00953 if(debug_)
00954 cout<<"PFClusterAlgo::buildTopoCluster out"<<endl;
00955 #endif
00956
00957 }
00958
00959
00960 void
00961 PFClusterAlgo::buildPFClusters( const std::vector< unsigned >& topocluster,
00962 const reco::PFRecHitCollection& rechits )
00963 {
00964
00965
00966
00967
00968
00969
00970
00971 vector<reco::PFCluster> curpfclusters;
00972 vector<reco::PFCluster> curpfclusterswodepthcor;
00973 vector< unsigned > seedsintopocluster;
00974
00975
00976 for(unsigned i=0; i<topocluster.size(); i++ ) {
00977
00978 unsigned rhi = topocluster[i];
00979
00980 if( seedStates_[rhi] == YES ) {
00981
00982 reco::PFCluster cluster;
00983 reco::PFCluster clusterwodepthcor;
00984
00985 double fraction = 1.0;
00986
00987 reco::PFRecHitRef recHitRef = createRecHitRef( rechits, rhi );
00988
00989 cluster.addRecHitFraction( reco::PFRecHitFraction( recHitRef,
00990 fraction ) );
00991
00992
00993
00994 calculateClusterPosition( cluster,
00995 clusterwodepthcor,
00996 true );
00997
00998
00999
01000 curpfclusters.push_back( cluster );
01001 curpfclusterswodepthcor.push_back( clusterwodepthcor );
01002 #ifdef PFLOW_DEBUG
01003 if(debug_) {
01004 cout << "PFClusterAlgo::buildPFClusters: seed "
01005 << rechit( rhi, rechits) <<endl;
01006 cout << "PFClusterAlgo::buildPFClusters: pfcluster initialized : "
01007 << cluster <<endl;
01008 }
01009 #endif
01010
01011
01012 seedsintopocluster.push_back( rhi );
01013
01014 }
01015 }
01016
01017
01018
01019
01020 int posCalcNCrystal = seedsintopocluster.size()>1 ? posCalcNCrystal_:-1;
01021 double ns2 = std::max(1.,(double)(seedsintopocluster.size())-1.);
01022 ns2 *= ns2;
01023
01024
01025
01026 unsigned iter = 0;
01027 unsigned niter = 50;
01028 double diff = ns2;
01029
01030
01031 vector<double> ener;
01032 vector<double> dist;
01033 vector<double> frac;
01034 vector<math::XYZVector> tmp;
01035 while ( iter++ < niter && diff > 1E-8*ns2 ) {
01036
01037
01038 ener.clear();
01039 tmp.clear();
01040
01041 for ( unsigned ic=0; ic<curpfclusters.size(); ic++ ) {
01042 ener.push_back( curpfclusters[ic].energy() );
01043
01044 math::XYZVector v;
01045 v = curpfclusters[ic].position();
01046
01047 tmp.push_back( v );
01048
01049 #ifdef PFLOW_DEBUG
01050 if(debug_) {
01051 cout<<"saving photon pos "<<ic<<" "<<curpfclusters[ic]<<endl;
01052 cout<<tmp[ic].X()<<" "<<tmp[ic].Y()<<" "<<tmp[ic].Z()<<endl;
01053 }
01054 #endif
01055
01056 curpfclusters[ic].reset();
01057 }
01058
01059
01060
01061 for( unsigned irh=0; irh<topocluster.size(); irh++ ) {
01062
01063 unsigned rhindex = topocluster[irh];
01064
01065 const reco::PFRecHit& rh = rechit( rhindex, rechits);
01066
01067
01068
01069 dist.clear();
01070 frac.clear();
01071 double fractot = 0.;
01072
01073 bool isaseed = isSeed(rhindex);
01074
01075 math::XYZVector cposxyzcell;
01076 cposxyzcell = rh.position();
01077
01078 #ifdef PFLOW_DEBUG
01079 if(debug_) {
01080 cout<<rh<<endl;
01081 cout<<"start loop on curpfclusters"<<endl;
01082 }
01083 #endif
01084
01085
01086 for ( unsigned ic=0; ic<tmp.size(); ic++) {
01087
01088 #ifdef PFLOW_DEBUG
01089 if(debug_) cout<<"pfcluster "<<ic<<endl;
01090 #endif
01091
01092 double frc=0.;
01093 bool seedexclusion=true;
01094
01095
01096
01097
01098 math::XYZVector cposxyzclust;
01099 cposxyzclust = curpfclusterswodepthcor[ic].position();
01100
01101 #ifdef PFLOW_DEBUG
01102 if(debug_) {
01103
01104 cout<<"CLUSTER "<<cposxyzclust.X()<<","
01105 <<cposxyzclust.Y()<<","
01106 <<cposxyzclust.Z()<<"\t\t"
01107 <<"CELL "<<cposxyzcell.X()<<","
01108 <<cposxyzcell.Y()<<","
01109 <<cposxyzcell.Z()<<endl;
01110 }
01111 #endif
01112
01113
01114
01115
01116 math::XYZVector deltav = cposxyzclust;
01117 deltav -= cposxyzcell;
01118 double d = deltav.R() / showerSigma_;
01119
01120
01121
01122
01123
01124 #ifdef PFLOW_DEBUG
01125 if( d > 10. && debug_ ) {
01126 paint(rhindex, SPECIAL);
01127 cout<<"PFClusterAlgo Warning: distance too large"<<d<<endl;
01128 }
01129 #endif
01130 dist.push_back( d );
01131
01132
01133 if( rhindex == seedsintopocluster[ic] && seedexclusion ) {
01134 frc = 1.;
01135 #ifdef PFLOW_DEBUG
01136 if(debug_) cout<<"this cell is a seed for the current photon"<<endl;
01137 #endif
01138 }
01139 else if( isaseed && seedexclusion ) {
01140 frc = 0.;
01141 #ifdef PFLOW_DEBUG
01142 if(debug_) cout<<"this cell is a seed for another photon"<<endl;
01143 #endif
01144 }
01145 else {
01146
01147
01148 frc = ener[ic] * exp ( - dist[ic]*dist[ic] / 2. );
01149
01150 #ifdef PFLOW_DEBUG
01151 if(debug_) {
01152 cout<<"dist["<<ic<<"] "<<dist[ic]
01153 <<", sigma="<<sigma
01154 <<", frc="<<frc<<endl;
01155 }
01156 #endif
01157
01158 }
01159 fractot += frc;
01160 frac.push_back(frc);
01161 }
01162
01163
01164 #ifdef PFLOW_DEBUG
01165 if(debug_) cout<<"start add cell"<<endl;
01166 #endif
01167 for ( unsigned ic=0; ic<tmp.size(); ++ic ) {
01168 #ifdef PFLOW_DEBUG
01169 if(debug_)
01170 cout<<" frac["<<ic<<"] "<<frac[ic]<<" "<<fractot<<" "<<rh<<endl;
01171 #endif
01172
01173 if( fractot )
01174 frac[ic] /= fractot;
01175 else {
01176 #ifdef PFLOW_DEBUG
01177 if( debug_ ) {
01178 int layer = rh.layer();
01179 cerr<<"fractot = 0 ! "<<layer<<endl;
01180
01181 for( unsigned trh=0; trh<topocluster.size(); trh++ ) {
01182 unsigned tindex = topocluster[trh];
01183 const reco::PFRecHit& rh = rechit( tindex, rechits);
01184 cout<<rh<<endl;
01185 }
01186
01187
01188 }
01189 #endif
01190
01191 continue;
01192 }
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205 if ( dist[ic] < 10. || frac[ic] > 0.99999 ) {
01206
01207 reco::PFRecHitRef recHitRef = createRecHitRef( rechits, rhindex );
01208 reco::PFRecHitFraction rhf( recHitRef,frac[ic] );
01209 curpfclusters[ic].addRecHitFraction( rhf );
01210 }
01211 }
01212
01213 }
01214
01215
01216
01217 diff = 0.;
01218 for ( unsigned ic=0; ic<tmp.size(); ++ic ) {
01219 calculateClusterPosition( curpfclusters[ic], curpfclusterswodepthcor[ic],
01220 true, posCalcNCrystal );
01221 #ifdef PFLOW_DEBUG
01222 if(debug_) cout<<"new iter "<<ic<<endl;
01223 if(debug_) cout<<curpfclusters[ic]<<endl;
01224 #endif
01225
01226 double delta = ROOT::Math::VectorUtil::DeltaR(curpfclusters[ic].position(),tmp[ic]);
01227 if ( delta > diff ) diff = delta;
01228 }
01229 }
01230
01231
01232
01233 #ifdef PFLOW_DEBUG
01234 if ( iter >= 50 && debug_ )
01235 cout << "PFClusterAlgo Warning: "
01236 << "more than "<<niter<<" iterations in pfcluster finding: "
01237 << setprecision(10) << diff << endl;
01238 #endif
01239
01240
01241
01242 for(unsigned ic=0; ic<curpfclusters.size(); ic++) {
01243 calculateClusterPosition(curpfclusters[ic], curpfclusterswodepthcor[ic],
01244 true, posCalcNCrystal);
01245 pfClusters_->push_back(curpfclusters[ic]);
01246 }
01247 }
01248
01249
01250
01251 void
01252 PFClusterAlgo::calculateClusterPosition(reco::PFCluster& cluster,
01253 reco::PFCluster& clusterwodepthcor,
01254 bool depcor,
01255 int posCalcNCrystal) {
01256
01257 if( posCalcNCrystal_ != -1 &&
01258 posCalcNCrystal_ != 5 &&
01259 posCalcNCrystal_ != 9 ) {
01260 throw "PFCluster::calculatePosition : posCalcNCrystal_ must be -1, 5, or 9.";
01261 }
01262
01263 if(!posCalcNCrystal) posCalcNCrystal = posCalcNCrystal_;
01264
01265 cluster.position_.SetXYZ(0,0,0);
01266
01267 cluster.energy_ = 0;
01268
01269 double normalize = 0;
01270
01271
01272
01273
01274 map <PFLayer::Layer, double> layers;
01275 unsigned seedIndex = 0;
01276 bool seedIndexFound = false;
01277
01278
01279
01280
01281 for (unsigned ic=0; ic<cluster.rechits_.size(); ic++ ) {
01282
01283 unsigned rhi = cluster.rechits_[ic].recHitRef().index();
01284
01285
01286 const reco::PFRecHit& rh = *(cluster.rechits_[ic].recHitRef());
01287 double fraction = cluster.rechits_[ic].fraction();
01288
01289
01290
01291 if( isSeed(rhi) && fraction > 1e-9 ) {
01292 seedIndex = rhi;
01293 seedIndexFound = true;
01294 }
01295
01296 double recHitEnergy = rh.energy() * fraction;
01297
01298
01299 if( recHitEnergy!=recHitEnergy ) {
01300 ostringstream ostr;
01301 edm::LogError("PFClusterAlgo")<<"rechit "<<rh.detId()<<" has a NaN energy... The input of the particle flow clustering seems to be corrupted.";
01302 }
01303
01304 cluster.energy_ += recHitEnergy;
01305
01306
01307 PFLayer::Layer layer = rh.layer();
01308 map <PFLayer::Layer, double>:: iterator it = layers.find(layer);
01309 if (it != layers.end())
01310 it->second += recHitEnergy;
01311 else
01312 layers.insert(make_pair(layer, recHitEnergy));
01313 }
01314
01315 assert(seedIndexFound);
01316
01317
01318 double Emax = 0.;
01319 PFLayer::Layer layer = PFLayer::NONE;
01320 for (map<PFLayer::Layer, double>::iterator it = layers.begin();
01321 it != layers.end(); ++it) {
01322 double e = it->second;
01323 if(e > Emax){
01324 Emax = e;
01325 layer = it->first;
01326 }
01327 }
01328
01329
01330 cluster.setLayer( layer );
01331
01332
01333
01334
01335 double p1 = posCalcP1_;
01336 if( p1 < 0 ) {
01337
01338
01339
01340
01341
01342 switch(cluster.layer() ) {
01343 case PFLayer::ECAL_BARREL:
01344 case PFLayer::HCAL_BARREL1:
01345 case PFLayer::HCAL_BARREL2:
01346 p1 = threshBarrel_;
01347 break;
01348 case PFLayer::ECAL_ENDCAP:
01349 case PFLayer::HCAL_ENDCAP:
01350 case PFLayer::HF_EM:
01351 case PFLayer::HF_HAD:
01352 case PFLayer::PS1:
01353 case PFLayer::PS2:
01354 p1 = threshEndcap_;
01355 break;
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374 default:
01375 cerr<<"Clusters weight_p1 -1 not yet allowed for layer "<<layer
01376 <<". Chose a better value in the opt file"<<endl;
01377 assert(0);
01378 break;
01379 }
01380 }
01381 else if( p1< 1e-9 ) {
01382 p1 = 1e-9;
01383 }
01384
01385
01386
01387 reco::PFCluster::REPPoint clusterpos;
01388 math::XYZPoint clusterposxyz;
01389 math::XYZPoint firstrechitposxyz;
01390
01391 double maxe = -9999;
01392 double x = 0;
01393 double y = 0;
01394 double z = 0;
01395
01396 for (unsigned ic=0; ic<cluster.rechits_.size(); ic++ ) {
01397
01398 unsigned rhi = cluster.rechits_[ic].recHitRef().index();
01399
01400
01401 const reco::PFRecHit& rh = *(cluster.rechits_[ic].recHitRef());
01402
01403 if(rhi != seedIndex) {
01404 if( posCalcNCrystal == 5 ) {
01405 if(!rh.isNeighbour4(seedIndex) ) {
01406 continue;
01407 }
01408 }
01409 if( posCalcNCrystal == 9 ) {
01410 if(!rh.isNeighbour8(seedIndex) ) {
01411 continue;
01412 }
01413 }
01414 }
01415
01416 double fraction = cluster.rechits_[ic].fraction();
01417 double recHitEnergy = rh.energy() * fraction;
01418
01419 double norm = fraction < 1E-9 ? 0. : max(0., log(recHitEnergy/p1 ));
01420
01421 const math::XYZPoint& rechitposxyz = rh.position();
01422
01423 if( recHitEnergy > maxe ) {
01424 firstrechitposxyz = rechitposxyz;
01425 maxe = recHitEnergy;
01426 }
01427
01428 x += rechitposxyz.X() * norm;
01429 y += rechitposxyz.Y() * norm;
01430 z += rechitposxyz.Z() * norm;
01431
01432
01433 normalize += norm;
01434 }
01435
01436
01437
01438 if( normalize < 1e-9 ) {
01439
01440
01441 cout << "Watch out : cluster too far from its seeding cell, set to 0,0,0" << endl;
01442 clusterposxyz.SetXYZ(0,0,0);
01443 clusterpos.SetCoordinates(0,0,0);
01444 return;
01445 }
01446 else {
01447 x /= normalize;
01448 y /= normalize;
01449 z /= normalize;
01450 clusterposxyz.SetCoordinates( x, y, z);
01451 clusterpos.SetCoordinates( clusterposxyz.Rho(), clusterposxyz.Eta(), clusterposxyz.Phi() );
01452 }
01453
01454 cluster.posrep_ = clusterpos;
01455 cluster.position_ = clusterposxyz;
01456
01457 clusterwodepthcor = cluster;
01458
01459
01460
01461
01462
01463
01464 if( depcor &&
01465 ( cluster.layer() == PFLayer::ECAL_BARREL ||
01466 cluster.layer() == PFLayer::ECAL_ENDCAP ) ) {
01467
01468
01469 double corra = reco::PFCluster::depthCorA_;
01470 double corrb = reco::PFCluster::depthCorB_;
01471 if( abs(clusterpos.Eta() ) < 2.6 &&
01472 abs(clusterpos.Eta() ) > 1.65 ) {
01473
01474
01475 corra = reco::PFCluster::depthCorAp_;
01476 corrb = reco::PFCluster::depthCorBp_;
01477 }
01478
01479 double depth = 0;
01480
01481 switch( reco::PFCluster::depthCorMode_ ) {
01482 case 1:
01483 depth = corra * ( corrb + log(cluster.energy_) );
01484 break;
01485 case 2:
01486 depth = corra;
01487 break;
01488 default:
01489 cerr<<"PFClusterAlgo::calculateClusterPosition : unknown function for depth correction! "<<endl;
01490 assert(0);
01491 }
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509 math::XYZVector depthv( clusterposxyz.X(),
01510 clusterposxyz.Y(),
01511 clusterposxyz.Z() );
01512 depthv /= sqrt(depthv.Mag2() );
01513 depthv *= depth;
01514
01515
01516
01517 math::XYZPoint clusterposxyzcor;
01518
01519 maxe = -9999;
01520 x = 0;
01521 y = 0;
01522 z = 0;
01523 cluster.posrep_.SetXYZ(0,0,0);
01524 normalize = 0;
01525 for (unsigned ic=0; ic<cluster.rechits_.size(); ic++ ) {
01526
01527 unsigned rhi = cluster.rechits_[ic].recHitRef().index();
01528
01529
01530 const reco::PFRecHit& rh = *(cluster.rechits_[ic].recHitRef());
01531
01532 if(rhi != seedIndex) {
01533 if( posCalcNCrystal == 5 ) {
01534 if(!rh.isNeighbour4(seedIndex) ) {
01535 continue;
01536 }
01537 }
01538 if( posCalcNCrystal == 9 ) {
01539 if(!rh.isNeighbour8(seedIndex) ) {
01540 continue;
01541 }
01542 }
01543 }
01544
01545 double fraction = cluster.rechits_[ic].fraction();
01546 double recHitEnergy = rh.energy() * fraction;
01547
01548 const math::XYZPoint& rechitposxyz = rh.position();
01549
01550
01551 math::XYZVector rechitaxis = rh.getAxisXYZ();
01552
01553
01554 math::XYZVector rechitaxisu( rechitaxis );
01555 rechitaxisu /= sqrt( rechitaxis.Mag2() );
01556
01557 math::XYZVector displacement( rechitaxisu );
01558
01559 displacement *= rechitaxisu.Dot( depthv );
01560
01561 math::XYZPoint rechitposxyzcor( rechitposxyz );
01562 rechitposxyzcor += displacement;
01563
01564 if( recHitEnergy > maxe ) {
01565 firstrechitposxyz = rechitposxyzcor;
01566 maxe = recHitEnergy;
01567 }
01568
01569 double norm = fraction < 1E-9 ? 0. : max(0., log(recHitEnergy/p1 ));
01570
01571 x += rechitposxyzcor.X() * norm;
01572 y += rechitposxyzcor.Y() * norm;
01573 z += rechitposxyzcor.Z() * norm;
01574
01575
01576 normalize += norm;
01577 }
01578
01579
01580 if(normalize < 1e-9) {
01581 cerr<<"--------------------"<<endl;
01582 cerr<< cluster <<endl;
01583 assert(0);
01584 }
01585 else {
01586 x /= normalize;
01587 y /= normalize;
01588 z /= normalize;
01589
01590
01591 clusterposxyzcor.SetCoordinates(x,y,z);
01592 cluster.posrep_.SetCoordinates( clusterposxyzcor.Rho(),
01593 clusterposxyzcor.Eta(),
01594 clusterposxyzcor.Phi() );
01595 cluster.position_ = clusterposxyzcor;
01596 clusterposxyz = clusterposxyzcor;
01597 }
01598 }
01599 }
01600
01601
01602
01603 const reco::PFRecHit&
01604 PFClusterAlgo::rechit(unsigned i,
01605 const reco::PFRecHitCollection& rechits ) {
01606
01607 if(i >= rechits.size() ) {
01608 string err = "PFClusterAlgo::rechit : out of range";
01609 throw std::out_of_range(err);
01610 }
01611
01612 return rechits[i];
01613 }
01614
01615
01616
01617 bool PFClusterAlgo::masked(unsigned rhi) const {
01618
01619 if(rhi>=mask_.size() ) {
01620 string err = "PFClusterAlgo::masked : out of range";
01621 throw std::out_of_range(err);
01622 }
01623
01624 return mask_[rhi];
01625 }
01626
01627
01628 unsigned PFClusterAlgo::color(unsigned rhi) const {
01629
01630 if(rhi>=color_.size() ) {
01631 string err = "PFClusterAlgo::color : out of range";
01632 throw std::out_of_range(err);
01633 }
01634
01635 return color_[rhi];
01636 }
01637
01638
01639
01640 bool PFClusterAlgo::isSeed(unsigned rhi) const {
01641
01642 if(rhi>=seedStates_.size() ) {
01643 string err = "PFClusterAlgo::isSeed : out of range";
01644 throw std::out_of_range(err);
01645 }
01646
01647 return seedStates_[rhi]>0 ? true : false;
01648 }
01649
01650
01651 void PFClusterAlgo::paint(unsigned rhi, unsigned color ) {
01652
01653 if(rhi>=color_.size() ) {
01654 string err = "PFClusterAlgo::color : out of range";
01655 throw std::out_of_range(err);
01656 }
01657
01658 color_[rhi] = color;
01659 }
01660
01661
01662 reco::PFRecHitRef
01663 PFClusterAlgo::createRecHitRef( const reco::PFRecHitCollection& rechits,
01664 unsigned rhi ) {
01665
01666 if( rechitsHandle_.isValid() ) {
01667 return reco::PFRecHitRef( rechitsHandle_, rhi );
01668 }
01669 else {
01670 return reco::PFRecHitRef( &rechits, rhi );
01671 }
01672 }
01673
01674
01675 ostream& operator<<(ostream& out,const PFClusterAlgo& algo) {
01676 if(!out) return out;
01677 out<<"PFClusterAlgo parameters : "<<endl;
01678 out<<"-----------------------------------------------------"<<endl;
01679 out<<"threshBarrel : "<<algo.threshBarrel_ <<endl;
01680 out<<"threshSeedBarrel : "<<algo.threshSeedBarrel_ <<endl;
01681 out<<"threshPtBarrel : "<<algo.threshPtBarrel_ <<endl;
01682 out<<"threshPtSeedBarrel : "<<algo.threshPtSeedBarrel_ <<endl;
01683 out<<"threshCleanBarrel : "<<algo.threshCleanBarrel_ <<endl;
01684 out<<"minS4S1Barrel : "<<algo.minS4S1Barrel_[0]<<" x log10(E) + "<<algo.minS4S1Barrel_[1]<<endl;
01685 out<<"threshEndcap : "<<algo.threshEndcap_ <<endl;
01686 out<<"threshSeedEndcap : "<<algo.threshSeedEndcap_ <<endl;
01687 out<<"threshPtEndcap : "<<algo.threshPtEndcap_ <<endl;
01688 out<<"threshPtSeedEndcap : "<<algo.threshPtSeedEndcap_ <<endl;
01689 out<<"threshEndcap : "<<algo.threshEndcap_ <<endl;
01690 out<<"threshCleanEndcap : "<<algo.threshCleanEndcap_ <<endl;
01691 out<<"minS4S1Endcap : "<<algo.minS4S1Endcap_[0]<<" x log10(E) + "<<algo.minS4S1Endcap_[1]<<endl;
01692 out<<"nNeighbours : "<<algo.nNeighbours_ <<endl;
01693 out<<"posCalcNCrystal : "<<algo.posCalcNCrystal_ <<endl;
01694 out<<"posCalcP1 : "<<algo.posCalcP1_ <<endl;
01695 out<<"showerSigma : "<<algo.showerSigma_ <<endl;
01696 out<<"useCornerCells : "<<algo.useCornerCells_ <<endl;
01697
01698 out<<endl;
01699 out<<algo.pfClusters_->size()<<" clusters:"<<endl;
01700
01701 for(unsigned i=0; i<algo.pfClusters_->size(); i++) {
01702 out<<(*algo.pfClusters_)[i]<<endl;
01703
01704 if(!out) return out;
01705 }
01706
01707 return out;
01708 }
01709
01710
01711
01712 std::pair<double,double>
01713 PFClusterAlgo::dCrack(double phi, double eta){
01714
01715 static double pi= M_PI;
01716
01717
01718 static std::vector<double> cPhi;
01719 if(cPhi.size()==0)
01720 {
01721 cPhi.resize(18,0);
01722 cPhi[0]=2.97025;
01723 for(unsigned i=1;i<=17;++i) cPhi[i]=cPhi[0]-2*i*pi/18;
01724 }
01725
01726
01727 static double delta_cPhi=0.00638;
01728
01729 double defi;
01730
01731
01732 if(eta<0) phi +=delta_cPhi;
01733
01734 if (phi>=-pi && phi<=pi){
01735
01736
01737 if (phi<cPhi[17] || phi>=cPhi[0]){
01738 if (phi<0) phi+= 2*pi;
01739 defi = std::min(fabs(phi -cPhi[0]),fabs(phi-cPhi[17]-2*pi));
01740 }
01741
01742
01743 else{
01744 bool OK = false;
01745 unsigned i=16;
01746 while(!OK){
01747 if (phi<cPhi[i]){
01748 defi=std::min(fabs(phi-cPhi[i+1]),fabs(phi-cPhi[i]));
01749 OK=true;
01750 }
01751 else i-=1;
01752 }
01753 }
01754 }
01755 else{
01756 defi=0.;
01757 std::cout<<"Problem in dminphi"<<std::endl;
01758 }
01759
01760
01761 static std::vector<double> cEta;
01762 if ( cEta.size() == 0 ) {
01763 cEta.push_back(0.0);
01764 cEta.push_back(4.44747e-01) ; cEta.push_back(-4.44747e-01) ;
01765 cEta.push_back(7.92824e-01) ; cEta.push_back(-7.92824e-01) ;
01766 cEta.push_back(1.14090e+00) ; cEta.push_back(-1.14090e+00) ;
01767 cEta.push_back(1.47464e+00) ; cEta.push_back(-1.47464e+00) ;
01768 }
01769 double deta = 999.;
01770
01771 for ( unsigned ieta=0; ieta<cEta.size(); ++ieta ) {
01772 deta = std::min(deta,fabs(eta-cEta[ieta]));
01773 }
01774
01775 defi /= 0.0175;
01776 deta /= 0.0175;
01777 return std::pair<double,double>(defi,deta);
01778
01779 }