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
00016
00017
00018 }
00019
00020 std::vector<PhotonMCTruth> PhotonMCTruthFinder::find(const std::vector<SimTrack>& theSimTracks, const std::vector<SimVertex>& theSimVertices ) {
00021
00022
00023 std::vector<PhotonMCTruth> result;
00024
00025
00026
00027
00028
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
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
00066 } else {
00067
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
00080 iFirstSimTk++;
00081 if ( iFirstSimTk!= theSimTracks.end() ) {
00082
00083 if ( (*iFirstSimTk).vertIndex() == iPV) {
00084 partType2 = (*iFirstSimTk).type();
00085
00086
00087 } else {
00088
00089 }
00090 }
00091
00092
00093
00094 int npv=0;
00095
00096
00097
00098 for (std::vector<SimTrack>::const_iterator iSimTk = theSimTracks.begin(); iSimTk != theSimTracks.end(); ++iSimTk){
00099 if ( (*iSimTk).noVertex() ) continue;
00100
00101
00102
00103
00104
00105
00106 if ( (*iSimTk).vertIndex() == iPV ) {
00107 npv++;
00108 if ( (*iSimTk).type() == 22) {
00109
00110
00111 photonTracks.push_back(&(const_cast<SimTrack&>(*iSimTk)));
00112
00113 }
00114
00115 }
00116
00117 }
00118
00119
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
00150
00151
00152
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
00164
00165
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
00181
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
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
00208
00209
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
00218
00219
00220
00221 trkFromConversion.push_back( (*iEleTk ) );
00222 SimTrack trLast =(*iEleTk);
00223 float remainingEnergy =trLast.momentum().e();
00224
00225
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
00245
00246 int vertexId1 = (*iSimTk).vertIndex();
00247 SimVertex vertex1 = theSimVertices[vertexId1];
00248 int vertexId2 = trLast.vertIndex();
00249
00250
00251
00252 int motherId=-1;
00253
00254 if( ( vertexId1 == vertexId2 ) && ( (*iSimTk).type() == (*iEleTk).type() ) && trLast.type() == 22 ) {
00255
00256
00257
00258
00259
00260
00261
00262
00263 float eLoss = remainingEnergy - ( (*iSimTk).momentum() + trLast.momentum()).e();
00264
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
00275
00276 if (theSimTracks[motherId].trackId() == eleId ) {
00277
00278
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
00301 }
00302
00303 }
00304 trLast=(*iSimTk);
00305
00306 }
00307
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
00324 }
00325
00326
00327 }
00328
00329
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
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
00360 isAconversion=1;
00361
00362
00363
00364 int convVtxId =electronsFromConversions[0].vertexInd();
00365 SimVertex convVtx = theSimVertices[convVtxId];
00366
00367 math::XYZTLorentzVectorD vtxPosition(convVtx.position().x(),
00368 convVtx.position().y(),
00369 convVtx.position().z(),
00370 convVtx.position().e());
00371
00372
00373
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
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
00392 result.push_back( PhotonMCTruth(isAconversion, tmpPhoMom, photonVertexIndex, phoTrkId, phoMotherType, phoMotherMom, phoMotherVtx, vtxPosition,
00393 tmpPrimVtx, electronsFromConversions ));
00394
00395 }
00396
00397
00398
00399 }
00400
00401
00402 }
00403
00404
00405
00406 }
00407
00408 return result;
00409
00410 }
00411
00412 void PhotonMCTruthFinder::fill(const std::vector<SimTrack>& simTracks, const std::vector<SimVertex>& simVertices ) {
00413
00414
00415
00416
00417
00418
00419 unsigned nVtx = simVertices.size();
00420 unsigned nTks = simTracks.size();
00421
00422
00423
00424
00425 if ( nVtx == 0 ) return;
00426
00427
00428
00429 for( unsigned it=0; it<nTks; ++it ) {
00430 geantToIndex_[ simTracks[it].trackId() ] = it;
00431
00432
00433 }
00434
00435
00436
00437
00438 }