8#include <analysis/dataobjects/Particle.h> 
    9#include <analysis/dataobjects/RestOfEvent.h> 
   10#include <analysis/dataobjects/ParticleExtraInfoMap.h> 
   11#include <mdst/dataobjects/MCParticle.h> 
   12#include <mdst/dataobjects/ECLCluster.h> 
   13#include <mdst/dataobjects/KLMCluster.h> 
   14#include <mdst/dataobjects/V0.h> 
   15#include <framework/datastore/StoreArray.h> 
   16#include <framework/datastore/StoreObjPtr.h> 
   17#include <framework/gearbox/Const.h> 
   18#include <framework/utilities/TestHelpers.h> 
   20#include <analysis/utility/ParticleCopy.h> 
   22#include <TDatabasePDG.h> 
   24#include <gtest/gtest.h> 
   29using namespace ROOT::Math;
 
   33  class ParticleTest : 
public ::testing::Test {
 
   39      StoreObjPtr<ParticleExtraInfoMap> particleExtraInfo;
 
   40      StoreArray<Particle> particles;
 
   41      StoreArray<MCParticle> mcparticles;
 
   42      StoreArray<RestOfEvent> roes;
 
   43      StoreArray<ECLCluster> eclClusters;
 
   44      StoreArray<KLMCluster> klmClusters;
 
   47      particles.registerInDataStore();
 
   53      particles.registerRelationTo(mcparticles);
 
   54      particles.registerRelationTo(roes);
 
   59    void TearDown()
 override 
   66  TEST_F(ParticleTest, Constructors)
 
   70      EXPECT_EQ(0, p.getPDGCode());
 
   71      EXPECT_TRUE(PxPyPzEVector(0, 0, 0, 0) == p.get4Vector());
 
   72      EXPECT_EQ(Particle::c_Undefined, p.getParticleSource());
 
   75      PxPyPzEVector momentum(1, 2, 3, 4);
 
   77      EXPECT_EQ(421, p.getPDGCode());
 
   78      EXPECT_FLOAT_EQ(0.0, momentum.phi() - p.get4Vector().phi());
 
   79      EXPECT_FLOAT_EQ(0.0, momentum.Rapidity() - p.get4Vector().Rapidity());
 
   80      EXPECT_FLOAT_EQ(momentum.energy(), p.get4Vector().energy());
 
   81      EXPECT_FLOAT_EQ(momentum.energy(), p.getEnergy());
 
   82      EXPECT_FLOAT_EQ(momentum.M(), p.getMass());
 
   83      EXPECT_EQ(Particle::c_Undefined, p.getParticleSource());
 
   86      PxPyPzEVector momentum(1, 2, 3, 4);
 
   88      EXPECT_EQ(22, p.getPDGCode());
 
   89      EXPECT_FLOAT_EQ(0.0, momentum.phi() - p.get4Vector().phi());
 
   90      EXPECT_FLOAT_EQ(0.0, momentum.Rapidity() - p.get4Vector().Rapidity());
 
   91      EXPECT_FLOAT_EQ(momentum.energy(), p.get4Vector().energy());
 
   93      EXPECT_EQ(Particle::c_MCParticle, p.getParticleSource());
 
   94      EXPECT_EQ(123u, p.getMdstArrayIndex());
 
  101      cluster->setIsTrack(
false);
 
  103      cluster->setEnergy(1337);
 
  106      EXPECT_EQ(22, p.getPDGCode());
 
  108      EXPECT_EQ(Particle::c_ECLCluster, p.getParticleSource());
 
  109      EXPECT_FLOAT_EQ(1337, p.getEnergy());
 
  110      EXPECT_EQ(cluster, p.getECLCluster());
 
  111      EXPECT_EQ(
nullptr, p.getTrack());
 
  119      PxPyPzEVector momentum(1, 2, 3, 4);
 
  121      EXPECT_EQ(310, p.getPDGCode());
 
  123      EXPECT_EQ(Particle::c_V0, p.getParticleSource());
 
  124      EXPECT_EQ(0u, p.getMdstArrayIndex());
 
  125      EXPECT_EQ(p.getV0(), v0); 
 
  129  TEST_F(ParticleTest, Daughters)
 
  131    PxPyPzEVector momentum;
 
  132    const int nDaughters = 6;
 
  134    std::vector<int> daughterIndices;
 
  135    for (
int i = 0; i < nDaughters; i++) {
 
  136      Particle d(PxPyPzEVector(1, 0, 0, 3.0), (i % 2) ? 211 : -211);
 
  137      momentum += d.get4Vector();
 
  138      Particle* newDaughters = particles.appendNew(d);
 
  143    EXPECT_EQ(411, p.getPDGCode());
 
  144    EXPECT_FLOAT_EQ(0.0, momentum.phi() - p.get4Vector().phi());
 
  145    EXPECT_FLOAT_EQ(0.0, momentum.Rapidity() - p.get4Vector().Rapidity());
 
  146    EXPECT_FLOAT_EQ(momentum.energy(), p.get4Vector().energy());
 
  148    EXPECT_EQ(Particle::c_Composite, p.getParticleSource());
 
  149    EXPECT_EQ(0u, p.getMdstArrayIndex());
 
  150    EXPECT_EQ((
unsigned int)nDaughters, p.getNDaughters());
 
  151    EXPECT_EQ((
unsigned int)nDaughters, p.getDaughters().size());
 
  152    EXPECT_EQ((
unsigned int)nDaughters, p.getFinalStateDaughters().size());
 
  153    EXPECT_EQ((
unsigned int)nDaughters, p.getDaughterProperties().size());
 
  156    EXPECT_DOUBLE_EQ(p.getMass(), pLocal.getMass());
 
  157    EXPECT_EQ((
unsigned int)nDaughters, pLocal.getNDaughters());
 
  158    EXPECT_EQ((
unsigned int)nDaughters, pLocal.getDaughters().size());
 
  159    EXPECT_EQ((
unsigned int)nDaughters, pLocal.getFinalStateDaughters().size());
 
  160    EXPECT_EQ((
unsigned int)nDaughters, pLocal.getDaughterProperties().size());
 
  167  TEST_F(ParticleTest, DaughterProperties)
 
  169    PxPyPzEVector momentum;
 
  170    const int nDaughters = 6;
 
  172    std::vector<int> daughterIndices;
 
  173    std::vector<int> daughterProperties;
 
  174    for (
int i = 0; i < nDaughters; i++) {
 
  175      Particle d(PxPyPzEVector(1, 0, 0, 3.0), (i % 2) ? 211 : -211);
 
  176      momentum += d.get4Vector();
 
  177      Particle* newDaughters = particles.appendNew(d);
 
  179      daughterProperties.push_back(Particle::PropertyFlags::c_Ordinary);
 
  183    EXPECT_EQ(411, p.getPDGCode());
 
  184    EXPECT_FLOAT_EQ(0.0, momentum.phi() - p.get4Vector().phi());
 
  185    EXPECT_FLOAT_EQ(0.0, momentum.Rapidity() - p.get4Vector().Rapidity());
 
  186    EXPECT_FLOAT_EQ(momentum.energy(), p.get4Vector().energy());
 
  188    EXPECT_EQ(Particle::c_Composite, p.getParticleSource());
 
  189    EXPECT_EQ(0u, p.getMdstArrayIndex());
 
  190    EXPECT_EQ((
unsigned int)nDaughters, p.getNDaughters());
 
  191    EXPECT_EQ((
unsigned int)nDaughters, p.getDaughters().size());
 
  192    EXPECT_EQ((
unsigned int)nDaughters, p.getFinalStateDaughters().size());
 
  193    EXPECT_EQ((
unsigned int)nDaughters, p.getDaughterProperties().size());
 
  194    EXPECT_EQ(Particle::PropertyFlags::c_Ordinary, (p.getDaughterProperties())[0]);
 
  198                          Particle::PropertyFlags::c_Ordinary, daughterProperties,
 
  200    EXPECT_DOUBLE_EQ(p.getMass(), pLocal.getMass());
 
  201    EXPECT_EQ((
unsigned int)nDaughters, pLocal.getNDaughters());
 
  202    EXPECT_EQ((
unsigned int)nDaughters, pLocal.getDaughters().size());
 
  203    EXPECT_EQ((
unsigned int)nDaughters, pLocal.getFinalStateDaughters().size());
 
  204    EXPECT_EQ((
unsigned int)nDaughters, pLocal.getDaughterProperties().size());
 
  212  struct ParticleChildrenCounter {
 
  215    bool operator()(
const Particle*) { ++count; 
return false; }
 
  218  TEST_F(ParticleTest, ForEachDaughters)
 
  221    PxPyPzEVector momentum;
 
  222    const int nDaughters = 6;
 
  224    std::vector<int> daughterIndices;
 
  225    int nGrandDaughters = 0;
 
  226    for (
int i = 0; i < nDaughters; i++) {
 
  227      Particle d(PxPyPzEVector(1, 0, 0, 3.0), (i % 2) ? 211 : -211);
 
  228      momentum += d.get4Vector();
 
  229      Particle* newDaughters = particles.appendNew(d);
 
  232        Particle* grandDaughter = particles.appendNew(d);
 
  241    auto counterFct = [&count](
const Particle*) { ++count; 
return false; };
 
  242    EXPECT_FALSE(p.forEachDaughter(counterFct, 
false, 
false));
 
  243    EXPECT_EQ(count, nDaughters);
 
  245    EXPECT_FALSE(p.forEachDaughter(counterFct, 
true, 
false));
 
  246    EXPECT_EQ(count, nDaughters + nGrandDaughters);
 
  248    EXPECT_FALSE(p.forEachDaughter(counterFct, 
false, 
true));
 
  249    EXPECT_EQ(count, nDaughters + 1);
 
  251    EXPECT_FALSE(p.forEachDaughter(counterFct, 
true, 
true));
 
  252    EXPECT_EQ(count, nDaughters + nGrandDaughters + 1);
 
  255    ParticleChildrenCounter counterStruct;
 
  256    EXPECT_FALSE(p.forEachDaughter(counterStruct));
 
  257    EXPECT_EQ(counterStruct.count, 0);
 
  259    EXPECT_FALSE(p.forEachDaughter(std::reference_wrapper<ParticleChildrenCounter>(counterStruct)));
 
  260    EXPECT_EQ(counterStruct.count, nDaughters + nGrandDaughters + 1);
 
  264    int maxchildren{1}, total{nDaughters + nGrandDaughters + 1};
 
  265    auto returnFctTester = [&count, &maxchildren](
const Particle*) {++count; 
return count >= maxchildren; };
 
  266    for (; maxchildren < 2 * total; ++maxchildren) {
 
  268      EXPECT_EQ(p.forEachDaughter(returnFctTester), maxchildren <= total);
 
  269      EXPECT_EQ(count, std::min(maxchildren, total));
 
  274  TEST_F(ParticleTest, ExtraInfo)
 
  278    EXPECT_THROW(p.getExtraInfo(
"htns"), std::runtime_error);
 
  280    p.addExtraInfo(
"htns", 32.0);
 
  283    EXPECT_THROW(p.addExtraInfo(
"htns", 1234.0), std::runtime_error);
 
  285    EXPECT_DOUBLE_EQ(32.0, p.getExtraInfo(
"htns"));
 
  290  TEST_F(ParticleTest, Copies)
 
  339                                                        Particle::c_ECLCluster,
 
  343    MC1Pion->
set4Vector(PxPyPzEVector(0, 0, 0, 0));
 
  351    EXPECT_TRUE(T1Pion->
isCopyOf(T1PionCopy));
 
  352    EXPECT_FALSE(T1Pion->
isCopyOf(T1Kaon));
 
  353    EXPECT_FALSE(T1Pion->
isCopyOf(T1Gamma));
 
  354    EXPECT_FALSE(T2Gamma->
isCopyOf(T1Gamma));
 
  357    EXPECT_TRUE(T1Pion->
isCopyOf(T1PionCopy,      
true));
 
  358    EXPECT_TRUE(T1Pion->
isCopyOf(T1Kaon,          
true));
 
  359    EXPECT_FALSE(T2Gamma->
isCopyOf(T1Gamma,       
true));
 
  360    EXPECT_TRUE(T3Gamma->
isCopyOf(T4KL,           
true));
 
  361    EXPECT_FALSE(T1PionFromMC->
isCopyOf(T1Pion, 
true));
 
  362    EXPECT_FALSE(T1Pion->
isCopyOf(T1PionFromMC, 
true));
 
  364    Particle* D0Pi1Pi2 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 421));
 
  368    Particle* D0Pi1Pi2Copy = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 421));
 
  372    Particle* D0Pi1Pi2Copy2 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 421));
 
  376    Particle* D0K1K2 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 421));
 
  380    Particle* D0K1Pi2 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 421));
 
  384    EXPECT_FALSE(D0Pi1Pi2->
isCopyOf(D0K1K2));
 
  385    EXPECT_FALSE(D0Pi1Pi2->
isCopyOf(D0K1Pi2));
 
  386    EXPECT_TRUE(D0Pi1Pi2->
isCopyOf(D0Pi1Pi2Copy));
 
  387    EXPECT_TRUE(D0Pi1Pi2->
isCopyOf(D0Pi1Pi2Copy2));
 
  388    EXPECT_TRUE(D0Pi1Pi2Copy->
isCopyOf(D0Pi1Pi2Copy2));
 
  391    Particle* D0K3K4 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 421));
 
  395    Particle* B0_1 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 511));
 
  399    Particle* B0_2 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 511));
 
  403    Particle* B0_3 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 511));
 
  411    Particle* B0_4 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 511));
 
  415    Particle* B0_5 = particles.appendNew(
Particle(PxPyPzEVector(0, 0, 0, 0), 511));
 
  425  TEST_F(ParticleTest, ExtraInfoMap)
 
  431    p.addExtraInfo(
"htns", 1.0);
 
  432    EXPECT_EQ(1u, map->getNMaps());
 
  435    p.addExtraInfo(
"somethingelse", 2.0);
 
  436    EXPECT_EQ(1u, map->getNMaps());
 
  441    EXPECT_EQ(1u, map->getNMaps());
 
  443    EXPECT_EQ(1u, map->getNMaps());
 
  446    p.addExtraInfo(
"thirdvar_p", 3.0);
 
  447    EXPECT_EQ(1u, map->getNMaps());
 
  450    EXPECT_EQ(2u, map->getNMaps());
 
  459    t.addExtraInfo(
"htns", 1.0);
 
  460    t.addExtraInfo(
"somethingelse", 2.0);
 
  461    t.addExtraInfo(
"thirdvar_q", 3.0);
 
  463    EXPECT_EQ(2u, map->getNMaps());
 
  465    EXPECT_THROW(s.
getExtraInfo(
"thirdvar_q"), std::runtime_error);
 
  466    EXPECT_THROW(t.getExtraInfo(
"thirdvar_p"), std::runtime_error);
 
  470    EXPECT_THROW(u.
getExtraInfo(
"htns"), std::runtime_error);
 
  472    EXPECT_THROW(u.
getExtraInfo(
"somethingelse"), std::runtime_error);
 
  473    EXPECT_THROW(u.
getExtraInfo(
"thirdvar_p"), std::runtime_error);
 
  474    EXPECT_THROW(u.
getExtraInfo(
"thirdvar_q"), std::runtime_error);
 
  476    EXPECT_THROW(u.
getExtraInfo(
"thirdvar_p"), std::runtime_error);
 
  477    EXPECT_THROW(u.
getExtraInfo(
"thirdvar_q"), std::runtime_error);
 
  489    EXPECT_DOUBLE_EQ(1.0, p.getExtraInfo(
"htns"));
 
  490    EXPECT_DOUBLE_EQ(2.0, p.getExtraInfo(
"somethingelse"));
 
  491    EXPECT_DOUBLE_EQ(3.0, p.getExtraInfo(
"thirdvar_p"));
 
  494    EXPECT_DOUBLE_EQ(12.0, q.
getExtraInfo(
"somethingelse"));
 
  501    EXPECT_DOUBLE_EQ(1.0, t.getExtraInfo(
"htns"));
 
  502    EXPECT_DOUBLE_EQ(2.0, t.getExtraInfo(
"somethingelse"));
 
  503    EXPECT_DOUBLE_EQ(3.0, t.getExtraInfo(
"thirdvar_q"));
 
  513    EXPECT_DOUBLE_EQ(2.0, tCopy.
getExtraInfo(
"somethingelse"));
 
  514    EXPECT_DOUBLE_EQ(3.0, tCopy.
getExtraInfo(
"thirdvar_q"));
 
  520  TEST_F(ParticleTest, ParticleCopyUtility)
 
  543                                                        Particle::c_Track, 4));
 
  546    Particle* D0KK = particles.appendNew(
Particle(PxPyPzEVector(4, 4, 4, 4), 421));
 
  550    Particle* B0 = particles.appendNew(
Particle(PxPyPzEVector(5, 5, 5, 5), 511));
 
  562    EXPECT_EQ(particles.getEntries(), 6);
 
  569    EXPECT_EQ(particles.getEntries(), 11);
 
  611    EXPECT_TRUE(mc1orig == mc1copy);
 
  612    EXPECT_TRUE(mc2orig == mc2copy);
 
  613    EXPECT_TRUE(mc3orig == mc3copy);
 
  615    EXPECT_TRUE(mc1orig->
getPDG() == mc1copy->getPDG());
 
  616    EXPECT_TRUE(mc2orig->getPDG() == mc2copy->getPDG());
 
  617    EXPECT_TRUE(mc3orig->getPDG() == mc3copy->getPDG());
 
  619    EXPECT_TRUE(roeorig->hasParticle(ROEPion) && roecopy->hasParticle(ROEPion));
 
  629    EXPECT_FALSE(mc4orig == 
nullptr);
 
  630    EXPECT_TRUE(mc4copy == 
nullptr);
 
  645    EXPECT_TRUE(mc5orig == 
nullptr);
 
  646    EXPECT_FALSE(mc5copy == 
nullptr);
 
  656  TEST_F(ParticleTest, ECLClusterBased)
 
  662      cluster->setEnergy(1.);
 
  663      cluster->setEnergyRaw(2.);
 
  666      EXPECT_FLOAT_EQ(1., p.getECLClusterEnergy());
 
  667      EXPECT_FLOAT_EQ(1., p.getEnergy());
 
  669      EXPECT_FLOAT_EQ(0, p.getMass());
 
  675      cluster->setEnergy(1.);
 
  676      cluster->setEnergyRaw(2.);
 
  679      EXPECT_EQ(130, p.getPDGCode());
 
  680      EXPECT_FLOAT_EQ(2., p.getECLClusterEnergy());
 
  681      EXPECT_FLOAT_EQ(std::sqrt(4. + 0.497614 * 0.497614), p.getEnergy());
 
  684      double m = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
 
  685      EXPECT_FLOAT_EQ(m, p.getMass());
 
  691      cluster->setEnergy(1.);
 
  692      cluster->setEnergyRaw(2.);
 
  695      EXPECT_EQ(2112, p.getPDGCode());
 
  696      EXPECT_FLOAT_EQ(2., p.getECLClusterEnergy());
 
  697      EXPECT_FLOAT_EQ(std::sqrt(4. + 0.93956536 * 0.93956536), p.getEnergy());
 
  700      double m = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
 
  701      EXPECT_FLOAT_EQ(m, p.getMass());
 
  706  TEST_F(ParticleTest, KLMClusterBased)
 
  711      cluster->setTime(1.1);
 
  712      cluster->setClusterPosition(1.1, 1.1, 1.0);
 
  713      cluster->setLayers(1);
 
  714      cluster->setInnermostLayer(1);
 
  715      cluster->setMomentumMag(1.0);
 
  719      EXPECT_EQ(pdg, p.getPDGCode());
 
  720      double m = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
 
  721      EXPECT_FLOAT_EQ(sqrt(1. + m * m), p.getEnergy());
 
  723      EXPECT_FLOAT_EQ(m, p.getMass());
 
  728      cluster->setTime(1.1);
 
  729      cluster->setClusterPosition(1.1, 1.1, 1.0);
 
  730      cluster->setLayers(1);
 
  731      cluster->setInnermostLayer(1);
 
  732      cluster->setMomentumMag(1.0);
 
  736      EXPECT_EQ(pdg, p.getPDGCode());
 
  737      double m = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
 
  738      EXPECT_FLOAT_EQ(sqrt(1. + m * m), p.getEnergy());
 
  740      EXPECT_FLOAT_EQ(m, p.getMass());
 
