CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoParticleFlow/PFClusterProducer/src/PFHcalSuperClusterAlgo.cc

Go to the documentation of this file.
00001 #include "RecoParticleFlow/PFClusterProducer/interface/PFHcalSuperClusterAlgo.h"
00002 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00003 #include "DataFormats/Math/interface/deltaR.h"
00004 #include "DataFormats/Math/interface/deltaPhi.h"
00005 #include "DataFormats/DetId/interface/DetId.h"
00006 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00007 #include "DataFormats/GeometryVector/interface/Pi.h"
00008 #include "DataFormats/Common/interface/PtrVector.h"
00009 #include "Math/GenVector/VectorUtil.h"
00010 #include "RecoParticleFlow/PFClusterProducer/interface/PFHcalSuperClusterInit.h"
00011 
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 
00014 #include <stdexcept>
00015 #include <string>
00016 #include <sstream>
00017 
00018 using namespace std;
00019 using namespace reco;
00020 
00021 unsigned PFHcalSuperClusterAlgo::prodNum_ = 1;
00022 
00023 //for debug only 
00024 //#define PFLOW_DEBUG
00025 
00026 PFHcalSuperClusterAlgo::PFHcalSuperClusterAlgo() :
00027   pfClusters_( new vector<reco::PFCluster> ),
00028   pfSuperClusters_( new vector<reco::PFSuperCluster> ),
00029   debug_(false) 
00030 {
00031 
00032 }
00033 
00034 void
00035 PFHcalSuperClusterAlgo::write() {
00036 }
00037 void PFHcalSuperClusterAlgo::doClustering( const PFClusterHandle& clustersHandle, const PFClusterHandle& clustersHOHandle ) {
00038   const reco::PFClusterCollection& clusters = * clustersHandle;
00039   const reco::PFClusterCollection& clustersHO = * clustersHOHandle;
00040 
00041   // cache the Handle to the clusters
00042   clustersHandle_ = clustersHandle;
00043   clustersHOHandle_ = clustersHOHandle;
00044 
00045   // perform clustering
00046   doClusteringWorker( clusters, clustersHO );
00047 }
00048 
00049 void PFHcalSuperClusterAlgo::doClustering( const reco::PFClusterCollection& clusters, const reco::PFClusterCollection& clustersHO ) {
00050   // using clusters without a Handle, clear to avoid a stale member
00051   clustersHandle_.clear();
00052   clustersHOHandle_.clear();
00053 
00054   // perform clustering
00055   doClusteringWorker( clusters, clustersHO );
00056 }
00057 
00058 
00059 // calculate cluster position: Rachel Myers, July 2012
00060 std::pair<double, double> PFHcalSuperClusterAlgo::calculatePosition(const reco::PFCluster& cluster)
00061 {
00062   double numeratorEta = 0.0;
00063   double numeratorPhi = 0.0;
00064   double denominator = 0.0;
00065   double posEta = 0.0;
00066   double posPhi = 0.0;
00067   double w0_ = 4.2;
00068   const double clusterEnergy = cluster.energy();
00069   if (cluster.energy()>0.0 && cluster.recHitFractions().size()>0) {
00070     const std::vector <reco::PFRecHitFraction >& pfhitsandfracs = cluster.recHitFractions();
00071     for (std::vector<reco::PFRecHitFraction>::const_iterator it = pfhitsandfracs.begin(); it != pfhitsandfracs.end(); ++it) {
00072       const reco::PFRecHitRef rechit = it->recHitRef();
00073       double hitEta = rechit->positionREP().Eta();
00074       double hitPhi = rechit->positionREP().Phi();
00075       //Change into the -pi to +pi angular range
00076       while (hitPhi > +Geom::pi()) { hitPhi -= Geom::twoPi(); }
00077       while (hitPhi < -Geom::pi()) { hitPhi += Geom::twoPi(); }
00078       double hitEnergy = rechit->energy();
00079       const double w = std::max(0.0, w0_ + log(hitEnergy / clusterEnergy));
00080       denominator += w;
00081       numeratorEta += w*hitEta;
00082       numeratorPhi += w*hitPhi;
00083     }
00084     posEta = numeratorEta/denominator;
00085     posPhi = numeratorPhi/denominator;
00086   }
00087 
00088   pair<double, double> posEtaPhi(posEta,posPhi);
00089 
00090   return posEtaPhi;
00091 }
00092 
00093 // calculate cluster width: Rachel Myers, July 2012
00094 std::pair<double, double> PFHcalSuperClusterAlgo::calculateWidths(const reco::PFCluster& cluster)
00095 {
00096   double numeratorEtaEta = 0;
00097   //  double numeratorEtaPhi = 0;
00098   double numeratorPhiPhi = 0;
00099   double denominator     = 0;
00100   double widthEta = 0.0;
00101   double widthPhi = 0.0;
00102 
00103   double w0_ = 4.2;
00104 
00105   const double clusterEta = calculatePosition(cluster).first;
00106   const double clusterPhi = calculatePosition(cluster).second;
00107   const double clusterEnergy = cluster.energy();
00108   if(cluster.energy()>0.0 && cluster.recHitFractions().size()>0) {
00109     double hitEta, hitPhi, hitEnergy, dEta, dPhi; 
00110     const std::vector< reco::PFRecHitFraction >& pfhitsandfracs = cluster.recHitFractions();
00111     for (std::vector<reco::PFRecHitFraction>::const_iterator it = pfhitsandfracs.begin(); it != pfhitsandfracs.end(); ++it) {
00112       const reco::PFRecHitRef rechit = it->recHitRef();
00113       //      rechit->calculatePositionREP();
00114       hitEta = rechit->positionREP().Eta();
00115       hitPhi = rechit->positionREP().Phi();
00116       hitEnergy = rechit->energy();
00117       dEta  = hitEta - clusterEta;
00118       dPhi  = hitPhi - clusterPhi;
00119 
00120       while (dPhi > +Geom::pi()) { dPhi -= Geom::twoPi(); }
00121       while (dPhi < -Geom::pi()) { dPhi += Geom::twoPi(); }
00122 
00123 
00124       const double w = std::max(0.0, w0_ + log(hitEnergy / clusterEnergy));
00125 
00126       denominator += w;
00127       numeratorEtaEta += w * dEta * dEta;
00128       //      numeratorEtaPhi += w * dEta * dPhi;
00129       numeratorPhiPhi += w * dPhi * dPhi;
00130     }
00131 
00132     double covEtaEta = numeratorEtaEta / denominator;
00133     //    double covEtaPhi_ = numeratorEtaPhi / denominator;
00134     double covPhiPhi = numeratorPhiPhi / denominator;
00135 
00136     widthEta = sqrt(abs(covEtaEta));
00137     widthPhi = sqrt(abs(covPhiPhi));
00138   }
00139   pair<double, double> widthEtaPhi(widthEta,widthPhi);
00140   return widthEtaPhi;
00141 }
00142 // do clustering with new widths, positions, parameters, merging conditions: Rachel Myers, July 2012
00143 void PFHcalSuperClusterAlgo::doClusteringWorker( const reco::PFClusterCollection& clusters, const reco::PFClusterCollection& clustersHO ) {
00144 
00145   double dRcut=0.17;
00146   double dEtacut = 0.0;
00147   double dPhicut = 0.0;
00148   double etaScale = 1.0;
00149   double phiScale = 0.5;
00150   //  double dRcut=0.30;
00151 
00152   if ( pfClusters_.get() )
00153     pfClusters_->clear();
00154   else 
00155     pfClusters_.reset( new std::vector<reco::PFCluster> );
00156 
00157   if ( pfSuperClusters_.get() )
00158     pfSuperClusters_->clear();
00159   else 
00160     pfSuperClusters_.reset( new std::vector<reco::PFSuperCluster> );
00161 
00162   // compute cluster depth index
00163   std::vector< unsigned > clusterdepth(clusters.size());
00164   //  cout << " clusters: " << clusters.size() <<endl; 
00165   int mclustersHB=0;
00166   int mclustersHE=0;
00167   for (unsigned short ic=0; ic<clusters.size();++ic) {
00168     if( clusters[ic].layer() == PFLayer::HCAL_BARREL1) mclustersHB++;
00169     if( clusters[ic].layer() == PFLayer::HCAL_ENDCAP) mclustersHE++;
00170   }
00171   for (unsigned short ic=0; ic<clusters.size();++ic)
00172     {
00173       if( clusters[ic].layer() == PFLayer::HCAL_BARREL1
00174           || clusters[ic].layer() == PFLayer::HCAL_ENDCAP ) { //Hcal case
00175 
00176         const std::vector< std::pair<DetId, float> > & hitsandfracs =
00177           clusters[ic].hitsAndFractions();
00178         unsigned clusterdepthfirst=0;
00179         for(unsigned ihandf=0; ihandf<hitsandfracs.size(); ihandf++) {
00180           unsigned depth = ((HcalDetId)hitsandfracs[ihandf].first).depth();
00181           //          cout << " depth parameter from clustering: " << depth <<endl; 
00182           clusterdepth[ic] = depth;         
00183           if( ihandf>0 && depth!=clusterdepthfirst) cout << " Problem with cluster depth: " << depth << " not equal to " << clusterdepthfirst <<endl;
00184           else if( ihandf==0 ) clusterdepthfirst = depth;
00185         }
00186         //        delete hitsandfracs;
00187       }
00188     }
00189   std::vector< unsigned > clusterdepthHO(clustersHO.size());
00190   //  cout << " HO clusters: " << clustersHO.size() <<endl; 
00191   double hcaleta1=0.0;
00192   double hcalphi1=0.0;
00193   double hcaleta2=0.0;
00194   double hcalphi2=0.0;
00195   double dR = 0.0;
00196   double dEta = 0.0;
00197   double dPhi = 0.0;
00198   for (unsigned short ic=0; ic<clustersHO.size();++ic)
00199     {
00200       if( clustersHO[ic].layer() == PFLayer::HCAL_BARREL2) { //HO case
00201 
00202         const std::vector< std::pair<DetId, float> > & hitsandfracs =
00203           clustersHO[ic].hitsAndFractions();
00204         unsigned clusterdepthfirst=0;
00205         for(unsigned ihandf=0; ihandf<hitsandfracs.size(); ihandf++) {
00206           unsigned depth = ((HcalDetId)hitsandfracs[ihandf].first).depth();
00207           //          cout << " depth parameter from HO clustering: " << depth <<endl; 
00208           clusterdepthHO[ic] = depth;          
00209           if( ihandf>0 && depth!=clusterdepthfirst) cout << " Problem with HO cluster depth: " << depth << " not equal to " << clusterdepthfirst <<endl;
00210           else if( ihandf==0 ) clusterdepthfirst = depth;
00211         }
00212         //        delete hitsandfracs;
00213       }
00214     }
00215 
00216   std::vector< unsigned > imerge(clusters.size());
00217   std::vector< unsigned > imergeHO(clustersHO.size());
00218   std::vector< bool > lmerge(clusters.size());
00219   std::vector< bool > lmergeHO(clustersHO.size());
00220 
00221   hcaleta1=0.0;
00222   hcalphi1=0.0;
00223   hcaleta2=0.0;
00224   hcalphi2=0.0;
00225   dR = 0.0;
00226   dEta = 0.0;
00227   dPhi = 0.0;
00228 
00229   //    cout << " setting up cluster merging indices "<<endl;
00230   for (unsigned short ic1=0; ic1<clusters.size();++ic1) {
00231     lmerge[ic1]=false;
00232   }
00233   for (unsigned short ic1=0; ic1<clustersHO.size();++ic1) {
00234     lmergeHO[ic1]=false;
00235   }
00236   for (unsigned short ic1=0; ic1<clusters.size();++ic1) {
00237     if( clusterdepth[ic1]==1 ){
00238       hcaleta1 = calculatePosition(clusters[ic1]).first;
00239       hcalphi1 = calculatePosition(clusters[ic1]).second;
00240       for (unsigned short ic2=0; ic2<clusters.size();++ic2) {
00241         hcaleta2 = calculatePosition(clusters[ic2]).first;
00242         hcalphi2 = calculatePosition(clusters[ic2]).second;
00243         dR = deltaR( hcaleta1, hcalphi1, hcaleta2, hcalphi2 );
00244         dEta = abs(hcaleta1 - hcaleta2);
00245         dPhi = abs(deltaPhi(hcalphi1, hcalphi2));
00246         double w1 = calculateWidths(clusters[ic1]).first;
00247         if (w1 == 0) w1 = 0.087;
00248         double w2 = calculateWidths(clusters[ic2]).first;
00249         if (w2 == 0) w2 = 0.087;
00250         double w3 = calculateWidths(clusters[ic1]).second;
00251         if (w3 < 0.087) w3 = 0.087;
00252         double w4 = calculateWidths(clusters[ic2]).second;
00253         if (w4 < 0.087) w4 = 0.087;
00254         double etawidth = sqrt(w1*w1 + w2*w2);
00255         double phiwidth = sqrt(w3*w3 + w4*w4);
00256         dEtacut = etaScale*etawidth;
00257         dPhicut = phiScale*phiwidth;
00258         if( clusterdepth[ic2]==2 ){
00259           //            cout << " depth 1-2 dR = " << dR <<endl;
00260           if((dR<dRcut) || (dEta<dEtacut && dPhi<dPhicut)) {
00261             imerge[ic2]=ic1;
00262             lmerge[ic2]=true;
00263           }
00264         } else if( clusterdepth[ic2]==3 ){
00265           //            cout << " depth 1-3 dR = " << dR <<endl;
00266           if((dR<dRcut) || (dEta<dEtacut && dPhi<dPhicut) ) {
00267             imerge[ic2]=ic1;
00268             lmerge[ic2]=true;
00269           }
00270         }
00271       }
00272     } else if( clusterdepth[ic1]==2 ){
00273       hcaleta1 = calculatePosition(clusters[ic1]).first;
00274       hcalphi1 = calculatePosition(clusters[ic1]).second;
00275       for (unsigned short ic2=0; ic2<clusters.size();++ic2) {
00276         hcaleta2 = calculatePosition(clusters[ic2]).first;
00277         hcalphi2 = calculatePosition(clusters[ic2]).second;
00278         dEta = abs(hcaleta1 - hcaleta2);
00279         dPhi = abs(deltaPhi(hcalphi1, hcalphi2));
00280         dR = deltaR( hcaleta1, hcalphi1, hcaleta2, hcalphi2 );
00281         double w1 = calculateWidths(clusters[ic1]).first;
00282         if (w1 == 0) w1 = 0.087;
00283         double w2 = calculateWidths(clusters[ic2]).first;
00284         if (w2 == 0) w2 = 0.087;
00285         double w3 = calculateWidths(clusters[ic1]).second;
00286         if (w3 < 0.087) w3 = 0.087;
00287         double w4 = calculateWidths(clusters[ic2]).second;
00288         if (w4 < 0.087) w4 = 0.087;
00289         double etawidth = sqrt(w1*w1+w2*w2);
00290         double phiwidth = sqrt(w3*w3+w4*w4);
00291         dEtacut = etaScale*etawidth;
00292         dPhicut = phiScale*phiwidth;
00293         if( clusterdepth[ic2]==3 ){
00294           if((dR<dRcut) || (dEta<dEtacut && dPhi<dPhicut)) {
00295             imerge[ic2]=ic1;
00296             lmerge[ic2]=true;
00297           }
00298         } else if( clusterdepth[ic2]==4 ){
00299           //            cout << " depth 2-4 dR = " << dR <<endl;
00300           if((dR<dRcut) || (dEta<dEtacut && dPhi<dPhicut)) {
00301             imerge[ic2]=ic1;
00302             lmerge[ic2]=true;
00303           }
00304         }
00305       }
00306     } else if( clusterdepth[ic1]==3 ){
00307       hcaleta1 = calculatePosition(clusters[ic1]).first;
00308       hcalphi1 = calculatePosition(clusters[ic1]).second;
00309       for (unsigned short ic2=0; ic2<clusters.size();++ic2) {
00310         hcaleta2 = calculatePosition(clusters[ic2]).first;
00311         hcalphi2 = calculatePosition(clusters[ic2]).second;
00312         dEta = abs(hcaleta1 - hcaleta2);
00313         dPhi = abs(deltaPhi(hcalphi1, hcalphi2));
00314         dR = deltaR( hcaleta1, hcalphi1, hcaleta2, hcalphi2 );
00315         double w1 = calculateWidths(clusters[ic1]).first;
00316         if (w1 == 0) w1 = 0.087;
00317         double w2 = calculateWidths(clusters[ic2]).first;
00318         if (w2 == 0) w2 = 0.087;
00319         double w3 = calculateWidths(clusters[ic1]).second;
00320         if (w3 < 0.087) w3 = 0.087;
00321         double w4 = calculateWidths(clusters[ic2]).second;
00322         if (w4 < 0.087) w4 = 0.087;
00323         double etawidth = sqrt(w1*w1+w2*w2);
00324         double phiwidth = sqrt(w3*w3+w4*w4);
00325         dEtacut = etaScale*etawidth;
00326         dPhicut = phiScale*phiwidth;
00327         if( clusterdepth[ic2]==4 ){
00328           //            cout << " depth 3-4 dR = " << dR <<endl;
00329           if((dR<dRcut) || (dEta<dEtacut && dPhi<dPhicut)) {
00330             imerge[ic2]=ic1;
00331             lmerge[ic2]=true;
00332           }
00333         } else if( clusterdepth[ic2]==5 ){
00334           //            cout << " depth 3-5 dR = " << dR <<endl;
00335           if((dR<dRcut) || (dEta<dEtacut && dPhi<dPhicut)) {
00336             imerge[ic2]=ic1;
00337             lmerge[ic2]=true;
00338           }
00339         }
00340       }
00341       for (unsigned short ic2=0; ic2<clustersHO.size();++ic2) {
00342         hcaleta2 = calculatePosition(clustersHO[ic2]).first;
00343         hcalphi2 = calculatePosition(clustersHO[ic2]).second;
00344         dEta = abs(hcaleta1 - hcaleta2);
00345         dPhi = abs(deltaPhi(hcalphi1, hcalphi2));
00346         dR = deltaR( hcaleta1, hcalphi1, hcaleta2, hcalphi2 );
00347         double w1 = calculateWidths(clusters[ic1]).first;
00348         if (w1 == 0) w1 = 0.087;
00349         double w2 = calculateWidths(clustersHO[ic2]).first;
00350         if (w2 == 0) w2 = 0.087;
00351         double w3 = calculateWidths(clusters[ic1]).second;
00352         if (w3 < 0.087) w3 = 0.087;
00353         double w4 = calculateWidths(clustersHO[ic2]).second;
00354         if (w4 < 0.087) w4 = 0.087;
00355         double etawidth = sqrt(w1*w1+w2*w2);
00356         double phiwidth = sqrt(w3*w3+w4*w4);
00357         dEtacut = etaScale*etawidth;
00358         dPhicut = phiScale*phiwidth;
00359         if( clusterdepthHO[ic2]==5 ){
00360           //            cout << " depth 3-HO dR = " << dR <<endl;
00361           if((dR<dRcut) || (dEta<dEtacut && dPhi<dPhicut)) {
00362             imergeHO[ic2]=ic1;
00363             lmergeHO[ic2]=true;
00364           }
00365         }
00366       }
00367     } else if( clusterdepth[ic1]==4 ){
00368       hcaleta1 = calculatePosition(clusters[ic1]).first;
00369       hcalphi1 = calculatePosition(clusters[ic1]).second;
00370       for (unsigned short ic2=0; ic2<clusters.size();++ic2) {
00371         hcaleta2 = calculatePosition(clusters[ic2]).first;
00372         hcalphi2 = calculatePosition(clusters[ic2]).second;
00373         dEta = abs(hcaleta1 - hcaleta2);
00374         dPhi = abs(deltaPhi(hcalphi1, hcalphi2));
00375         dR = deltaR( hcaleta1, hcalphi1, hcaleta2, hcalphi2 );
00376         double w1 = calculateWidths(clusters[ic1]).first;
00377         if (w1 < 0.087) w1 = 0.087;
00378         double w2 = calculateWidths(clusters[ic2]).first;
00379         if (w2 < 0.087) w2 = 0.087;
00380         double w3 = calculateWidths(clusters[ic1]).second;
00381         if (w3 < 0.087) w3 = 0.087;
00382         double w4 = calculateWidths(clusters[ic2]).second;
00383         if (w4 < 0.087) w4 = 0.087;
00384         double etawidth = sqrt(w1*w1+w2*w2);
00385         double phiwidth = sqrt(w3*w3+w4*w4);
00386         dEtacut = etaScale*etawidth;
00387         dPhicut = phiScale*phiwidth;
00388         if( clusterdepth[ic2]==5 ){
00389           //            cout << " depth 4-5 dR = " << dR <<endl;
00390           if((dR<dRcut) || (dEta<dEtacut && dPhi<dPhicut)) {
00391             imerge[ic2]=ic1;
00392             lmerge[ic2]=true;
00393           }
00394         }
00395       }
00396     } else if( clusterdepth[ic1]==5 ){
00397       hcaleta1 = calculatePosition(clusters[ic1]).first;
00398       hcalphi1 = calculatePosition(clusters[ic1]).second;
00399     }
00400   }
00401 
00402   // start a supercluster with a depth=1 cluster, then loop on all other
00403   // clusters to add to cluster list, then for each cluster to add, loop
00404   // on remaining clusters to check 2nd level of addition, repeat for all layers
00405   
00406   // need to add HO cluster logic
00407   edm::PtrVector< reco::PFCluster >  mergeclusters;
00408   std::vector< bool >  lmergeclusters(clusters.size());
00409   for (unsigned short id=0; id<4;++id) {
00410     //    cout << " merging with starting depth: "<<id<<endl;
00411     for (unsigned short ic1=0; ic1<clusters.size();++ic1) {
00412       if( clusterdepth[ic1]==(unsigned)(1+id) ){
00413         if(!lmerge[ic1]) {
00414           for (unsigned short ic=0; ic<clusters.size();++ic) {
00415             lmergeclusters[ic]=false;
00416           }
00417           //          mergeclusters.push_back(clusters[ic1]);
00418           for (unsigned short ic2=0; ic2<clusters.size();++ic2) {
00419             if( clusterdepth[ic2]==(unsigned)(2+id) ){
00420               if( imerge[ic2]==ic1 && lmerge[ic2] ) {
00421                 //                mergeclusters.push_back(clusters[ic2]);
00422                 lmergeclusters[ic2]=true;
00423                 for (unsigned short ic3=0; ic3<clusters.size();++ic3) {
00424                   if( clusterdepth[ic3]==(unsigned)(3+id) ){
00425                     if( imerge[ic3]==ic2 && lmerge[ic3] ) {
00426                       //                      mergeclusters.push_back(clusters[ic3]);
00427                       lmergeclusters[ic3]=true;
00428                       for (unsigned short ic4=0; ic4<clusters.size();++ic4) {
00429                         if( clusterdepth[ic4]==(unsigned)(4+id) ){
00430                           if( imerge[ic4]==ic3 && lmerge[ic4] ) {
00431                             //                            mergeclusters.push_back(clusters[ic4]);
00432                             lmergeclusters[ic4]=true;
00433                             for (unsigned short ic5=0; ic5<clusters.size();++ic5) {
00434                               if( clusterdepth[ic5]==(unsigned)(5+id) ){
00435                                 //                                if( imerge[ic5]==ic4 && lmerge[ic5] ) mergeclusters.push_back(clusters[ic5]);
00436                                 if( imerge[ic5]==ic4 && lmerge[ic5] ) lmergeclusters[ic5]=true;
00437                               }
00438                             }
00439                           } else if( clusterdepth[ic4]==(unsigned)(5+id) ){
00440                             //                            if( imerge[ic4]==ic3 && lmerge[ic4] ) mergeclusters.push_back(clusters[ic4]);
00441                             if( imerge[ic4]==ic3 && lmerge[ic4] ) lmergeclusters[ic4]=true;
00442                           }
00443                         }
00444                       }
00445                     } else if( clusterdepth[ic3]==(unsigned)(4+id) ){
00446                       if( imerge[ic3]==ic2 && lmerge[ic3] ) {
00447                         //                        mergeclusters.push_back(clusters[ic3]);
00448                         lmergeclusters[ic3]=true;
00449                         for (unsigned short ic4=0; ic4<clusters.size();++ic4) {
00450                           if( clusterdepth[ic4]==(unsigned)(5+id) ){
00451                             //                            if( imerge[ic4]==ic3 && lmerge[ic4] ) mergeclusters.push_back(clusters[ic4]);
00452                             if( imerge[ic4]==ic3 && lmerge[ic4] ) lmergeclusters[ic4]=true;
00453                           }
00454                         }
00455                       }
00456                     }
00457                   } if( clusterdepth[ic3]==(unsigned)(5+id) ){
00458                     //                    if( imerge[ic3]==ic2 && lmerge[ic3] ) mergeclusters.push_back(clusters[ic3]);
00459                     if( imerge[ic3]==ic2 && lmerge[ic3] ) lmergeclusters[ic3]=true;
00460                   }
00461                 }
00462               }
00463             } else if( clusterdepth[ic2]==(unsigned)(3+id) ){
00464               if( imerge[ic2]==ic1 && lmerge[ic2] ) {
00465                 //                mergeclusters.push_back(clusters[ic2]);
00466                 lmergeclusters[ic2]=true;
00467                 for (unsigned short ic3=0; ic3<clusters.size();++ic3) {
00468                   if( clusterdepth[ic3]==(unsigned)(4+id) ){
00469                     if( imerge[ic3]==ic2 && lmerge[ic3] ) {
00470                       //                      mergeclusters.push_back(clusters[ic3]);
00471                       lmergeclusters[ic3]=true;
00472                       for (unsigned short ic4=0; ic4<clusters.size();++ic4) {
00473                         if( clusterdepth[ic4]==(unsigned)(5+id) ){
00474                           //                          if( imerge[ic4]==ic3 && lmerge[ic4] ) mergeclusters.push_back(clusters[ic4]);
00475                           if( imerge[ic4]==ic3 && lmerge[ic4] ) lmergeclusters[ic4]=true;
00476                         }
00477                       }
00478                     } else if( clusterdepth[ic3]==(unsigned)(5+id) ){
00479                       //                      if( imerge[ic3]==ic2 && lmerge[ic3] ) mergeclusters.push_back(clusters[ic3]);
00480                       if( imerge[ic3]==ic2 && lmerge[ic3] ) lmergeclusters[ic3]=true;
00481                     }
00482                   }
00483                 }
00484               }
00485             }
00486           }
00487           mergeclusters.push_back( PFClusterPtr( clustersHandle_, ic1));
00488           for (unsigned short ic=0; ic<clusters.size();++ic) {
00489             if(lmergeclusters[ic]) {
00490               mergeclusters.push_back( PFClusterPtr(clustersHandle_, ic ) );
00491             }
00492           }
00493           if(mergeclusters.size()>0) {
00494             //            cout << " number of clusters to merge: " <<mergeclusters.size()<<endl;
00495             reco::PFSuperCluster ipfsupercluster(mergeclusters);
00496             PFHcalSuperClusterInit init;
00497             init.initialize( ipfsupercluster, clusters_);
00498             pfSuperClusters_->push_back(ipfsupercluster);
00499             pfClusters_->push_back((reco::PFCluster)ipfsupercluster);
00500             mergeclusters.clear();
00501           }
00502           
00503         }
00504       } // end of depth 1+id initiated logic
00505     }
00506   }
00507 
00508   /*
00509     for (unsigned short ic=0; ic<clusters.size();++ic) {
00510     mergeclusters.clear();
00511     mergeclusters.push_back(clusters[ic]);
00512     reco::PFSuperCluster ipfsupercluster(mergeclusters);
00513     pfSuperClusters_->push_back(ipfsupercluster);
00514     pfClusters_->push_back((reco::PFCluster)ipfsupercluster);
00515     //    pfClusters_->push_back(clusters[ic]);
00516     }
00517   */
00518 
00519   clusterdepth.clear();
00520   clusterdepthHO.clear();
00521   imerge.clear();
00522   imergeHO.clear();
00523   lmerge.clear();
00524   lmergeHO.clear();
00525   mergeclusters.clear();
00526 
00527 }
00528 ostream& operator<<(ostream& out,const PFHcalSuperClusterAlgo& algo) { 
00529   if(!out) return out;
00530   out<<"PFSuperClusterAlgo parameters : "<<endl;
00531   out<<"-----------------------------------------------------"<<endl;
00532   
00533   out<<endl;
00534   out<<algo.pfClusters_->size()<<" clusters:"<<endl;
00535   
00536   for(unsigned i=0; i<algo.pfClusters_->size(); i++) {
00537     out<<(*algo.pfClusters_)[i]<<endl;
00538     
00539     if(!out) return out;
00540   }
00541   
00542   out<<algo.pfSuperClusters_->size()<<" superclusters:"<<endl;
00543     
00544   for(unsigned i=0; i<algo.pfSuperClusters_->size(); i++) {
00545     out<<(*algo.pfSuperClusters_)[i]<<endl;
00546     
00547     if(!out) return out;
00548   }   
00549   return out;
00550 }