00001
00002
00003
00004
00005 #include <math.h>
00006 #include <cstdlib>
00007 #include <iostream>
00008
00009 #include "HepPDT/ParticleID.hh"
00010
00011 #include "SimTracker/TrackHistory/interface/VertexClassifier.h"
00012
00013
00014 #define update(a, b) do { (a) = (a) | (b); } while(0)
00015
00016
00017 VertexClassifier::VertexClassifier(edm::ParameterSet const & config) : VertexCategories(), tracer_(config),
00018 hepMCLabel_( config.getUntrackedParameter<edm::InputTag>("hepMC") )
00019 {
00020
00021 tracer_.depth(-2);
00022
00023
00024 longLivedDecayLength_ = config.getUntrackedParameter<double>("longLivedDecayLength");
00025
00026
00027 vertexClusteringDistance_ = config.getUntrackedParameter<double>("vertexClusteringDistance");
00028 }
00029
00030
00031 void VertexClassifier::newEvent(edm::Event const & event, edm::EventSetup const & setup)
00032 {
00033
00034 tracer_.newEvent(event, setup);
00035
00036
00037 event.getByLabel(hepMCLabel_, mcInformation_);
00038
00039
00040 setup.getData(particleDataTable_);
00041
00042
00043 genPrimaryVertices();
00044 }
00045
00046
00047 VertexClassifier const & VertexClassifier::evaluate (reco::VertexBaseRef const & vertex)
00048 {
00049
00050 reset();
00051
00052
00053 if ( tracer_.evaluate(vertex) )
00054 {
00055
00056 simulationInformation();
00057
00058
00059 processesAtGenerator();
00060
00061
00062 processesAtSimulation();
00063
00064
00065 vertexInformation();
00066
00067
00068 unknownVertex();
00069 }
00070 else
00071 flags_[Fake] = true;
00072
00073 return *this;
00074 }
00075
00076
00077 VertexClassifier const & VertexClassifier::evaluate (TrackingVertexRef const & vertex)
00078 {
00079
00080 reset();
00081
00082
00083 tracer_.evaluate(vertex);
00084
00085
00086 if ( tracer_.recoVertex().isNonnull() )
00087 flags_[Reconstructed] = true;
00088 else
00089 flags_[Reconstructed] = false;
00090
00091
00092 simulationInformation();
00093
00094
00095 processesAtGenerator();
00096
00097
00098 processesAtSimulation();
00099
00100
00101 vertexInformation();
00102
00103
00104 unknownVertex();
00105
00106 return *this;
00107 }
00108
00109
00110 void VertexClassifier::simulationInformation()
00111 {
00112
00113 EncodedEventId eventId = tracer_.simVertex()->eventId();
00114
00115 flags_[SignalEvent] = !eventId.bunchCrossing() && !eventId.event();
00116 }
00117
00118
00119 void VertexClassifier::processesAtGenerator()
00120 {
00121
00122 VertexHistory::GenVertexTrail const & genVertexTrail = tracer_.genVertexTrail();
00123
00124
00125 for (
00126 VertexHistory::GenVertexTrail::const_iterator ivertex = genVertexTrail.begin();
00127 ivertex != genVertexTrail.end();
00128 ++ivertex
00129 )
00130 {
00131
00132 HepMC::GenVertex * vertex = const_cast<HepMC::GenVertex *>(*ivertex);
00133
00134
00135 for (
00136 HepMC::GenVertex::particle_iterator iparent = vertex->particles_begin(HepMC::parents);
00137 iparent != vertex->particles_end(HepMC::parents);
00138 ++iparent
00139 )
00140 {
00141
00142 int pdgid = std::abs((*iparent)->pdg_id());
00143
00144 HepPDT::ParticleID particleID(pdgid);
00145
00146
00147 if (particleID.isValid())
00148 {
00149
00150 ParticleData const * particleData = particleDataTable_->particle(particleID);
00151
00152 if (particleData)
00153 {
00154
00155 if ( particleData->lifetime() > longLivedDecayLength_ )
00156 {
00157
00158 update(flags_[BWeakDecay], particleID.hasBottom());
00159 update(flags_[CWeakDecay], particleID.hasCharm());
00160 update(flags_[LongLivedDecay], true);
00161 }
00162
00163 update(flags_[TauDecay], pdgid == 15);
00164 update(flags_[KsDecay], pdgid == 310);
00165 update(flags_[LambdaDecay], pdgid == 3122);
00166 update(flags_[JpsiDecay], pdgid == 443);
00167 update(flags_[XiDecay], pdgid == 3312);
00168 update(flags_[OmegaDecay], pdgid == 3334);
00169 update(flags_[SigmaPlusDecay], pdgid == 3222);
00170 update(flags_[SigmaMinusDecay], pdgid == 3112);
00171 }
00172 }
00173 }
00174 }
00175 }
00176
00177
00178 void VertexClassifier::processesAtSimulation()
00179 {
00180 VertexHistory::SimVertexTrail const & simVertexTrail = tracer_.simVertexTrail();
00181
00182 for (
00183 VertexHistory::SimVertexTrail::const_iterator ivertex = simVertexTrail.begin();
00184 ivertex != simVertexTrail.end();
00185 ++ivertex
00186 )
00187 {
00188
00189 int pdgid = 0;
00190
00191
00192 bool flag = false;
00193 TrackingVertex::tp_iterator itd, its;
00194
00195 for (its = (*ivertex)->sourceTracks_begin(); its != (*ivertex)->sourceTracks_end(); ++its)
00196 {
00197 for (itd = (*ivertex)->daughterTracks_begin(); itd != (*ivertex)->daughterTracks_end(); ++itd)
00198 if (itd != its)
00199 {
00200 flag = true;
00201 break;
00202 }
00203 if (flag)
00204 break;
00205 }
00206
00207 if ( its != (*ivertex)->sourceTracks_end() )
00208 pdgid = std::abs((*its)->pdgId());
00209 else
00210 pdgid = 0;
00211
00212
00213 for (
00214 TrackingVertex::tp_iterator iparticle = (*ivertex)->daughterTracks_begin();
00215 iparticle != (*ivertex)->daughterTracks_end();
00216 ++iparticle
00217 )
00218 {
00219
00220 if ( (*iparticle)->numberOfTrackerLayers() )
00221 {
00222 #warning "This file has been modified just to get it to compile without any regard as to whether it still functions as intended"
00223 #ifdef REMOVED_JUST_TO_GET_IT_TO_COMPILE__THIS_CODE_NEEDS_TO_BE_CHECKED
00224
00225 unsigned short process = (*iparticle)->pSimHit_begin()->processType();
00226 #else
00227 unsigned short process = 0;
00228 #endif
00229
00230
00231 update(
00232 flags_[KnownProcess],
00233 process != G4::Undefined &&
00234 process != G4::Unknown &&
00235 process != G4::Primary
00236 );
00237
00238 update(flags_[UndefinedProcess], process == G4::Undefined);
00239 update(flags_[UnknownProcess], process == G4::Unknown);
00240 update(flags_[PrimaryProcess], process == G4::Primary);
00241 update(flags_[HadronicProcess], process == G4::Hadronic);
00242 update(flags_[DecayProcess], process == G4::Decay);
00243 update(flags_[ComptonProcess], process == G4::Compton);
00244 update(flags_[AnnihilationProcess], process == G4::Annihilation);
00245 update(flags_[EIoniProcess], process == G4::EIoni);
00246 update(flags_[HIoniProcess], process == G4::HIoni);
00247 update(flags_[MuIoniProcess], process == G4::MuIoni);
00248 update(flags_[PhotonProcess], process == G4::Photon);
00249 update(flags_[MuPairProdProcess], process == G4::MuPairProd);
00250 update(flags_[ConversionsProcess], process == G4::Conversions);
00251 update(flags_[EBremProcess], process == G4::EBrem);
00252 update(flags_[SynchrotronRadiationProcess], process == G4::SynchrotronRadiation);
00253 update(flags_[MuBremProcess], process == G4::MuBrem);
00254 update(flags_[MuNuclProcess], process == G4::MuNucl);
00255
00256
00257 if (process == G4::Decay)
00258 {
00259
00260 HepPDT::ParticleID particleID(pdgid);
00261
00262 if (particleID.isValid())
00263 {
00264
00265 ParticleData const * particleData = particleDataTable_->particle(particleID);
00266
00267 if (particleData)
00268 {
00269
00270 if ( particleDataTable_->particle(particleID)->lifetime() > longLivedDecayLength_ )
00271 {
00272
00273 update(flags_[BWeakDecay], particleID.hasBottom());
00274 update(flags_[CWeakDecay], particleID.hasCharm());
00275 update(flags_[LongLivedDecay], true);
00276 }
00277
00278 update(flags_[TauDecay], pdgid == 15);
00279 update(flags_[KsDecay], pdgid == 310);
00280 update(flags_[LambdaDecay], pdgid == 3122);
00281 update(flags_[JpsiDecay], pdgid == 443);
00282 update(flags_[XiDecay], pdgid == 3312);
00283 update(flags_[OmegaDecay], pdgid == 3334);
00284 update(flags_[SigmaPlusDecay], pdgid == 3222);
00285 update(flags_[SigmaMinusDecay], pdgid == 3112);
00286 }
00287 }
00288 }
00289 }
00290 }
00291 }
00292 }
00293
00294
00295 void VertexClassifier::vertexInformation()
00296 {
00297
00298 typedef std::multimap<double, HepMC::ThreeVector> Clusters;
00299 typedef std::pair<double, HepMC::ThreeVector> ClusterPair;
00300
00301 Clusters clusters;
00302
00303
00304 GeneratedPrimaryVertex const & genpv = genpvs_.back();
00305
00306
00307 VertexHistory::GenVertexTrail & genVertexTrail = const_cast<VertexHistory::GenVertexTrail &> (tracer_.genVertexTrail());
00308
00309
00310 double const mm = 0.1;
00311
00312
00313 for (
00314 VertexHistory::GenVertexTrail::const_iterator ivertex = genVertexTrail.begin();
00315 ivertex != genVertexTrail.end();
00316 ++ivertex
00317 )
00318 {
00319
00320 if (*ivertex)
00321 {
00322
00323 HepMC::ThreeVector p = (*ivertex)->point3d();
00324 double distance = sqrt( pow(p.x() * mm - genpv.x, 2) + pow(p.y() * mm - genpv.y, 2) + pow(p.z() * mm - genpv.z, 2) );
00325
00326
00327 if ( clusters.empty() )
00328 {
00329 clusters.insert( ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)) );
00330 continue;
00331 }
00332
00333
00334 Clusters::const_iterator icluster = clusters.lower_bound(distance - vertexClusteringDistance_);
00335
00336 if ( icluster == clusters.upper_bound(distance + vertexClusteringDistance_) )
00337 {
00338 clusters.insert ( ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)) );
00339 continue;
00340 }
00341
00342 bool cluster = false;
00343
00344
00345 for (;
00346 icluster != clusters.upper_bound(distance + vertexClusteringDistance_);
00347 ++icluster
00348 )
00349 {
00350 double difference = sqrt (
00351 pow(p.x() * mm - icluster->second.x(), 2) +
00352 pow(p.y() * mm - icluster->second.y(), 2) +
00353 pow(p.z() * mm - icluster->second.z(), 2)
00354 );
00355
00356 if ( difference < vertexClusteringDistance_ )
00357 {
00358 cluster = true;
00359 break;
00360 }
00361 }
00362
00363 if (!cluster) clusters.insert ( ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)) );
00364 }
00365 }
00366
00367 VertexHistory::SimVertexTrail & simVertexTrail = const_cast<VertexHistory::SimVertexTrail &> (tracer_.simVertexTrail());
00368
00369
00370 for (
00371 VertexHistory::SimVertexTrail::reverse_iterator ivertex = simVertexTrail.rbegin();
00372 ivertex != simVertexTrail.rend();
00373 ++ivertex
00374 )
00375 {
00376
00377 TrackingVertex::LorentzVector p = (*ivertex)->position();
00378
00379 double distance = sqrt( pow(p.x() - genpv.x, 2) + pow(p.y() - genpv.y, 2) + pow(p.z() - genpv.z, 2) );
00380
00381
00382 if ( clusters.empty() )
00383 {
00384 clusters.insert( ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())) );
00385 continue;
00386 }
00387
00388
00389 Clusters::const_iterator icluster = clusters.lower_bound(distance - vertexClusteringDistance_);
00390
00391 if ( icluster == clusters.upper_bound(distance + vertexClusteringDistance_) )
00392 {
00393 clusters.insert ( ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())) );
00394 continue;
00395 }
00396
00397 bool cluster = false;
00398
00399
00400 for (;
00401 icluster != clusters.upper_bound(distance + vertexClusteringDistance_);
00402 ++icluster
00403 )
00404 {
00405 double difference = sqrt (
00406 pow(p.x() - icluster->second.x(), 2) +
00407 pow(p.y() - icluster->second.y(), 2) +
00408 pow(p.z() - icluster->second.z(), 2)
00409 );
00410
00411 if ( difference < vertexClusteringDistance_ )
00412 {
00413 cluster = true;
00414 break;
00415 }
00416 }
00417
00418 if (!cluster) clusters.insert ( ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())) );
00419 }
00420
00421 if ( clusters.size() == 1 )
00422 flags_[PrimaryVertex] = true;
00423 else if ( clusters.size() == 2 )
00424 flags_[SecondaryVertex] = true;
00425 else
00426 flags_[TertiaryVertex] = true;
00427 }
00428
00429
00430 bool VertexClassifier::isFinalstateParticle(const HepMC::GenParticle * p)
00431 {
00432 return !p->end_vertex() && p->status() == 1;
00433 }
00434
00435
00436 bool VertexClassifier::isCharged(const HepMC::GenParticle * p)
00437 {
00438 const ParticleData * part = particleDataTable_->particle( p->pdg_id() );
00439 if (part)
00440 return part->charge()!=0;
00441 else
00442 {
00443
00444 return particleDataTable_->particle( -p->pdg_id() ) != 0;
00445 }
00446 }
00447
00448
00449 void VertexClassifier::genPrimaryVertices()
00450 {
00451 genpvs_.clear();
00452
00453 const HepMC::GenEvent * event = mcInformation_->GetEvent();
00454
00455 if (event)
00456 {
00457 int idx = 0;
00458
00459
00460 for ( HepMC::GenEvent::vertex_const_iterator ivertex = event->vertices_begin(); ivertex != event->vertices_end(); ++ivertex )
00461 {
00462 bool hasParentVertex = false;
00463
00464
00465 for (
00466 HepMC::GenVertex::particle_iterator iparent = (*ivertex)->particles_begin(HepMC::parents);
00467 iparent != (*ivertex)->particles_end(HepMC::parents);
00468 ++iparent
00469 )
00470 if ( (*iparent)->production_vertex() )
00471 {
00472 hasParentVertex = true;
00473 break;
00474 }
00475
00476
00477 if (hasParentVertex) continue;
00478
00479
00480 HepMC::FourVector pos = (*ivertex)->position();
00481
00482 double const mm = 0.1;
00483
00484 GeneratedPrimaryVertex pv(pos.x()*mm, pos.y()*mm, pos.z()*mm);
00485
00486 std::vector<GeneratedPrimaryVertex>::iterator ientry = genpvs_.begin();
00487
00488
00489 for (; ientry != genpvs_.end(); ++ientry)
00490 {
00491 double distance = sqrt( pow(pv.x - ientry->x, 2) + pow(pv.y - ientry->y, 2) + pow(pv.z - ientry->z, 2) );
00492 if ( distance < vertexClusteringDistance_ )
00493 break;
00494 }
00495
00496
00497 if (ientry == genpvs_.end())
00498 ientry = genpvs_.insert(ientry,pv);
00499
00500
00501 ientry->genVertex.push_back((*ivertex)->barcode());
00502
00503
00504 for (
00505 HepMC::GenVertex::particle_iterator idecendants = (*ivertex)->particles_begin(HepMC::descendants);
00506 idecendants != (*ivertex)->particles_end(HepMC::descendants);
00507 ++idecendants
00508 )
00509 {
00510 if (isFinalstateParticle(*idecendants))
00511 if ( find(ientry->finalstateParticles.begin(), ientry->finalstateParticles.end(), (*idecendants)->barcode()) == ientry->finalstateParticles.end() )
00512 {
00513 ientry->finalstateParticles.push_back((*idecendants)->barcode());
00514 HepMC::FourVector m = (*idecendants)->momentum();
00515
00516 ientry->ptot.setPx(ientry->ptot.px() + m.px());
00517 ientry->ptot.setPy(ientry->ptot.py() + m.py());
00518 ientry->ptot.setPz(ientry->ptot.pz() + m.pz());
00519 ientry->ptot.setE(ientry->ptot.e() + m.e());
00520 ientry->ptsq += m.perp() * m.perp();
00521
00522 if ( m.perp() > 0.8 && std::abs(m.pseudoRapidity()) < 2.5 && isCharged(*idecendants) ) ientry->nGenTrk++;
00523 }
00524 }
00525 idx++;
00526 }
00527 }
00528
00529 std::sort(genpvs_.begin(), genpvs_.end());
00530 }