diff --git a/Generators/TruthUtils/CMakeLists.txt b/Generators/TruthUtils/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7e05a94e31ae6754d3961b6cfbb55a992a9aa264 --- /dev/null +++ b/Generators/TruthUtils/CMakeLists.txt @@ -0,0 +1,22 @@ +################################################################################ +# Package: TruthUtils +################################################################################ + +# Declare the package name: +atlas_subdir( TruthUtils ) + +# External dependencies: +find_package( Boost COMPONENTS filesystem thread system ) +find_package( FastJet ) +find_package( HEPUtils ) +find_package( HepMC ) +find_package( MCUtils ) +find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread ) + +# Component(s) in the package: +atlas_add_library( TruthUtils + Root/*.cxx + PUBLIC_HEADERS TruthUtils + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} ${HEPUTILS_INCLUDE_DIRS} ${MCUTILS_INCLUDE_DIRS} ${HEPMC_INCLUDE_DIRS} ${FASTJET_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${ROOT_LIBRARIES} ${HEPUTILS_LIBRARIES} ${MCUTILS_LIBRARIES} ${HEPMC_LIBRARIES} ${FASTJET_LIBRARIES} ) + diff --git a/Generators/TruthUtils/Root/GeneratorName.cxx b/Generators/TruthUtils/Root/GeneratorName.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f7fb8b65401600c30bf90670a8339075bcad2a22 --- /dev/null +++ b/Generators/TruthUtils/Root/GeneratorName.cxx @@ -0,0 +1,206 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TruthUtils/GeneratorName.h" +#include <iostream> +#include <algorithm> + +/// @todo This scheme doesn't work anymore... + +GeneratorName generator_name (const int& index) { + switch (index) { + //new scheme for first generators + case 110000000 : return PYTHIA; + case 20000000 : return HERWIG; + case 30000000 : return ISAJET; + case 40000000 : return SINGLE; + case 50000000 : return HIJING; + case 60000000 : return PHOJET; + case 70000000 : return Sherpa; + case 80000000 : return CASCADE; + case 90000000 : return JIMMY; + case 100000000 : return HYDJET; + // note 110000000 used for PYTHIA + case 120000000 : return EPOS; + case 100000 : return COMPHEP; + // case 150000 : return CHARYBDIS; + case 200000 : return USER; + case 300000 : return ACERMC; + case 400000 : return ALPGEN; + case 500000 : return MADGRAPH; + case 600000 : return MADCUP; + case 700000 : return TOPREX; + case 800000 : return LHAEXT; + case 900000 : return MCATNLO; + // new second generators in a new scheme + case 1001000000 : return CHARYBDIS; + case 1001100000 : return HORACE; + case 1001200000 : return LHEF; + case 1001300000 : return MATCHIG; + case 1001400000 : return HVGEN; + case 1001500000 : return EXOGRAVITON; + case 1001600000 : return PYTHIABC; + case 1001700000 : return PROTOS; + case 1001800000 : return GRAVADD; + case 1001900000 : return HELAC; + case 1002000000 : return PYTHIASGLUON; + // third generators + case 10000 : return TAUOLA; + case 20000 : return PHOTOS; + case 30000 : return TAUOLA_PHOTOS; + } + return UNKNOWN; +} + + +GeneratorName first_generator(const int& index) { + int gen1; + if (isNewGenCoding(index)) { + gen1 = 10000000*(index/10000000); + if (gen1 >= 1000000000) gen1=gen1-1000000000; + } else{ + // Extract the first generator int representation (/1000000 *1000000) + // and convert to a new scheme (*10) + gen1 = 10000000*(index/1000000); + //special treatment for PYTHIA, as the coding is not standard + if (gen1 == 10000000) gen1=110000000; + } + return generator_name(gen1); +} + +GeneratorName second_generator(const int& index) { + int gen1,gen2; + if (isNewGenCoding(index)){ + gen1 = first_generator(index); + gen2 = index - gen1; + gen2 = 100000*(gen2/100000); + // if (gen2==100000 && (gen1==2000000 || gen1==9000000)) gen2 += 50000; + } else{ + gen1 = 1000000*(index/1000000); + gen2 = index - gen1; + gen2 = 100000*(gen2/100000); + } + return generator_name(gen2); +} + + +GeneratorName third_generator(const int& index) { + int gen1,gen2,gen3; + if (isNewGenCoding(index)){ + gen1 = first_generator(index); + gen2 = second_generator(index); + gen3 = index - gen1 - gen2; + gen3 = 10000*(gen3/10000); + } else{ + gen1 = 1000000*(index/1000000); + gen2 = index - gen1; + gen2 = 100000*(gen2/100000); + gen3 = index - gen1 - gen2; + gen3 = 10000*(gen3/10000); + } + return generator_name(gen3); +} + + +int generator_process(int& index) { return index % 10000; } + +void GeneratorName_print(int& id) { + std::cout << first_generator(id) << " " + << second_generator(id) << " " + << third_generator(id) << " + " + << generator_process(id); +} + +std::string generator_string(const int& index) { + switch (index) { + case 110000000 : return "PYTHIA"; + case 20000000 : return "HERWIG"; + case 30000000 : return "ISAJET"; + case 40000000 : return "SINGLE"; + case 50000000 : return "HIJING"; + case 60000000 : return "PHOJET"; + case 70000000 : return "Sherpa"; + case 80000000 : return "CASCADE"; + case 90000000 : return "JIMMY"; + case 100000000 : return "HYDJET"; + case 120000000 : return "EPOS"; + case 100000 : return "COMPHEP"; + // case 150000 : return "CHARYBDIS"; + case 200000 : return "USER"; + case 300000 : return "ACERMC"; + case 400000 : return "ALPGEN"; + case 500000 : return "MADGRAPH"; + case 600000 : return "MADCUP"; + case 700000 : return "TOPREX"; + case 800000 : return "LHAEXT"; + case 900000 : return "MCATNLO"; + case 1001000000 : return "CHARYBDIS"; + case 1001100000 : return "HORACE"; + case 1001200000 : return "LHEF"; + case 1001300000 : return "MATCHIG"; + case 1001400000 : return "HVGEN"; + case 1001500000 : return "EXOGRAVITON"; + case 1001600000 : return "PYTHIABC"; + case 1001700000 : return "PROTOS"; + case 1001800000 : return "GRAVADD"; + case 1001900000 : return "HELAC"; + case 1002000000 : return "PYTHIASGLUON"; + case 10000 : return "TAUOLA"; + case 20000 : return "PHOTOS"; + case 30000 : return "TAUOLA_PHOTOS"; + } + return ""; +} + +int generator_int (std::string& name) { + /// @note Sherpa cannot be written with capital letters as it interferes with the namespace name from external Sherpa package. EML 11.12.2008 + if (name == "sherpa") name = "Sherpa"; + else transform(name.begin(), name.end(), name.begin(), toupper); + if ( name == "PYTHIA" ) return 110000000; + if ( name == "HERWIG" ) return 20000000; + if ( name == "ISAJET" ) return 30000000; + if ( name == "SINGLE" ) return 40000000; + if ( name == "HIJING" ) return 50000000; + if ( name == "PHOJET" ) return 60000000; + if ( name == "Sherpa" ) return 70000000; + if ( name == "CASCADE" ) return 80000000; + if ( name == "JIMMY" ) return 90000000; + if ( name == "HYDJET" ) return 100000000; + if ( name == "EPOS" ) return 120000000; + if ( name == "COMPHEP" ) return 100000; + // if ( name == "CHARYBDIS" ) return 150000; + if ( name == "USER" ) return 200000; + if ( name == "ACERMC" ) return 300000; + if ( name == "ALPGEN" ) return 400000; + if ( name == "MADGRAPH" ) return 500000; + if ( name == "MADCUP" ) return 600000; + if ( name == "TOPREX" ) return 700000; + if ( name == "LHAEXT" ) return 800000; + if ( name == "MCATNLO" ) return 900000; + if ( name == "CHARYBDIS" ) return 1001000000; + if (name == "HORACE" ) return 1001100000; + if (name == "LHEF") return 1001200000; + if (name == "MATCHIG") return 1001300000; + if (name == "HVGEN") return 1001400000; + if (name == "EXOGRAVITON") return 1001500000; + if (name == "PYTHIABC") return 1001600000; + if (name == "PROTOS") return 1001700000; + if (name == "GRAVADD") return 1001800000; + if (name == "HELAC") return 1001900000; + if (name == "PYTHIASGLUON") return 1002000000; + if ( name == "TAUOLA" ) return 10000; + if ( name == "PHOTOS" ) return 20000; + if ( name == "TAUOLA_PHOTOS" ) return 30000; + return -999; +} + +std::ostream& operator<<(std::ostream& lhs, GeneratorName rhs) { + lhs << generator_string(rhs); + return lhs; +} + +bool isNewGenCoding(const int& index) { + if (index < 20000000) return false; + else return true; +} diff --git a/Generators/TruthUtils/TruthUtils/GeneratorName.h b/Generators/TruthUtils/TruthUtils/GeneratorName.h new file mode 100644 index 0000000000000000000000000000000000000000..9f702d852c3009f3322c4ae190261fe96b7d500a --- /dev/null +++ b/Generators/TruthUtils/TruthUtils/GeneratorName.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TRUTHUTILS_GENERATORNAME_H +#define TRUTHUTILS_GENERATORNAME_H + +#include <iosfwd> +#include <string> + +/// @file GeneratorName.h +/// @brief Enum and tools for decoding generator information from the process code -- yuck! +/// @todo This thing is a mess that completely breaks down with LHE files and new gens. REMOVE! + + +/// @note Sherpa cannot be used with capital letters as it interferes with the namespace name from external Sherpa package. +/// @note New generators need to be added in genames.inc too EML 12.12.2008 +/// @note PYTHIA instead of a special number 1010000000 is now 110000000 (the special number may be used when we run out of other numbers) EML 19.01.2009 +enum GeneratorName { + /* + PYTHIA = 1000000, + HERWIG = 2000000, + ISAJET = 3000000, + SINGLE = 4000000, + HIJING = 5000000, + PHOJET = 6000000, + Sherpa = 7000000, + CASCADE = 8000000, + JIMMY = 9000000, + HYDJET = 10000000, + */ + // first generators - new scheme + PYTHIA = 110000000, + HERWIG = 20000000, + ISAJET = 30000000, + SINGLE = 40000000, + HIJING = 50000000, + PHOJET = 60000000, + Sherpa = 70000000, + CASCADE = 80000000, + JIMMY = 90000000, + HYDJET = 100000000, + // note 110000000 used for PYTHIA + EPOS = 120000000, + + // second generators + COMPHEP = 100000, + // CHARYBDIS = 150000, + USER = 200000, + ACERMC = 300000, + ALPGEN = 400000, + MADGRAPH = 500000, + MADCUP = 600000, + TOPREX = 700000, + LHAEXT = 800000, + MCATNLO = 900000, + // new second generators - new scheme + CHARYBDIS = 1001000000, + HORACE = 1001100000, + LHEF = 1001200000, + MATCHIG = 1001300000, + HVGEN = 1001400000, + EXOGRAVITON = 1001500000, + PYTHIABC = 1001600000, + PROTOS = 1001700000, + GRAVADD = 1001800000, + HELAC = 1001900000, + PYTHIASGLUON = 1002000000, + + // third generators + TAUOLA = 10000, + PHOTOS = 20000, + TAUOLA_PHOTOS = 30000, + UNKNOWN = -999 +}; + + +GeneratorName generator_name(const int& index); +GeneratorName first_generator(const int& index); +GeneratorName second_generator(const int& index); +GeneratorName third_generator(const int& index); + +int generator_process(int& index); + +void GeneratorName_print(int& id); +std::string generator_string(const int& index); +int generator_int(std::string& name); + +std::ostream &operator<< (std::ostream& lhs, GeneratorName rhs); +bool isNewGenCoding(const int& index); + + +#endif // GENERATORMODULES_GENERATORNAME_H diff --git a/Generators/TruthUtils/TruthUtils/HepMCHelpers.h b/Generators/TruthUtils/TruthUtils/HepMCHelpers.h new file mode 100644 index 0000000000000000000000000000000000000000..27964dc5a2f374c9ebc157a3a4b99f1627602ec3 --- /dev/null +++ b/Generators/TruthUtils/TruthUtils/HepMCHelpers.h @@ -0,0 +1,96 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#pragma once + +/// @file +/// +/// Provides the HepMC tools from the external MCUtils header package, +/// ATLAS-specific HepMC functions not suitable for MCUtils. + +#include "TruthUtils/PIDHelpers.h" +#include "TruthUtils/TruthParticleHelpers.h" +#include "MCUtils/HepMCUtils.h" +// #include "MCUtils/Clustering.h" + +// Common imports from external namespaces +using HepMC::GenEvent; +using HepMC::GenParticle; +using HepMC::GenVertex; +//using fastjet::PseudoJet; +//using fastjet::ClusterSequence; + +// Alias BOOST_FOREACH as foreach in this semi-safe way +#include <boost/foreach.hpp> +#ifndef foreach +namespace boost { namespace BOOST_FOREACH = foreach; } +#define foreach BOOST_FOREACH +#endif + + +namespace MC { + + // Use the MCUtils and HEPUtils functions as if they were defined in the ATLAS MC and MC::PID namespaces + using namespace MCUtils; + using namespace HEPUtils; + + + /// @name Extra ATLAS-specific particle classifier functions + //@{ + + /// @brief Determine if the particle is stable at the generator (not det-sim) level, + /// + /// The receipe for this is barcode < 200k and status = 1. Gen-stable particles decayed by + /// G4 are not set to have status = 2 in ATLAS, but simply have more status = 1 children, + /// with barcodes > 200k. + inline bool isGenStable(const HepMC::GenParticle* p) { + return isGenStable(p->status(), p->barcode()); + } + + + /// @todo There are many kinds of stable: stable from generator, stable at intermediate stage of det sim transport, or stable after all det sim. Need fns for each? + + + /// @brief Identify if the particle is considered stable at the post-detector-sim stage + inline bool isSimStable(const HepMC::GenParticle* p) { + if (p->status() != 1) return false; + if (isGenStable(p)) return p->end_vertex() == NULL; + return true; + } + + /// @brief Identify if the particle is considered stable at the post-detector-sim stage + /// @todo I'm sure this shouldn't be exactly the same as isGenStable, but it is... + /// @deprecated Use isSimulStable: this function _will_ be removed! + inline bool isGenSimulStable(const HepMC::GenParticle* p) { + return isSimStable(p); + } + + + /// @brief Identify if the particle would not interact with the detector, i.e. not a neutrino or WIMP + inline bool isNonInteracting(const HepMC::GenParticle* p) { + return MC::isNonInteracting(p->pdg_id()); //< From TruthUtils/PIDHelpers.h + } + + /// @brief Identify if the particle could interact with the detector during the simulation, e.g. not a neutrino or WIMP + /// @todo This one can't be made to only take a PDG ID argument since it needs to check gen-stability via status & decay links + // inline bool isSimInteracting(int pid) { + // if (! MC::isGenStable(pid)) return false; //skip particles which the simulation would not see + // return !MC::isNonInteracting(pid); + // } + /// @brief Identify if the particle could interact with the detector during the simulation, e.g. not a neutrino or WIMP + inline bool isSimInteracting(const HepMC::GenParticle* p) { + if (! MC::isGenStable(p)) return false; //skip particles which the simulation would not see + return !MC::isNonInteracting(p); + } + + /// @brief Oddly-named alias for isSimInteracting + /// @deprecated Use isSimInteracting: this function _will_ be removed! + inline bool isGenInteracting(const HepMC::GenParticle* p) { + return isSimInteracting(p); + } + + //@} + + +} diff --git a/Generators/TruthUtils/TruthUtils/PIDHelpers.h b/Generators/TruthUtils/TruthUtils/PIDHelpers.h new file mode 100644 index 0000000000000000000000000000000000000000..b10272803c4e193b0cbbc888ae09ace530319a89 --- /dev/null +++ b/Generators/TruthUtils/TruthUtils/PIDHelpers.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#pragma once + +/// @file +/// +/// PID-only functions with no HepMC dependence, both from MCUtils and ATLAS-specific. + +#include "MCUtils/PIDUtils.h" + +namespace MC { + + // Use the MCUtils and HEPUtils functions as if they were defined in the ATLAS MC and MC::PID namespaces + using namespace MCUtils; + using namespace HEPUtils; + + + /// @brief Identify if the particle with given PDG ID would not interact with the detector, i.e. not a neutrino or WIMP + inline bool isNonInteracting(int pid) { + return !(PID::isStrongInteracting(pid) || PID::isEMInteracting(pid)); + } + + + /// @brief Identify if the particle with given PDG ID would produce ID tracks but not shower in the detector if stable + inline bool isChargedNonShowering(int pid) { + if (PID::isMuon(pid)) return true; + if (PID::isSUSY(pid)) return true; //(meta)stable charginos, R-hadrons etc + return false; + } + +} diff --git a/Generators/TruthUtils/TruthUtils/TruthParticleHelpers.h b/Generators/TruthUtils/TruthUtils/TruthParticleHelpers.h new file mode 100644 index 0000000000000000000000000000000000000000..22a9ff510fc3f50f42fa20adc8295c7f392bcef6 --- /dev/null +++ b/Generators/TruthUtils/TruthUtils/TruthParticleHelpers.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#pragma once + +/// @file +/// +/// Provides the HepMC tools from the external MCUtils header package, +/// ATLAS-specific HepMC functions not suitable for MCUtils. + +#include "TruthUtils/PIDHelpers.h" + +namespace MC { + + // Use the MCUtils and HEPUtils functions as if they were defined in the ATLAS MC and MC::PID namespaces + using namespace MCUtils; + using namespace HEPUtils; + + + /// @brief Constant defining the barcode threshold distinguishing generator record entries from detector sim ones + /// @todo The sim barcodes start at 1M in MC15, so we should update the 200k threshold, + /// but >= 200k is still a valid test for b = 1M so let's keep it this way until MC12 is long-dead. + const int SIM_BARCODE_THRESHOLD = 200000; + + + /// @name Extra ATLAS-specific particle classifier functions + //@{ + + /// @brief Determine if the particle is stable at the generator (not det-sim) level, + /// + /// The receipe for this is barcode < 200k and status = 1. Gen-stable particles decayed by + /// G4 are not set to have status = 2 in ATLAS, but simply have more status = 1 children, + /// with barcodes > 200k. + inline bool isGenStable(int status, int barcode) { + if (status != 1) return false; + return barcode < SIM_BARCODE_THRESHOLD; + } + + //@} + + +} diff --git a/Generators/TruthUtils/cmt/Makefile.RootCore b/Generators/TruthUtils/cmt/Makefile.RootCore new file mode 100644 index 0000000000000000000000000000000000000000..fb79602e0c08ab4c09763cb558ec32602f05eaae --- /dev/null +++ b/Generators/TruthUtils/cmt/Makefile.RootCore @@ -0,0 +1,24 @@ +# this makefile also gets parsed by shell scripts +# therefore it does not support full make syntax and features +# edit with care + +# for full documentation check: +# https://twiki.cern.ch/twiki/bin/viewauth/Atlas/RootCore#Package_Makefile + +PACKAGE = TruthUtils +PACKAGE_PRELOAD = +PACKAGE_CXXFLAGS = +PACKAGE_OBJFLAGS = +PACKAGE_LDFLAGS = +PACKAGE_BINFLAGS = +PACKAGE_LIBFLAGS = +PACKAGE_DEP = Asg_Boost +PACKAGE_TRYDEP = +PACKAGE_CLEAN = +PACKAGE_NOGRID = +PACKAGE_PEDANTIC = 0 +PACKAGE_NOOPT = 0 +PACKAGE_NOCC = 0 +PACKAGE_REFLEX = 0 + +include $(ROOTCOREDIR)/Makefile-common diff --git a/Generators/TruthUtils/cmt/requirements b/Generators/TruthUtils/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..16a8a9a5b757572ce10c6e6d8c25cece53811831 --- /dev/null +++ b/Generators/TruthUtils/cmt/requirements @@ -0,0 +1,14 @@ +package TruthUtils + +author Andy Buckley + +use AtlasPolicy AtlasPolicy-* +use AtlasHepMC AtlasHepMC-* External +use AtlasBoost AtlasBoost-* External +use AtlasFastJet AtlasFastJet-* External +use AtlasROOT AtlasROOT-* External +use MCUtils MCUtils-* External +use HEPUtils HEPUtils-* External + +library TruthUtils ../Root/*.cxx +apply_pattern installed_library diff --git a/Projects/Calypso/package_filters.txt b/Projects/Calypso/package_filters.txt index 1eaecdb54f06cd6c309f009f84ae1e0bffa5ddb1..5e7804ee05b89fabc0506e40320b750890cb10c7 100644 --- a/Projects/Calypso/package_filters.txt +++ b/Projects/Calypso/package_filters.txt @@ -9,4 +9,4 @@ - Database/.* - DetectorDescription/.* - Scintillator/.* -- Tracker/TrackerDetDescr/.* \ No newline at end of file +- Tracker/.* \ No newline at end of file diff --git a/xAOD/xAODBase/CMakeLists.txt b/xAOD/xAODBase/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..866ebe3bf79054080bdd85fed766f956f862ee4c --- /dev/null +++ b/xAOD/xAODBase/CMakeLists.txt @@ -0,0 +1,42 @@ +# $Id: CMakeLists.txt 744422 2016-05-03 11:34:39Z krasznaa $ +################################################################################ +# Package: xAODBase +################################################################################ + +# Declare the package name: +atlas_subdir( xAODBase ) + +# Extra dependencies based on what environment we are in: +if( NOT XAOD_STANDALONE ) + set( extra_deps Control/SGTools ) + set( extra_libs SGTools ) +endif() + +# Declare the package's dependencies: +atlas_depends_on_subdirs( + PUBLIC + Control/AthContainers + ${extra_deps} + PRIVATE + Control/AthLinks ) + +# External dependencies: +find_package( ROOT COMPONENTS Core Physics ) + +# Component(s) in the package: +atlas_add_library( xAODBase + xAODBase/*.h Root/*.cxx + PUBLIC_HEADERS xAODBase + INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} + LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers ${extra_libs} + PRIVATE_LINK_LIBRARIES AthLinks ) + +atlas_add_dictionary( xAODBaseDict + xAODBase/xAODBaseDict.h + xAODBase/selection.xml + LINK_LIBRARIES xAODBase ) + +# Test(s) in the package: +atlas_add_test( ut_xAODObjectType_test + SOURCES test/ut_xAODObjectType_test.cxx + LINK_LIBRARIES xAODBase ) diff --git a/xAOD/xAODBase/Root/IParticleHelpers.cxx b/xAOD/xAODBase/Root/IParticleHelpers.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1350ca88bb59ed6d4de2d8993edd7ea3ea645aa5 --- /dev/null +++ b/xAOD/xAODBase/Root/IParticleHelpers.cxx @@ -0,0 +1,161 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IParticleHelpers.cxx 700032 2015-10-12 11:38:33Z krasznaa $ + +// System include(s): +#include <iostream> + +// EDM include(s): +#include "AthLinks/ElementLink.h" + +// Local include(s): +#include "xAODBase/IParticleHelpers.h" + +namespace xAOD { + + /// Object used for setting/getting the dynamic decoration in question + static SG::AuxElement::Accessor< ElementLink< IParticleContainer > > + acc( "originalObjectLink" ); + + /// This function should be used by CP tools when they make a deep copy + /// of an object in their correctedCopy(...) function. So that the deep + /// copy would hold an ElementLink pointing back to its original, which + /// the MET calculations can use later on. + /// + /// @param original Reference to the original object + /// @param copy Reference to the (deep/shallow) copy of the original object + /// @returns <code>true</code> if the link setting was successful, + /// <code>false</code> if it wasn't + /// + bool setOriginalObjectLink( const IParticle& original, + IParticle& copy ) { + + // We mustn't check for the availability of the decoration on the copied + // object here. Since if the copy is already part of a container, the + // decoration may well exist on it already. But it will not be set to + // anything meaningful yet. + + // Check if the original is part of a container. If not, we can't set + // up a link. + const IParticleContainer* container = + dynamic_cast< const IParticleContainer* >( original.container() ); + if( ! container ) { + std::cerr << "xAOD::setOriginalObjectLink ERROR Original object is " + << "not part of a container" << std::endl; + return false; + } + + // Construct the ElementLink that points back to the original. + // We have to be tricky here. The original itself may already be a + // copy. In which case the new object should point back to the same + // original that "our original" is pointing to. + const ElementLink< IParticleContainer > link = + ( acc.isAvailable( original ) ? + acc( original ) : + ElementLink< IParticleContainer >( *container, original.index() ) ); + + // Now set this link on the copy: + acc( copy ) = link; + + // We were successful: + return true; + } + + /// This function should be used by the users when they make deep/shallow + /// copies of an entire container. It sets up links from all the copied + /// object to their originals. So in later stages of the analysis one can + /// navigate back to them. (This is mostly necessary for proper MET + /// handling.) + /// + /// This function assumes that the original container is *not* a view + /// container, to be able to optimise the code a bit. If you want to use + /// a view container, loop over its elements by hand, and use the version + /// of this function operating on individual xAOD::IParticle objects. + /// + /// @param original Reference to the original container + /// @param copy Reference to the (deep/shallow) copy of the original + /// container + /// @returns <code>true</code> if the link setting was successful, + /// <code>false</code> if it wasn't + /// + bool setOriginalObjectLink( const IParticleContainer& original, + IParticleContainer& copy ) { + + // Check that the containers are of the same size: + if( original.size() != copy.size() ) { + std::cerr << "xAOD::setOriginalObjectLink ERROR Size of original " + << "and copy containers differs" << std::endl; + return false; + } + + // Make sure that the original is not a view container. As the function + // doesn't work correctly for those. + if( original.ownPolicy() != SG::OWN_ELEMENTS ) { + std::cerr << "xAOD::setOriginalObjectLink ERROR Received a view " + << "container" << std::endl; + return false; + } + + // If the containers are empty, we're done: + if( ! copy.size() ) { + return true; + } + + // Create an ElementLink to the first element in the original container. + // To be able to re-use the hashed key of this object in the loop. + const ElementLink< IParticleContainer > refLink( original, 0 ); + + // Loop over the copied container: + IParticleContainer::const_iterator orig_itr = original.begin(); + IParticleContainer::const_iterator orig_end = original.end(); + IParticleContainer::iterator copy_itr = copy.begin(); + // To speed up the loop over large containers a bit, make the decision + // about how to create the links, just once: + if( acc.isAvailable( **orig_itr ) ) { + for( ; orig_itr != orig_end; ++orig_itr, ++copy_itr ) { + // Copy the variable from the original object: + acc( **copy_itr ) = acc( **orig_itr ); + } + } else { + for( ; orig_itr != orig_end; ++orig_itr, ++copy_itr ) { + // Construct the link from scratch: + acc( **copy_itr ) = + ElementLink< IParticleContainer >( refLink.key(), + ( *orig_itr )->index() ); + } + } + + // We were successful: + return true; + } + + /// This function can be used to conveniently get a pointer back to the + /// original object from which a copy was created. If there is no such + /// parent, the function silently returns a null pointer. + /// + /// @param copy The object that should have a parent set on it + /// @returns A pointer to the objects parent if it exists and its available, + /// a null pointer otherwise + /// + const IParticle* getOriginalObject( const IParticle& copy ) { + + // Check if the decoration is available on the object: + if( ! acc.isAvailable( copy ) ) { + return 0; + } + + // Get the link: + const ElementLink< IParticleContainer >& link = acc( copy ); + + // Check if the link is valid: + if( ! link.isValid() ) { + return 0; + } + + // Apparently all is fine: + return *link; + } + +} // namespace xAOD diff --git a/xAOD/xAODBase/Root/ObjectType.cxx b/xAOD/xAODBase/Root/ObjectType.cxx new file mode 100644 index 0000000000000000000000000000000000000000..cfb84e6853322278fd337c620b1657aa403df6a4 --- /dev/null +++ b/xAOD/xAODBase/Root/ObjectType.cxx @@ -0,0 +1,53 @@ +// System include(s): +#include <iostream> + +// Local include(s): +#include "xAODBase/ObjectType.h" + +/// Helper macro for printing the object type as a string +#define PRINT_TYPE( TYPE ) \ + case TYPE: \ + out << #TYPE; \ + break + +/// This function can be used in (debug) printouts to easily show the type +/// name returned by an object. +/// +/// @param out The STL stream to print to +/// @param type The type whose name to print in the stream +/// @returns The same stream that it received +/// +std::ostream& operator<< ( std::ostream& out, xAOD::Type::ObjectType type ) { + + switch( type ) { + + PRINT_TYPE( xAOD::Type::Other ); + + PRINT_TYPE( xAOD::Type::CaloCluster ); + PRINT_TYPE( xAOD::Type::Track ); + PRINT_TYPE( xAOD::Type::NeutralParticle ); + PRINT_TYPE( xAOD::Type::Electron ); + PRINT_TYPE( xAOD::Type::Photon ); + PRINT_TYPE( xAOD::Type::Muon ); + + PRINT_TYPE( xAOD::Type::Vertex ); + + PRINT_TYPE( xAOD::Type::TruthParticle ); + PRINT_TYPE( xAOD::Type::TruthVertex ); + PRINT_TYPE( xAOD::Type::TruthEvent ); + PRINT_TYPE( xAOD::Type::TruthPileupEvent ); + + PRINT_TYPE( xAOD::Type::EventInfo ); + PRINT_TYPE( xAOD::Type::EventFormat ); + + PRINT_TYPE( xAOD::Type::Particle ); + PRINT_TYPE( xAOD::Type::CompositeParticle ); + + default: + out << "UNKNOWN"; + break; + } + + // Return the stream object: + return out; +} diff --git a/xAOD/xAODBase/cmt/Makefile.RootCore b/xAOD/xAODBase/cmt/Makefile.RootCore new file mode 100644 index 0000000000000000000000000000000000000000..eb90d13563386d545435fa7d02ac78ecb49f14db --- /dev/null +++ b/xAOD/xAODBase/cmt/Makefile.RootCore @@ -0,0 +1,24 @@ +# this makefile also gets parsed by shell scripts +# therefore it does not support full make syntax and features +# edit with care + +# for full documentation check: +# https://twiki.cern.ch/twiki/bin/viewauth/Atlas/RootCore#Package_Makefile + +PACKAGE = xAODBase +PACKAGE_PRELOAD = Physics +PACKAGE_CXXFLAGS = +PACKAGE_OBJFLAGS = +PACKAGE_LDFLAGS = +PACKAGE_BINFLAGS = +PACKAGE_LIBFLAGS = +PACKAGE_DEP = AthContainers AthLinks +PACKAGE_TRYDEP = +PACKAGE_CLEAN = +PACKAGE_NOGRID = +PACKAGE_PEDANTIC = 1 +PACKAGE_NOOPT = 0 +PACKAGE_NOCC = 0 +PACKAGE_REFLEX = 1 + +include $(ROOTCOREDIR)/Makefile-common diff --git a/xAOD/xAODBase/cmt/requirements b/xAOD/xAODBase/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..8886e2cbdd84e4aa42f6de90907e8bd7041cdbcf --- /dev/null +++ b/xAOD/xAODBase/cmt/requirements @@ -0,0 +1,31 @@ +package xAODBase +# $Id: requirements 744422 2016-05-03 11:34:39Z krasznaa $ +# + +author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + +# Base package(s): +use AtlasPolicy AtlasPolicy-* +use AtlasROOT AtlasROOT-* External +use SGTools SGTools-* Control + +# EDM package(s): +use AthContainers AthContainers-* Control + +apply_tag ROOTMathLibs + +library xAODBase ../Root/*.cxx +apply_pattern installed_library + +private + +use AtlasReflex AtlasReflex-* External +use AthLinks AthLinks-* Control + +apply_pattern lcgdict dict=xAODBase selectionfile=selection.xml \ + headerfiles="../xAODBase/xAODBaseDict.h" + +# Set up the test(s): +use TestTools TestTools-* AtlasTest + +apply_pattern UnitTest_run unit_test=ut_xAODObjectType diff --git a/xAOD/xAODBase/doc/mainpage.h b/xAOD/xAODBase/doc/mainpage.h new file mode 100644 index 0000000000000000000000000000000000000000..a13fe15701e55beb5a1a9297a4c112b09131119d --- /dev/null +++ b/xAOD/xAODBase/doc/mainpage.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** + @mainpage xAODBase package + + @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + + $Revision: 567380 $ + $Date: 2013-10-28 11:48:26 +0100 (Mon, 28 Oct 2013) $ + + @section xAODBaseOverview Overview + + This is the most base-package of the xAOD EDM. It defines general + interfaces that are used in all parts of the xAOD code. + + @section xAODBaseClasses Main Types + + The main enumerations, definitions and classes of the package are + the following: + - xAOD::Type::ObjectType: Enumeration describing all major xAOD + object types. + - xAOD::IParticle: Interface for all particle-like EDM classes + - xAOD::IParticleContainer: Base class for all the particle-like + containers in the xAOD EDM. + + @htmlinclude used_packages.html + + @include requirements +*/ diff --git a/xAOD/xAODBase/share/ut_xAODObjectType_test.ref b/xAOD/xAODBase/share/ut_xAODObjectType_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..4b97169887aa3febeae8301c2d28af06d3419ad0 --- /dev/null +++ b/xAOD/xAODBase/share/ut_xAODObjectType_test.ref @@ -0,0 +1,2 @@ +xAOD::Type::Track, xAOD::Type::CaloCluster +UNKNOWN diff --git a/xAOD/xAODBase/test/ut_xAODObjectType_test.cxx b/xAOD/xAODBase/test/ut_xAODObjectType_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..14e31e0ab642450876e904246b94510a34cdbde3 --- /dev/null +++ b/xAOD/xAODBase/test/ut_xAODObjectType_test.cxx @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: ut_xAODObjectType_test.cxx 618658 2014-09-26 09:31:10Z krasznaa $ +// +// This is an extremely simple test to check the health of the output operator +// defined in xAODBase/ObjectType.h. +/// + +// System include(s): +#include <iostream> + +// Local include(s): +#include "xAODBase/ObjectType.h" + +int main() { + + // Print some random values: + std::cout << xAOD::Type::Track << ", " << xAOD::Type::CaloCluster + << std::endl; + std::cout << static_cast< xAOD::Type::ObjectType >( 1500 ) << std::endl; + + // Return gracefully: + return 0; +} diff --git a/xAOD/xAODBase/xAODBase/IParticle.h b/xAOD/xAODBase/xAODBase/IParticle.h new file mode 100644 index 0000000000000000000000000000000000000000..97e598ef97a242465ccf80cae6c8674f85eddf59 --- /dev/null +++ b/xAOD/xAODBase/xAODBase/IParticle.h @@ -0,0 +1,169 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IParticle.h 604340 2014-07-01 04:04:52Z ssnyder $ +#ifndef XAODBASE_IPARTICLE_H +#define XAODBASE_IPARTICLE_H + +// ROOT include(s): +#include <TLorentzVector.h> + +// EDM include(s): +#include "AthContainers/AuxElement.h" + +// Local include(s): +#include "ObjectType.h" + +/// Namespace holding all the xAOD EDM classes +namespace xAOD { + + /// Class providing the definition of the 4-vector interface + /// + /// All particle-like classes in the xAOD EDM inherit from this simple + /// interface class to make it simple to write generic analysis code + /// for the objects. + /// + /// @author Andy Buckley <Andy.Buckley@cern.ch> + /// @author Till Eifert <Till.Eifert@cern.ch> + /// @author Markus Elsing <Markus.Elsing@cern.ch> + /// @author Dag Gillberg <Dag.Gillberg@cern.ch> + /// @author Karsten Koeneke <karstenkoeneke@gmail.com> + /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + /// @author Edward Moyse <Edward.Moyse@cern.ch> + /// + /// $Revision: 604340 $ + /// $Date: 2014-07-01 06:04:52 +0200 (Tue, 01 Jul 2014) $ + /// + class IParticle : public SG::AuxElement { + + public: + /// Virtual destructor, to make vtable happy... + virtual ~IParticle() {} + + + /// @name Functions describing the 4-momentum of the object + /// @{ + + /// The transverse momentum (\f$p_T\f$) of the particle + virtual double pt() const = 0; + /// The pseudorapidity (\f$\eta\f$) of the particle + virtual double eta() const = 0; + /// The azimuthal angle (\f$\phi\f$) of the particle + virtual double phi() const = 0; + /// The invariant mass of the particle + virtual double m() const = 0; + /// The total energy of the particle + virtual double e() const = 0; + /// The true rapidity (y) of the particle + virtual double rapidity() const = 0; + + /// Definition of the 4-momentum type + typedef TLorentzVector FourMom_t; + + /// The full 4-momentum of the particle + virtual const FourMom_t& p4() const = 0; + + /// @} + + + /// The type of the object as a simple enumeration + virtual Type::ObjectType type() const = 0; + + + /// @name Functions for getting and setting user properties + /// @{ + + /// Fetch an aux data variable, as a non-const reference + /// + /// This function provides an easy way for users to decorate objects + /// with auxiliary data. + /// + /// Take note that this function is slow. Should not be used inside + /// time-critical code. + /// + /// @param name Name of the aux variable + /// @param clsname The name of the associated class. May be blank + /// @returns A modifyable reference to the decoration + /// + template< class T > + T& auxdata( const std::string& name, + const std::string& clsname = "" ) { + + return SG::AuxElement::auxdata< T >( name, clsname ); + } + + /// Fetch an aux data variable, as a const reference + /// + /// This function provides an easy way for users to retrieve auxiliary + /// decorations from an object. + /// + /// Take note that this function is slow. Should not be used inside + /// time-critical code. + /// + /// @param name Name of the aux variable + /// @param clsname The name of the associated class. May be blank + /// @returns A constant reference to the decoration + /// + template< class T > + const T& auxdata( const std::string& name, + const std::string& clsname = "" ) const { + + return SG::AuxElement::auxdata< T >( name, clsname ); + } + + /// Check if a user property is available for reading or not + /// + /// This function should be used to check if a user property which + /// may or may not exist, is set on the object. + /// + /// @param name Name of the auxiliary variable + /// @param clsname The name of the associated class. May be blank + /// @returns Whether the decoration exists or not + /// + template< class T > + bool isAvailable( const std::string& name, + const std::string& clsname = "" ) const { + + return SG::AuxElement::isAvailable< T >( name, clsname ); + } + + /// Check if a user property is available for writing or not + /// + /// This function can be used to check whether it will be possible to + /// set a user property on the object. + /// + /// @param name Name of the auxiliary variable + /// @param clsname The name of the associated class. May be blank + /// @returns Whether the decoration is possible to set + /// + template< class T > + bool isAvailableWritable( const std::string& name, + const std::string& clsname = "" ) const { + + return SG::AuxElement::isAvailableWritable< T >( name, clsname ); + } + + /// @} + + + protected: + // Hide some functions from the regular xAOD users + using SG::AuxElement::getConstStore; + using SG::AuxElement::getStore; + + // Hide the Accessor class from the regular xAOD users + using SG::AuxElement::Accessor; + + }; // class IParticle + +} // namespace xAOD + +#ifndef XAOD_STANDALONE +#include "SGTools/BaseInfo.h" +SG_BASE (xAOD::IParticle, SG::AuxElement); +#endif // not XAOD_STANDALONE + +#endif // XAODBASE_IPARTICLE_H diff --git a/xAOD/xAODBase/xAODBase/IParticleContainer.h b/xAOD/xAODBase/xAODBase/IParticleContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..eef2cac5f653486eac3c943f305b1c9e2ad13667 --- /dev/null +++ b/xAOD/xAODBase/xAODBase/IParticleContainer.h @@ -0,0 +1,42 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IParticleContainer.h 567380 2013-10-28 10:48:26Z krasznaa $ +#ifndef XAODBASE_IPARTICLECONTAINER_H +#define XAODBASE_IPARTICLECONTAINER_H + +// EDM include(s): +#include "AthContainers/DataVector.h" + +// Local include(s): +#include "xAODBase/IParticle.h" + +namespace xAOD { + + /// Simple convenience declaration of IParticleContainer + /// + /// Note that this structure should be used with care. It should + /// mainly be used in tool interfaces, and nowhere else. For instance + /// it is possible to put view containers of this type into StoreGate, + /// but it is not possible to write out an object of this type into + /// an output file. + /// + /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + /// + /// $Revision: 567380 $ + /// $Date: 2013-10-28 11:48:26 +0100 (Mon, 28 Oct 2013) $ + /// + typedef DataVector< IParticle > IParticleContainer; + +} // namespace xAOD + +// To make it possible to put IParticleContainers into StoreGate: +#ifndef XAOD_STANDALONE +#include "SGTools/CLASS_DEF.h" +CLASS_DEF( xAOD::IParticleContainer, 1241842700, 1 ) +#endif // not XAOD_STANDALONE + +#endif // XAODBASE_IPARTICLECONTAINER_H diff --git a/xAOD/xAODBase/xAODBase/IParticleHelpers.h b/xAOD/xAODBase/xAODBase/IParticleHelpers.h new file mode 100644 index 0000000000000000000000000000000000000000..707cd033a0f3111bb3eec716a5fa755258194cc2 --- /dev/null +++ b/xAOD/xAODBase/xAODBase/IParticleHelpers.h @@ -0,0 +1,30 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: IParticleHelpers.h 618909 2014-09-29 10:16:52Z krasznaa $ +#ifndef XAODBASE_IPARTICLEHELPERS_H +#define XAODBASE_IPARTICLEHELPERS_H + +// Local include(s): +#include "xAODBase/IParticle.h" +#include "xAODBase/IParticleContainer.h" + +namespace xAOD { + + /// Function setting a link on a deep copy back to its original object + bool setOriginalObjectLink( const IParticle& original, + IParticle& copy ); + + /// Function setting links on a deep/shallow copy container to the originals + bool setOriginalObjectLink( const IParticleContainer& original, + IParticleContainer& copy ); + + /// Function getting a pointer to the original object from a deep/shallow copy + const IParticle* getOriginalObject( const IParticle& copy ); + +} // namespace xAOD + +#endif // XAODBASE_IPARTICLEHELPERS_H diff --git a/xAOD/xAODBase/xAODBase/ObjectType.h b/xAOD/xAODBase/xAODBase/ObjectType.h new file mode 100644 index 0000000000000000000000000000000000000000..657a09ffa4baf4004c5ab2f4df2de71a9ba7bca9 --- /dev/null +++ b/xAOD/xAODBase/xAODBase/ObjectType.h @@ -0,0 +1,91 @@ +// $Id: ObjectType.h 618658 2014-09-26 09:31:10Z krasznaa $ +#ifndef XAODBASE_OBJECTTYPE_H +#define XAODBASE_OBJECTTYPE_H + +// System include(s): +#include <iosfwd> + +namespace xAOD { + + /// Namespace for the xAOD object types + /// + /// The reason for introducing an extra namespace like this is so the users + /// will write things like + /// <code>if( mypart->type() == xAOD::Type::Muon ) {...}</code> + /// instead of using <code>xAOD::MuonType</code> or something similar. + /// + namespace Type { + + /// Type of objects that have a representation in the xAOD EDM + /// + /// xAOD classes identify themselves by all of them providing a function + /// with the signature: + /// + /// <code> + /// xAOD::Type::ObjectType type() const; + /// </code> + /// + /// This can be used to easily identify what sort of object some generic + /// code is dealing with, avoiding doing a lot of + /// <code>dynamic_cast</code>-s instead. + /// + /// Note that Doxygen doesn't allow to group enumeration variables + /// together like it does for members of a class, that's why the grouping + /// comments are not created according to the Doxygen rules. + /// + enum ObjectType { + + Other = 0, ///< An object not falling into any of the other categories + + // Reconstructed particle types + // { + + CaloCluster = 1, ///< The object is a calorimeter cluster + + Track = 2, ///< The object is a charged track particle + NeutralParticle = 3, ///< The object is a neutral particle + + Electron = 4, ///< The object is an electron + Photon = 5, ///< The object is a photon + Muon = 6, ///< The object is a muon + + // } + + // Reconstructed non-particle types + // { + + Vertex = 101, ///< The object is a vertex + + // } + + // Truth types + // { + + TruthParticle = 201, ///< The object is a truth particle + TruthVertex = 202, ///< The object is a truth vertex + TruthEvent = 203, ///< The object is a truth event + TruthPileupEvent = 204, ///< The object is a truth pileup event + + // } + + // Auxiliary types + // { + + EventInfo = 1001, ///< The object is an event information one + EventFormat = 1002, ///< The object is an event format one + + Particle = 1101, ///< Generic particle object, for analysis + CompositeParticle = 1102 ///< Particle composed of other particles + + // } + + }; // enum ObjectType + + } // namespace Type + +} // namespace xAOD + +/// Convenience operator for printing the object type in a (debug) message +std::ostream& operator<< ( std::ostream& out, xAOD::Type::ObjectType type ); + +#endif // XAODBASE_OBJECTTYPE_H diff --git a/xAOD/xAODBase/xAODBase/selection.xml b/xAOD/xAODBase/xAODBase/selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..b85d3b28a25a37140c0015e1c86d728f77871f61 --- /dev/null +++ b/xAOD/xAODBase/xAODBase/selection.xml @@ -0,0 +1,33 @@ +<!-- $Id: selection.xml 618909 2014-09-29 10:16:52Z krasznaa $ --> +<lcgdict> + + <!-- All the dictionaries for xAOD::IParticle: --> + <class name="xAOD::IParticle" /> + <class name="xAOD::IParticleContainer" /> + <class name="std::vector<xAOD::IParticle*>" /> + + <!-- All smart pointer dictionaries for xAOD::IParticle --> + <class name="DataLink<xAOD::IParticleContainer>" /> + <class name="std::vector<DataLink<xAOD::IParticleContainer> >" /> + + <class name="ElementLink<xAOD::IParticleContainer>" /> + <class name="std::vector<ElementLink<xAOD::IParticleContainer> >" /> + <class name="std::vector<std::vector<ElementLink<xAOD::IParticleContainer> > >" /> + + <class name="ElementLinkVector<xAOD::IParticleContainer>" /> + <class name="std::vector<ElementLinkVector<xAOD::IParticleContainer> >" /> + + <!-- An attempt to make the ObjectType enumeration visible in Python... --> + <enum name="xAOD::Type::ObjectType" /> + + <!-- The helper functions: --> + <function pattern="xAOD::*" /> + + <!-- Suppress the unwanted classes found by ROOT 6. --> + <!-- Hopefully we can remove these extra lines at one point... --> + <exclusion> + <class name="SG::IConstAuxStore" /> + <class name="DataLink<SG::IConstAuxStore>" /> + </exclusion> + +</lcgdict> diff --git a/xAOD/xAODBase/xAODBase/xAODBaseDict.h b/xAOD/xAODBase/xAODBase/xAODBaseDict.h new file mode 100644 index 0000000000000000000000000000000000000000..33067c7bfd1b83bcf846eacc86cda9ae55b3a409 --- /dev/null +++ b/xAOD/xAODBase/xAODBase/xAODBaseDict.h @@ -0,0 +1,108 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: xAODBaseDict.h 618909 2014-09-29 10:16:52Z krasznaa $ +#ifndef XAODBASE_XAODBASEDICT_H +#define XAODBASE_XAODBASEDICT_H + +// STL include(s): +#include <vector> + +// EDM include(s): +#include "AthLinks/DataLink.h" +#include "AthLinks/ElementLink.h" +#include "AthLinks/ElementLinkVector.h" + +// Local include(s): +#include "xAODBase/ObjectType.h" +#include "xAODBase/IParticleContainer.h" +#include "xAODBase/IParticleHelpers.h" + +namespace { + struct GCCXML_DUMMY_INSTANTIATION_XAODBASE { + xAOD::IParticleContainer c1; + DataLink< xAOD::IParticleContainer > l1; + ElementLink< xAOD::IParticleContainer > l2; + ElementLinkVector< xAOD::IParticleContainer > l3; + std::vector< DataLink< xAOD::IParticleContainer > > l4; + std::vector< ElementLink< xAOD::IParticleContainer > > l5; + std::vector< ElementLinkVector< xAOD::IParticleContainer > > l6; + std::vector< std::vector< ElementLink< xAOD::IParticleContainer > > > l7; + }; +} + +template +bool& xAOD::IParticle::auxdata< bool >( const std::string& name, + const std::string& clsname = "" ); + +template +float& xAOD::IParticle::auxdata< float >( const std::string& name, + const std::string& clsname = "" ); + +template +int& xAOD::IParticle::auxdata< int >( const std::string& name, + const std::string& clsname = "" ); + +template +unsigned int& +xAOD::IParticle::auxdata< unsigned int >( const std::string& name, + const std::string& clsname = "" ); + +template +uint8_t& xAOD::IParticle::auxdata< uint8_t >( const std::string& name, + const std::string& clsname = "" ); + +template +const bool& +xAOD::IParticle::auxdata< bool >( const std::string& name, + const std::string& clsname = "" ) const; + +template +const float& +xAOD::IParticle::auxdata< float >( const std::string& name, + const std::string& clsname = "" ) const; + +template +const int& +xAOD::IParticle::auxdata< int >( const std::string& name, + const std::string& clsname = "" ) const; + +template +const unsigned int& +xAOD::IParticle::auxdata< unsigned int >( const std::string& name, + const std::string& clsname = "" ) const; + +template +const uint8_t& +xAOD::IParticle::auxdata< uint8_t >( const std::string& name, + const std::string& clsname = "" ) const; + +template +bool +xAOD::IParticle::isAvailable< bool >( const std::string& name, + const std::string& clsname = "" ) const; + +template +bool +xAOD::IParticle::isAvailable< float >( const std::string& name, + const std::string& clsname = "" ) const; + +template +bool +xAOD::IParticle::isAvailable< int >( const std::string& name, + const std::string& clsname = "" ) const; + +template +bool +xAOD::IParticle::isAvailable< unsigned int >( const std::string& name, + const std::string& clsname = "" ) const; + +template +bool +xAOD::IParticle::isAvailable< uint8_t >( const std::string& name, + const std::string& clsname = "" ) const; + +#endif // XAODBASE_XAODBASEDICT_H diff --git a/xAOD/xAODTracking/CMakeLists.txt b/xAOD/xAODTracking/CMakeLists.txt index 0af665fab93b84a0a687755682cc8fcf9e55f71e..a0e7480507737d3bdd5835df695c975f1c5081dc 100755 --- a/xAOD/xAODTracking/CMakeLists.txt +++ b/xAOD/xAODTracking/CMakeLists.txt @@ -7,6 +7,7 @@ atlas_depends_on_subdirs( PUBLIC Control/AthContainers Control/AthLinks + Event/xAOD/xAODBase Event/xAOD/xAODCore ${extra_deps} ) @@ -19,7 +20,7 @@ atlas_add_library( xAODTracking xAODTracking/*.h Root/*.cxx PUBLIC_HEADERS xAODTracking INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS} - LINK_LIBRARIES ${EIGEN_LIBRARIES} ${ROOT_LIBRARIES} AthContainers AthLinks xAODCore ${extra_libs} ) + LINK_LIBRARIES ${EIGEN_LIBRARIES} ${ROOT_LIBRARIES} AthContainers AthLinks xAODBase xAODCore ${extra_libs} ) atlas_add_dictionary( xAODTrackingDict xAODTracking/xAODTrackingDict.h @@ -36,7 +37,6 @@ atlas_add_test( xAODTracking_StripRawData_test SOURCES test/xAODTracking_StripRawData_test.cxx LINK_LIBRARIES xAODTracking ) -atlas_add_test( xAODTracking_TrackParticlexAODHelpers_test - SOURCES test/xAODTracking_TrackParticlexAODHelpers_test.cxx - LINK_LIBRARIES xAODTracking - EXTRA_PATTERNS "^DEBUG" ) \ No newline at end of file +atlas_add_test( xAODTracking_Track_test + SOURCES test/xAODTracking_Track_test.cxx + LINK_LIBRARIES xAODTracking ) \ No newline at end of file diff --git a/xAOD/xAODTracking/Root/Track.cxx b/xAOD/xAODTracking/Root/Track.cxx index bd2c2c8d376fb563353246f4941043c7789acf68..2412c7f5b3f3c14d9148ecfe63430d0af6637655 100644 --- a/xAOD/xAODTracking/Root/Track.cxx +++ b/xAOD/xAODTracking/Root/Track.cxx @@ -7,11 +7,7 @@ // Local include(s): #include "xAODTracking/Track.h" -#include "xAODTracking/TrackSummaryAccessors_v1.h" -#include "EventPrimitives/EventPrimitivesHelpers.h" - -// Amg include -//#include "EventPrimitives/EventPrimitives.h" +#include "xAODTracking/TrackSummaryAccessors.h" namespace xAOD { @@ -38,16 +34,27 @@ namespace xAOD { Track::~Track(){ } - double Track::p() const { - return p4().P(); + double Track::pt() const { + return p4().Pt(); } - + + double Track::eta() const { + return p4().Eta(); + } + + double Track::phi() const { + return p4().Phi(); + } + double Track::m() const { - return p4().M(); + return p4().M(); } - + double Track::e() const { - return p4().E(); + return p4().E(); + } + double Track::rapidity() const { + return p4().Rapidity(); } const Track::FourMom_t& Track::p4() const { @@ -71,7 +78,7 @@ namespace xAOD { } Type::ObjectType Track::type() const { - return Type::TrackParticle; + return Type::Track; } float Track::charge() const { @@ -80,28 +87,24 @@ namespace xAOD { AUXSTORE_PRIMITIVE_GETTER(Track, float, x0) AUXSTORE_PRIMITIVE_GETTER(Track, float, y0) + AUXSTORE_PRIMITIVE_GETTER(Track, float, phi0) AUXSTORE_PRIMITIVE_GETTER(Track, float, theta) AUXSTORE_PRIMITIVE_GETTER(Track, float, qOverP) const DefiningParameters_t Track::definingParameters() const{ DefiningParameters_t tmp; - tmp << d0() , z0() , phi0() , theta() , qOverP(); + tmp << x0() , y0() , phi0() , theta() , qOverP(); return tmp; } - void Track::setDefiningParameters(float d0, float z0, float phi0, float theta, float qOverP) { - m_perigeeCached=false; -#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) ) - delete m_perigeeParameters; - m_perigeeParameters=0; -#endif // not XAOD_STANDALONE and not XAOD_MANACORE - static Accessor< float > acc1( "d0" ); - acc1( *this ) = d0; + void Track::setDefiningParameters(float x0, float y0, float phi0, float theta, float qOverP) { + static Accessor< float > acc1( "x0" ); + acc1( *this ) = x0; - static Accessor< float > acc2( "z0" ); - acc2( *this ) = z0; + static Accessor< float > acc2( "y0" ); + acc2( *this ) = y0; - static Accessor< float > acc3( "phi" ); + static Accessor< float > acc3( "phi0" ); acc3( *this ) = phi0; static Accessor< float > acc4( "theta" ); @@ -115,20 +118,15 @@ namespace xAOD { } void Track::setDefiningParametersCovMatrix(const xAOD::ParametersCovMatrix_t& cov){ - m_perigeeCached=false; -#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) ) - delete m_perigeeParameters; - m_perigeeParameters=0; -#endif // not XAOD_STANDALONE and not XAOD_MANACORE static Accessor< std::vector<float> > acc( "definingParametersCovMatrix" ); - Amg::compress(cov,acc(*this)); + FMath::compress(cov,acc(*this)); } const xAOD::ParametersCovMatrix_t Track::definingParametersCovMatrix() const { xAOD::ParametersCovMatrix_t cov; const std::vector<float>& covVec = definingParametersCovMatrixVec(); - if( !covVec.empty() ) Amg::expand( covVec.begin(), covVec.end(),cov ); + if( !covVec.empty() ) FMath::expand( covVec.begin(), covVec.end(),cov ); else cov.setIdentity(); return cov; } @@ -160,43 +158,6 @@ namespace xAOD { acc3( *this ) = z; } -#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) ) - const Trk::Perigee& Track::perigeeParameters() const { - if (m_perigeeCached) - return *m_perigeeParameters; - m_perigeeCached=true; - - static Accessor< float > acc1( "d0" ); - static Accessor< float > acc2( "z0" ); - static Accessor< float > acc3( "phi" ); - static Accessor< float > acc4( "theta" ); - static Accessor< float > acc5( "qOverP" ); - static Accessor< std::vector<float> > acc6( "definingParametersCovMatrix" ); - ParametersCovMatrix_t* cov = new ParametersCovMatrix_t(definingParametersCovMatrix()); - // cov->setZero(); - // auto it= acc6(*this).begin(); - // for (size_t irow = 0; irow<5; ++irow) - // for (size_t icol =0; icol<=irow; ++icol) - // cov->fillSymmetric(irow,icol,*it++) ; - static Accessor< float > acc7( "beamlineTiltX" ); - static Accessor< float > acc8( "beamlineTiltY" ); - - if(!acc7.isAvailable( *this ) || !acc8.isAvailable( *this )){ - m_perigeeParameters = new Trk::Perigee(acc1(*this),acc2(*this),acc3(*this),acc4(*this),acc5(*this),Trk::PerigeeSurface(Amg::Vector3D(vx(),vy(),vz())),cov); - return *m_perigeeParameters; - } - - Amg::Transform3D * amgTransf = new Amg::Transform3D(); - Amg::Translation3D amgtranslation(vx(),vy(),vz()); - *amgTransf = amgtranslation * Amg::RotationMatrix3D::Identity(); - *amgTransf *= Amg::AngleAxis3D(acc8(*this), Amg::Vector3D(0.,1.,0.)); - *amgTransf *= Amg::AngleAxis3D(acc7(*this), Amg::Vector3D(1.,0.,0.)); - m_perigeeParameters = new Trk::Perigee(acc1(*this),acc2(*this),acc3(*this),acc4(*this),acc5(*this),Trk::PerigeeSurface(amgTransf),cov); - - return *m_perigeeParameters; - } -#endif // not XAOD_STANDALONE and not XAOD_MANACORE - AUXSTORE_PRIMITIVE_GETTER(Track, float, chiSquared) AUXSTORE_PRIMITIVE_GETTER(Track, float, numberDoF) @@ -207,18 +168,10 @@ namespace xAOD { acc2( *this ) = numberDoF; } - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, float, radiusOfFirstHit, setRadiusOfFirstHit) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, uint64_t, identifierOfFirstHit, setIdentifierOfFirstHit) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, float, beamlineTiltX, setBeamlineTiltX) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, float, beamlineTiltY, setBeamlineTiltY) - + static SG::AuxElement::Accessor< Track::StripClusterLinks_t > clusterAcc( "clusterLinks" ); + AUXSTORE_OBJECT_SETTER_AND_GETTER( Track, Track::StripClusterLinks_t, clusterLinks, setClusterLinks ) AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, uint32_t, hitPattern, setHitPattern) - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, uint8_t,numberOfUsedHitsdEdx ,setNumberOfUsedHitsdEdx ) - - AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(Track, uint8_t,numberOfIBLOverflowsdEdx , setNumberOfIBLOverflowsdEdx) - size_t Track::numberOfParameters() const{ ///@todo - Can we do this in a better way? Not great to force retrieval of one specific parameter - any would do. static Accessor< std::vector<float> > acc( "parameterX" ); @@ -304,7 +257,7 @@ namespace xAOD { // copy the correct values into the temp matrix xAOD::ParametersCovMatrix_t tmp; std::vector<float>::const_iterator it = acc(*this).begin()+offset; - Amg::expand(it,it+15,tmp); + FMath::expand(it,it+15,tmp); return tmp; } @@ -342,69 +295,14 @@ namespace xAOD { acc( *this ).at(index) = static_cast<uint8_t>(pos); } -#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) ) - const Trk::CurvilinearParameters Track::curvilinearParameters(unsigned int index) const { - - static Accessor< std::vector<float> > acc( "trackParameterCovarianceMatrices" ); - unsigned int offset = index*15; - // copy the correct values into the temp matrix - ParametersCovMatrix_t* cov = new ParametersCovMatrix_t(); - auto it = acc(*this).begin()+offset; - Amg::expand(it,it+15,*cov); - // retrieve the parameters to build the curvilinear frame - Amg::Vector3D pos(parameterX(index),parameterY(index),parameterZ(index)); - Amg::Vector3D mom(parameterPX(index),parameterPY(index),parameterPZ(index)); - Trk::CurvilinearParameters param(pos,mom,charge(),cov); - - return param; - } -#endif // not XAOD_STANDALONE and not XAOD_MANACORE - - AUXSTORE_PRIMITIVE_GETTER_WITH_CAST(Track, uint8_t, xAOD::TrackProperties,trackProperties) - AUXSTORE_PRIMITIVE_SETTER_WITH_CAST(Track, uint8_t, xAOD::TrackProperties,trackProperties, setTrackProperties) - AUXSTORE_PRIMITIVE_GETTER_WITH_CAST(Track, uint8_t, xAOD::TrackFitter,trackFitter) AUXSTORE_PRIMITIVE_SETTER_WITH_CAST(Track, uint8_t, xAOD::TrackFitter,trackFitter, setTrackFitter) - std::bitset<xAOD::NumberOfTrackRecoInfo> Track::patternRecoInfo() const { - static Accessor< uint64_t > acc( "patternRecoInfo" ); - std::bitset<xAOD::NumberOfTrackRecoInfo> tmp(acc(*this)); - return tmp; - } - - void Track::setPatternRecognitionInfo(uint64_t patternReco) { - static Accessor< uint64_t > acc( "patternRecoInfo" ); - acc( *this ) = patternReco; - } - - void Track::setPatternRecognitionInfo(const std::bitset<xAOD::NumberOfTrackRecoInfo>& patternReco) { - static Accessor< uint64_t > acc( "patternRecoInfo" ); - #if __cplusplus < 201100 - uint64_t value = 0; - unsigned int i = 0; - unsigned int size=patternReco.size(); - for (;i<32;++i) value |= ((patternReco[i]) << i); - for (i=32;i<size;++i) value |= ((patternReco[i]) << (i-32)); - acc( *this ) = value; - - #else - acc( *this ) = patternReco.to_ullong(); - #endif - } - AUXSTORE_PRIMITIVE_SETTER_WITH_CAST(Track, uint8_t, xAOD::ParticleHypothesis, particleHypothesis, setParticleHypothesis) AUXSTORE_PRIMITIVE_GETTER_WITH_CAST(Track, uint8_t, xAOD::ParticleHypothesis, particleHypothesis) bool Track::summaryValue(uint8_t& value, const SummaryType &information) const { - xAOD::Track::Accessor< uint8_t >* acc = trackSummaryAccessorV1<uint8_t>( information ); - if( ( ! acc ) || ( ! acc->isAvailable( *this ) ) ) return false; - // Retrieve the value: - value = ( *acc )( *this ); - return true; - } - - bool Track::summaryValue(float& value, const SummaryType &information) const { - xAOD::Track::Accessor< float >* acc = trackSummaryAccessorV1<float>( information ); + xAOD::Track::Accessor< uint8_t >* acc = trackSummaryAccessor<uint8_t>( information ); if( ( ! acc ) || ( ! acc->isAvailable( *this ) ) ) return false; // Retrieve the value: value = ( *acc )( *this ); @@ -412,85 +310,9 @@ namespace xAOD { } void Track::setSummaryValue(uint8_t& value, const SummaryType &information){ - xAOD::Track::Accessor< uint8_t >* acc = trackSummaryAccessorV1<uint8_t>( information ); - // Set the value: - ( *acc )( *this ) = value; - } - - void Track::setSummaryValue(float& value, const SummaryType &information){ - xAOD::Track::Accessor< float >* acc = trackSummaryAccessorV1<float>( information ); + xAOD::Track::Accessor< uint8_t >* acc = trackSummaryAccessor<uint8_t>( information ); // Set the value: ( *acc )( *this ) = value; } - - -#if ( ! defined(XAOD_STANDALONE) ) && ( ! defined(XAOD_MANACORE) ) - /// The function will return an invalid ElementLink in case nothing was set - /// for it yet. This is to avoid users having to always check both for - /// the decoration being available, and the link being valid. - /// - /// @returns An element link to the parent Trk::Track of this track particle - /// - const ElementLink< TrackCollection >& Track::trackLink() const { - - // The accessor: - static ConstAccessor< ElementLink< TrackCollection > > acc( "trackLink" ); - - // Check if one of them is available: - if( acc.isAvailable( *this ) ) { - return acc( *this ); - } - - // If no Trk::Track link was not set (yet), return a dummy object: - static const ElementLink< TrackCollection > dummy; - return dummy; - } - - void Track:: - setTrackLink( const ElementLink< TrackCollection >& el ) { - - // The accessor: - static Accessor< ElementLink< TrackCollection > > acc( "trackLink" ); - - // Do the deed: - acc( *this ) = el; - return; - } - - const Trk::Track* Track::track() const{ - - // The accessor: - static ConstAccessor< ElementLink< TrackCollection > > acc( "trackLink" ); - - if( ! acc.isAvailable( *this ) ) { - return 0; - } - if( ! acc( *this ).isValid() ) { - return 0; - } - - return *( acc( *this ) ); - } - -#endif // not XAOD_STANDALONE and not XAOD_MANACORE - - AUXSTORE_OBJECT_SETTER_AND_GETTER( Track, - ElementLink< VertexContainer >, - vertexLink, setVertexLink ) - - const Vertex* Track::vertex() const { - - // The accessor: - static SG::AuxElement::Accessor< ElementLink< VertexContainer > > - acc( "vertexLink" ); - - if( ! acc.isAvailable( *this ) ) { - return 0; - } - if( ! acc( *this ).isValid() ) { - return 0; - } - return *( acc( *this ) ); - } } // namespace xAOD \ No newline at end of file diff --git a/xAOD/xAODTracking/Root/TrackAuxContainer.cxx b/xAOD/xAODTracking/Root/TrackAuxContainer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..93fcb47f62e1f6f116300141a3951fc85dfbcfcc --- /dev/null +++ b/xAOD/xAODTracking/Root/TrackAuxContainer.cxx @@ -0,0 +1,73 @@ +// Local include(s): +#include "xAODTracking/TrackAuxContainer.h" + +namespace xAOD { + + TrackAuxContainer::TrackAuxContainer() + : AuxContainerBase() { + + AUX_VARIABLE( x0 ); + AUX_VARIABLE( y0 ); + AUX_VARIABLE( phi0 ); + AUX_VARIABLE( theta ); + AUX_VARIABLE( qOverP ); + + AUX_VARIABLE( definingParametersCovMatrix ); + + AUX_VARIABLE( vx ); + AUX_VARIABLE( vy ); + AUX_VARIABLE( vz ); + + AUX_VARIABLE( clusterLinks); + AUX_VARIABLE( hitPattern ); + + AUX_VARIABLE( chiSquared ); + AUX_VARIABLE( numberDoF ); + + AUX_VARIABLE( trackFitter ); + AUX_VARIABLE( particleHypothesis ); + + // TrackSummary information +#ifndef XAODTRACK_SUMMARYDYNAMIC + // uint8_ts + AUX_VARIABLE( numberOfContribStripLayers ); + AUX_VARIABLE( numberOfStripHits ); + AUX_VARIABLE( numberOfStripOutliers ); + AUX_VARIABLE( numberOfStripHoles ); + AUX_VARIABLE( numberOfStripDoubleHoles ); + AUX_VARIABLE( numberOfStripSharedHits ); + AUX_VARIABLE( numberOfStripDeadSensors ); + AUX_VARIABLE( numberOfStripSpoiltHits ); + + AUX_VARIABLE( numberOfOutliersOnTrack ); + AUX_VARIABLE( standardDeviationOfChi2OS ); +#endif + + } + + void TrackAuxContainer::dump() const { + std::cout<<" Dumping TrackAuxContainer"<<std::endl; + std::cout<<"x0:"; + std::copy(x0.begin(), x0.end(), + std::ostream_iterator<float>(std::cout, ", ")); + std::cout<<"y0:"; + std::copy(y0.begin(), y0.end(), + std::ostream_iterator<float>(std::cout, ", ")); + std::cout<<"phi0:"; + std::copy(phi0.begin(), phi0.end(), + std::ostream_iterator<float>(std::cout, ", ")); + std::cout<<"theta:"; + std::copy(theta.begin(), theta.end(), + std::ostream_iterator<float>(std::cout, ", ")); + std::cout<<"qOverP:"; + std::copy(qOverP.begin(), qOverP.end(), + std::ostream_iterator<float>(std::cout, ", ")); + std::cout<<"definingParametersCovMatrix: ["<<&definingParametersCovMatrix<<"]"; + for (unsigned int i=0; i<definingParametersCovMatrix.size();++i){ + std::copy(definingParametersCovMatrix[i].begin(), definingParametersCovMatrix[i].end(), + std::ostream_iterator<float>(std::cout, ", ")); + std::cout<<std::endl; + } + } + +} // namespace xAOD diff --git a/xAOD/xAODTracking/Root/TrackSummaryAccessors.cxx b/xAOD/xAODTracking/Root/TrackSummaryAccessors.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d94ee097d53e9416c229634863b16bf80bff4848 --- /dev/null +++ b/xAOD/xAODTracking/Root/TrackSummaryAccessors.cxx @@ -0,0 +1,49 @@ +// System include(s): +extern "C" { +# include <stdint.h> +} +#include <iostream> + +// Local include(s): +#include "xAODTracking/TrackSummaryAccessors.h" + +/// Helper macro for Accessor objects +#define DEFINE_ACCESSOR(TYPE, NAME ) \ + case xAOD::NAME: \ + { \ + static SG::AuxElement::Accessor< TYPE > a( #NAME ); \ + return &a; \ + } \ + break; + +namespace xAOD { + + // Generic case. Maybe return warning? + template<class T> + SG::AuxElement::Accessor< T >* + trackSummaryAccessor( xAOD::SummaryType /*type*/ ) + {} + + template<> + SG::AuxElement::Accessor< uint8_t >* + trackSummaryAccessor<uint8_t>( xAOD::SummaryType type ) { + + switch( type ) { + DEFINE_ACCESSOR( uint8_t, numberOfContribStripLayers ); + DEFINE_ACCESSOR( uint8_t, numberOfStripHits ); + DEFINE_ACCESSOR( uint8_t, numberOfStripOutliers ); + DEFINE_ACCESSOR( uint8_t, numberOfStripHoles ); + DEFINE_ACCESSOR( uint8_t, numberOfStripDoubleHoles ); + DEFINE_ACCESSOR( uint8_t, numberOfStripSharedHits ); + DEFINE_ACCESSOR( uint8_t, numberOfStripDeadSensors ); + DEFINE_ACCESSOR( uint8_t, numberOfStripSpoiltHits ); + + DEFINE_ACCESSOR( uint8_t, numberOfOutliersOnTrack ); + DEFINE_ACCESSOR( uint8_t, standardDeviationOfChi2OS ); + default: + std::cerr << "xAOD::Track ERROR Unknown SummaryType (" + << type << ") requested" << std::endl; + return 0; + } + } +} // namespace xAOD diff --git a/xAOD/xAODTracking/share/xAODTracking_Track_test.ref b/xAOD/xAODTracking/share/xAODTracking_Track_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..8f4fb0652d50f4df057dd14a6d9011da9b0eb8e1 --- /dev/null +++ b/xAOD/xAODTracking/share/xAODTracking_Track_test.ref @@ -0,0 +1,25 @@ +Filling Track +setDefiningParameters +setDefiningParametersCovMatrixVec +setParametersOrigin +setTrackParameters +setParameterPosition +Printing Track +x0 = 1, y0 = 2, phi = 1.23, theta = 0.5, qOverP = 0.25 +definingParametersCovMatrixVec = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3] +vx = 0, vy = 1, vz = 2 +numberOfParameters = 2 + - x = 0, y = 1, z = 2, px = 3, py = 4, pz = 5 + - x = 6, y = 7, z = 8, px = 9, py = 10, pz = 11 +parameterPosition( 0 ) = 1 +parameterPosition( 1 ) = 3 + Dumping TrackAuxContainer +x0:1, y0:2, phi0:1.23, theta:0.5, qOverP:0.25, definingParametersCovMatrix: [0x7ffd160b5370]1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, +x0 = 1, y0 = 2, phi = 1.23, theta = 0.5, qOverP = 0.25 +definingParametersCovMatrixVec = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3] +vx = 0, vy = 1, vz = 2 +numberOfParameters = 2 + - x = 0, y = 1, z = 2, px = 3, py = 4, pz = 5 + - x = 6, y = 7, z = 8, px = 9, py = 10, pz = 11 +parameterPosition( 0 ) = 1 +parameterPosition( 1 ) = 3 \ No newline at end of file diff --git a/xAOD/xAODTracking/test/xAODTracking_Track_test.cxx b/xAOD/xAODTracking/test/xAODTracking_Track_test.cxx index 9395da84ef19fa958b7ae896d557545021cd6934..97dc59998d2eaff9bf0e944db3efe00fdd8425da 100644 --- a/xAOD/xAODTracking/test/xAODTracking_Track_test.cxx +++ b/xAOD/xAODTracking/test/xAODTracking_Track_test.cxx @@ -21,10 +21,10 @@ std::ostream& operator<< ( std::ostream& out, } /// Function filling one Track with information -void fill( xAOD::Track& tp ) { - +void fill( xAOD::Track& tp) { + tp.setDefiningParameters( 1.0, 2.0, 1.23, 0.5, 0.25 ); - + std::cout << "setDefiningParameters" << std::endl; static const float covMatrix[ 15 ] = { 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0, @@ -33,9 +33,9 @@ void fill( xAOD::Track& tp ) { static const std::vector< float > covMatrixVec( covMatrix, covMatrix + 15 ); tp.setDefiningParametersCovMatrixVec( covMatrixVec ); - + std::cout << "setDefiningParametersCovMatrixVec" << std::endl; tp.setParametersOrigin( 0.0, 1.0, 2.0 ); - + std::cout << "setParametersOrigin" << std::endl; static const float parameters[ 2 ][ 6 ] = { { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 }, { 6.0, 7.0, 8.0, 9.0, 10.0, 11.0 } @@ -49,9 +49,11 @@ void fill( xAOD::Track& tp ) { } } tp.setTrackParameters( parametersVec ); + std::cout << "setTrackParameters" << std::endl; tp.setParameterPosition( 0, xAOD::FirstMeasurement ); tp.setParameterPosition( 1, xAOD::CalorimeterEntrance ); + std::cout << "setParameterPosition" << std::endl; return; } @@ -60,7 +62,7 @@ void fill( xAOD::Track& tp ) { void print( const xAOD::Track& tp ) { std::cout << "x0 = " << tp.x0() << ", y0 = " << tp.y0() - << ", phi = " << tp.phi() << ", theta = " << tp.theta() + << ", phi = " << tp.phi0() << ", theta = " << tp.theta() << ", qOverP = " << tp.qOverP() << std::endl; std::cout << "definingParametersCovMatrixVec = " << tp.definingParametersCovMatrixVec() << std::endl; @@ -89,14 +91,14 @@ int main() { xAOD::TrackAuxContainer aux; xAOD::TrackContainer tpc; tpc.setStore( &aux ); - + // Add one track particle to the container: xAOD::Track* p = new xAOD::Track(); tpc.push_back( p ); - + std::cout << "Filling Track" << std::endl; // Fill it with information: fill( *p ); - + std::cout << "Printing Track" << std::endl; // Print the information: print( *p ); diff --git a/xAOD/xAODTracking/xAODTracking/Track.h b/xAOD/xAODTracking/xAODTracking/Track.h index 123257ebc0c2bddc084e680899b88ff3781ef665..f06867b07e5af2fb094bf06612bdc4a3f54e26e9 100644 --- a/xAOD/xAODTracking/xAODTracking/Track.h +++ b/xAOD/xAODTracking/xAODTracking/Track.h @@ -13,6 +13,7 @@ extern "C" { // xAOD include(s): #include "xAODBase/IParticle.h" +#include "xAODTracking/StripClusterContainer.h" #include "xAODTracking/TrackingPrimitives.h" namespace xAOD { @@ -54,7 +55,14 @@ namespace xAOD { /// The type of the object as a simple enumeration virtual Type::ObjectType type() const; /// @} - + + /// @name ElementLinks to StripClusters + /// @{ + typedef std::vector< ElementLink< xAOD::StripClusterContainer > > StripClusterLinks_t; + const StripClusterLinks_t& clusterLinks() const; + void setClusterLinks(const StripClusterLinks_t& clusterLinks); + /// @} + /// @name Defining parameters functions /// The 'defining parameters' are key to the concept of a Track, and give the values for the IParticle interface /// ( pt(), phi(), eta() etc.). @@ -70,8 +78,8 @@ namespace xAOD { float x0() const; /// Returns the \f$y_0\f$ parameter float y0() const; - /// Returns the \f$\phi\f$ parameter, which has range \f$-\pi\f$ to \f$+\pi\f$. - float phi() const; + /// Returns the \f$phi_0\f$ parameter + float phi0() const; /// Returns the \f$\theta\f$ parameter, which has range 0 to \f$\pi\f$. float theta() const; /// Returns the \f$q/p\f$ parameter @@ -85,7 +93,7 @@ namespace xAOD { /// Returns the length 6 vector containing the elements of defining parameters covariance matrix. const std::vector<float>& definingParametersCovMatrixVec() const; /// Set the defining parameters. - void setDefiningParameters(float x0, float y0, float phi, float theta, float qOverP); + void setDefiningParameters(float x0, float y0, float phi0, float theta, float qOverP); /// Set the defining parameters covariance matrix. void setDefiningParametersCovMatrix(const ParametersCovMatrix_t& cov); /// Set the defining parameters covariance matrix using a length 15 vector. @@ -177,7 +185,7 @@ namespace xAOD { /// Method for setting the particle type, using the ParticleHypothesis enum. void setParticleHypothesis(const ParticleHypothesis hypo); /// Returns the particle hypothesis used for Track fitting. - ParticleHypothesis particleHypothesis() const + ParticleHypothesis particleHypothesis() const; /// Returns the fitter. TrackFitter trackFitter() const; /// @} diff --git a/xAOD/xAODTracking/xAODTracking/TrackAuxContainer.h b/xAOD/xAODTracking/xAODTracking/TrackAuxContainer.h index 97f7ffc9785d1ab532602d841dbefbc0bb164b21..867d274768d8f08f14e291bcbca395ae1af3f89a 100644 --- a/xAOD/xAODTracking/xAODTracking/TrackAuxContainer.h +++ b/xAOD/xAODTracking/xAODTracking/TrackAuxContainer.h @@ -12,7 +12,7 @@ extern "C" { #include "AthLinks/ElementLink.h" // Local include(s): -#include "xAODTracking/TrackAuxContainer.h" +#include "xAODTracking/Track.h" namespace xAOD { class TrackAuxContainer : public AuxContainerBase { @@ -29,7 +29,7 @@ namespace xAOD { /// @{ std::vector< float > x0; std::vector< float > y0; - std::vector< float > phi; + std::vector< float > phi0; std::vector< float > theta; std::vector< float > qOverP; @@ -54,6 +54,7 @@ namespace xAOD { std::vector< std::vector<float> > trackParameterCovarianceMatrices; std::vector< std::vector<uint8_t> > parameterPosition; + std::vector< xAOD::Track::StripClusterLinks_t > clusterLinks; std::vector< uint32_t > hitPattern; /// @name Fit quality functions diff --git a/xAOD/xAODTracking/xAODTracking/TrackSummaryAccessors.h b/xAOD/xAODTracking/xAODTracking/TrackSummaryAccessors.h new file mode 100644 index 0000000000000000000000000000000000000000..7e15800eace01216d6352b1aa90d7286950efe55 --- /dev/null +++ b/xAOD/xAODTracking/xAODTracking/TrackSummaryAccessors.h @@ -0,0 +1,30 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TrackSummaryAccessors_v1.h 574227 2013-12-06 14:20:39Z emoyse $ +#ifndef XAOD_TRACKSUMMARYACCESSORS_H +#define XAOD_TRACKSUMMARYACCESSORS_H + +// EDM include(s): +#include "AthContainers/AuxElement.h" + +// Local include(s): +#include "xAODTracking/TrackingPrimitives.h" + +namespace xAOD { + + /// Helper function for managing TrackSummary Accessor objects + /// + /// This function holds on to Accessor objects that can be used by each + /// TrackParticle_v1 object at runtime to get/set summary values on themselves. + /// + template <class T> + SG::AuxElement::Accessor< T >* + trackSummaryAccessor( xAOD::SummaryType type ); + +} // namespace xAOD + +#endif // XAODCALOEVENT_CALOCLUSTERACCESSORS_H diff --git a/xAOD/xAODTracking/xAODTracking/TrackingPrimitives.h b/xAOD/xAODTracking/xAODTracking/TrackingPrimitives.h index d75bce1058668d57fc7e242e654827efdf4aaed5..da9d408d7e0545bbff1627042d4b239d0b70194c 100644 --- a/xAOD/xAODTracking/xAODTracking/TrackingPrimitives.h +++ b/xAOD/xAODTracking/xAODTracking/TrackingPrimitives.h @@ -5,10 +5,41 @@ #include <Eigen/Core> #include <Eigen/Dense> +namespace FMath{ + template <int N> + inline void compress(const Eigen::Matrix<double, N,N,0,N,N>& covMatrix, std::vector<float>& vec) { + int rows = covMatrix.rows(); + for (int i = 0; i < rows; ++i) { + for (int j = 0; j <= i; ++j) { + vec.push_back(covMatrix(i, j)); + } + } + } + + template <int N> + inline void expand(std::vector<float>::const_iterator it, + std::vector<float>::const_iterator it_end, Eigen::Matrix<double, N,N,0,N,N>& covMatrix) { + unsigned int dist = std::distance(it, it_end); + unsigned int n; + for (n = 1; dist > n; ++n) { + dist = dist - n; + } + covMatrix = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>(n, n); + for (unsigned int i = 0; i < n; ++i) { + for (unsigned int j = 0; j <= i; ++j) { + covMatrix(i,j) = *it; + ++it; + } + } + } +} + namespace xAOD { - using DefiningParameters_t Eigen::Matrix<double, 5, 1>; - using ParametersCovMatrix_t Eigen::Matrix<double, 5, 5>; + using DefiningParameters_t = Eigen::Matrix<double, 5, 1>; + using ParametersCovMatrix_t = Eigen::Matrix<double, 5, 5>; + using CurvilinearParameters_t = Eigen::Matrix<double, 6, 1>; + /// Enums to identify who created this track and which properties does it have. enum TrackFitter { @@ -51,7 +82,7 @@ namespace xAOD { /// When adding a new transient information type, please make sure to increase numberOfTrackSummaryTypes.*/ enum SummaryType { // --- Inner Detector - numberOfContribSCTLayers = 1, //!< number of contributing layers of the pixel detector [unit8_t]. + numberOfContribStripLayers = 1, //!< number of contributing layers of the pixel detector [unit8_t]. numberOfStripHits = 2, //!< number of hits in Strip [unit8_t]. numberOfStripOutliers = 3, //!< number of Strip outliers [unit8_t]. numberOfStripHoles = 4, //!< number of Strip holes [unit8_t]. diff --git a/xAOD/xAODTracking/xAODTracking/xAODTrackingDict.h b/xAOD/xAODTracking/xAODTracking/xAODTrackingDict.h index cb4bb673e608ac61b110e1a4c66dbbc5f5e3d7bf..f4cfd8d135a18e0b47d2b78fa8a989b47f80688b 100644 --- a/xAOD/xAODTracking/xAODTracking/xAODTrackingDict.h +++ b/xAOD/xAODTracking/xAODTracking/xAODTrackingDict.h @@ -17,11 +17,10 @@ // EDM include(s): #include "AthLinks/DataLink.h" -#include "AthLinks/ElementLink.h" +#include "AthLinks/ElementLinkVector.h" // Local include(s): #include "xAODTracking/TrackContainer.h" -#include "xAODTracking/TrackContainer.h" #include "xAODTracking/TrackAuxContainer.h" #include "xAODTracking/StripClusterContainer.h" diff --git a/xAOD/xAODTruth/CMakeLists.txt b/xAOD/xAODTruth/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4d63992e69e11bb11f78d216565560daf12c584a --- /dev/null +++ b/xAOD/xAODTruth/CMakeLists.txt @@ -0,0 +1,37 @@ +# $Id: CMakeLists.txt 761796 2016-07-14 08:06:02Z krasznaa $ +################################################################################ +# Package: xAODTruth +################################################################################ + +# Declare the package name: +atlas_subdir( xAODTruth ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( + PUBLIC + Control/AthContainers + Control/AthLinks + Event/xAOD/xAODBase + Event/xAOD/xAODCore + PRIVATE + Generators/TruthUtils ) + +# Component(s) in the package: +atlas_add_library( xAODTruth + xAODTruth/*.h xAODTruth/versions/*.h Root/*.h Root/*.cxx + PUBLIC_HEADERS xAODTruth + LINK_LIBRARIES AthContainers AthLinks xAODBase xAODCore + PRIVATE_LINK_LIBRARIES TruthUtils ) + +atlas_add_dictionary( xAODTruthDict + xAODTruth/xAODTruthDict.h + xAODTruth/selection.xml + LINK_LIBRARIES xAODTruth + EXTRA_FILES Root/dict/*.cxx ) + +atlas_generate_cliddb( xAODTruth ) + +# Test(s) in the package: +atlas_add_test( ut_xaodtruth_particle_test + SOURCES test/ut_xaodtruth_particle_test.cxx + LINK_LIBRARIES xAODTruth ) diff --git a/xAOD/xAODTruth/Root/TruthAccessors.cxx b/xAOD/xAODTruth/Root/TruthAccessors.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0e8785e95a82cee519859354cc77bde790d61130 --- /dev/null +++ b/xAOD/xAODTruth/Root/TruthAccessors.cxx @@ -0,0 +1,74 @@ +// System include(s): +#include <iostream> + +// Local include(s): +#include "TruthAccessors.h" + +/// Helper macro for managing cluster moment Accessor objects +#define DEFINE_ACCESSOR( PARENT, TYPE, NAME ) \ + case PARENT::NAME: \ + { \ + static SG::AuxElement::Accessor< TYPE > a( #NAME ); \ + return &a; \ + } \ + break + +namespace xAOD { + + SG::AuxElement::Accessor< float >* + polarizationAccessor( TruthParticle::PolParam type ) { + + switch( type ) { + + DEFINE_ACCESSOR( TruthParticle, float, polarizationTheta ); + DEFINE_ACCESSOR( TruthParticle, float, polarizationPhi ); + + default: + std::cerr << "xAOD::polarizationAccessor ERROR Unknown PolParam (" + << type << ") requested" << std::endl; + return 0; + } + + return 0; + } + + SG::AuxElement::Accessor< int >* + pdfInfoAccessorInt( TruthEvent::PdfParam type ) { + + switch( type ) { + + DEFINE_ACCESSOR( TruthEvent, int, PDGID1 ); + DEFINE_ACCESSOR( TruthEvent, int, PDGID2 ); + DEFINE_ACCESSOR( TruthEvent, int, PDFID1 ); + DEFINE_ACCESSOR( TruthEvent, int, PDFID2 ); + + default: + std::cerr << "xAOD::pdfInfoAccessorInt ERROR Unknown PdfParam (" + << type << ") requested" << std::endl; + return 0; + } + + return 0; + } + + SG::AuxElement::Accessor< float >* + pdfInfoAccessorFloat( TruthEvent::PdfParam type ) { + + switch( type ) { + + DEFINE_ACCESSOR( TruthEvent, float, X1 ); + DEFINE_ACCESSOR( TruthEvent, float, X2 ); + DEFINE_ACCESSOR( TruthEvent, float, Q ); + DEFINE_ACCESSOR( TruthEvent, float, XF1 ); + DEFINE_ACCESSOR( TruthEvent, float, XF2 ); + + default: + std::cerr << "xAOD::pdfInfoAccessorFloat ERROR Unknown ParamDef (" + << type << ") requested" << std::endl; + return 0; + } + + return 0; + } + +} // namespace xAOD diff --git a/xAOD/xAODTruth/Root/TruthAccessors.h b/xAOD/xAODTruth/Root/TruthAccessors.h new file mode 100644 index 0000000000000000000000000000000000000000..704ad790ae8d6a1d13ba3d420707678c794b463c --- /dev/null +++ b/xAOD/xAODTruth/Root/TruthAccessors.h @@ -0,0 +1,36 @@ +// -*- C++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TruthAccessors_v1.h 623284 2014-10-22 14:07:48Z krasznaa $ +#ifndef XAODTRUTH_TRUTHACCESSORS_H +#define XAODTRUTH_TRUTHACCESSORS_H + +// EDM include(s): +#include "AthContainers/AuxElement.h" + +// Local include(s): +#include "xAODTruth/TruthEvent.h" +#include "xAODTruth/TruthParticle.h" + +namespace xAOD { + + /// This function holds on to Accessor objects that can be used by each + /// TruthParticle object at runtime to get/set parameter values on + /// themselves. + SG::AuxElement::Accessor< float >* + polarizationAccessor( TruthParticle::PolParam type ); + + /// Helper function for getting accessors for integer type PDF information + SG::AuxElement::Accessor< int >* + pdfInfoAccessorInt( TruthEvent::PdfParam type ); + + /// Helper function for getting accessors for floating point PDF information + SG::AuxElement::Accessor< float >* + pdfInfoAccessorFloat( TruthEvent::PdfParam type ); + +} // namespace xAOD + +#endif // XAODTRUTH_TRUTHACCESSORS_H diff --git a/xAOD/xAODTruth/Root/TruthEvent.cxx b/xAOD/xAODTruth/Root/TruthEvent.cxx new file mode 100644 index 0000000000000000000000000000000000000000..aa83accfca23d73aca89821b3b3503438b5d2ba8 --- /dev/null +++ b/xAOD/xAODTruth/Root/TruthEvent.cxx @@ -0,0 +1,341 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TruthEvent.cxx 761798 2016-07-14 08:15:01Z krasznaa $ + +// System include(s): +#include <cmath> + +// EDM include(s): +#include "xAODCore/AuxStoreAccessorMacros.h" + +// Local include(s): +#include "xAODTruth/TruthEvent.h" +#include "TruthAccessors.h" + +namespace xAOD { + + + TruthEvent::TruthEvent() + : SG::AuxElement() { + + } + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of the truth particle accessor functions + + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent, + TruthEvent::TruthParticleLinks_t, + truthParticleLinks, + setTruthParticleLinks ) + + /// Accessor for the truth particles + static SG::AuxElement::Accessor< TruthEvent::TruthParticleLinks_t > + truthParticleLinksAcc( "truthParticleLinks" ); + + size_t TruthEvent::nTruthParticles() const { + + // If the variable is not available, we don't have any truth particles + // associated... + if( ! truthParticleLinksAcc.isAvailable( *this ) ) { + return 0; + } + + // Return the size of the vector: + return truthParticleLinksAcc( *this ).size(); + } + + const TruthEvent::TruthParticleLink_t& + TruthEvent::truthParticleLink( size_t index ) const { + + return truthParticleLinksAcc( *this ).at( index ); + } + + const TruthParticle* TruthEvent::truthParticle( size_t index ) const { + + // Check if the variable is available: + if( ! truthParticleLinksAcc.isAvailable( *this ) ) { + return 0; + } + + // Check if the link is valid: + const TruthParticleLinks_t& links = truthParticleLinksAcc( *this ); + if( ! links[ index ].isValid() ) { + return 0; + } + + // Return the de-referenced link: + return *( links[ index ] ); + } + + void + TruthEvent::addTruthParticleLink( const TruthParticleLink_t& link ) { + + truthParticleLinksAcc( *this ).push_back( link ); + return; + } + + void TruthEvent::clearTruthParticleLinks() { + + truthParticleLinksAcc( *this ).clear(); + return; + } + + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // Implementation of the truth vertex accessor functions + + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent, + TruthEvent::TruthVertexLinks_t, + truthVertexLinks, + setTruthVertexLinks ) + + /// Accessor for the truth vertices + static SG::AuxElement::Accessor< TruthEvent::TruthVertexLinks_t > + truthVertexLinksAcc( "truthVertexLinks" ); + + size_t TruthEvent::nTruthVertices() const { + + // If the variable is not available, we don't have any truth particles + // associated... + if( ! truthVertexLinksAcc.isAvailable( *this ) ) { + return 0; + } + + // Return the size of the vector: + return truthVertexLinksAcc( *this ).size(); + } + + const TruthEvent::TruthVertexLink_t& + TruthEvent::truthVertexLink( size_t index ) const { + + return truthVertexLinksAcc( *this ).at(index); + } + + const TruthVertex* TruthEvent::truthVertex( size_t index ) const { + + // Check if the variable is available: + if( ! truthVertexLinksAcc.isAvailable( *this ) ) { + return 0; + } + + // Check if the link is valid: + const TruthVertexLinks_t& links = truthVertexLinksAcc( *this ); + if( ! links[ index ].isValid() ) { + return 0; + } + + // Return the de-referenced link: + return *( links[ index ] ); + } + + void TruthEvent::addTruthVertexLink( const TruthVertexLink_t& link ) { + + truthVertexLinksAcc( *this ).push_back( link ); + return; + } + + void TruthEvent::clearTruthVertexLinks() { + + truthVertexLinksAcc( *this ).clear(); + return; + } + + + ///////////////////////////////////////////////////////////////////////////// + // Simple, always-present event properties + + /// @todo Need upgrade to allow string-valued map-like access... or access a + /// corresponding vector of names + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent, std::vector< float >, + weights, setWeights ) + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthEvent, float, crossSection, + setCrossSection ) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthEvent, float, + crossSectionError, + setCrossSectionError ) + + void TruthEvent::setCrossSection( float value, float error ) { + + setCrossSection( value ); + setCrossSectionError( error ); + return; + } + + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // Optional PDF info accessors + + bool TruthEvent::pdfInfoParameter( int& value, + PdfParam information ) const { + + // Look for the accessor object: + auto* acc = pdfInfoAccessorInt( information ); + if( ! acc ) return false; + + // Get the value: + value = ( *acc )( *this ); + return true; + } + + bool TruthEvent::pdfInfoParameter( float& value, + PdfParam information ) const { + + // Look for the accessor object: + auto* acc = pdfInfoAccessorFloat( information ); + if( ! acc ) return false; + + // Get the value: + value = ( *acc )( *this ); + return true; + } + + bool TruthEvent::setPdfInfoParameter( int value, + PdfParam information ) { + + // Look for the accessor object: + auto* acc = pdfInfoAccessorInt( information ); + if( ! acc ) return false; + + // Set the value: + ( *acc )( *this ) = value; + return true; + } + + bool TruthEvent::setPdfInfoParameter( float value, + PdfParam information ) { + + // Look for the accessor object: + auto* acc = pdfInfoAccessorFloat( information ); + if( ! acc ) return false; + + // Set the value: + ( *acc )( *this ) = value; + return true; + } + + TruthEvent::PdfInfo::PdfInfo() + : pdgId1( 0 ), pdgId2( 0 ), pdfId1( -1 ), pdfId2( -1 ), + x1( NAN ), x2( NAN ), Q( NAN ), xf1( NAN ), xf2( NAN ) { + + } + + bool TruthEvent::PdfInfo::valid() const { + + return ( ( pdgId1 != 0 ) && ( pdgId2 != 0 ) && + ( pdfId1 >= 0 ) && ( pdfId2 >= 0 ) && + ( ! std::isnan( x1 ) ) && ( ! std::isnan( x2 ) ) && + ( ! std::isnan( Q ) ) && + ( ! std::isnan( xf1 ) ) && ( ! std::isnan( xf2 ) ) ); + } + + TruthEvent::PdfInfo TruthEvent::pdfInfo() const { + + // The result object: + PdfInfo rtn; + + // Retrieve all of its elements: + pdfInfoParameter( rtn.pdgId1, PDGID1 ); + pdfInfoParameter( rtn.pdgId2, PDGID2 ); + pdfInfoParameter( rtn.pdfId1, PDFID1 ); + pdfInfoParameter( rtn.pdfId2, PDFID2 ); + pdfInfoParameter( rtn.x1, X1 ); + pdfInfoParameter( rtn.x2, X2 ); + pdfInfoParameter( rtn.Q, Q ); + pdfInfoParameter( rtn.xf1, XF1 ); + pdfInfoParameter( rtn.xf2, XF2 ); + + return rtn; + } + + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // Implementation for the links to truth particles/vertices + + // Accessor for the signal vertex + static SG::AuxElement::Accessor< TruthEvent::TruthVertexLink_t > + signalProcessVertexLinkAcc( "signalProcessVertexLink" ); + + const TruthVertex* TruthEvent::signalProcessVertex() const { + + // Check if the link variable is available: + if( ! signalProcessVertexLinkAcc.isAvailable( *this ) ) { + return 0; + } + + // Get the link: + const TruthVertexLink_t& vertLink = signalProcessVertexLinkAcc( *this ); + + // Check if it's valid: + if( ! vertLink.isValid() ) { + return 0; + } + + // Return the de-referenced link: + return *vertLink; + } + + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent, + TruthEvent::TruthVertexLink_t, + signalProcessVertexLink, + setSignalProcessVertexLink ) + + // Accessors for the beam particles + static SG::AuxElement::Accessor< TruthEvent::TruthParticleLink_t > + primaryParticleLinkLinkAcc( "primaryParticleLink" ); + + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthEvent, + TruthEvent::TruthParticleLink_t, + primaryParticleLink, + setPrimaryParticleLink ) + + ///////////////////////////////////////////////////////////////////////////// + + Type::ObjectType TruthEvent::type() const { + + return Type::TruthEvent; + } + + AUXSTORE_OBJECT_SETTER_AND_GETTER(TruthEvent, std::vector < std::string >, weightNames, setWeightNames ) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER(TruthEvent, uint32_t, mcChannelNumber, setMcChannelNumber ) + + void TruthEvent::toPersistent() { + + if( primaryParticleLinkLinkAcc.isAvailableWritable( *this ) ) { + primaryParticleLinkLinkAcc( *this ).toPersistent(); + } + + if( signalProcessVertexLinkAcc.isAvailableWritable( *this ) ) { + signalProcessVertexLinkAcc( *this ).toPersistent(); + } + + // Prepare the truth particle links for writing: + if( truthParticleLinksAcc.isAvailableWritable( *this ) ) { + TruthParticleLinks_t::iterator itr = + truthParticleLinksAcc( *this ).begin(); + TruthParticleLinks_t::iterator end = + truthParticleLinksAcc( *this ).end(); + for( ; itr != end; ++itr ) { + itr->toPersistent(); + } + } + + // Prepare the truth vertex links for writing: + if( truthVertexLinksAcc.isAvailableWritable( *this ) ) { + TruthVertexLinks_t::iterator itr = + truthVertexLinksAcc( *this ).begin(); + TruthVertexLinks_t::iterator end = + truthVertexLinksAcc( *this ).end(); + for( ; itr != end; ++itr ) { + itr->toPersistent(); + } + } + return; + } + +} // namespace xAOD diff --git a/xAOD/xAODTruth/Root/TruthEventAuxContainer.cxx b/xAOD/xAODTruth/Root/TruthEventAuxContainer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..52bfe7e6cccee143a9a7b3b4825f48f2b7d4cf88 --- /dev/null +++ b/xAOD/xAODTruth/Root/TruthEventAuxContainer.cxx @@ -0,0 +1,23 @@ +// Local include(s): +#include "xAODTruth/TruthEventAuxContainer.h" + +namespace xAOD { + + TruthEventAuxContainer::TruthEventAuxContainer() + : AuxContainerBase() { + + AUX_VARIABLE( signalProcessVertexLink ); + + AUX_VARIABLE( weights ); + + AUX_VARIABLE( crossSection ); + AUX_VARIABLE( crossSectionError ); + + AUX_VARIABLE( truthVertexLinks ); + AUX_VARIABLE( truthParticleLinks ); + + AUX_VARIABLE( weightNames ); + AUX_VARIABLE( mcChannelNumber ); + } + +} // namespace xAOD diff --git a/xAOD/xAODTruth/Root/TruthParticle.cxx b/xAOD/xAODTruth/Root/TruthParticle.cxx new file mode 100644 index 0000000000000000000000000000000000000000..39142e928fc06561e65286ab96b65aa227cd5788 --- /dev/null +++ b/xAOD/xAODTruth/Root/TruthParticle.cxx @@ -0,0 +1,391 @@ +// -*- C++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TruthParticle.cxx 690336 2015-08-20 10:54:57Z abuckley $ + +// System include(s): +#include <cmath> +#include <iostream> +#include <stdexcept> + +// Utility include(s): +#include "TruthUtils/PIDHelpers.h" + +// xAOD include(s): +#include "xAODCore/AuxStoreAccessorMacros.h" + +// Local include(s): +#include "xAODTruth/TruthParticle.h" +#include "xAODTruth/TruthVertexContainer.h" +#include "TruthAccessors.h" + +namespace xAOD { + + TruthParticle::TruthParticle() + : IParticle(), m_p4(), m_p4Cached( false ) { + + } + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation for functions identifying the particle in the MC record + // + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthParticle, int, pdgId, + setPdgId ) + + int TruthParticle::absPdgId() const { + + return std::abs( pdgId() ); + } + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthParticle, int, barcode, + setBarcode ) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthParticle, int, status, + setStatus ) + + // + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation of the links to the vertices + // + + /// Accessor for the production vertex + static SG::AuxElement::Accessor< ElementLink< TruthVertexContainer > > + prodVtxLinkAcc( "prodVtxLink" ); + /// Accessor for the decay vertex + static SG::AuxElement::Accessor< ElementLink< TruthVertexContainer > > + decayVtxLinkAcc( "decayVtxLink" ); + + bool TruthParticle::hasProdVtx() const { + + return ( prodVtxLinkAcc.isAvailable( *this ) && + prodVtxLinkAcc( *this ).isValid() ); + } + + const TruthVertex* TruthParticle::prodVtx() const { + + return hasProdVtx() ? *prodVtxLink() : 0; + } + + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthParticle, + ElementLink< TruthVertexContainer >, + prodVtxLink, setProdVtxLink ) + + bool TruthParticle::hasDecayVtx() const { + + return ( decayVtxLinkAcc.isAvailable( *this ) && + decayVtxLinkAcc( *this ).isValid() ); + } + + const TruthVertex* TruthParticle::decayVtx() const { + + return hasDecayVtx() ? *decayVtxLink() : 0; + } + + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthParticle, + ElementLink< TruthVertexContainer >, + decayVtxLink, setDecayVtxLink ) + + // + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // + // Direct access to parents and children + // + + size_t TruthParticle::nParents() const { + + return hasProdVtx() ? prodVtx()->nIncomingParticles() : 0; + } + + const TruthParticle* TruthParticle::parent( size_t i ) const { + + return hasProdVtx() ? prodVtx()->incomingParticle( i ) : 0; + } + + size_t TruthParticle::nChildren() const { + + return hasDecayVtx() ? decayVtx()->nOutgoingParticles() : 0; + } + + const TruthParticle* TruthParticle::child( size_t i ) const { + + return hasDecayVtx() ? decayVtx()->outgoingParticle( i ) : 0; + } + + // + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation of the IParticle interface + // + + double TruthParticle::pt() const { + + // Do the calculation by hand: + const double localPx = static_cast< double >( px() ); + const double localPy = static_cast< double >( py() ); + return std::sqrt( localPx * localPx + localPy * localPy ); + } + + double TruthParticle::eta() const { + + // Calculate the pseudo-rapidity using TLorentzVector. + // Could do something more lightweight later on. + return p4().Eta(); + } + + double TruthParticle::phi() const { + + // Calculate the azimuth angle using TLorentzVector. + // Could do something more lightweight later on. + return p4().Phi(); + } + + AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TruthParticle, float, double, m ) + AUXSTORE_PRIMITIVE_GETTER_WITH_CAST( TruthParticle, float, double, e ) + + double TruthParticle::rapidity() const { + + return p4().Rapidity(); + } + + const TruthParticle::FourMom_t& TruthParticle::p4() const { + + // Cache the 4-momentum if it's not already: + if( ! m_p4Cached ) { + m_p4.SetPxPyPzE( px(), py(), pz(), e() ); + m_p4Cached = true; + } + + return m_p4; + } + + Type::ObjectType TruthParticle::type() const { + + return Type::TruthParticle; + } + + // + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation of the truth particle specific 4-momentum functions + // + + double TruthParticle::abseta() const { + + return std::abs( eta() ); + } + + double TruthParticle::absrapidity() const { + + return std::abs( rapidity() ); + } + + AUXSTORE_PRIMITIVE_GETTER( TruthParticle, float, px ) + + void TruthParticle::setPx( float value ) { + static Accessor< float > acc( "px" ); + m_p4Cached = false; + acc( *this ) = value; + return; + } + + AUXSTORE_PRIMITIVE_GETTER( TruthParticle, float, py ) + + void TruthParticle::setPy( float value ) { + static Accessor< float > acc( "py" ); + m_p4Cached = false; + acc( *this ) = value; + return; + } + + AUXSTORE_PRIMITIVE_GETTER( TruthParticle, float, pz ) + + void TruthParticle::setPz( float value ) { + static Accessor< float > acc( "pz" ); + m_p4Cached = false; + acc( *this ) = value; + return; + } + + void TruthParticle::setE( float value ) { + static Accessor< float > acc( "e" ); + m_p4Cached = false; + acc( *this ) = value; + return; + } + + void TruthParticle::setM( float value ) { + static Accessor< float > acc( "m" ); + // note: this does not invalidate the cache + acc( *this ) = value; + return; + } + + // + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation of the particle species decoder functions + // + +/// Helper macro to implement the functions that rely in functions from MC::PID +#define MC_PID_HELPER( TYPE, FNAME ) \ + TYPE TruthParticle::FNAME() const { \ + return MC::PID::FNAME( pdgId() ); \ + } + + MC_PID_HELPER( double, charge ) + MC_PID_HELPER( int, threeCharge ) + + MC_PID_HELPER( bool, isCharged ) + MC_PID_HELPER( bool, isNeutral ) + + MC_PID_HELPER( bool, isPhoton ) + MC_PID_HELPER( bool, isLepton ) + MC_PID_HELPER( bool, isChLepton ) + MC_PID_HELPER( bool, isElectron ) + MC_PID_HELPER( bool, isMuon ) + MC_PID_HELPER( bool, isTau ) + MC_PID_HELPER( bool, isNeutrino ) + + MC_PID_HELPER( bool, isHadron ) + MC_PID_HELPER( bool, isMeson ) + MC_PID_HELPER( bool, isBaryon ) + + MC_PID_HELPER( bool, hasStrange ) + MC_PID_HELPER( bool, hasCharm ) + MC_PID_HELPER( bool, hasBottom ) + + MC_PID_HELPER( bool, isLightMeson ) + MC_PID_HELPER( bool, isLightBaryon ) + MC_PID_HELPER( bool, isLightHadron ) + + MC_PID_HELPER( bool, isHeavyMeson ) + MC_PID_HELPER( bool, isHeavyBaryon ) + MC_PID_HELPER( bool, isHeavyHadron ) + + MC_PID_HELPER( bool, isBottomMeson ) + MC_PID_HELPER( bool, isBottomBaryon ) + MC_PID_HELPER( bool, isBottomHadron ) + + MC_PID_HELPER( bool, isCharmMeson ) + MC_PID_HELPER( bool, isCharmBaryon ) + MC_PID_HELPER( bool, isCharmHadron ) + + MC_PID_HELPER( bool, isStrangeMeson ) + MC_PID_HELPER( bool, isStrangeBaryon ) + MC_PID_HELPER( bool, isStrangeHadron ) + + MC_PID_HELPER( bool, isQuark ) + MC_PID_HELPER( bool, isParton ) + MC_PID_HELPER( bool, isTop ) + MC_PID_HELPER( bool, isW ) + MC_PID_HELPER( bool, isZ ) + MC_PID_HELPER( bool, isHiggs ) + MC_PID_HELPER( bool, isResonance ) + MC_PID_HELPER( bool, isGenSpecific ) + +// Forget about this macro: +#undef MC_PID_HELPER + + // + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation of the optional polarization accessors + // + + bool TruthParticle::polarizationParameter( float& value, + PolParam param ) const { + + // Get the accessor object: + Accessor< float >* acc = polarizationAccessor( param ); + if( ! acc ) { + // The user asked for a non-existent parameter type. o.O + std::cerr << "xAOD::TruthParticle::polarizationParameter ERROR " + << "Request for an unknown (" << param << ") polarization " + << "parameter type" << std::endl; + return false; + } + // Check if the variable is available: + if( ! acc->isAvailable( *this ) ) { + // No, it is not. + return false; + } + + // Read the value: + value = ( *acc )( *this ); + return true; + } + + bool TruthParticle::setPolarizationParameter( float value, + PolParam param ) { + + // Get the accessor object: + Accessor< float >* acc = polarizationAccessor( param ); + if( ! acc ) { + // The user asked for a non-existent parameter type. o.O + std::cerr << "xAOD::TruthParticle::setPolarizationParameter ERROR " + << "Request for an unknown (" << param << ") polarization " + << "parameter type" << std::endl; + return false; + } + + // Set the value: + ( *acc )( *this ) = value; + return true; + } + + float TruthParticle::polarizationPatameter( PolParam param ) const { + + // Get the accessor object: + Accessor< float >* acc = polarizationAccessor( param ); + if( ! acc ) { + // Throw an exception: + throw std::runtime_error( "Unrecognized polarization parameter " + "requested" ); + } + + // Read the value: + return ( *acc )( *this ); + } + + TruthParticle::Polarization TruthParticle::polarization() const { + + // Construct the object: + Polarization rtn; + polarizationParameter( rtn.phi, polarizationPhi ); + polarizationParameter( rtn.theta, polarizationTheta ); + + return rtn; + } + + // + ///////////////////////////////////////////////////////////////////////////// + + void TruthParticle::toPersistent() { + + if( prodVtxLinkAcc.isAvailableWritable( *this ) ) { + prodVtxLinkAcc( *this ).toPersistent(); + } + if( decayVtxLinkAcc.isAvailableWritable( *this ) ) { + decayVtxLinkAcc( *this ).toPersistent(); + } + return; + } + +} // namespace xAOD diff --git a/xAOD/xAODTruth/Root/TruthParticleAuxContainer.cxx b/xAOD/xAODTruth/Root/TruthParticleAuxContainer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8a4fede3de464d9cb78628e8a34ab25b98ff82fe --- /dev/null +++ b/xAOD/xAODTruth/Root/TruthParticleAuxContainer.cxx @@ -0,0 +1,21 @@ +// Local include(s): +#include "xAODTruth/TruthParticleAuxContainer.h" + +namespace xAOD { + + TruthParticleAuxContainer::TruthParticleAuxContainer() + : AuxContainerBase() { + + AUX_VARIABLE( pdgId ); + AUX_VARIABLE( barcode ); + AUX_VARIABLE( status ); + AUX_VARIABLE( prodVtxLink ); + AUX_VARIABLE( decayVtxLink ); + AUX_VARIABLE( px ); + AUX_VARIABLE( py ); + AUX_VARIABLE( pz ); + AUX_VARIABLE( e ); + AUX_VARIABLE( m ); + } + +} // namespace xAOD diff --git a/xAOD/xAODTruth/Root/TruthVertex.cxx b/xAOD/xAODTruth/Root/TruthVertex.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fcc606097f29f9caae6a664be94ec454b7d59710 --- /dev/null +++ b/xAOD/xAODTruth/Root/TruthVertex.cxx @@ -0,0 +1,251 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TruthVertex.cxx 624338 2014-10-27 15:08:55Z krasznaa $ + +// System include(s): +#include <cmath> + +// xAOD include(s): +#include "xAODCore/AuxStoreAccessorMacros.h" + +// Local include(s): +#include "xAODTruth/TruthVertex.h" +#include "xAODTruth/TruthParticleContainer.h" + +namespace xAOD { + + TruthVertex::TruthVertex() + : SG::AuxElement(), m_v4(), m_v4Cached( false ) { + + } + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation for the "MC specific" functions + // + + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthVertex, int, id, setId ) + AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( TruthVertex, int, barcode, + setBarcode ) + + // + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation for the links to the truth particles + // + + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthVertex, TruthVertex::TPLinks_t, + incomingParticleLinks, + setIncomingParticleLinks ) + + /// Accessor for the incoming particles + static SG::AuxElement::Accessor< TruthVertex::TPLinks_t > + incomingParticleLinksAcc( "incomingParticleLinks" ); + + size_t TruthVertex::nIncomingParticles() const { + + // Check if the variable is available: + if( ! incomingParticleLinksAcc.isAvailable( *this ) ) { + // If not, just tell the user that there aren't any incoming particles: + return 0; + } + + // Return the size of the vector: + return incomingParticleLinksAcc( *this ).size(); + } + + const TruthParticle* TruthVertex::incomingParticle( size_t index ) const { + + // Check that the variable exists, and that it has enough elements in it: + if( ( ! incomingParticleLinksAcc.isAvailable( *this ) ) || + ( incomingParticleLinksAcc( *this ).size() <= index ) ) { + return 0; + } + + // Retrieve the link object and check its validity: + const TPLink_t& ipl = incomingParticleLinksAcc( *this )[ index ]; + if( ! ipl.isValid() ) { + return 0; + } + + // Finally, de-reference the link: + return *ipl; + } + + void TruthVertex::addIncomingParticleLink( const TPLink_t& link ) { + + incomingParticleLinksAcc( *this ).push_back( link ); + return; + } + + void TruthVertex::clearIncomingParticleLinks() { + + incomingParticleLinksAcc( *this ).clear(); + return; + } + + AUXSTORE_OBJECT_SETTER_AND_GETTER( TruthVertex, TruthVertex::TPLinks_t, + outgoingParticleLinks, + setOutgoingParticleLinks ) + + /// Accessor for the outgoing particles + static SG::AuxElement::Accessor< TruthVertex::TPLinks_t > + outgoingParticleLinksAcc( "outgoingParticleLinks" ); + + size_t TruthVertex::nOutgoingParticles() const { + + // Check if the variable is available: + if( ! outgoingParticleLinksAcc.isAvailable( *this ) ) { + // If not, just tell the user that there aren't any outgoing particles: + return 0; + } + + // Return the size of the vector: + return outgoingParticleLinksAcc( *this ).size(); + } + + const TruthParticle* TruthVertex::outgoingParticle( size_t index ) const { + + // Check that the variable exists, and that it has enough elements in it: + if( ( ! outgoingParticleLinksAcc.isAvailable( *this ) ) || + ( outgoingParticleLinksAcc( *this ).size() <= index ) ) { + return 0; + } + + // Retrieve the link object and check its validity: + const TPLink_t& opl = outgoingParticleLinksAcc( *this )[ index ]; + if( ! opl.isValid() ) { + return 0; + } + + // Finally, de-reference the link: + return *opl; + } + + void TruthVertex::addOutgoingParticleLink( const TPLink_t& link ) { + + outgoingParticleLinksAcc( *this ).push_back( link ); + return; + } + + void TruthVertex::clearOutgoingParticleLinks() { + + outgoingParticleLinksAcc( *this ).clear(); + return; + } + + // + ///////////////////////////////////////////////////////////////////////////// + + ///////////////////////////////////////////////////////////////////////////// + // + // Implementation of the functions specifying the vertex's position + // + + AUXSTORE_PRIMITIVE_GETTER( TruthVertex, float, x ) + + void TruthVertex::setX( float x ) { + + static SG::AuxElement::Accessor< float > acc( "x" ); + m_v4Cached = false; + acc( *this ) = x; + return; + } + + AUXSTORE_PRIMITIVE_GETTER( TruthVertex, float, y ) + + void TruthVertex::setY( float y ) { + + static SG::AuxElement::Accessor< float > acc( "y" ); + m_v4Cached = false; + acc( *this ) = y; + return; + } + + AUXSTORE_PRIMITIVE_GETTER( TruthVertex, float, z ) + + void TruthVertex::setZ( float z ) { + + static SG::AuxElement::Accessor< float > acc( "z" ); + m_v4Cached = false; + acc( *this ) = z; + return; + } + + float TruthVertex::perp() const { + + // Do the calculation by hand. Could make it faster than this even in a + // future iteration... + return std::sqrt( x() * x() + y() * y() ); + } + + float TruthVertex::eta() const { + + // This is not necessarily what Andy was thinking about... + return v4().Eta(); + } + + float TruthVertex::phi() const { + + // This is not necessarily what Andy was thinking about... + return v4().Phi(); + } + + AUXSTORE_PRIMITIVE_GETTER( TruthVertex, float, t ) + + void TruthVertex::setT( float t ) { + + static SG::AuxElement::Accessor< float > acc( "t" ); + m_v4Cached = false; + acc( *this ) = t; + return; + } + + const TruthVertex::FourVec_t& TruthVertex::v4() const { + + // Cache the 4-vector if it's not already: + if( ! m_v4Cached ) { + m_v4.SetXYZT( x(), y(), z(), t() ); + m_v4Cached = true; + } + + // Return the cached object: + return m_v4; + } + + // + ///////////////////////////////////////////////////////////////////////////// + + Type::ObjectType TruthVertex::type() const { + + return Type::TruthVertex; + } + + void TruthVertex::toPersistent() { + + // Prepare the incoming particle links for persistification: + if( incomingParticleLinksAcc.isAvailableWritable( *this ) ) { + TPLinks_t::iterator itr = incomingParticleLinksAcc( *this ).begin(); + TPLinks_t::iterator end = incomingParticleLinksAcc( *this ).end(); + for( ; itr != end; ++itr ) { + itr->toPersistent(); + } + } + + // Prepare the outgoing particle links for persistification: + if( outgoingParticleLinksAcc.isAvailableWritable( *this ) ) { + TPLinks_t::iterator itr = outgoingParticleLinksAcc( *this ).begin(); + TPLinks_t::iterator end = outgoingParticleLinksAcc( *this ).end(); + for( ; itr != end; ++itr ) { + itr->toPersistent(); + } + } + + return; + } + +} // namespace xAOD diff --git a/xAOD/xAODTruth/Root/TruthVertexAuxContainer.cxx b/xAOD/xAODTruth/Root/TruthVertexAuxContainer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a0b3f0d606f64ff8224cabeeb4760fb857acc548 --- /dev/null +++ b/xAOD/xAODTruth/Root/TruthVertexAuxContainer.cxx @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TruthVertexAuxContainer.cxx 624338 2014-10-27 15:08:55Z krasznaa $ + +// Local include(s): +#include "xAODTruth/TruthVertexAuxContainer.h" + +namespace xAOD { + + TruthVertexAuxContainer::TruthVertexAuxContainer() + : AuxContainerBase() { + + AUX_VARIABLE( id ); + AUX_VARIABLE( barcode ); + AUX_VARIABLE( incomingParticleLinks ); + AUX_VARIABLE( outgoingParticleLinks ); + AUX_VARIABLE( x ); + AUX_VARIABLE( y ); + AUX_VARIABLE( z ); + AUX_VARIABLE( t ); + } + +} // namespace xAOD diff --git a/xAOD/xAODTruth/Root/dict/ContainerProxies.cxx b/xAOD/xAODTruth/Root/dict/ContainerProxies.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c3086181764205a40e47b54a7cabdde37ea85bbe --- /dev/null +++ b/xAOD/xAODTruth/Root/dict/ContainerProxies.cxx @@ -0,0 +1,12 @@ +// EDM include(s): +#include "xAODCore/AddDVProxy.h" + +// Local include(s): +#include "xAODTruth/TruthParticleContainer.h" +#include "xAODTruth/TruthVertexContainer.h" +#include "xAODTruth/TruthEventContainer.h" + +// Set up the collection proxies: +ADD_NS_DV_PROXY( xAOD, TruthParticleContainer ); +ADD_NS_DV_PROXY( xAOD, TruthVertexContainer ); +ADD_NS_DV_PROXY( xAOD, TruthEventContainer ); diff --git a/xAOD/xAODTruth/Root/xAODTruthCLIDs.cxx b/xAOD/xAODTruth/Root/xAODTruthCLIDs.cxx new file mode 100644 index 0000000000000000000000000000000000000000..50c624ca9b6fe760a22eaba20505d412f3e02359 --- /dev/null +++ b/xAOD/xAODTruth/Root/xAODTruthCLIDs.cxx @@ -0,0 +1,14 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + + +//simple includes to force the CLASS_DEF to be encountered during compile + +#include "xAODTruth/TruthVertexContainer.h" +#include "xAODTruth/TruthVertexAuxContainer.h" +#include "xAODTruth/TruthEventContainer.h" +#include "xAODTruth/TruthEventAuxContainer.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "xAODTruth/TruthParticleAuxContainer.h" + diff --git a/xAOD/xAODTruth/Root/xAODTruthHelpers.cxx b/xAOD/xAODTruth/Root/xAODTruthHelpers.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3d00de95e602944a5a772eff2a659cb1f4afe9cf --- /dev/null +++ b/xAOD/xAODTruth/Root/xAODTruthHelpers.cxx @@ -0,0 +1,90 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: xAODTruthHelpers.cxx 668406 2015-05-19 15:32:15Z krasznaa $ + +// Core EDM include(s): +#include "AthLinks/ElementLink.h" +#include "AthContainers/AuxElement.h" + +// xAOD include(s): +#include "xAODBase/IParticle.h" + +// Local include(s): +#include "xAODTruth/xAODTruthHelpers.h" +#include "xAODTruth/TruthParticle.h" +#include "xAODTruth/TruthParticleContainer.h" + +namespace xAOD { + + namespace TruthHelpers { + + /// @param p The particle that we find the associated truth particle for + /// @returns A pointer to the associated truth particle if available, + /// or a null pointer if not + /// + const xAOD::TruthParticle* getTruthParticle( const xAOD::IParticle& p ) { + + /// A convenience type declaration + typedef ElementLink< xAOD::TruthParticleContainer > Link_t; + + /// A static accessor for the information + static SG::AuxElement::ConstAccessor< Link_t > acc( "truthParticleLink" ); + + // Check if such a link exists on the object: + if( ! acc.isAvailable( p ) ) { + return 0; + } + + // Get the link: + const Link_t& link = acc( p ); + + // Check if the link is valid: + if( ! link.isValid() ) { + return 0; + } + + // Everything has passed, let's return the pointer: + return *link; + } + + /// @param p The particle that we want to find the truth type of + /// @returns 0 if the truth type is not available, or the truth type + /// determined by MCTruthClassifier, if it is + /// + int getParticleTruthType( const xAOD::IParticle& p ) { + + /// A static accessor for the information + static SG::AuxElement::ConstAccessor< int > acc( "truthType" ); + + // Check if such a variable exists on the object: + if( ! acc.isAvailable( p ) ) { + return 0; + } + + // Let's return the value: + return acc( p ); + } + + /// @param p The particle that we want to find the truth origin of + /// @returns 0 if the truth origin is not available, or the truth origin + /// determined by MCTruthClassifier, if it is + /// + int getParticleTruthOrigin( const xAOD::IParticle& p ) { + + /// A static accessor for the information + static SG::AuxElement::ConstAccessor< int > acc( "truthOrigin" ); + + // Check if such a variable exists on the object: + if( ! acc.isAvailable( p ) ) { + return 0; + } + + // Let's return the value: + return acc( p ); + } + + } // namespace TruthHelpers + +} // namespace xAOD diff --git a/xAOD/xAODTruth/TODO b/xAOD/xAODTruth/TODO new file mode 100644 index 0000000000000000000000000000000000000000..65552242600f222c6c7417e5bd35dd24d2af6b29 --- /dev/null +++ b/xAOD/xAODTruth/TODO @@ -0,0 +1,8 @@ +xAOD truth TODOs +================ + +* Tidy TruthEvent attrs, add named weight vector + +* Handling run-level info like cross-sections? + +* Add a vector of separate TruthPileupEvent objects, which store no event-level info diff --git a/xAOD/xAODTruth/cmt/Makefile.RootCore b/xAOD/xAODTruth/cmt/Makefile.RootCore new file mode 100644 index 0000000000000000000000000000000000000000..e44442caa389d2963ed687991bbed33a412b1654 --- /dev/null +++ b/xAOD/xAODTruth/cmt/Makefile.RootCore @@ -0,0 +1,24 @@ +# this makefile also gets parsed by shell scripts +# therefore it does not support full make syntax and features +# edit with care + +# for full documentation check: +# https://twiki.cern.ch/twiki/bin/viewauth/Atlas/RootCore#Package_Makefile + +PACKAGE = xAODTruth +PACKAGE_PRELOAD = +PACKAGE_CXXFLAGS = +PACKAGE_OBJFLAGS = +PACKAGE_LDFLAGS = +PACKAGE_BINFLAGS = +PACKAGE_LIBFLAGS = +PACKAGE_DEP = AthContainers AthLinks xAODBase xAODCore TruthUtils +PACKAGE_TRYDEP = +PACKAGE_CLEAN = +PACKAGE_NOGRID = +PACKAGE_PEDANTIC = 1 +PACKAGE_NOOPT = 0 +PACKAGE_NOCC = 0 +PACKAGE_REFLEX = 1 + +include $(ROOTCOREDIR)/Makefile-common diff --git a/xAOD/xAODTruth/cmt/requirements b/xAOD/xAODTruth/cmt/requirements new file mode 100644 index 0000000000000000000000000000000000000000..44f457ab07aacdadc7b5440f8ba1ab3fcd1062ec --- /dev/null +++ b/xAOD/xAODTruth/cmt/requirements @@ -0,0 +1,42 @@ +package xAODTruth +# $Id: requirements 761796 2016-07-14 08:06:02Z krasznaa $ + +author Andy Buckley <andy.buckley@cern.ch> +author James Catmore <james.catmore@cern.ch> +author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> +author Jovan Mitrevski <Jovan.Mitrevski@cern.ch> + +public + +# Central packages: +use AtlasPolicy AtlasPolicy-* +use AthContainers AthContainers-* Control +use AthLinks AthLinks-* Control + +# EDM packages: +use xAODBase xAODBase-* Event/xAOD +use xAODCore xAODCore-* Event/xAOD +use AtlasROOT AtlasROOT-* External + +# Specify the ROOT components that are necessary for cmake. Transparent to CMT +apply_pattern cmake_add_command command="find_package(ROOT COMPONENTS Physics)" + +library xAODTruth ../Root/*.cxx +apply_pattern installed_library + +private + +use TruthUtils TruthUtils-* Generators +use AtlasReflex AtlasReflex-* External + +# Generate a dictionary for the package: +apply_pattern lcgdict dict=xAODTruth selectionfile=selection.xml \ + headerfiles="../xAODTruth/xAODTruthDict.h" \ + extralibfiles=../Root/dict/*.cxx + +apply_pattern do_genCLIDDB library=xAODTruth + +# Specify the unit test(s) of the package: +use TestTools TestTools-* AtlasTest +apply_pattern UnitTest_run unit_test=ut_xaodtruth_particle + diff --git a/xAOD/xAODTruth/share/ut_xaodtruth_particle_test.ref b/xAOD/xAODTruth/share/ut_xaodtruth_particle_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..fdaff706b58a58b373166733cd7d08319568a231 --- /dev/null +++ b/xAOD/xAODTruth/share/ut_xaodtruth_particle_test.ref @@ -0,0 +1 @@ +All tests succeeded diff --git a/xAOD/xAODTruth/test/ut_xaodtruth_helpers_test.py b/xAOD/xAODTruth/test/ut_xaodtruth_helpers_test.py new file mode 100644 index 0000000000000000000000000000000000000000..4147126363f0779555b4663a4acca857d0c98252 --- /dev/null +++ b/xAOD/xAODTruth/test/ut_xaodtruth_helpers_test.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +# +# $Id: ut_xaodtruth_helpers_test.py 761304 2016-07-12 12:03:36Z krasznaa $ +# +# This is a simple unit test for checking the health of the truth helper +# functions in the standalone analysis environment. +# + +## C/C++ style main function +def main(): + + # Initialise the environment: + import ROOT + ROOT.gROOT.Macro( "$ROOTCOREDIR/scripts/load_packages.C" ) + + # Open an input xAOD file: + import os + FNAME = os.getenv( "ROOTCORE_TEST_FILE", "FileNotSpecifiedInEnvironment" ) + f = ROOT.TFile.Open( FNAME, "READ" ) + if not f: + print( "Couldn't open \"%s\"" % FNAME ) + return 1 + print( "Opened: %s" % FNAME ) + + # Make a transient tree from it: + treeMgr = ROOT.xAOD.TTreeMgr( ROOT.xAOD.TEvent.kAthenaAccess ) + if not treeMgr.readFrom( f ).isSuccess(): + print( "Couldn't make a transient tree from the input file!" ) + return 1 + import xAODRootAccess.GenerateDVIterators + t = treeMgr.eventTree() + + # Loop on the first few events: + for entry in xrange( 10 ): + # Load the event: + if t.GetEntry( entry ) < 0: + print( "Couldn't load entry %i from the input!" % entry ) + return 1 + # Print some header info: + print( "Processing run #%i event #%i (%i events processed so far)" % \ + ( t.EventInfo.runNumber(), t.EventInfo.eventNumber(), entry ) ) + # Exercise the functions on electrons: + for el in t.Electrons: + print( " - Electron: eta = %g, phi = %g, pt = %g" % \ + ( el.eta(), el.phi(), el.pt() ) ) + print( " truthType = %i, truthOrigin = %i" % \ + ( ROOT.xAOD.TruthHelpers.getParticleTruthType( el ), + ROOT.xAOD.TruthHelpers.getParticleTruthOrigin( el ) ) ) + tp = ROOT.xAOD.TruthHelpers.getTruthParticle( el ) + if tp: + print( " - TruthParticle: eta = %g, phi = %g, pt = %g" % \ + ( tp.eta(), tp.phi(), tp.pt() ) ) + pass + pass + pass + + return 0; + +# Execute the main function: +if __name__ == "__main__": + import sys + sys.exit( main() ) diff --git a/xAOD/xAODTruth/test/ut_xaodtruth_particle_test.cxx b/xAOD/xAODTruth/test/ut_xaodtruth_particle_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..363f3b15cb5bc712f1111babdea7cde394b23718 --- /dev/null +++ b/xAOD/xAODTruth/test/ut_xaodtruth_particle_test.cxx @@ -0,0 +1,73 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: ut_xaodtruth_particle_test.cxx 687313 2015-08-04 12:07:38Z krasznaa $ + +// System include(s): +#include <iostream> +#include <cmath> + +// Local include(s): +#include "xAODTruth/TruthParticle.h" +#include "xAODTruth/TruthParticleContainer.h" +#include "xAODTruth/TruthParticleAuxContainer.h" + +/// Helper macro to test assertions +#define SIMPLE_ASSERT( EXP ) \ + do { \ + if( ! ( EXP ) ) { \ + std::cout << "Error evaluating: " << #EXP << std::endl; \ + return 1; \ + } \ + } while( 0 ) + +int main() { + + // Create a container to test: + xAOD::TruthParticleContainer c; + xAOD::TruthParticleAuxContainer aux; + c.setStore( &aux ); + + // Construct a particle that we can test. The values are chosen on purpose + // to not be possible to represent in exactly the same way at single and + // double precision. + static const double PX = std::sqrt( ( double ) 1.2345 ); + static const double PY = std::sqrt( ( double ) 2.3456 ); + static const double PZ = std::sqrt( ( double ) 3.4567 ); + static const double E = std::sqrt( ( double ) 4.5678 ); + static const double M = std::sqrt( ( double ) 5.6789 ); + xAOD::TruthParticle* p = new xAOD::TruthParticle(); + c.push_back( p ); + p->setPx( PX ); + p->setPy( PY ); + p->setPz( PZ ); + p->setE( E ); + p->setM( M ); + + // The precisions that we want: + static const double FLOAT_PRECISION = 1e-5; + static const double DOUBLE_PRECISION = 1e-10; + + // Start with the most basic checks: + SIMPLE_ASSERT( std::abs( p->px() - PX ) < FLOAT_PRECISION ); + SIMPLE_ASSERT( std::abs( p->py() - PY ) < FLOAT_PRECISION ); + SIMPLE_ASSERT( std::abs( p->pz() - PZ ) < FLOAT_PRECISION ); + SIMPLE_ASSERT( std::abs( p->e() - E ) < FLOAT_PRECISION ); + SIMPLE_ASSERT( std::abs( p->m() - M ) < FLOAT_PRECISION ); + + // Now something more tricky: + SIMPLE_ASSERT( std::abs( p->pt() - p->p4().Pt() ) < DOUBLE_PRECISION ); + SIMPLE_ASSERT( std::abs( p->eta() - p->p4().Eta() ) < DOUBLE_PRECISION ); + SIMPLE_ASSERT( std::abs( p->phi() - p->p4().Phi() ) < DOUBLE_PRECISION ); + SIMPLE_ASSERT( std::abs( p->e() - p->p4().E() ) < DOUBLE_PRECISION ); + + // And finally something not completely obvious: + SIMPLE_ASSERT( std::abs( p->m() - p->p4().M() ) > 0.1 ); + + // Let the user know what happened: + std::cout << "All tests succeeded" << std::endl; + + // Return gracefully: + return 0; +} diff --git a/xAOD/xAODTruth/xAODTruth/TruthEvent.h b/xAOD/xAODTruth/xAODTruth/TruthEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..939dd937c16c70a64fa3bf5dbee0fb48802b1ddf --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthEvent.h @@ -0,0 +1,210 @@ +#ifndef XAODTRUTH_TRUTHEVENT_H +#define XAODTRUTH_TRUTHEVENT_H + +// System include(s): +#include <utility> +#include <vector> + +// EDM include(s): +#include "AthContainers/AuxElement.h" +#include "AthLinks/ElementLink.h" +#include "xAODBase/ObjectType.h" + +// Local include(s): +#include "xAODTruth/TruthParticleContainer.h" +#include "xAODTruth/TruthVertexContainer.h" + +namespace xAOD { + + /// Class describing a signal truth event in the MC record + /// + class TruthEvent : public SG::AuxElement { + + public: + /// Default constructor + TruthEvent(); + /// Virtual destructor, to make vtable happy + virtual ~TruthEvent() {} + + /// @name Access to all the particles associated with the event + /// @{ + + /// Type of a single truth particle link + typedef ElementLink< TruthParticleContainer > TruthParticleLink_t; + /// Type of the truth particle links vector + typedef std::vector< TruthParticleLink_t > TruthParticleLinks_t; + + /// Get all the truth particles + const TruthParticleLinks_t& truthParticleLinks() const; + /// Set all the truth particles + void setTruthParticleLinks( const TruthParticleLinks_t& plinks ); + /// Get the number of truth particles + size_t nTruthParticles() const; + /// Get the link to one of the truth particles + const TruthParticleLink_t& truthParticleLink( size_t index ) const; + /// Get a pointer to one of the truth particles + const TruthParticle* truthParticle( size_t index ) const; + /// Add one truth particle + void addTruthParticleLink( const TruthParticleLink_t& plink ); + /// Remove all truth particles + void clearTruthParticleLinks(); + + /// @} + + /// @name Access to all the vertices associated with the event + /// @{ + + /// Type of a single truth vertex link + typedef ElementLink< TruthVertexContainer > TruthVertexLink_t; + /// Type of the truth particle links vector + typedef std::vector< TruthVertexLink_t > TruthVertexLinks_t; + + /// Get all the truth vertices + const TruthVertexLinks_t& truthVertexLinks() const; + /// Set all the truth vertices + void setTruthVertexLinks( const TruthVertexLinks_t& links ); + /// Get the number of truth vertices + size_t nTruthVertices() const; + /// Get the link to one of the truth vertices + const TruthVertexLink_t& truthVertexLink( size_t index ) const; + /// Get a pointer to one of the truth vertices + const TruthVertex* truthVertex( size_t index ) const; + /// Add one truth vertex + void addTruthVertexLink( const TruthVertexLink_t& vlink ); + /// Remove all truth vertices + void clearTruthVertexLinks(); + + /// @} + + /// @name Simple event properties + /// @{ + + /// Const access to the weights vector + /// @todo Need to add the map-like interface for the weights: very important! + const std::vector< float >& weights() const; + /// Set the event weights + /// @todo Need to add named weight access: vector<string> + void setWeights( const std::vector< float >& weights ); + + /// Get the cross section + float crossSection() const; + /// Set the cross-section + void setCrossSection( float value ); + + /// Get the cross section error + float crossSectionError() const; + /// Set the cross-section error + void setCrossSectionError( float value ); + + /// Set the cross-section and its error + void setCrossSection( float value, float error ); + + /// @} + + /// @name Parton density info + /// + /// Optional due to particle gun & NLO events where a single PDF info + /// doesn't work. + /// + /// @{ + + /// Accessor enums for PDF info parameter lookup + enum PdfParam { + PDGID1 = 0, ///< [int] + PDGID2 = 1, ///< [int] + PDFID1 = 2, ///< [int] + PDFID2 = 3, ///< [int] + X1 = 4, ///< [float] + X2 = 5, ///< [float] + SCALE = 6, ///< Not implemented!!! + Q = 6, ///< [float] + PDF1 = 7, ///< Not implemented!!! + PDF2 = 8, ///< Not implemented!!! + XF1 = 7, ///< [float] + XF2 = 8 ///< [float] + }; // enum PdfParam + + /// Read an integer PDF info parameter + bool pdfInfoParameter( int& value, PdfParam parameter ) const; + /// Read a floating point PDF info parameter + bool pdfInfoParameter( float& value, PdfParam parameter ) const; + + /// Set an integer PDF info parameter + bool setPdfInfoParameter( int value, PdfParam parameter ); + /// Set a floating point PDF info parameter + bool setPdfInfoParameter( float value, PdfParam parameter ); + + /// Helper struct holding a full set of PDF info values + struct PdfInfo { + + /// Constructor to set (invalid) defaults + PdfInfo(); + + /// Check if all the variables in the object are valid + bool valid() const; + + int pdgId1; + int pdgId2; + int pdfId1; + int pdfId2; + float x1; + float x2; + float Q; + float xf1; + float xf2; + + }; // struct PdfInfo + + /// Retrieve a full PdfInfo with a single call + /// @note May have invalid values -- use valid() to check. + PdfInfo pdfInfo() const; + + /// @} + + /// @name Links to particles and vertices in the event + /// @{ + + /// Pointer to a vertex representing the primary interaction point + /// + /// The naming of the function is a bit misleading. The returned vertex + /// can only be interpreted as an interaction *position*. + /// + const TruthVertex* signalProcessVertex() const; + /// Link to the vertex representing the primary interaction point + const TruthVertexLink_t& signalProcessVertexLink() const; + /// Set pointer to a vertex representing the primary interaction point + void setSignalProcessVertexLink( const TruthVertexLink_t& link ); + + /// Pointer to the incoming primary particle + const TruthParticle* primaryParticle() const; + + /// Get the link to the primary particle + const TruthParticleLink_t& primaryParticleLink() const; + + /// Set incoming primary particle + void setPrimaryParticleLink( const TruthParticleLink_t& pcl); + + /// @} + + /// The type of the object as a simple enumeration + virtual Type::ObjectType type() const; + + /// @name Simple truth meta data properties + /// @{ + + uint32_t mcChannelNumber() const; + void setMcChannelNumber( uint32_t value ); + + const std::vector< std::string >& weightNames() const; + void setWeightNames( const std::vector< std::string >& value ); + + /// @} + + /// Function making sure that the object is ready for persistification + void toPersistent(); + + }; // class TruthEvent + +} // namespace xAOD + +#endif // XAODTRUTH_TRUTHEVENT_H diff --git a/xAOD/xAODTruth/xAODTruth/TruthEventAuxContainer.h b/xAOD/xAODTruth/xAODTruth/TruthEventAuxContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..57c6e62ccd9de8455859654f3dbd3d2cc10a71fe --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthEventAuxContainer.h @@ -0,0 +1,62 @@ +#ifndef XAODTRUTH_TRUTHEVENTAUXCONTAINER_H +#define XAODTRUTH_TRUTHEVENTAUXCONTAINER_H + +// System include(s): +#include <vector> + +// EDM include(s): +#include "AthLinks/ElementLink.h" +#include "xAODCore/AuxContainerBase.h" + +// Local include(s): +#include "xAODTruth/TruthParticleContainer.h" +#include "xAODTruth/TruthVertexContainer.h" + +namespace xAOD { + + /// Auxiliary store for the truth vertices + /// + class TruthEventAuxContainer : public AuxContainerBase { + + public: + /// Default constructor + TruthEventAuxContainer(); + + private: + /// @name Links to the interaction particles/vertices + /// @{ + std::vector< ElementLink< TruthVertexContainer > > + signalProcessVertexLink; + /// @} + + /// @todo Needs to be a map or similar (perhaps two linked vectors?) + std::vector< std::vector< float > > weights; + + /// @name Cross sections and errors coming from the generator + /// @{ + std::vector< float > crossSection; + std::vector< float > crossSectionError; + /// @} + + /// @name Links to the generated/simulated particles/vertices + /// @{ + std::vector< std::vector< ElementLink< TruthParticleContainer > > > + truthParticleLinks; + std::vector< std::vector< ElementLink< TruthVertexContainer > > > + truthVertexLinks; + /// @} + + //Two vectors (of vectors) to store association between weight name and weight + //index. No std::map is used for increased read-back speed in ROOT + std::vector < std::vector < std::string > > weightNames; + std::vector < uint32_t > mcChannelNumber; + + }; // class TruthEventAuxContainer + +} // namespace xAOD + +// Declare the class's inheritance to StoreGate: +#include "xAODCore/BaseInfo.h" +SG_BASE( xAOD::TruthEventAuxContainer, xAOD::AuxContainerBase ); + +#endif // XAODTRUTH_TRUTHEVENTAUXCONTAINER_H diff --git a/xAOD/xAODTruth/xAODTruth/TruthEventContainer.h b/xAOD/xAODTruth/xAODTruth/TruthEventContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..eb99877bae90dab0f76ace26b4fff0b3f7371d2b --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthEventContainer.h @@ -0,0 +1,22 @@ +// -*- C++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TruthEventContainer_v1.h 622193 2014-10-16 16:08:34Z krasznaa $ +#ifndef XAODTRUTH_TRUTHEVENTCONTAINER_H +#define XAODTRUTH_TRUTHEVENTCONTAINER_H + +// EDM include(s): +#include "AthContainers/DataVector.h" + +// Local include(s): +#include "xAODTruth/TruthEvent.h" + +namespace xAOD { + /// Alias + typedef DataVector< TruthEvent > TruthEventContainer; +} + +#endif // XAODTRUTH_TRUTHEVENTCONTAINER_H diff --git a/xAOD/xAODTruth/xAODTruth/TruthParticle.h b/xAOD/xAODTruth/xAODTruth/TruthParticle.h new file mode 100644 index 0000000000000000000000000000000000000000..3a230b018d4e8ad54afe337312efe6de18b1aa34 --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthParticle.h @@ -0,0 +1,360 @@ +#ifndef XAODTRUTH_TRUTHPARTICLE_H +#define XAODTRUTH_TRUTHPARTICLE_H + +// EDM include(s): +#include "AthLinks/ElementLink.h" +#include "AthContainers/DataVector.h" + +// xAOD include(s): +#include "xAODBase/IParticle.h" +#include "xAODBase/ObjectType.h" + +namespace xAOD { + class TruthVertex; + typedef DataVector< TruthVertex > TruthVertexContainer; + + /// Class describing a truth particle in the MC record + /// + /// The xAOD truth record mimics the structure of HepMC. Truth particles + /// and truth vertices form a decay tree. Where each truth particle is + /// connected to a single production and decay vertex. And each vertex is + /// connected to one or more incoming, and one or more outgoing particles. + /// + class TruthParticle : public IParticle { + + public: + /// Default constructor + TruthParticle(); + + /// @name Functions identifying the particle in the MC record + /// @{ + + /// Set PDG ID code + void setPdgId( int pid ); + /// PDG ID code + int pdgId() const; + /// Absolute PDG ID code (often useful) + int absPdgId() const; + + /// Barcode + /// @note Meaning of barcode may change -- be careful! + int barcode() const; + /// Set barcode + void setBarcode( int value ); + + /// Status code + int status() const; + /// Set status code + void setStatus( int value ); + + /// @} + + /// @name Links to the production and decay vertices + /// @{ + + /// Check for a production vertex on this particle + bool hasProdVtx() const; + /// The production vertex of this particle + const TruthVertex* prodVtx() const; + /// The production vertex link of this particle + const ElementLink< TruthVertexContainer >& prodVtxLink() const; + /// Set the production vertex of the particle + void setProdVtxLink( const ElementLink< TruthVertexContainer >& link ); + + /// Check for a decay vertex on this particle + bool hasDecayVtx() const; + /// The decay vertex of this particle + const TruthVertex* decayVtx() const; + /// The decay vertex link of this particle + const ElementLink< TruthVertexContainer >& decayVtxLink() const; + /// Set the decay vertex of the particle + void setDecayVtxLink( const ElementLink< TruthVertexContainer >& link ); + + /// @} + + /// @name Particle connection / origin / decay information + /// @{ + + /// Number of parents of this particle + size_t nParents() const; + + /// Retrieve the i-th mother (TruthParticle) of this TruthParticle + const TruthParticle* parent( size_t i = 0 ) const; + + /// Number of children of this particle + size_t nChildren() const; + + /// Retrieve the i-th mother (TruthParticle) of this TruthParticle + const TruthParticle* child( size_t i = 0 ) const; + + /// @} + + /// @name Functions implementing the xAOD::IParticle interface + /// @{ + + /// The transverse momentum (\f$p_T\f$) of the particle + virtual double pt() const; + /// The pseudorapidity (\f$\eta\f$) of the particle + virtual double eta() const; + /// The azimuthal angle (\f$\phi\f$) of the particle + virtual double phi() const; + /// The mass of the particle + /// + /// Note, not necessarily = \f$E^2-p^2\f$ if not on mass shell. + /// + virtual double m() const; + /// The total energy of the particle + virtual double e() const; + /// The true rapidity (\f$y\f$) of the particle + virtual double rapidity() const; + + /// Definition of the 4-momentum type + typedef IParticle::FourMom_t FourMom_t; + + /// The full 4-momentum of the particle + /// + /// Note that m may not be right, though, if not on mass shell. In which + /// case <code>p4().M()</code> will be different from <code>m()</code>. + /// + virtual const FourMom_t& p4() const; + + /// The type of the object as a simple enumeration + virtual Type::ObjectType type() const; + + /// @} + + /// @name 4-momentum accessors specific to truth particles + /// @{ + + /// The absolute pseudorapidity (\f$|\eta|\f$) of the particle + double abseta() const; + /// The true absolute rapidity (\f$|y|\f$) of the particle + double absrapidity() const; + + /// The x component of the particle's momentum + float px() const; + /// Set the x component of the particle's momentum + void setPx( float value ); + + /// The y component of the particle's momentum + float py() const; + /// Set the y component of the particle's momentum + void setPy( float value ); + + /// The z component of the particle's momentum + float pz() const; + /// Set the z component of the particle's momentum + void setPz( float value ); + + /// Set the energy of the particle + void setE( float value ); + + /// Also store the mass + void setM( float value ); + + /// @} + + /// @name Particle species information + /// + /// Just convenience methods here, since they all just forward to the + /// utility functions operating on the PDG particle ID code. + /// + /// @{ + + /// Physical charge + double charge() const; + /// 3 x the physical charge (so it can be an int for quarks) + int threeCharge() const; + + /// Whether the particle is electrically charged + bool isCharged() const; + /// Whether the particle is electrically neutral + bool isNeutral() const; + + /// Whether the particle is a photon + bool isPhoton() const; + /// Whether the particle is a lepton + bool isLepton() const; + /// Whether the particle is a charged lepton + bool isChLepton() const; + /// Whether the particle is an electron (or positron) + bool isElectron() const; + /// Whether the particle is a muon (or antimuon) + bool isMuon() const; + /// Whether the particle is a tau (or antitau) + bool isTau() const; + /// Whether the particle is a neutrino (or antineutrino) + bool isNeutrino() const; + + /// Whether the particle is a hadron + bool isHadron() const; + /// Whether the particle is a meson + bool isMeson() const; + /// Whether the particle is a baryon + bool isBaryon() const; + + /// Whether the particle contains a strange quark (or antiquark) + bool hasStrange() const; + /// Whether the particle contains a charm quark (or antiquark) + bool hasCharm() const; + /// Whether the particle contains a bottom quark (or antiquark) + bool hasBottom() const; + + /// Determine if the PID is that of a light flavour (not b or c) meson + bool isLightMeson() const; + /// Determine if the PID is that of a light flavour (not b or c) baryon + bool isLightBaryon() const; + /// Determine if the PID is that of a light flavour (not b or c) hadron + bool isLightHadron() const; + + /// Determine if the PID is that of a heavy flavour (b or c) meson + bool isHeavyMeson() const; + /// Determine if the PID is that of a heavy flavour (b or c) baryon + bool isHeavyBaryon() const; + /// Determine if the PID is that of a heavy flavour (b or c) hadron + bool isHeavyHadron() const; + + /// Determine if the PID is that of a b-meson. + bool isBottomMeson() const; + /// Determine if the PID is that of a b-baryon. + bool isBottomBaryon() const; + /// Determine if the PID is that of a b-hadron. + bool isBottomHadron() const; + + /// @brief Determine if the PID is that of a c-meson. + /// + /// Specifically, the _heaviest_ quark is a c: a B_c is a b-meson and NOT + /// a c-meson. Charmonia (closed charm) are counted as c-mesons here. + /// + bool isCharmMeson() const; + /// @brief Determine if the PID is that of a c-baryon. + /// + /// Specifically, the _heaviest_ quark is a c: a baryon containing a b & c + /// is a b-baryon and NOT a c-baryon. To test for the simpler case, just + /// use a combination of hasCharm() and isBaryon(). + /// + bool isCharmBaryon() const; + /// Determine if the PID is that of a c-hadron. + bool isCharmHadron() const; + + /// Determine if the PID is that of a strange meson + bool isStrangeMeson() const; + /// Determine if the PID is that of a strange baryon + bool isStrangeBaryon() const; + /// Determine if the PID is that of a strange hadron + bool isStrangeHadron() const; + + /// Check if this particle is a quark + bool isQuark() const; + /// Check if this particle is a parton + bool isParton() const; + /// Check if this particle is a top quark + bool isTop() const; + /// Check if this particle is a W boson + bool isW() const; + /// Check if this particle is a Z boson + bool isZ() const; + /// Check if this particle is a Higgs boson + bool isHiggs() const; + /// Check if this particle is a resonant state + bool isResonance() const; + /// Check if this is a generator specific (non-physical) particle + bool isGenSpecific() const; + + /// @} + + /// @name Polarization properties (optional) + /// @{ + + /// Polarization parameter types + enum PolParam { + polarizationPhi = 0, ///< Polarization in (\f$\phi\f$) + polarizationTheta = 1 ///< Polarization in (\f$\theta\f$) + }; + + /// Accessor for polarization parameters + /// + /// Generic C++ code should use this function to retrieve the polarization + /// parameters of a truth particle. Since these parameters are optional, + /// the function is designed to tell the user whether the requested + /// parameter could be retrieved or not. + /// + /// @param value The polarization parameter value read from the object + /// @param parameter The polarization parameter that we are interested in + /// @return <code>true</code> if the retrieval was successful, + /// <code>false</code> if it wasn't + /// + bool polarizationParameter( float& value, PolParam parameter ) const; + + /// Set method for polarization parameter values + /// + /// In order to keep the symmetry with the getter function, this setter + /// communicates a possible failure in its operation through a return + /// value. Setting a polariozation parameter is much less likely to fail + /// than retrieving one, but in some situations it may still happen... + /// + /// @param value The polarization parameter value to set on the object + /// @param parameter The polarization parameter type that we want to set + /// @return <code>true</code> if the operation was successful, or + /// <code>false</code> if it wasn't + /// + bool setPolarizationParameter( float value, PolParam parameter ); + + /// Convenience accessor for a polariozation parameter. + /// + /// Throws an exception if the request can't be completed. It should + /// mostly be used in PyROOT, as the other form of this function is very + /// hard to use there. But one needs to know for sure that the requested + /// parameter will exist. + /// + /// @param parameter The polarion parameter that we are interested in + /// @return The value of the polarization parameter requested + /// + float polarizationPatameter( PolParam parameter ) const; + + /// Single container for full polarization information + /// + /// It can be used as a convenient way for accessing the polarization of + /// the particle with a single call. + /// + struct Polarization { + + /// Constructor to set (invalid) defaults + /// @todo Use C++11 inline member init when allowed + Polarization() + : phi( -1.0 ), theta( -1.0 ) {} + + /// Check if the stored values are valid + bool valid() const { + return ( ( phi > 0.0 ) && ( theta > 0.0 ) ); + } + + float phi; ///< Polarization in (\f$\phi\f$) + float theta; ///< Polarization in (\f$\theta\f$) + + }; // struct Polarization + + /// Retrieve a full Polarization with a single call + /// + /// @note May have invalid values -- use valid() to check. + /// + /// @return An object holding the full polarization information + /// + Polarization polarization() const; + + /// @} + + /// Function making sure that the object is ready for persistification + void toPersistent(); + + private: + /// Cached four momentum + mutable FourMom_t m_p4; + /// Flag specifying if the four-momentum is cached + mutable bool m_p4Cached; + + }; // class TruthParticle + +} // namespace xAOD + +#endif diff --git a/xAOD/xAODTruth/xAODTruth/TruthParticleAuxContainer.h b/xAOD/xAODTruth/xAODTruth/TruthParticleAuxContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..ca8ec36160eec199005d0f664863ae426d4e74cb --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthParticleAuxContainer.h @@ -0,0 +1,47 @@ +#ifndef XAODTRUTH_TRUTHPARTICLEAUXCONTAINER_H +#define XAODTRUTH_TRUTHPARTICLEAUXCONTAINER_H + +#include <vector> + +#include "AthLinks/ElementLink.h" +#include "xAODCore/AuxContainerBase.h" + +#include "xAODTruth/TruthParticleContainer.h" +#include "xAODTruth/TruthVertexContainer.h" + +namespace xAOD { + + + /// Auxiliary store for the truth vertices + /// + /// @author Andy Buckley <Andy.Buckey@cern.ch> + /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + /// @author Jovan Mitrevski <Jovan.Mitrevski@cern.h> + /// + class TruthParticleAuxContainer : public AuxContainerBase { + + public: + /// Default constructor + TruthParticleAuxContainer(); + + private: + std::vector< int > pdgId; + std::vector< int > barcode; + std::vector< int > status; + std::vector< ElementLink< TruthVertexContainer > > prodVtxLink; + std::vector< ElementLink< TruthVertexContainer > > decayVtxLink; + std::vector< float > px; + std::vector< float > py; + std::vector< float > pz; + std::vector< float > e; + std::vector< float > m; // needed since not necessarily on shell + + }; // class TruthParticleAuxContainer + +} // namespace xAOD + +// Declare a CLID for the class +#include "xAODCore/CLASS_DEF.h" +CLASS_DEF( xAOD::TruthParticleAuxContainer, 1107340896, 1 ) + +#endif // XAODTRUTH_TRUTHPARTICLEAUXCONTAINER_H diff --git a/xAOD/xAODTruth/xAODTruth/TruthParticleContainer.h b/xAOD/xAODTruth/xAODTruth/TruthParticleContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..89dc05cb0e73d2cf5914a7a11b2858d17d365af4 --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthParticleContainer.h @@ -0,0 +1,26 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TruthParticleContainer.h 622193 2014-10-16 16:08:34Z krasznaa $ +#ifndef XAODTRUTH_TRUTHPARTICLECONTAINER_H +#define XAODTRUTH_TRUTHPARTICLECONTAINER_H + +// Local include(s): +#include "xAODTruth/TruthParticle.h" +// EDM include(s): +#include "AthContainers/DataVector.h" + + +namespace xAOD { + // Alias + typedef DataVector< TruthParticle > TruthParticleContainer; +} + +// Declare a CLID for the class for Athena: +#include "xAODCore/CLASS_DEF.h" +CLASS_DEF( xAOD::TruthParticleContainer, 1237340765, 1 ) + +#endif // XAODTRUTH_TRUTHPARTICLECONTAINER_H diff --git a/xAOD/xAODTruth/xAODTruth/TruthVertex.h b/xAOD/xAODTruth/xAODTruth/TruthVertex.h new file mode 100644 index 0000000000000000000000000000000000000000..6f24fbd975800bc3708c9256dccc1f32c931276e --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthVertex.h @@ -0,0 +1,142 @@ +#ifndef XAODTRUTH_TRUTHVERTEX_H +#define XAODTRUTH_TRUTHVERTEX_H + +// ROOT include(s): +#include <TLorentzVector.h> + +// EDM include(s): +#include "AthContainers/AuxElement.h" +#include "AthLinks/ElementLink.h" + +// xAOD include(s): +#include "xAODBase/ObjectType.h" + +// Local include(s): +#include "xAODTruth/TruthParticleContainer.h" + +namespace xAOD { + + /// Class describing a truth vertex in the MC record + /// + /// The xAOD truth record mimics the structure of HepMC. Truth particles + /// and truth vertices form a decay tree. Where each truth particle is + /// connected to a single production and decay vertex. And each vertex is + /// connected to one or more incoming, and one or more outgoing particles. + /// + /// @author Andy Buckley <Andy.Buckley@cern.ch> + /// + /// $Revision: 624338 $ + /// $Date: 2014-10-27 16:08:55 +0100 (Mon, 27 Oct 2014) $ + /// + class TruthVertex : public SG::AuxElement { + + public: + /// Default constructor + TruthVertex(); + + /// @name Functions identifying the vertex in the MC record + /// @{ + + /// Set vertex ID code + void setId( int value ); + /// Vertex ID code + int id() const; + + /// Set barcode + void setBarcode( int value ); + /// Barcode + int barcode() const; + + /// @} + + /// @name Links to the particles associated with this vertex + /// @{ + + /// Type of one truth particle link + typedef ElementLink< TruthParticleContainer > TPLink_t; + /// Type used to save the links to incoming and outgoing particles + typedef std::vector< TPLink_t > TPLinks_t; + + /// Get all the incoming particles + const TPLinks_t& incomingParticleLinks() const; + /// Set all the incoming particles + void setIncomingParticleLinks( const TPLinks_t& links ); + /// Get the number of incoming particles + size_t nIncomingParticles() const; + /// Get one of the incoming particles + const TruthParticle* incomingParticle( size_t index ) const; + /// Add one incoming particle + void addIncomingParticleLink( const TPLink_t& link ); + /// Remove all incoming particles + void clearIncomingParticleLinks(); + + /// Get all the outgoing particles + const TPLinks_t& outgoingParticleLinks() const; + /// Set all the outgoing particles + void setOutgoingParticleLinks( const TPLinks_t& links ); + /// Get the number of outgoing particles + size_t nOutgoingParticles() const; + /// Get one of the outgoing particles + const TruthParticle* outgoingParticle( size_t index ) const; + /// Add one outgoing particle + void addOutgoingParticleLink( const TPLink_t& link ); + /// Remove all outgoing particles + void clearOutgoingParticleLinks(); + + /// @} + + /// @name Vertex position functions + /// @{ + + /// Vertex x displacement + float x() const; + /// Set the x displacement of the vertex + void setX( float value ); + + /// Vertex y displacement + float y() const; + /// Set the y displacement of the vertex + void setY( float value ); + + /// Vertex longitudinal distance along the beam line form the origin + float z() const; + /// Set the vertex's longitudinal distance from the origin + void setZ( float value ); + + /// Vertex transverse distance from the beam line + float perp() const; + /// Vertex pseudorapidity + float eta() const; + /// Vertex azimuthal angle + float phi() const; + + /// Vertex time + float t() const; + /// Set the vertex time + void setT( float value ); + + /// The 4-vector type + typedef TLorentzVector FourVec_t; + + /// The full 4-vector of the vertex + const FourVec_t& v4() const; + + /// @} + + /// The type of the object as a simple enumeration + Type::ObjectType type() const; + + /// Function making sure that the object is ready for persistification + void toPersistent(); + + private: + /// Cached four vector + mutable FourVec_t m_v4; + /// Flag showing whether the four-vector is cached + mutable bool m_v4Cached; + + }; // class TruthVertex + +} // namespace xAOD + +#endif diff --git a/xAOD/xAODTruth/xAODTruth/TruthVertexAuxContainer.h b/xAOD/xAODTruth/xAODTruth/TruthVertexAuxContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..b6098f4323eeee6a834f33495c00133a942571ea --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthVertexAuxContainer.h @@ -0,0 +1,50 @@ +#ifndef XAODTRUTH_TRUTHVERTEXAUXCONTAINER_H +#define XAODTRUTH_TRUTHVERTEXAUXCONTAINER_H + +// System include(s): +#include <vector> + +// EDM include(s): +#include "AthLinks/ElementLink.h" +#include "xAODCore/AuxContainerBase.h" + +// Local include(s): +#include "xAODTruth/TruthParticleContainer.h" + +namespace xAOD { + + /// Auxiliary store for the truth vertices + /// + /// @author Andy Buckley <Andy.Buckey@cern.ch> + /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> + /// + /// $Revision: 624338 $ + /// $Date: 2014-10-27 16:08:55 +0100 (Mon, 27 Oct 2014) $ + /// + class TruthVertexAuxContainer : public AuxContainerBase { + + public: + /// Default constructor + TruthVertexAuxContainer(); + + private: + std::vector< int > id; + std::vector< int > barcode; + std::vector< std::vector< ElementLink< TruthParticleContainer > > > + incomingParticleLinks; + std::vector< std::vector< ElementLink< TruthParticleContainer > > > + outgoingParticleLinks; + std::vector< float > x; + std::vector< float > y; + std::vector< float > z; + std::vector< float > t; + + }; // class TruthVertexAuxContainer + +} // namespace xAOD + +// Declare a CLID for the class +#include "xAODCore/CLASS_DEF.h" +CLASS_DEF( xAOD::TruthVertexAuxContainer, 1254939514, 1 ) + +#endif // XAODTRUTH_TRUTHVERTEXAUXCONTAINER_H diff --git a/xAOD/xAODTruth/xAODTruth/TruthVertexContainer.h b/xAOD/xAODTruth/xAODTruth/TruthVertexContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..464ffd7766ce27c26973140b316cb2d0682f7463 --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/TruthVertexContainer.h @@ -0,0 +1,25 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: TruthVertexContainer.h 622193 2014-10-16 16:08:34Z krasznaa $ +#ifndef XAODTRUTH_TRUTHVERTEXCONTAINER_H +#define XAODTRUTH_TRUTHVERTEXCONTAINER_H + +// Local include(s): +#include "xAODTruth/TruthVertex.h" +// EDM include(s): +#include "AthContainers/DataVector.h" + +namespace xAOD { + // Alias + typedef DataVector< TruthVertex > TruthVertexContainer; +} + +// Declare a CLID for the class for Athena: +#include "xAODCore/CLASS_DEF.h" +CLASS_DEF( xAOD::TruthVertexContainer, 1239726567, 1 ) + +#endif // XAODTRUTH_TRUTHVERTEXCONTAINER_H diff --git a/xAOD/xAODTruth/xAODTruth/selection.xml b/xAOD/xAODTruth/xAODTruth/selection.xml new file mode 100644 index 0000000000000000000000000000000000000000..f1ab8990a0e2c13bf7ef2154c6f593a9368805aa --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/selection.xml @@ -0,0 +1,66 @@ +<!-- $Id: selection.xml 670153 2015-05-27 11:42:29Z tbisanz $ --> +<lcgdict> + + <!-- The TruthParticle class(es): --> + <class name="xAOD::TruthParticle" > + <field name="m_p4" transient="true" /> + <field name="m_p4Cached" transient="true" /> + </class> + <read sourceClass="xAOD::TruthParticle" version="[1-]" + targetClass="xAOD::TruthParticle" source="" target="m_p4Cached" > + <![CDATA[ + m_p4Cached = false; + ]]> + </read> + <class name="xAOD::TruthParticle::Polarization" /> + + <!-- The TruthVertex class: --> + <class name="xAOD::TruthVertex" > + <field name="m_v4" transient="true" /> + <field name="m_v4Cached" transient="true" /> + </class> + <read sourceClass="xAOD::TruthVertex" version="[1-]" + targetClass="xAOD::TruthVertex" source="" target="m_v4Cached" > + <![CDATA[ + m_v4Cached = false; + ]]> + </read> + + <!-- The TruthEvent class(es): --> + <class name="xAOD::TruthEvent" /> + <class name="xAOD::TruthEvent::PdfInfo" /> + <class name="xAOD::TruthMetaData" /> + + <!-- The persistent classes: --> + <class name="xAOD::TruthParticleContainer" + id="58F98A16-E465-4CA5-A099-73033206D8E3" /> + <class name="xAOD::TruthVertexContainer" + id="5FBAE0AB-09F7-4B6C-B066-0A003FC38ECF" /> + <class name="xAOD::TruthEventContainer" + id="6290F297-F529-40EE-9FE5-1C577678306D" /> + + <class name="xAOD::TruthParticleAuxContainer" + id="BA8FA08F-8DD6-420D-97D5-8B54EABECD65" /> + <class name="xAOD::TruthVertexAuxContainer" + id="B6BD3B02-C411-4EB9-903F-5B099D3B1A3E" /> + <class name="xAOD::TruthEventAuxContainer" + id="1B945EFD-4F7D-4BDD-9FB1-6FB975315961" /> + + <!-- Smart pointers for TruthParticle: --> + <class name="DataLink<xAOD::TruthParticleContainer>" /> + <class name="std::vector<DataLink<xAOD::TruthParticleContainer> >" /> + <class name="ElementLink<xAOD::TruthParticleContainer>" /> + <class name="std::vector<ElementLink<xAOD::TruthParticleContainer> >" /> + <class name="std::vector<std::vector<ElementLink<xAOD::TruthParticleContainer> > >" /> + + <!-- Smart pointers for TruthVertex: --> + <class name="DataLink<xAOD::TruthVertexContainer>" /> + <class name="std::vector<DataLink<xAOD::TruthVertexContainer> >" /> + <class name="ElementLink<xAOD::TruthVertexContainer>" /> + <class name="std::vector<ElementLink<xAOD::TruthVertexContainer> >" /> + <class name="std::vector<std::vector<ElementLink<xAOD::TruthVertexContainer> > >" /> + + <!-- The helper functions: --> + <function pattern="xAOD::TruthHelpers::*" /> + +</lcgdict> diff --git a/xAOD/xAODTruth/xAODTruth/xAODTruthDict.h b/xAOD/xAODTruth/xAODTruth/xAODTruthDict.h new file mode 100644 index 0000000000000000000000000000000000000000..e7aec67bad32a4ef53afa3f23e493bc4ad0696a7 --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/xAODTruthDict.h @@ -0,0 +1,41 @@ +#ifndef XAODTRUTH_XAODTRUTHDICT_H +#define XAODTRUTH_XAODTRUTHDICT_H + +// System include(s): +#include <vector> + +// EDM include(s): +#include "AthLinks/DataLink.h" +#include "AthLinks/ElementLink.h" + +// Local include(s): +#include "xAODTruth/TruthParticleContainer.h" +#include "xAODTruth/TruthParticleAuxContainer.h" +#include "xAODTruth/TruthVertexContainer.h" +#include "xAODTruth/TruthVertexAuxContainer.h" +#include "xAODTruth/TruthEventContainer.h" +#include "xAODTruth/TruthEventAuxContainer.h" +#include "xAODTruth/xAODTruthHelpers.h" + +namespace { + struct GCCXML_DUMMY_INSTANTIATION_XAODTRUTH { + // The DataVector types: + xAOD::TruthParticleContainer c1; + xAOD::TruthVertexContainer c2; + xAOD::TruthEventContainer c3; + + // The smart pointer types: + DataLink< xAOD::TruthParticleContainer > dl1; + std::vector< DataLink< xAOD::TruthParticleContainer > > dl2; + DataLink< xAOD::TruthVertexContainer > dl3; + std::vector< DataLink< xAOD::TruthVertexContainer > > dl4; + ElementLink< xAOD::TruthParticleContainer > el1; + std::vector< ElementLink< xAOD::TruthParticleContainer > > el2; + std::vector< std::vector< ElementLink< xAOD::TruthParticleContainer > > > el3; + ElementLink< xAOD::TruthVertexContainer > el4; + std::vector< ElementLink< xAOD::TruthVertexContainer > > el5; + std::vector< std::vector< ElementLink< xAOD::TruthVertexContainer > > > el6; + }; +} + +#endif // XAODTRUTH_XAODTRUTHDICT_H diff --git a/xAOD/xAODTruth/xAODTruth/xAODTruthHelpers.h b/xAOD/xAODTruth/xAODTruth/xAODTruthHelpers.h new file mode 100644 index 0000000000000000000000000000000000000000..cb8ca9cdb3ffee257b1af09c0d2427f8d177e8ff --- /dev/null +++ b/xAOD/xAODTruth/xAODTruth/xAODTruthHelpers.h @@ -0,0 +1,37 @@ +// Dear emacs, this is -*- c++ -*- + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// $Id: xAODTruthHelpers.h 668406 2015-05-19 15:32:15Z krasznaa $ +#ifndef XAODTRUTH_XAODTRUTHHELPERS_H +#define XAODTRUTH_XAODTRUTHHELPERS_H + +// Local include(s): +#include "xAODTruth/TruthParticle.h" + +namespace xAOD { + + // Forward declaration(s): + class IParticle; + + /// Dedicated namespace for the helper functions + namespace TruthHelpers { + + /// Return the truthParticle associated to the given IParticle (if any) + const TruthParticle* getTruthParticle( const xAOD::IParticle& p ); + + /// Return the particle's truth type (as defined by the MC Truth + /// Classifier) + int getParticleTruthType( const xAOD::IParticle& p ); + + /// Return the particle's truth origin (as defined by the MC Truth + /// Classifier) + int getParticleTruthOrigin( const xAOD::IParticle& p ); + + } // namespace TruthHelpers + +} // namespace xAOD + +#endif // XAODTRUTH_XAODTRUTHHELPERS_H