CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoParticleFlow/PFProducer/src/PFConversionAlgo.cc

Go to the documentation of this file.
00001 #include "RecoParticleFlow/PFProducer/interface/PFConversionAlgo.h"
00002 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
00003 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
00004 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementBrem.h"
00005 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h"
00006 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" 
00007 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00008 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00009 #include "DataFormats/ParticleFlowReco/interface/PFConversion.h" 
00010 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00011 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
00012 #include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h"
00013 #include "RecoParticleFlow/PFProducer/interface/Utils.h"
00014 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00015 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyResolution.h"
00016 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00017 
00018 using namespace std;
00019 using namespace reco;
00020 PFConversionAlgo::PFConversionAlgo( ) {
00021 
00022 }
00023 
00024 void PFConversionAlgo::runPFConversion(const reco::PFBlockRef&  blockRef, 
00025                                        std::vector<bool>& active) {
00026 
00027   //  std::cout << " PFConversionAlgo::RunPFConversion " << std::endl;
00028 
00029   AssMap elemAssociatedToConv;
00030   
00031   bool blockHasConversion = setLinks(blockRef,elemAssociatedToConv, active );
00032   
00033   if (  blockHasConversion ) {
00034     conversionCandidate_.clear();
00035     setCandidates(blockRef,elemAssociatedToConv);
00036     if (conversionCandidate_.size() > 0 ){
00037       isvalid_ = true;
00038       //cout << " There is a candidate " << endl;
00039       // if there is at least a candidate the active vector is modified
00040       // setting = false all the elements used to build the candidate
00041       setActive(blockRef,elemAssociatedToConv, active);
00042       // this is just debug to check that all is going fine. Will take it out later      
00043       std::vector<reco::PFCandidate>::iterator it;
00044       for ( it = conversionCandidate_.begin(); it != conversionCandidate_.end(); ++it )  {
00045         reco::PFCandidate::ParticleType type = (*it).particleId();
00046         bool isConverted =  (*it).flag( reco::PFCandidate::GAMMA_TO_GAMMACONV );
00047         if ( type == reco::PFCandidate::gamma && isConverted ) {
00048           //      cout<<"Conversion PFCandidate!"<<  *it <<  endl;
00049         }
00050       }
00051     }
00052     
00053   } // conversion was found in the block
00054 
00055 }
00056 
00057 
00058 bool PFConversionAlgo::setLinks(const reco::PFBlockRef& blockRef,  
00059                                 AssMap&  elemAssociatedToConv,  
00060                                 std::vector<bool>& active ) {
00061 
00062   bool conversionFound = false;
00063   typedef std::multimap<double, unsigned>::iterator IE;
00064   const reco::PFBlock& block = *blockRef;
00065   //  std::cout << " PFConversionAlgo::setLinks block " << block << std::endl;
00066   const edm::OwnVector< reco::PFBlockElement >&  elements = block.elements();
00067   PFBlock::LinkData linkData =  block.linkData();    
00068 
00069   // this method looks in all elements in a block, idenitifies those 
00070   // blonging to a conversions and stores them in a local map 
00071   // so that in the further code the search needs not be done again
00072 
00073   unsigned convTrack1Ind=100;
00074   unsigned convTrack2Ind=100;
00075   unsigned convEcal1Ind=200;
00076   unsigned convEcal2Ind=200;
00077   unsigned convHcal1Ind=200;
00078   unsigned convHcal2Ind=200;
00079 
00080   for(unsigned iElem=0; iElem<elements.size(); iElem++) {
00081     bool trackFromConv = elements[iElem].trackType( PFBlockElement::T_FROM_GAMMACONV);
00082 
00083     if (!active[iElem]) continue;  
00084     if ( !trackFromConv ) continue;
00085     conversionFound = true;    
00086 
00087     //    std::cout << " Track " <<  iElem << " is from conversion" << std::endl;
00088     convTrack1Ind= iElem;
00089 
00090     std::multimap<unsigned, std::vector<unsigned> >::iterator found = elemAssociatedToConv.find(iElem);
00091     if ( found!= elemAssociatedToConv.end()) {
00092       //      std::cout << " Track " <<  iElem << " has already been included " << std::endl;
00093       continue;
00094     }
00095     
00096     
00097     bool alreadyTaken=false;
00098     for (  std::multimap<unsigned, std::vector<unsigned> >::iterator i=elemAssociatedToConv.begin(); 
00099            i!=  elemAssociatedToConv.end(); ++i) {
00100       for (unsigned int j=0; j< (i->second).size(); ++j ) {
00101         if ( iElem == (i->second)[j] )  alreadyTaken=true;
00102       }
00103     }
00104     if ( alreadyTaken ) {
00105       //      std::cout << " iElem " << iElem << " already taken" <<  std::endl;
00106       continue;
00107     }
00108 
00109  
00110     vector<unsigned> assElements(0);     
00111     vector<unsigned>::iterator iVec;
00112 
00113     std::multimap<double, unsigned> ecalElems;
00114     block.associatedElements(iElem ,  linkData,
00115                               ecalElems ,
00116                               reco::PFBlockElement::ECAL );
00117 
00118     std::multimap<double, unsigned> hcalElems;
00119     block.associatedElements( iElem ,  linkData,
00120                               hcalElems,
00121                               reco::PFBlockElement::HCAL,
00122                               reco::PFBlock::LINKTEST_ALL );
00123     
00124     std::multimap<double, unsigned> trackElems;
00125     block.associatedElements( iElem,  linkData,
00126                               trackElems ,
00127                               reco::PFBlockElement::TRACK,
00128                               reco::PFBlock::LINKTEST_RECHIT);
00129 
00130 
00131     if(trackElems.empty() ) {
00132       //      std::cout<<"PFConversionAlgo::setLinks no track element connected to track "<<iElem<<std::endl;
00133     }
00134     
00135     if(ecalElems.empty() ) {
00136       //  std::cout<<"PFConversionAlgo::setLinks no ecal element connected to track "<<iElem<<std::endl;
00137     }
00138     
00139     if(hcalElems.empty() ) {
00140       //  std::cout<<"PFConversionAlgo::setLinks no hcal element connected to track "<<iElem<<std::endl;
00141     }
00142     
00143     //std::cout<<"PFConversionAlgo::setLinks now looping on elements associated to the track"<<std::endl;
00144 
00145 
00146 
00147     //    std::cout<<"  look at linked hcal clusters"<<std::endl;
00148     for(IE iTk = hcalElems.begin(); iTk != hcalElems.end(); ++iTk ) {
00149       unsigned index = iTk->second;
00150       PFBlockElement::Type type = elements[index].type();
00151       if ( type ==  reco::PFBlockElement::HCAL) {
00152         // link track-ecal is found 
00153         convHcal1Ind=index;
00154         //      std::cout << " Hcal-Track link found with " << convHcal1Ind << std::endl;
00155         //      if ( index< 100)  assElements.push_back(index);
00156       }
00157     }
00158 
00159 
00160 
00161     //    std::cout<<"  look at linked ecal clusters"<<std::endl;
00162     for(IE iTk = ecalElems.begin(); iTk != ecalElems.end(); ++iTk ) {
00163       unsigned index = iTk->second;
00164       PFBlockElement::Type type = elements[index].type();
00165       if ( type ==  reco::PFBlockElement::ECAL) {
00166         // link track-ecal is found 
00167         convEcal1Ind=index;
00168         //std::cout << " Ecal-Track link found with " << convEcal1Ind << std::endl;
00169         iVec = find ( assElements.begin(), assElements.end(), index) ;        
00170         if ( index< 100 && iVec == assElements.end() )  assElements.push_back(index);
00171       }
00172     }
00173 
00174 
00175     //    std::cout<<"PFConversionAlgo::setLinks  look at linked tracks"<<std::endl;    
00176     for(IE iTk = trackElems.begin(); iTk != trackElems.end(); ++iTk ) {
00177       unsigned index = iTk->second;
00178       //PFBlockElement::Type type = elements[index].type();
00179         // link track-track is found 
00180         convTrack2Ind=index;
00181         if ( index< 100)  assElements.push_back(index);
00182         //std::cout << " Track-Track link found with " << convTrack2Ind << std::endl;
00183         std::multimap<double, unsigned> ecalElems2;
00184         block.associatedElements(convTrack2Ind ,  linkData,
00185                                  ecalElems2 ,
00186                                  reco::PFBlockElement::ECAL );
00187 
00188 
00189         for(IE iTk = ecalElems2.begin(); iTk != ecalElems2.end(); ++iTk ) {
00190           unsigned index = iTk->second;
00191           PFBlockElement::Type type = elements[index].type();
00192           if ( type ==  reco::PFBlockElement::ECAL) {
00193             convEcal2Ind=index;
00194             //      std::cout << " 2nd ecal track link found betwtenn track " << convTrack2Ind  << " and Ecal " << convEcal2Ind << std::endl;
00195             iVec = find ( assElements.begin(), assElements.end(), index) ;        
00196             if ( index< 100 && iVec== assElements.end() )  assElements.push_back(index);
00197           
00198           }
00199         }
00200 
00201         std::multimap<double, unsigned> hcalElems2;
00202         block.associatedElements(convTrack2Ind ,  linkData,
00203                                  hcalElems2 ,
00204                                  reco::PFBlockElement::HCAL );
00205         for(IE iTk = hcalElems.begin(); iTk != hcalElems.end(); ++iTk ) {
00206           unsigned index = iTk->second;
00207           PFBlockElement::Type type = elements[index].type();
00208           if ( type ==  reco::PFBlockElement::HCAL) {
00209             // link track-ecal is found 
00210             convHcal2Ind=index;
00211             std::cout << " Hcal-Track link found with " << convHcal2Ind << std::endl;
00212             //   if ( index< 100)  assElements.push_back(index);
00213           }
00214         }
00215 
00216     }
00217 
00218 
00219     elemAssociatedToConv.insert(make_pair(convTrack1Ind, assElements));
00220 
00221     // This is just for debug
00222     //std::cout << " PFConversionAlgo::setLink map size " << elemAssociatedToConv.size() << std::endl;
00223     // for (  std::multimap<unsigned, std::vector<unsigned> >::iterator i=elemAssociatedToConv.begin(); 
00224            //   i!=  elemAssociatedToConv.end(); ++i) {
00225       //std::cout << " links found for " << i->first << std::endl;
00226       //std::cout << " elements " << (i->second).size() << std::endl;
00227     // for (unsigned int j=0; j< (i->second).size(); ++j ) {
00228         //      unsigned int iEl = (i->second)[j];
00229         //std::cout  << " ass element " << iEl << std::endl;
00230     // }
00231     // }
00232 
00233 
00234 
00235   } // end loop over elements of the block looking for conversion track
00236 
00237 
00238   return conversionFound;
00239 
00240 }
00241 
00242 
00243 void PFConversionAlgo::setCandidates(const reco::PFBlockRef& blockRef,  
00244                                      AssMap&  elemAssociatedToConv ) {
00245 
00246   
00247   vector<unsigned int> elementsToAdd(0);
00248   const reco::PFBlock& block = *blockRef;
00249   PFBlock::LinkData linkData =  block.linkData();     
00250   const edm::OwnVector< reco::PFBlockElement >&  elements = block.elements();
00251 
00254   float EcalEne=0;
00255   float pairPx=0;
00256   float pairPy=0;
00257   float pairPz=0;
00258   const reco::PFBlockElementTrack*  elTrack=0;
00259   reco::TrackRef convTrackRef;
00260   for (  std::multimap<unsigned, std::vector<unsigned> >::iterator i=elemAssociatedToConv.begin(); 
00261          i!=  elemAssociatedToConv.end(); ++i) {
00262 
00263     unsigned int iTrack =  i->first;
00264     elementsToAdd.push_back(iTrack);
00265     //    std::cout << " setCandidates adding track " << iTrack << " to block in PFCandiate " << std::endl;
00266     elTrack = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[iTrack]));
00267     convTrackRef= elTrack->trackRef();     
00268     pairPx+=convTrackRef->innerMomentum().x();
00269     pairPy+=convTrackRef->innerMomentum().y();
00270     pairPz+=convTrackRef->innerMomentum().z();
00271     
00272     ConversionRef origConv = elements[iTrack].convRef();
00273     //    std::cout << " Ref to original conversions: track size " << origConv->tracks().size() << " SC energy " << origConv->caloCluster()[0]->energy() << std::endl;
00274     // std::cout  << " SC Et " <<  origConv->caloCluster()[0]->energy()/cosh(origConv->caloCluster()[0]->eta()) <<" eta " << origConv->caloCluster()[0]->eta() << " phi " << origConv->caloCluster()[0]->phi() <<  std::endl;
00275 
00276     unsigned int nEl=  (i->second).size();
00277     //    std::cout << " Number of elements connected " << nEl << std::endl;
00278     for (unsigned int j=0; j< nEl; ++j ) {
00279       unsigned int iEl = (i->second)[j];
00280       //std::cout  << " Adding element " << iEl << std::endl;
00281       PFBlockElement::Type typeassCalo = elements[iEl].type();
00282 
00284       if ( typeassCalo == reco::PFBlockElement::TRACK) {
00285         const reco::PFBlockElementTrack * elTrack = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[iEl]));   
00286         elTrack = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[iEl]));
00287         convTrackRef= elTrack->trackRef();     
00288         pairPx+=convTrackRef->innerMomentum().x();
00289         pairPy+=convTrackRef->innerMomentum().y();
00290         pairPz+=convTrackRef->innerMomentum().z();
00291       }
00292 
00293       if ( typeassCalo == reco::PFBlockElement::ECAL) {
00294         const reco::PFBlockElementCluster * clu = dynamic_cast<const reco::PFBlockElementCluster*>((&elements[iEl]));
00295         reco::PFCluster cl=*clu->clusterRef();
00296         EcalEne+= cl.energy();
00297       }
00298 
00299       elementsToAdd.push_back(iEl);
00300     }
00301 
00302     //    std::cout << " setCandidates EcalEne " << EcalEne << std::endl;
00303     reco::PFCandidate::ParticleType particleType = reco::PFCandidate::gamma;
00304 
00305     // define energy and momentum of the conversion. Momentum from the track pairs and Energy from 
00306     // the sum of the ecal cluster(s)
00307     math::XYZTLorentzVector  momentum;
00308     momentum.SetPxPyPzE(pairPx , pairPy, pairPz, EcalEne);
00309 
00311 
00312     float deltaCotTheta=origConv->pairCotThetaSeparation();
00313     float phiTk1=  origConv->tracks()[0]->innerMomentum().phi();
00314     float phiTk2=  origConv->tracks()[1]->innerMomentum().phi();
00315     float deltaPhi = phiTk1-phiTk2;
00316     if(deltaPhi >  pi) {deltaPhi = deltaPhi - twopi;}
00317     if(deltaPhi < -pi) {deltaPhi = deltaPhi + twopi;}
00318 
00320     if (  fabs(deltaCotTheta) < 0.05 && abs(deltaPhi<0.1) )  {
00321       
00322       
00324       reco::PFCandidate aCandidate = PFCandidate(0, momentum,particleType);
00325       for (unsigned int elad=0; elad<elementsToAdd.size();elad++){
00326         aCandidate.addElementInBlock(blockRef,elementsToAdd[elad]);
00327       }
00328       
00329       
00330       aCandidate.setFlag( reco::PFCandidate::GAMMA_TO_GAMMACONV, true);
00331       aCandidate.setConversionRef(origConv);
00332       aCandidate.setEcalEnergy(EcalEne);
00333       aCandidate.setHcalEnergy(0.); 
00334       aCandidate.setPs1Energy(0.); 
00335       aCandidate.setPs2Energy(0.); 
00336       
00337       
00338       conversionCandidate_.push_back( aCandidate);       
00339     }  
00340     
00341 
00342   }
00343 
00344 
00345 
00346   return;
00347 }
00348 
00349 
00350 
00351 
00352 void PFConversionAlgo::setActive(const reco::PFBlockRef& blockRef,  
00353                                  AssMap&  elemAssociatedToConv, std::vector<bool>& active ) {
00354 
00355   // Lock tracks and clusters belonging to the conversion
00356   for (  std::multimap<unsigned, std::vector<unsigned> >::iterator i=elemAssociatedToConv.begin(); 
00357          i!=  elemAssociatedToConv.end(); ++i) {
00358     unsigned int iConvTrk =  i->first;
00359     active[iConvTrk]=false;
00360     //std::cout << "  PFConversionAlgo::setActive locking all elements linked to a conversion " << std::endl;
00361     for (unsigned int j=0; j< (i->second).size(); ++j ) {
00362       active[(i->second)[j]]=false;
00363       //std::cout << " Locking element " << (i->second)[j] << std::endl;
00364     }
00365   }
00366 
00367   
00368   return;
00369 }
00370