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