CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoEgamma/EgammaMCTools/src/PhotonMCTruthFinder.cc

Go to the documentation of this file.
00001 #include "RecoEgamma/EgammaMCTools/interface/PhotonMCTruthFinder.h"
00002 #include "RecoEgamma/EgammaMCTools/interface/PhotonMCTruth.h"
00003 #include "RecoEgamma/EgammaMCTools/interface/ElectronMCTruth.h"
00004 //
00005 //
00006 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
00007 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
00008 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticleFwd.h"
00009 #include "SimDataFormats/TrackingAnalysis/interface/TrackingVertexContainer.h"
00010 
00011 #include <algorithm>
00012 
00013 
00014 PhotonMCTruthFinder::PhotonMCTruthFinder( ) {
00015  //std::cout << " PhotonMCTruthFinder CTOR " << std::endl;
00016 
00017  
00018 }
00019 
00020 std::vector<PhotonMCTruth> PhotonMCTruthFinder::find(const std::vector<SimTrack>& theSimTracks, const std::vector<SimVertex>& theSimVertices ) {
00021   //  std::cout << "  PhotonMCTruthFinder::find " << std::endl;
00022 
00023   std::vector<PhotonMCTruth> result;
00024 
00025   //const float pi = 3.141592653592;
00026   //const float twopi=2*pi;
00027 
00028 // Local variables  
00029   const int SINGLE=1;
00030   const int DOUBLE=2;
00031   const int PYTHIA=3;
00032   const int ELECTRON_FLAV=1;
00033   const int PIZERO_FLAV=2;
00034   const int PHOTON_FLAV=3;
00035   
00036   int ievtype=0;
00037   int ievflav=0;
00038   
00039   
00040   std::vector<SimTrack*> photonTracks;
00041   
00042   std::vector<SimTrack> trkFromConversion;
00043   std::vector<ElectronMCTruth> electronsFromConversions;
00044   SimVertex primVtx;   
00045 
00046   
00047   fill(theSimTracks,  theSimVertices);
00048 
00049   //  std::cout << " After fill " << theSimTracks.size() << " " << theSimVertices.size() << std::endl;
00050   if (    theSimTracks.size() != 0 ) {
00051   
00052   int iPV=-1;   
00053   int partType1=0;
00054   int partType2=0;
00055   std::vector<SimTrack>::const_iterator iFirstSimTk = theSimTracks.begin();
00056   if (  !(*iFirstSimTk).noVertex() ) {
00057     iPV =  (*iFirstSimTk).vertIndex();
00058     
00059     int vtxId =   (*iFirstSimTk).vertIndex();
00060     primVtx = theSimVertices[vtxId];
00061     
00062     
00063     
00064     partType1 = (*iFirstSimTk).type();
00065     //    std::cout <<  " Primary vertex id " << iPV << " first track type " << (*iFirstSimTk).type() << std::endl;  
00066   } else {
00067     //std::cout << " First track has no vertex " << std::endl;
00068     
00069   }
00070   
00071 
00072 
00073   math::XYZTLorentzVectorD primVtxPos(primVtx.position().x(),
00074                                        primVtx.position().y(),
00075                                        primVtx.position().z(),
00076                                        primVtx.position().e());           
00077  
00078 
00079   // Look at a second track
00080   iFirstSimTk++;
00081   if ( iFirstSimTk!=  theSimTracks.end() ) {
00082     
00083     if (  (*iFirstSimTk).vertIndex() == iPV) {
00084       partType2 = (*iFirstSimTk).type();  
00085       //      std::cout <<  " second track type " << (*iFirstSimTk).type() << " vertex " <<  (*iFirstSimTk).vertIndex() << std::endl;  
00086       
00087     } else {
00088       // std::cout << " Only one kine track from Primary Vertex " << std::endl;
00089     }
00090   }
00091   
00092   //std::cout << " Loop over all particles " << std::endl;
00093   
00094   int npv=0;
00095   //int iPho=0;
00096   //int iPizero=0;
00097   //   theSimTracks.reset();
00098   for (std::vector<SimTrack>::const_iterator iSimTk = theSimTracks.begin(); iSimTk != theSimTracks.end(); ++iSimTk){
00099     if (  (*iSimTk).noVertex() ) continue;
00100 
00101 
00102     //int vertexId = (*iSimTk).vertIndex();
00103     //SimVertex vertex = theSimVertices[vertexId];
00104  
00105     //    std::cout << " Particle type " <<  (*iSimTk).type() << " Sim Track ID " << (*iSimTk).trackId() << " momentum " << (*iSimTk).momentum() <<  " vertex position " << vertex.position() << " vertex index " << (*iSimTk).vertIndex() << std::endl;  
00106     if ( (*iSimTk).vertIndex() == iPV ) {
00107       npv++;
00108       if ( (*iSimTk).type() == 22) {
00109         //      std::cout << " Found a primary photon with ID  " << (*iSimTk).trackId() << " momentum " << (*iSimTk).momentum() <<  std::endl; 
00110 
00111         photonTracks.push_back(&(const_cast<SimTrack&>(*iSimTk)));
00112 
00113       } 
00114       
00115     }
00116     
00117   } 
00118   
00119   //  std::cout << " There are " << npv << " particles originating in the PV " << std::endl;
00120   
00121    if(npv >= 3) {
00122      ievtype = PYTHIA;
00123    } else if(npv == 1) {
00124      if( std::abs(partType1) == 11 ) {
00125        ievtype = SINGLE; ievflav = ELECTRON_FLAV;
00126      } else if(partType1 == 111) {
00127        ievtype = SINGLE; ievflav = PIZERO_FLAV;
00128      } else if(partType1 == 22) {
00129        ievtype = SINGLE; ievflav = PHOTON_FLAV;
00130      }
00131    } else if(npv == 2) {
00132      if (  std::abs(partType1) == 11 && std::abs(partType2) == 11 ) {
00133        ievtype = DOUBLE; ievflav = ELECTRON_FLAV;
00134      } else if(partType1 == 111 && partType2 == 111)   {
00135        ievtype = DOUBLE; ievflav = PIZERO_FLAV;
00136      } else if(partType1 == 22 && partType2 == 22)   {
00137        ievtype = DOUBLE; ievflav = PHOTON_FLAV;
00138      }
00139    }      
00140    
00142 
00143    int isAconversion=0;   
00144    int phoMotherType=-1;
00145    int phoMotherVtxIndex=-1;
00146    int phoMotherId=-1;
00147    if( ievflav == PHOTON_FLAV || ievflav== PIZERO_FLAV || ievtype == PYTHIA ) {
00148 
00149      //     std::cout << " It's a primary PHOTON or PIZERO or PYTHIA event with " << photonTracks.size() << " photons ievtype " << ievtype << " ievflav " << ievflav<<  std::endl;
00150 
00151      //    for (std::vector<SimTrack*>::iterator iPhoTk = photonTracks.begin(); iPhoTk != photonTracks.end(); ++iPhoTk){
00152      //      std::cout << " All gamma found from PV " << (*iPhoTk)->momentum() << " photon track ID " << (*iPhoTk)->trackId() << " vertex index " << (*iPhoTk)->vertIndex() << std::endl;  
00153      //  }        
00154 
00155      for (std::vector<SimTrack>::const_iterator iPhoTk = theSimTracks.begin(); iPhoTk != theSimTracks.end(); ++iPhoTk){
00156 
00157        trkFromConversion.clear();           
00158        electronsFromConversions.clear();
00159 
00160        if ( (*iPhoTk).type() != 22 ) continue;
00161        int photonVertexIndex= (*iPhoTk).vertIndex();
00162        int phoTrkId= (*iPhoTk).trackId();
00163        //std::cout << " Looping on gamma looking for conversions " << (*iPhoTk).momentum() << " photon track ID " << (*iPhoTk).trackId() << std::endl;
00164      
00165        // check who is his mother
00166        SimVertex vertex = theSimVertices[ photonVertexIndex];
00167        phoMotherId=-1;
00168        if ( vertex.parentIndex() != -1 ) {
00169          
00170          unsigned  motherGeantId = vertex.parentIndex(); 
00171          std::map<unsigned, unsigned >::iterator association = geantToIndex_.find( motherGeantId );
00172          if(association != geantToIndex_.end() )
00173            phoMotherId = association->second;
00174          phoMotherType = phoMotherId == -1 ? 0 : theSimTracks[phoMotherId].type();
00175 
00176          
00177 
00178          if ( phoMotherType == 111 || phoMotherType == 221 || phoMotherType == 331 ) {
00179          
00180            //std::cout << " Parent to this vertex   motherId " << phoMotherId << " mother type " <<  phoMotherType << " Sim track ID " <<  theSimTracks[phoMotherId].trackId() << std::endl;
00181            //std::cout << " Son of a pizero or eta " << phoMotherType << std::endl;
00182          }
00183          
00184        }
00185 
00186 
00187 
00188        for (std::vector<SimTrack>::const_iterator iEleTk = theSimTracks.begin(); iEleTk != theSimTracks.end(); ++iEleTk){
00189          if (  (*iEleTk).noVertex() )                    continue;
00190          if ( (*iEleTk).vertIndex() == iPV )             continue; 
00191          if ( std::abs((*iEleTk).type()) != 11  )             continue;
00192 
00193          int vertexId = (*iEleTk).vertIndex();
00194          SimVertex vertex = theSimVertices[vertexId];
00195          int motherId=-1;
00196         
00197 
00198          //std::cout << " Secondary from photons particle type " << (*iEleTk).type() << " trackId " <<  (*iEleTk).trackId() << " vertex ID " << vertexId << std::endl;
00199          if ( vertex.parentIndex() != -1 ) {
00200 
00201            unsigned  motherGeantId = vertex.parentIndex(); 
00202            std::map<unsigned, unsigned >::iterator association = geantToIndex_.find( motherGeantId );
00203            if(association != geantToIndex_.end() )
00204              motherId = association->second;
00205            
00206            
00207            //int motherType = motherId == -1 ? 0 : theSimTracks[motherId].type();
00208            
00209            //std::cout << " Parent to this vertex   motherId " << motherId << " mother type " <<  motherType << " Sim track ID " <<  theSimTracks[motherId].trackId() << std::endl;
00210 
00211            std::vector<CLHEP::Hep3Vector> bremPos;  
00212            std::vector<CLHEP::HepLorentzVector> pBrem;
00213            std::vector<float> xBrem;
00214            
00215            if ( theSimTracks[motherId].trackId() == (*iPhoTk).trackId() ) {
00216              //std::cout << " Found the Mother Photon " << std::endl;
00218 
00219 
00220 
00221              trkFromConversion.push_back( (*iEleTk ) );
00222              SimTrack trLast =(*iEleTk); 
00223              float remainingEnergy =trLast.momentum().e();
00224              //HepLorentzVector primEleMom=(*iEleTk).momentum();  
00225              //HepLorentzVector motherMomentum=(*iEleTk).momentum();  
00226              math::XYZTLorentzVectorD primEleMom((*iEleTk).momentum().x(),
00227                                              (*iEleTk).momentum().y(),
00228                                              (*iEleTk).momentum().z(),
00229                                              (*iEleTk).momentum().e());  
00230              math::XYZTLorentzVectorD motherMomentum(primEleMom);  
00231              unsigned int eleId = (*iEleTk).trackId();     
00232              int eleVtxIndex= (*iEleTk).vertIndex();
00233            
00234     
00235              bremPos.clear();
00236              pBrem.clear();
00237              xBrem.clear();   
00238                      
00239              for (std::vector<SimTrack>::const_iterator iSimTk = theSimTracks.begin(); iSimTk != theSimTracks.end(); ++iSimTk){
00240                
00241                if (  (*iSimTk).noVertex() )                    continue;
00242                if ( (*iSimTk).vertIndex() == iPV )             continue;
00243                
00244                //std::cout << " (*iEleTk)->trackId() " << (*iEleTk).trackId() << " (*iEleTk)->vertIndex() "<< (*iEleTk).vertIndex()  << " (*iSimTk).vertIndex() "  <<  (*iSimTk).vertIndex() << " (*iSimTk).type() " <<   (*iSimTk).type() << " (*iSimTk).trackId() " << (*iSimTk).trackId() << std::endl;
00245                
00246                int vertexId1 = (*iSimTk).vertIndex();
00247                SimVertex vertex1 = theSimVertices[vertexId1];
00248                int vertexId2 = trLast.vertIndex();
00249                //SimVertex vertex2 = theSimVertices[vertexId2];
00250                
00251                
00252                int motherId=-1;
00253                
00254                if(  (  vertexId1 ==  vertexId2 ) && ( (*iSimTk).type() == (*iEleTk).type() ) && trLast.type() == 22   ) {
00255                  //std::cout << " Here a e/gamma brem vertex " << std::endl;
00256                  
00257                  //std::cout << " Secondary from electron:  particle1  type " << (*iSimTk).type() << " trackId " <<  (*iSimTk).trackId() << " vertex ID " << vertexId1 << " vertex position " << sqrt(vertex1.position().perp2()) << " parent index "<< vertex1.parentIndex() << std::endl;
00258                  
00259                  //std::cout << " Secondary from electron:  particle2  type " << trLast.type() << " trackId " <<  trLast.trackId() << " vertex ID " << vertexId2 << " vertex position " << sqrt(vertex2.position().perp2()) << " parent index " << vertex2.parentIndex() << std::endl;
00260                  
00261                  //std::cout << " Electron pt " << sqrt((*iSimTk).momentum().perp2()) << " photon pt " << sqrt(trLast.momentum().perp2()) << " Mother electron pt " <<  sqrt(motherMomentum.perp2()) << std::endl;
00262                  //std::cout << " eleId " << eleId << std::endl;
00263                  float eLoss = remainingEnergy - ( (*iSimTk).momentum() + trLast.momentum()).e();
00264                  //std::cout << " eLoss " << eLoss << std::endl;              
00265                  
00266                  
00267                  if ( vertex1.parentIndex() != -1  ) {
00268                    
00269                    unsigned  motherGeantId = vertex1.parentIndex(); 
00270                    std::map<unsigned, unsigned >::iterator association = geantToIndex_.find( motherGeantId );
00271                    if(association != geantToIndex_.end() )
00272                      motherId = association->second;
00273                    
00274                    //int motherType = motherId == -1 ? 0 : theSimTracks[motherId].type();
00275                    //std::cout << " Parent to this vertex   motherId " << motherId << " mother type " <<  motherType << " Sim track ID " <<  theSimTracks[motherId].trackId() << std::endl; 
00276                    if (theSimTracks[motherId].trackId() == eleId ) {
00277                      
00278                      //std::cout << "  ***** Found the Initial Mother Electron ****   theSimTracks[motherId].trackId() " <<  theSimTracks[motherId].trackId() << " eleId " <<  eleId << std::endl;
00279                      eleId= (*iSimTk).trackId();
00280                      remainingEnergy =   (*iSimTk).momentum().e();
00281                      motherMomentum = (*iSimTk).momentum();
00282                      
00283                      
00284                      pBrem.push_back( CLHEP::HepLorentzVector(trLast.momentum().px(),
00285                                                        trLast.momentum().py(),
00286                                                        trLast.momentum().pz(),
00287                                                        trLast.momentum().e()) );
00288                      bremPos.push_back( CLHEP::HepLorentzVector(vertex1.position().x(),
00289                                                          vertex1.position().y(),
00290                                                          vertex1.position().z(),
00291                                                          vertex1.position().t()) );
00292                      xBrem.push_back(eLoss);
00293                      
00294                    }
00295                    
00296                    
00297                    
00298                    
00299                  } else {
00300                    //std::cout << " This vertex has no parent tracks " <<  std::endl;
00301                  }
00302                  
00303                }
00304                trLast=(*iSimTk);
00305                
00306              } // End loop over all SimTracks 
00307              //std::cout << " Going to build the ElectronMCTruth for this electron from converted photon: pBrem size " << pBrem.size() << std::endl;
00309 
00310              CLHEP::HepLorentzVector tmpEleMom(primEleMom.px(),primEleMom.py(),
00311                                         primEleMom.pz(),primEleMom.e() );
00312              CLHEP::HepLorentzVector tmpVtxPos(primVtxPos.x(),primVtxPos.y(),
00313                                         primVtxPos.z(),primVtxPos.t() );
00314              electronsFromConversions.push_back ( 
00315                 ElectronMCTruth( tmpEleMom, eleVtxIndex,  bremPos, pBrem, 
00316                                  xBrem,  tmpVtxPos , const_cast<SimTrack&>(*iEleTk)  )  ) ;
00317            }   
00318  
00319            
00320 
00321 
00322          } else {
00323            //std::cout << " This vertex has no parent tracks " <<  std::endl;
00324          }
00325          
00326          
00327        } // End of loop over the SimTracks      
00328        
00329        //std::cout << " DEBUG trkFromConversion.size() " << trkFromConversion.size() << " electronsFromConversions.size() " << electronsFromConversions.size() << std::endl;
00330 
00331        math::XYZTLorentzVectorD motherVtxPosition(0.,0.,0.,0.);
00332        CLHEP::HepLorentzVector phoMotherMom(0.,0.,0.,0.);
00333        CLHEP::HepLorentzVector phoMotherVtx(0.,0.,0.,0.); 
00334 
00335        if ( phoMotherId >= 0) {
00336         
00337          phoMotherVtxIndex = theSimTracks[phoMotherId].vertIndex();
00338          SimVertex motherVtx = theSimVertices[ phoMotherVtxIndex];
00339          motherVtxPosition =math::XYZTLorentzVectorD (motherVtx.position().x(),
00340                                                       motherVtx.position().y(),
00341                                                       motherVtx.position().z(),
00342                                                       motherVtx.position().e());
00343          
00344          phoMotherMom.setPx( theSimTracks[phoMotherId].momentum().x());
00345          phoMotherMom.setPy( theSimTracks[phoMotherId].momentum().y());
00346          phoMotherMom.setPz( theSimTracks[phoMotherId].momentum().z() );
00347          phoMotherMom.setE( theSimTracks[phoMotherId].momentum().t());
00348          // std::cout << " PhotonMCTruthFinder mother " << phoMotherId << " type " << phoMotherType << " Momentum" <<  phoMotherMom.et() << std::endl;  
00349  
00350          phoMotherVtx.setX ( motherVtxPosition.x());
00351          phoMotherVtx.setY ( motherVtxPosition.y());
00352          phoMotherVtx.setZ ( motherVtxPosition.z());
00353          phoMotherVtx.setT ( motherVtxPosition.t());
00354        
00355        }
00356 
00357 
00358        if ( electronsFromConversions.size() > 0 ) {
00359        // if ( trkFromConversion.size() > 0 ) {
00360          isAconversion=1;
00361          //std::cout  << " CONVERTED photon " <<   "\n";    
00362 
00363          //int convVtxId =  trkFromConversion[0].vertIndex();
00364          int convVtxId =electronsFromConversions[0].vertexInd();
00365          SimVertex convVtx = theSimVertices[convVtxId];
00366          // CLHEP::HepLorentzVector vtxPosition = convVtx.position();
00367          math::XYZTLorentzVectorD vtxPosition(convVtx.position().x(),
00368                                           convVtx.position().y(),
00369                                           convVtx.position().z(),
00370                                           convVtx.position().e());
00371          
00372            
00373          //result.push_back( PhotonMCTruth(isAconversion, (*iPhoTk).momentum(), photonVertexIndex, phoTrkId, vtxPosition,   primVtx.position(), trkFromConversion ));
00374          CLHEP::HepLorentzVector tmpPhoMom( (*iPhoTk).momentum().px(), (*iPhoTk).momentum().py(),
00375                                      (*iPhoTk).momentum().pz(), (*iPhoTk).momentum().e() ) ;
00376          CLHEP::HepLorentzVector tmpVertex( vtxPosition.x(), vtxPosition.y(), vtxPosition.z(), vtxPosition.t() );
00377          CLHEP::HepLorentzVector tmpPrimVtx( primVtxPos.x(), primVtxPos.y(), primVtxPos.z(), primVtxPos.t() ) ;
00378 
00379 
00380 
00381          result.push_back( PhotonMCTruth(isAconversion, tmpPhoMom, photonVertexIndex, phoTrkId, phoMotherType,phoMotherMom, phoMotherVtx, tmpVertex,  
00382          tmpPrimVtx, electronsFromConversions ));
00383 
00384        } else {
00385          isAconversion=0;
00386          //std::cout  << " UNCONVERTED photon " <<   "\n";    
00387          CLHEP::HepLorentzVector vtxPosition(0.,0.,0.,0.);
00388          CLHEP::HepLorentzVector tmpPhoMom( (*iPhoTk).momentum().px(), (*iPhoTk).momentum().py(),
00389                                      (*iPhoTk).momentum().pz(), (*iPhoTk).momentum().e() ) ;
00390          CLHEP::HepLorentzVector tmpPrimVtx( primVtxPos.x(), primVtxPos.y(), primVtxPos.z(), primVtxPos.t() ) ;
00391          //      result.push_back( PhotonMCTruth(isAconversion, (*iPhoTk).momentum(),  photonVertexIndex, phoTrkId, vtxPosition,   primVtx.position(), trkFromConversion ));
00392          result.push_back( PhotonMCTruth(isAconversion, tmpPhoMom,  photonVertexIndex, phoTrkId, phoMotherType, phoMotherMom, phoMotherVtx, vtxPosition,   
00393          tmpPrimVtx, electronsFromConversions ));
00394         
00395        }
00396        
00397 
00398 
00399      } // End loop over the primary photons
00400      
00401      
00402    }   // Event with one or two photons 
00403 
00404 
00405    //std::cout << "  PhotonMCTruthFinder photon size " << result.size() << std::endl;
00406   }
00407 
00408    return result;
00409 
00410 }
00411 
00412 void PhotonMCTruthFinder::fill(const std::vector<SimTrack>& simTracks, const std::vector<SimVertex>& simVertices ) {
00413   //  std::cout << "  PhotonMCTruthFinder::fill " << std::endl;
00414 
00415 
00416 
00417  // Watch out there ! A SimVertex is in mm (stupid), 
00418  
00419   unsigned nVtx = simVertices.size();
00420   unsigned nTks = simTracks.size();
00421 
00422   //  std::cout << "  PhotonMCTruthFinder::fill " << nVtx << " " << nTks << std::endl;
00423 
00424   // Empty event, do nothin'
00425   if ( nVtx == 0 ) return;
00426 
00427   // create a map associating geant particle id and position in the 
00428   // event SimTrack vector
00429   for( unsigned it=0; it<nTks; ++it ) {
00430     geantToIndex_[ simTracks[it].trackId() ] = it;
00431     //    std::cout << " PhotonMCTruthFinder::fill it " << it << " simTracks[it].trackId() " <<  simTracks[it].trackId() << std::endl;
00432  
00433   }  
00434 
00435 
00436 
00437 
00438 }