4 using EVENT::LCCollection;
5 using EVENT::MCParticle;
6 using IMPL::MCParticleImpl;
8 namespace TTbarAnalysis
10 MCOperator:: MCOperator (LCCollection * col, LCCollection * rel)
13 myRelCollection = rel;
14 myPrimaryVertex[0] = 0.0;
15 myPrimaryVertex[1] = 0.0;
16 myPrimaryVertex[2] = 0.0;
21 if (!initial || initial->
GetSize() < 2)
27 for (
int i = 1; i < size; i++)
29 MCParticle * particle = initial->
Get(i);
30 vector< MCParticle * > parents = particle->getParents();
31 MCParticle * parent = NULL;
32 if (parents.size() == 1 && CheckParticle(parents[0],typeOfProducts[i-1]))
38 parent = initial->
Get(i-1);
46 result->
Add(initial->
Get(size-1));
49 DecayChain * MCOperator::Construct(
string name,
int pdg, vector<PDGTYPE> typeOfProducts)
52 int number = myCollection->getNumberOfElements();
53 bool finished =
false;
54 for (
int i = 0; i < number; i++)
56 MCParticle * particle =
dynamic_cast<MCParticle*
>( myCollection->getElementAt(i) ) ;
57 if (i > 100 && result->
GetSize() == 0)
59 streamlog_out(MESSAGE) <<
"WARNING: EVENT RUN OUT OF TRIALS!\n";
62 if (particle->getPDG() == pdg)
64 if (CheckForUnification(particle, pdg))
69 for (
unsigned int j = 0; j < typeOfProducts.size(); j++)
71 PDGTYPE currentPDG = typeOfProducts[j];
72 MCParticle * found = FindYoungestChild(particle, currentPDG);
75 if (CheckForColorString(found, pdg))
77 MCParticle * service = found->getParents()[0];
78 MCParticle * consistent = GetConsistentDaughter(particle, service, currentPDG);
81 result->
Add(consistent);
96 particle =(finished)? found : NULL;
106 bool MCOperator::CheckForUnification(MCParticle * particle,
int pdg)
108 vector< MCParticle * > daughters = particle->getDaughters();
109 if (daughters.size() == 0)
113 if (daughters.size() == 1 && daughters[0]->getPDG() == pdg)
115 return CheckForUnification(daughters[0], pdg);
117 if (daughters.size() == 1 && (daughters[0]->getPDG() == 92 || daughters[0]->getPDG() == 94))
119 vector< MCParticle * > grandDaughters = daughters[0]->getDaughters();
120 bool foundParticle =
false;
121 bool foundAntiparticle =
false;
122 for (
unsigned int i = 0; i < grandDaughters.size(); i++)
124 if (grandDaughters[i]->getPDG() == pdg)
126 foundParticle =
true;
128 if (grandDaughters[i]->getPDG() == -pdg)
130 foundAntiparticle =
true;
133 return foundParticle && foundAntiparticle;
138 bool MCOperator::CheckParticle(MCParticle * particle,
PDGTYPE type)
141 vector<int> pdg = ConstantStorage::GET_PDG(type);
142 for (
unsigned int i = 0; i < pdg.size(); i++)
144 if (abs(particle->getPDG()) == pdg[i])
152 bool MCOperator::CheckForColorString(EVENT::MCParticle * daughter,
int pdgOfParent)
154 vector< MCParticle * > parents = daughter->getParents();
155 if (parents.size() == 1)
157 MCParticle * parent = parents[0];
158 if (parent->getPDG() == 92)
160 vector< MCParticle * > grandParents = parent->getParents();
162 for (
unsigned int i = 0; i < grandParents.size(); i++)
164 if (abs(grandParents[i]->getPDG()) == abs(pdgOfParent))
170 streamlog_out(MESSAGE) <<
"United color string found for PDG " << pdgOfParent <<
"!\n";
179 MCParticle * MCOperator::GetConsistentDaughter(MCParticle * parent, MCParticle * service,
PDGTYPE type)
181 vector< MCParticle * > daughters = SelectDaughtersOfType(service, type);
182 streamlog_out(MESSAGE) <<
"Parent PDG: " << parent->getPDG() <<
";\n";
183 int size = daughters.size();
190 for (
int i = 0; i < size; i++)
192 MCParticle * daughter = daughters[i];
194 if (MathOperator::getModule(daughter->getMomentum()) > MathOperator::getModule(parent->getMomentum())+dE)
196 streamlog_out(MESSAGE) <<
"Discarded by energy!\n";
199 if (daughter->getCharge()*parent->getCharge() > 0.0
209 angle.push_back(MathOperator::getAngle(daughter->getMomentum(), parent->getMomentum()));
211 float minAngle = myAngleCut;
214 for (
unsigned int i = 0; i < angle.size(); i++)
217 if (angle[i] < minAngle)
230 streamlog_out(MESSAGE) <<
"INFO: Charge is wrong!\n";
233 return daughters[winner];
239 bool MCOperator::IsReconstructed(MCParticle * particle)
241 LCRelationNavigator navigator(myRelCollection);
242 vector< LCObject * > obj = navigator.getRelatedFromObjects(particle);
243 int nvtx = obj.size();
246 streamlog_out(MESSAGE) <<
"INFO: Particle not reconstructed\n";
249 const vector< float > weights = navigator.getRelatedFromWeights(particle);
253 float maxweight = 0.0;
254 for (
unsigned int j = 0; j < obj.size(); j++)
256 ReconstructedParticle * reco =
dynamic_cast< ReconstructedParticle *
>(obj[j]);
257 if (weights[j] > maxweight && std::abs(reco->getCharge()) > 0.09)
259 maxweight = weights[j];
265 return nvtx > 0 && weights[0] > 0.5;
268 PDGTYPE MCOperator::GetParticleType(MCParticle * particle)
272 for (
int i = 1; i < count; i++)
275 vector<int> pdg = ConstantStorage::GET_PDG(candidate);
276 for (
unsigned int j = 0; j < pdg.size(); j++)
278 if (abs(particle->getPDG()) == pdg[j])
288 MCParticle * MCOperator::FindExceptionalChild(MCParticle * parent,
PDGTYPE parentType)
295 vector< MCParticle * > daughters = parent->getDaughters();
296 if (daughters.size() < 1)
303 parentType = GetParticleType(parent);
306 streamlog_out(MESSAGE) <<
"ERROR: Probably, parent is not meson, to be continue....\n";
311 for (
unsigned int i = 0; i < daughters.size(); i++)
313 MCParticle * daughter = daughters.at(i);
314 if (CheckParticle(daughter,parentType))
326 for (
unsigned int i = 0; i < daughters.size(); i++)
328 MCParticle * daughter = daughters.at(i);
329 if (daughter->getEnergy() < 1.0 && daughter->getMass() < 300.0)
334 return FindExceptionalChild(daughter, parentType);
338 MCParticle * MCOperator::FindYoungestChild(MCParticle * parent,
PDGTYPE type)
345 if (type ==
TAU_LEPTON && CheckParticle(parent,type))
353 vector< MCParticle * > daughters = parent->getDaughters();
354 if (daughters.size() < 1)
356 streamlog_out(MESSAGE)<<
"ERROR: Found 0 daughters!\n";
360 MCParticle * result = NULL;
362 for (
unsigned int i = 0; i < daughters.size(); i++)
364 MCParticle * daughter = daughters.at(i);
365 if (CheckParticle(daughter,type))
376 streamlog_out(MESSAGE)<<
"FATAL: Daughter multiplicity found for meson type " << type <<
" and parent " << parent->getPDG() <<
"!\n";
382 for (
unsigned int i = 0; i < daughters.size(); i++)
384 MCParticle * daughter = daughters.at(i);
385 if (daughter->getEnergy() < 1.0 && daughter->getMass() < 300.0)
390 return FindYoungestChild(daughter, type);
394 EVENT::MCParticle * MCOperator::cureDoubleCharmDecay(std::vector< EVENT::MCParticle * > & selected)
396 MCParticleImpl * newparticle =
new MCParticleImpl();
397 newparticle->setMomentum(selected[0]->getMomentum());
398 newparticle->setMass(selected[0]->getMass());
399 newparticle->setCharge(selected[0]->getCharge());
400 newparticle->setPDG(selected[0]->getPDG() + selected[1]->getPDG());
403 vector< MCParticle * > MCOperator::SelectDaughtersOfType(MCParticle * parent,
PDGTYPE type)
405 vector< MCParticle * > daughters = parent->getDaughters();
406 vector< MCParticle * > result;
407 for (
unsigned int i = 0; i < daughters.size(); i++)
409 if (CheckParticle(daughters[i], type))
411 result.push_back(daughters[i]);
417 vector< MCParticle * > MCOperator::GetPairParticles(
int pdg)
420 vector< MCParticle * > pair;
425 int number = myCollection->getNumberOfElements();
426 MCParticle * b = NULL;
427 MCParticle * bbar = NULL;
428 for (
int i = 0; i < number; i++)
430 MCParticle * particle =
dynamic_cast<MCParticle*
>( myCollection->getElementAt(i) );
431 if (particle->getPDG() == pdg)
435 if (particle->getPDG() == -pdg)
442 pair.push_back(
new MCParticleImpl((
const IMPL::MCParticleImpl&)(*b)));
443 streamlog_out(MESSAGE)<<
"INFO: Found b!\n";
447 pair.push_back(
new MCParticleImpl((
const IMPL::MCParticleImpl&)(*bbar)));
448 streamlog_out(MESSAGE)<<
"INFO: Found bbar!\n";
452 vector< MCParticle * > MCOperator::GetPairParticles(
PDGTYPE type)
454 vector< MCParticle * > pair;
455 int number = myCollection->getNumberOfElements();
456 for (
int i = 0; i < number; i++)
458 MCParticle * particle =
dynamic_cast<MCParticle*
>( myCollection->getElementAt(i) );
459 if (CheckParticle(particle, type) && particle->getParents()[0]->getPDG() == 92)
461 pair.push_back(
new MCParticleImpl((
const IMPL::MCParticleImpl&)(*particle)));
462 streamlog_out(MESSAGE)<<
"Found a suitable particle of type " << particle->getPDG() <<
'\n';
496 vector< MCParticle * > * MCOperator::CheckProcessForPair(
int pdg)
503 MCParticle * particle = NULL;
504 MCParticle * antiparticle = NULL;
505 vector< MCParticle * > * result = NULL;
506 int number = (myCollection->getNumberOfElements() > 100)? 100 : myCollection->getNumberOfElements();
507 for (
int i = 0; i < number; i++)
509 MCParticle * candidate =
dynamic_cast<MCParticle*
>( myCollection->getElementAt(i) );
510 if (candidate->getPDG() == pdg && !particle)
512 particle = candidate;
513 streamlog_out(MESSAGE)<<
"Found a suitable particle of type " << particle->getPDG() <<
'\n';
515 if (candidate->getPDG() == -pdg && !antiparticle)
517 antiparticle = candidate;
518 streamlog_out(MESSAGE)<<
"Found a suitable particle of type " << antiparticle->getPDG() <<
'\n';
521 if (particle && antiparticle)
523 result =
new vector< MCParticle * >();
524 result->push_back(particle);
525 result->push_back(antiparticle);
529 vector< MCParticle * > MCOperator::SelectStableCloseDaughters(MCParticle * parent,
int excludePDG,
bool selectReco, vector<MCParticle *> * misReconstructed)
531 vector< MCParticle * > result;
534 parent->getPDG() == excludePDG)
538 vector< MCParticle * > daughters = parent->getDaughters();
539 if (daughters.size()<1)
543 if ( parent && MathOperator::getDistance(daughters[0]->getVertex(), parent->getVertex()) > 100.0)
545 streamlog_out(MESSAGE)<<
"WARNING: Long-lived noninteracting particle " << parent->getPDG() <<
"!\n";
548 bool finished =
false;
549 for (
unsigned int i = 0; i < daughters.size(); i++)
551 MCParticle * daughter = daughters[i];
555 if (MathOperator::getModule(daughter->getMomentum()) < 0.1)
560 if (selectReco && IsReconstructed(daughter))
562 result.push_back(daughter);
566 result.push_back(daughter);
568 if (misReconstructed && !IsReconstructed(daughter))
570 misReconstructed->push_back(daughter);
575 vector< MCParticle * > grannies = SelectStableCloseDaughters(daughter, excludePDG);
576 for (
unsigned int j = 0; j < grannies.size(); j++)
578 result.push_back(grannies[j]);
584 float MCOperator::GetAccuracy(MCParticle * particle,
float a,
float b)
586 float p = MathOperator::getModule(particle->getMomentum());
587 float m = particle->getMass();
588 float gamma = sqrt( 1 + (p * p) / (m * m));
589 vector<float> direction = MathOperator::getDirection(particle->getMomentum());
590 vector<float> angles = MathOperator::getAngles(direction);
591 float accuracy = sqrt(a*a + b*b /( p * p * pow(sin(angles[1]), 4.0/3.0)) );
592 return gamma*accuracy;
594 bool MCOperator::CheckCompatibility(
const vector< MCParticle * > & daughters, MCParticle * parent,
int plusCharge)
598 for (
unsigned int i = 0; i < daughters.size(); i++)
600 MCParticle * daughter = daughters[i];
601 mass += daughter->getMass();
602 charge += daughter->getCharge();
604 if (charge + plusCharge != (
int)(parent->getCharge()))
606 streamlog_out(MESSAGE)<<
"CAUTION: Charge is not compatible: charges " << charge <<
" and " << parent->getCharge() <<
", " << plusCharge <<
"!\n";
609 if (mass > parent->getMass())
611 streamlog_out(MESSAGE)<<
"CAUTION: Mass is not compatible!\n";
616 vector< MCParticle * > MCOperator::CheckDaughterVisibility(
const vector< MCParticle * > & daughters)
618 int size = daughters.size();
619 vector< MCParticle * > filtered;
620 for (
int i = 0; i < size; i++)
622 MCParticle * daughter = daughters[i];
623 vector< float > direction = MathOperator::getDirection(daughter->getMomentum());
624 float offset = MathOperator::getDistanceTo(myPrimaryVertex, direction, daughter->getVertex());
625 float pt = MathOperator::getPt(daughter->getMomentum());
626 float p = MathOperator::getModule(daughter->getMomentum());
627 float eta = MathOperator::getAngles(direction)[1];
628 streamlog_out(MESSAGE) <<
"\tPDG: " << daughter->getPDG()
632 <<
" offset: " << offset
634 if (offset > 0.01 && std::fabs(eta) < 4 && p > 0.6)
636 filtered.push_back(daughter);
std::string GetName() const
void Add(EVENT::MCParticle *particle)
EVENT::MCParticle * Get(int i)