CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:43:25 2009 for CMSSW by  doxygen 1.5.4