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(std::vector<SimTrack> theSimTracks, std::vector<SimVertex> theSimVertices ) {
00021
00022
00023 std::vector<PhotonMCTruth> result;
00024
00025 const float pi = 3.141592653592;
00026 const float twopi=2*pi;
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
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
00066 } else {
00067
00068
00069 }
00070
00071
00072 math::XYZTLorentzVectorD primVtxPos(primVtx.position().x(),
00073 primVtx.position().y(),
00074 primVtx.position().z(),
00075 primVtx.position().e());
00076
00077
00078 iFirstSimTk++;
00079 if ( iFirstSimTk!= theSimTracks.end() ) {
00080
00081 if ( (*iFirstSimTk).vertIndex() == iPV) {
00082 partType2 = (*iFirstSimTk).type();
00083
00084
00085 } else {
00086
00087 }
00088 }
00089
00090
00091
00092 int npv=0;
00093 int iPho=0;
00094 int iPizero=0;
00095
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
00104 if ( (*iSimTk).vertIndex() == iPV ) {
00105 npv++;
00106 if ( (*iSimTk).type() == 22) {
00107
00108
00109
00110 photonTracks.push_back( &(*iSimTk) );
00111
00112 }
00113
00114 }
00115
00116 }
00117
00118
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
00149
00150
00151
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
00163
00164
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
00180
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
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
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
00217
00218
00219
00220 trkFromConversion.push_back( (*iEleTk ) );
00221 SimTrack trLast =(*iEleTk);
00222 float remainingEnergy =trLast.momentum().e();
00223
00224
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
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
00255
00256
00257
00258
00259
00260
00261
00262 float eLoss = remainingEnergy - ( (*iSimTk).momentum() + trLast.momentum()).e();
00263
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
00275 if ( theSimTracks[motherId].trackId() == eleId ) {
00276
00277
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
00300 }
00301
00302 }
00303 trLast=(*iSimTk);
00304
00305 }
00306
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
00323 }
00324
00325
00326 }
00327
00328
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
00357 isAconversion=1;
00358
00359
00360
00361 int convVtxId =electronsFromConversions[0].vertexInd();
00362 SimVertex convVtx = theSimVertices[convVtxId];
00363
00364 math::XYZTLorentzVectorD vtxPosition(convVtx.position().x(),
00365 convVtx.position().y(),
00366 convVtx.position().z(),
00367 convVtx.position().e());
00368
00369
00370
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
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
00389 result.push_back( PhotonMCTruth(isAconversion, tmpPhoMom, photonVertexIndex, phoTrkId, phoMotherType, phoMotherMom, phoMotherVtx, vtxPosition,
00390 tmpPrimVtx, electronsFromConversions ));
00391
00392 }
00393
00394
00395
00396 }
00397
00398
00399 }
00400
00401
00402
00403
00404
00405 return result;
00406
00407 }
00408
00409 void PhotonMCTruthFinder::fill(std::vector<SimTrack>& simTracks, std::vector<SimVertex>& simVertices ) {
00410
00411
00412
00413
00414
00415
00416 unsigned nVtx = simVertices.size();
00417 unsigned nTks = simTracks.size();
00418
00419
00420 if ( nVtx == 0 ) return;
00421
00422
00423
00424 for( unsigned it=0; it<nTks; ++it ) {
00425 geantToIndex_[ simTracks[it].trackId() ] = it;
00426
00427
00428 }
00429
00430
00431
00432
00433 }