static const ParticleType neutron
neutron particle
static const ChargedStable pion
charged pion particle
static const ParticleType Klong
K^0_L particle.
static DataStore & Instance()
Instance of singleton Store.
void setInitializeActive(bool active)
Setter for m_initializeActive.
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
void setConnectedRegionId(int crid)
Set connected region id.
void setClusterId(int clusterid)
Set cluster id.
void setHypothesis(EHypothesisBit hypothesis)
Set hypotheses.
@ c_nPhotons
CR is split into n photons (N1)
@ c_neutralHadron
CR is reconstructed as a neutral hadron (N2)
A Class to store the Monte Carlo particle information.
void setPDG(int pdg)
Set PDG code of the particle.
int getPDG() const
Return PDG code of particle.
void set4Vector(const ROOT::Math::PxPyPzEVector &p4)
Sets the 4Vector of particle.
Class to store reconstructed particles.
void appendDaughter(const Particle *daughter, const bool updateType=true, const int daughterProperty=c_Ordinary)
Appends index of daughter to daughters index array.
bool overlapsWith(const Particle *oParticle) const
Returns true if final state ancestors of oParticle overlap.
bool isCopyOf(const Particle *oParticle, bool doDetailedComparison=false) const
Returns true if this Particle and oParticle are copies of each other.
int getPDGCode(void) const
Returns PDG code.
unsigned getNDaughters(void) const
Returns number of daughter particles.
TClonesArray * getArrayPointer() const
Returns the pointer to the store array which holds the daughter particles.
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
void addExtraInfo(const std::string &name, double value)
Sets the user-defined data of given name to the given value.
void print() const
Prints the contents of a Particle object to standard output.
@ c_Unflavored
Is its own antiparticle or we don't know whether it is a particle/antiparticle.
@ c_Flavored
Is either particle or antiparticle.
const Particle * getDaughter(unsigned i) const
Returns a pointer to the i-th daughter particle.
double getExtraInfo(const std::string &name) const
Return given value if set.
void addRelationTo(const RelationsInterface< BASE > *object, float weight=1.0, const std::string &namedRelation="") const
Add a relation from this object to another object (with caching).
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
This is a general purpose class for collecting reconstructed MDST data objects that are not used in r...
void addParticles(const std::vector< const Particle * > &particle)
Add StoreArray indices of given Particles to the list of unused particles in the event.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
Type-safe access to single objects in the data store.
Object holding information for V0s.
Functions that create copies of Particles.
Particle * copyParticle(const Particle *original)
Function takes argument Particle and creates a copy of it and copies of all its (grand-)^n-daughters.
Abstract base class for different kinds of events.