From c6fd02f0be4b2cdf466ce2fbdfd96438ea88ad28 Mon Sep 17 00:00:00 2001 From: Benedikt Volkel Date: Thu, 15 Jun 2023 16:34:14 +0200 Subject: [PATCH 1/3] Introduce proper generator IDs * 3 values * global ID assigend to a o2::eventgen::PrimaryGenerator * cocktail constituent ID in case a o2::eventgen::Generator consists of multiple cocktail constituents. If a specific constituent is used for an event, that event will be flagged with that ID * source ID to mark source in emebdding scenarios * all 3 values are encoded into a single short, passed to mcCollision table at the end * provide decoding via helper functions/dynamic columns in mcCOllision table Set the IDs * Global ID (and short description) * can be set via o2-sim --confKeyValues \ "PrimaryGenerator.id=3;PrimaryGenerator.description=a specific gen" * Each cocktail constituent must first be registered via o2::eventgen::Generator::addCocktailConstituent(int, std::string) then, each egnerated event must set a valid ID during o2::eventgen::Generator::GenerateEvent or o2::eventgen::Generator::importParticles if cocktail constituents are set but no valid ID is given, no event will be generated * source ID is derived by the framework as before, not up to the user * combine MC Gen ID and particle status to MCGenProperties (naming not final, MCGenHelper, MCGenUtils?) Please consider the following formatting changes --- DataFormats/simulation/CMakeLists.txt | 5 ++ .../{MCGenStatus.h => MCGenProperties.h} | 54 ++++++++++++++++++- .../include/SimulationDataFormat/MCTrack.h | 2 +- .../include/SimulationDataFormat/MCUtils.h | 4 +- DataFormats/simulation/src/MCUtils.cxx | 2 +- DataFormats/simulation/test/testMCGenId.cxx | 54 +++++++++++++++++++ .../simulation/test/testMCGenStatus.cxx | 2 +- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 5 +- .../include/Framework/AnalysisDataModel.h | 11 +++- Generators/CMakeLists.txt | 10 ++-- Generators/include/Generators/Generator.h | 28 +++++++--- .../Generators/GeneratorExternalParam.h | 2 +- .../include/Generators/PrimaryGenerator.h | 12 ++++- .../Generators/PrimaryGeneratorParam.h | 37 +++++++++++++ Generators/src/Generator.cxx | 25 ++++++++- Generators/src/GeneratorFactory.cxx | 4 +- Generators/src/GeneratorFromFile.cxx | 1 - Generators/src/GeneratorPythia8.cxx | 2 +- Generators/src/GeneratorTGenerator.cxx | 2 +- Generators/src/GeneratorsLinkDef.h | 1 + Generators/src/PrimaryGenerator.cxx | 25 ++++++++- Generators/src/PrimaryGeneratorParam.cxx | 13 +++++ 22 files changed, 271 insertions(+), 30 deletions(-) rename DataFormats/simulation/include/SimulationDataFormat/{MCGenStatus.h => MCGenProperties.h} (57%) create mode 100644 DataFormats/simulation/test/testMCGenId.cxx create mode 100644 Generators/include/Generators/PrimaryGeneratorParam.h create mode 100644 Generators/src/PrimaryGeneratorParam.cxx diff --git a/DataFormats/simulation/CMakeLists.txt b/DataFormats/simulation/CMakeLists.txt index d0f1cc87cdaa2..fac67cc927562 100644 --- a/DataFormats/simulation/CMakeLists.txt +++ b/DataFormats/simulation/CMakeLists.txt @@ -84,3 +84,8 @@ o2_add_test(MCGenStatus SOURCES test/testMCGenStatus.cxx COMPONENT_NAME SimulationDataFormat PUBLIC_LINK_LIBRARIES O2::SimulationDataFormat) + +o2_add_test(MCGenId + SOURCES test/testMCGenId.cxx + COMPONENT_NAME SimulationDataFormat + PUBLIC_LINK_LIBRARIES O2::SimulationDataFormat) diff --git a/DataFormats/simulation/include/SimulationDataFormat/MCGenStatus.h b/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h similarity index 57% rename from DataFormats/simulation/include/SimulationDataFormat/MCGenStatus.h rename to DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h index 09b2b51c8e483..e9ebf8c3a81a4 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/MCGenStatus.h +++ b/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h @@ -9,8 +9,8 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef ALICEO2_SIMDATA_MCGENSTATUS_H_ -#define ALICEO2_SIMDATA_MCGENSTATUS_H_ +#ifndef ALICEO2_SIMDATA_MCGENPROPERTIES_H_ +#define ALICEO2_SIMDATA_MCGENPROPERTIES_H_ namespace o2 { @@ -76,6 +76,56 @@ inline int getGenStatusCode(int encoded) } // namespace mcgenstatus +namespace mcgenid +{ + +// Define some common properties that can be set for Generators +class GeneratorProperty +{ + public: + typedef const char* Property; + static constexpr Property GENERATORID{"generator_id"}; + static constexpr Property GENERATORDESCRIPTION{"generator_description"}; + static constexpr Property COCKTAILID{"cocktail_id"}; + static constexpr Property COCKTAILDESCRIPTIONMAP{"gcocktail_description_map"}; +}; + +// internal structure to allow convenient manipulation of properties as bits on an int to (dis)entangle HepMC and specific generator status codes +union MCGenIdEncoding { + MCGenIdEncoding() : fullEncoding(0) {} + MCGenIdEncoding(int enc) : fullEncoding(enc) {} + // To be backward-compatible, only set transport to 1 if hepmc status is 1 + MCGenIdEncoding(int generatorId, int sourceId, int cocktailId = -1) : generatorId(generatorId), sourceId(sourceId), cocktailId(cocktailId) {} + short fullEncoding; + struct { + short generatorId : 5; // an additional identifier for a generator which can be set by the user + short sourceId : 5; // ID used in embedding scenarios + short cocktailId : 6; // reserved bits for future encodings, for instance to identify single cocktail constituents of a generator + }; +}; + +inline short getEncodedGenId(int generatorId, int sourceId, int cocktailId = -1) +{ + return MCGenIdEncoding(generatorId, sourceId, cocktailId).fullEncoding; +} + +inline int getGeneratorId(short encoded) +{ + return static_cast(MCGenIdEncoding(encoded).generatorId); +} + +inline int getSourceId(short encoded) +{ + return static_cast(MCGenIdEncoding(encoded).sourceId); +} + +inline int getCocktailId(short encoded) +{ + return static_cast(MCGenIdEncoding(encoded).cocktailId); +} + +} // namespace mcgenid + } // namespace o2 #endif diff --git a/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h b/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h index ed4092cb9f5f8..103c37fed7986 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h +++ b/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h @@ -17,7 +17,7 @@ #define ALICEO2_DATA_MCTRACK_H_ #include "SimulationDataFormat/ParticleStatus.h" -#include "SimulationDataFormat/MCGenStatus.h" +#include "SimulationDataFormat/MCGenProperties.h" #include "DetectorsCommonDataFormats/DetID.h" #include "Rtypes.h" #include "SimulationDataFormat/O2DatabasePDG.h" diff --git a/DataFormats/simulation/include/SimulationDataFormat/MCUtils.h b/DataFormats/simulation/include/SimulationDataFormat/MCUtils.h index d6bdbbe79498e..c54b424eb0238 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/MCUtils.h +++ b/DataFormats/simulation/include/SimulationDataFormat/MCUtils.h @@ -16,8 +16,8 @@ #ifndef O2_MCUTILS_H #define O2_MCUTILS_H +#include #include -#include #include #include "TPDGCode.h" #include "TParticle.h" @@ -26,6 +26,7 @@ namespace o2 { namespace mcutils { + /// A couple of functions to query on MC tracks ( that needs navigation within the global container /// of available tracks. It is a class so as to make it available for interactive ROOT more easily. class MCTrackNavigator @@ -79,7 +80,6 @@ class MCGenHelper // Has to be in a class as a static methid. Just in a namespace it doesn't work to use this function in ROOT macros. static void encodeParticleStatusAndTracking(TParticle& particle, bool wanttracking = true); static void encodeParticleStatusAndTracking(TParticle& particle, int hepmcStatus, int genStatus, bool wanttracking = true); - ClassDefNV(MCGenHelper, 1) }; diff --git a/DataFormats/simulation/src/MCUtils.cxx b/DataFormats/simulation/src/MCUtils.cxx index 8c1e242a5332b..14cf7ab7048a4 100644 --- a/DataFormats/simulation/src/MCUtils.cxx +++ b/DataFormats/simulation/src/MCUtils.cxx @@ -14,7 +14,7 @@ // #include -#include +#include namespace o2::mcutils { diff --git a/DataFormats/simulation/test/testMCGenId.cxx b/DataFormats/simulation/test/testMCGenId.cxx new file mode 100644 index 0000000000000..4c90d4e4cf8f9 --- /dev/null +++ b/DataFormats/simulation/test/testMCGenId.cxx @@ -0,0 +1,54 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#define BOOST_TEST_MODULE Test MCGenStatus class +#define BOOST_TEST_MAIN +#define BOOST_TEST_DYN_LINK +#include +#include "SimulationDataFormat/MCGenProperties.h" +#include "TRandom.h" + +using namespace o2::mcgenid; + +BOOST_AUTO_TEST_CASE(MCGenId_test) +{ + // create 2 vectors each with some random integers + constexpr size_t length{100}; + constexpr int low{-2}; + constexpr int high{16}; + + // initialise the seed (could be anything) + gRandom->SetSeed(); + + for (size_t i = 0; i < length; i++) { + // draw random integers + auto sourceId = static_cast(gRandom->Uniform(low, high)); + auto generatorId = static_cast(gRandom->Uniform(low, high)); + auto cocktailId = static_cast(gRandom->Uniform(low, high)); + + // encode them + auto encoded = getEncodedGenId(generatorId, sourceId, cocktailId); + + // decode them + auto sourceIdAfter = getSourceId(encoded); + auto generatorIdAfter = getGeneratorId(encoded); + auto cocktailIdAfter = getCocktailId(encoded); + + std::cout << "SourceID: " << sourceId << " ==> " << sourceIdAfter << "\n" + << "generatorId: " << generatorId << " ==> " << generatorIdAfter << "\n" + << "cocktailId: " << cocktailId << " ==> " << cocktailIdAfter << "\n"; + + // check if original and decoded numbers are the same + BOOST_CHECK(sourceIdAfter == sourceId); + BOOST_CHECK(generatorIdAfter == generatorId); + BOOST_CHECK(cocktailId == cocktailIdAfter); + } +} diff --git a/DataFormats/simulation/test/testMCGenStatus.cxx b/DataFormats/simulation/test/testMCGenStatus.cxx index 6156f20b0fa47..a9b8b7277b3e7 100644 --- a/DataFormats/simulation/test/testMCGenStatus.cxx +++ b/DataFormats/simulation/test/testMCGenStatus.cxx @@ -15,7 +15,7 @@ #include #include "SimulationDataFormat/MCTrack.h" #include "SimulationDataFormat/ParticleStatus.h" -#include "SimulationDataFormat/MCGenStatus.h" +#include "SimulationDataFormat/MCGenProperties.h" #include "SimulationDataFormat/MCUtils.h" #include "TFile.h" #include "TParticle.h" diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 3b7e588bab03e..68023aed1b637 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -72,6 +72,7 @@ #include "SimulationDataFormat/MCTrack.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "SimulationDataFormat/MCUtils.h" +#include "SimulationDataFormat/MCGenProperties.h" #include "ZDCBase/Constants.h" #include "TPCBase/ParameterElectronics.h" #include "GPUTPCGMMergedTrackHit.h" @@ -1838,10 +1839,10 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) if (nParts == 1 || sourceID == 0) { // FIXME: // use generators' names for generatorIDs (?) - short generatorID = sourceID; auto& header = mcReader->getMCEventHeader(sourceID, eventID); + bool isValid{}; mcCollisionsCursor(bcID, - generatorID, + o2::mcgenid::getEncodedGenId(header.getInfo(o2::mcgenid::GeneratorProperty::GENERATORID, isValid), header.getInfo(o2::mcgenid::GeneratorProperty::COCKTAILID, isValid), sourceID), truncateFloatFraction(header.GetX(), mCollisionPosition), truncateFloatFraction(header.GetY(), mCollisionPosition), truncateFloatFraction(header.GetZ(), mCollisionPosition), diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index 3d44a5b756d06..71ff91f961368 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -19,7 +19,7 @@ #include "CommonConstants/PhysicsConstants.h" #include "CommonConstants/GeomConstants.h" #include "CommonConstants/ZDCConstants.h" -#include "SimulationDataFormat/MCGenStatus.h" +#include "SimulationDataFormat/MCGenProperties.h" using namespace o2::constants::math; @@ -1271,13 +1271,20 @@ namespace mccollision { DECLARE_SOA_INDEX_COLUMN(BC, bc); //! BC index // TODO enum to be added to O2 -DECLARE_SOA_COLUMN(GeneratorsID, generatorsID, short); //! +DECLARE_SOA_COLUMN(GeneratorsID, generatorsID, short); //! disentangled generator IDs should be accessed from dynamic columns using getGenId, getCocktailId and getSourceId DECLARE_SOA_COLUMN(PosX, posX, float); //! X vertex position in cm DECLARE_SOA_COLUMN(PosY, posY, float); //! Y vertex position in cm DECLARE_SOA_COLUMN(PosZ, posZ, float); //! Z vertex position in cm DECLARE_SOA_COLUMN(T, t, float); //! Collision time relative to given bc in ns DECLARE_SOA_COLUMN(Weight, weight, float); //! MC weight DECLARE_SOA_COLUMN(ImpactParameter, impactParameter, float); //! Impact parameter for A-A +DECLARE_SOA_DYNAMIC_COLUMN(GetGenId, getGenId, //! The global generator ID which might have been assigned by the user + [](short generatorsID) -> int { return o2::mcgenid::getGeneratorId(generatorsID); }); +DECLARE_SOA_DYNAMIC_COLUMN(GetCocktailId, getCocktailId, //! A specific cocktail ID in case the generator consisted of multiple cocktail constituents + [](short generatorsID) -> int { return o2::mcgenid::getCocktailId(generatorsID); }); +DECLARE_SOA_DYNAMIC_COLUMN(GetSourceId, getSourceId, //! The source ID to differentiate between signals and background in an embedding simulation + [](short generatorsID) -> int { return o2::mcgenid::getSourceId(generatorsID); }); + } // namespace mccollision DECLARE_SOA_TABLE(McCollisions, "AOD", "MCCOLLISION", //! MC collision table diff --git a/Generators/CMakeLists.txt b/Generators/CMakeLists.txt index 9a8a433f67218..0b0f92955a651 100644 --- a/Generators/CMakeLists.txt +++ b/Generators/CMakeLists.txt @@ -30,6 +30,7 @@ o2_add_library(Generators src/GeneratorFromFile.cxx src/GeneratorFromO2KineParam.cxx src/PrimaryGenerator.cxx + src/PrimaryGeneratorParam.cxx src/TriggerExternalParam.cxx src/TriggerParticleParam.cxx src/BoxGunParam.cxx @@ -71,6 +72,7 @@ set(headers include/Generators/GeneratorFromFile.h include/Generators/GeneratorFromO2KineParam.h include/Generators/PrimaryGenerator.h + include/Generators/PrimaryGeneratorParam.h include/Generators/TriggerExternalParam.h include/Generators/TriggerParticleParam.h include/Generators/BoxGunParam.h @@ -81,11 +83,11 @@ set(headers if (pythia6_FOUND) list(APPEND headers include/Generators/GeneratorPythia6.h - include/Generators/GeneratorPythia6Param.h) + include/Generators/GeneratorPythia6Param.h) endif() if(pythia_FOUND) - list(APPEND headers + list(APPEND headers include/Generators/GeneratorPythia8.h include/Generators/DecayerPythia8.h include/Generators/GeneratorPythia8Param.h @@ -137,8 +139,8 @@ o2_add_test_root_macro(share/external/trigger_mpi.C o2_add_test_root_macro(share/egconfig/pythia8_userhooks_charm.C PUBLIC_LINK_LIBRARIES O2::Generators LABELS generators) -endif() - +endif() + o2_data_file(COPY share/external DESTINATION Generators) o2_data_file(COPY share/egconfig DESTINATION Generators) o2_data_file(COPY share/pythia8 DESTINATION Generators) diff --git a/Generators/include/Generators/Generator.h b/Generators/include/Generators/Generator.h index 6f2fc8ea8502d..b0650114b2d31 100644 --- a/Generators/include/Generators/Generator.h +++ b/Generators/include/Generators/Generator.h @@ -19,6 +19,7 @@ #include "Generators/Trigger.h" #include #include +#include namespace o2 { @@ -61,12 +62,12 @@ class Generator : public FairGenerator Bool_t Init() override; /** Abstract method ReadEvent must be implemented by any derived class. - It has to handle the generation of input tracks (reading from input - file) and the handing of the tracks to the FairPrimaryGenerator. I - t is called from FairMCApplication. - *@param pStack The stack - *@return kTRUE if successful, kFALSE if not - **/ + has to handle the generation of input tracks (reading from input + file) and the handing of the tracks to the FairPrimaryGenerator. It is + called from FairMCApplication. + *@param pStack The stack + *@return kTRUE if successful, kFALSE if not + **/ Bool_t ReadEvent(FairPrimaryGenerator* primGen) final; /** methods to override **/ @@ -109,6 +110,13 @@ class Generator : public FairGenerator Bool_t boostEvent(); Bool_t triggerEvent(); + /** to handle cocktail constituents **/ + void addCocktailConstituent(int cocktailId, std::string const& cocktailDescription) + { + mCocktailIdToDesc.insert({cocktailId, cocktailDescription}); + } + void notifyCocktailConstituent(int cocktailId) { mCocktailId = cocktailId; } + /** generator interface **/ void* mInterface = nullptr; std::string mInterfaceName; @@ -136,7 +144,13 @@ class Generator : public FairGenerator /** lorentz boost data members **/ Double_t mBoost; - ClassDefOverride(Generator, 1); + private: + void updateCocktailInformation(o2::dataformats::MCEventHeader* header) const; + + std::unordered_map mCocktailIdToDesc; + int mCocktailId = -1; + + ClassDefOverride(Generator, 2); }; /** class Generator **/ diff --git a/Generators/include/Generators/GeneratorExternalParam.h b/Generators/include/Generators/GeneratorExternalParam.h index e55d184af9dda..167ca74129b6b 100644 --- a/Generators/include/Generators/GeneratorExternalParam.h +++ b/Generators/include/Generators/GeneratorExternalParam.h @@ -25,7 +25,7 @@ namespace eventgen /** ** a parameter class/struct to keep the settings of ** the external event-generator and - ** allow the user to modify them + ** allow the user to modify them **/ struct GeneratorExternalParam : public o2::conf::ConfigurableParamHelper { std::string fileName = ""; diff --git a/Generators/include/Generators/PrimaryGenerator.h b/Generators/include/Generators/PrimaryGenerator.h index 2d149f5572229..5ce6b1584e70f 100644 --- a/Generators/include/Generators/PrimaryGenerator.h +++ b/Generators/include/Generators/PrimaryGenerator.h @@ -85,6 +85,10 @@ class PrimaryGenerator : public FairPrimaryGenerator // sets the vertex mode; if mode is kCCDB, a valid MeanVertexObject pointer must be given at the same time void setVertexMode(o2::conf::VertexMode const& mode, o2::dataformats::MeanVertexObject const* obj = nullptr); + // set identifier and description + void setGeneratorId(int id) { mGeneratorId = id; } + void setGeneratorDescription(std::string const& desc) { mGeneratorDescription = desc; } + protected: /** copy constructor **/ // PrimaryGenerator(const PrimaryGenerator&) = default; @@ -113,7 +117,13 @@ class PrimaryGenerator : public FairPrimaryGenerator o2::conf::VertexMode mVertexMode = o2::conf::VertexMode::kDiamondParam; // !vertex mode std::unique_ptr mMeanVertex; - ClassDefOverride(PrimaryGenerator, 2); + private: + void setGeneratorInformation(); + // generator identifier and description + int mGeneratorId = -1; + std::string mGeneratorDescription; + + ClassDefOverride(PrimaryGenerator, 3); }; /** class PrimaryGenerator **/ diff --git a/Generators/include/Generators/PrimaryGeneratorParam.h b/Generators/include/Generators/PrimaryGeneratorParam.h new file mode 100644 index 0000000000000..9487ab90188ce --- /dev/null +++ b/Generators/include/Generators/PrimaryGeneratorParam.h @@ -0,0 +1,37 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef ALICEO2_EVENTGEN_PRIMARYGENERATORPARAM_H_ +#define ALICEO2_EVENTGEN_PRIMARYGENERATORPARAM_H_ + +#include "CommonUtils/ConfigurableParam.h" +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2 +{ +namespace eventgen +{ + +/** + ** a parameter class/struct to keep the settings of + ** the event-generator external trigger and + ** allow the user to modify them + **/ +struct PrimaryGeneratorParam : public o2::conf::ConfigurableParamHelper { + int id = -1; + std::string description = ""; + O2ParamDef(PrimaryGeneratorParam, "PrimaryGenerator"); +}; + +} // end namespace eventgen +} // end namespace o2 + +#endif // ALICEO2_EVENTGEN_PRIMARYGENERATORPARAM_H_ diff --git a/Generators/src/Generator.cxx b/Generators/src/Generator.cxx index 8cbf98040a4d5..8d6a767b2cb12 100644 --- a/Generators/src/Generator.cxx +++ b/Generators/src/Generator.cxx @@ -16,7 +16,7 @@ #include "Generators/PrimaryGenerator.h" #include "SimulationDataFormat/MCEventHeader.h" #include "SimulationDataFormat/ParticleStatus.h" -#include "SimulationDataFormat/MCGenStatus.h" +#include "SimulationDataFormat/MCGenProperties.h" #include "FairPrimaryGenerator.h" #include #include @@ -70,6 +70,9 @@ Bool_t /** clear particle vector **/ mParticles.clear(); + /** reset the cocktail ID **/ + mCocktailId = -1; + /** generate event **/ if (!generateEvent()) { return kFALSE; @@ -80,6 +83,14 @@ Bool_t return kFALSE; } + if (mCocktailIdToDesc.empty() && mCocktailId > -1) { + return kFALSE; + } + + if (!mCocktailIdToDesc.empty() && mCocktailId < 0) { + return kFALSE; + } + /** trigger event **/ if (triggerEvent()) { mTriggerOkHook(mParticles, mReadEventCounter); @@ -102,6 +113,7 @@ Bool_t return kFALSE; } updateHeader(o2header); + updateCocktailInformation(o2header); /** success **/ return kTRUE; @@ -206,6 +218,17 @@ Bool_t return triggered; } +/*****************************************************************/ + +void Generator::updateCocktailInformation(o2::dataformats::MCEventHeader* header) const +{ + if (mCocktailId < 0) { + return; + } + header->putInfo(o2::mcgenid::GeneratorProperty::COCKTAILID, mCocktailId); + header->putInfo>(o2::mcgenid::GeneratorProperty::COCKTAILDESCRIPTIONMAP, mCocktailIdToDesc); +} + /*****************************************************************/ /*****************************************************************/ diff --git a/Generators/src/GeneratorFactory.cxx b/Generators/src/GeneratorFactory.cxx index 7d4270a473e30..82cc30c8e88a8 100644 --- a/Generators/src/GeneratorFactory.cxx +++ b/Generators/src/GeneratorFactory.cxx @@ -13,7 +13,6 @@ #include #include -#include "FairPrimaryGenerator.h" #include "FairGenerator.h" #include "FairBoxGenerator.h" #include @@ -33,6 +32,7 @@ #include #include #endif +#include #include #include #include @@ -55,6 +55,8 @@ void GeneratorFactory::setPrimaryGenerator(o2::conf::SimConfig const& conf, Fair return; } + auto primGenO2 = dynamic_cast(primGen); + auto makeBoxGen = [](int pdgid, int mult, double etamin, double etamax, double pmin, double pmax, double phimin, double phimax, bool debug = false) { auto gen = new FairBoxGenerator(pdgid, mult); gen->SetEtaRange(etamin, etamax); diff --git a/Generators/src/GeneratorFromFile.cxx b/Generators/src/GeneratorFromFile.cxx index 1764717254108..57a3080e3e513 100644 --- a/Generators/src/GeneratorFromFile.cxx +++ b/Generators/src/GeneratorFromFile.cxx @@ -13,7 +13,6 @@ #include "Generators/GeneratorFromO2KineParam.h" #include "SimulationDataFormat/MCTrack.h" #include "SimulationDataFormat/MCEventHeader.h" -#include "SimulationDataFormat/MCGenStatus.h" #include #include #include diff --git a/Generators/src/GeneratorPythia8.cxx b/Generators/src/GeneratorPythia8.cxx index 335e8c3b20148..74ac6565a2452 100644 --- a/Generators/src/GeneratorPythia8.cxx +++ b/Generators/src/GeneratorPythia8.cxx @@ -19,7 +19,7 @@ #include "TF1.h" #include "TRandom.h" #include "SimulationDataFormat/MCEventHeader.h" -#include "SimulationDataFormat/MCGenStatus.h" +#include "SimulationDataFormat/MCGenProperties.h" #include "SimulationDataFormat/ParticleStatus.h" #include "Pythia8/HIUserHooks.h" #include "TSystem.h" diff --git a/Generators/src/GeneratorTGenerator.cxx b/Generators/src/GeneratorTGenerator.cxx index bd4d61c7cc4b8..2659b95673a4c 100644 --- a/Generators/src/GeneratorTGenerator.cxx +++ b/Generators/src/GeneratorTGenerator.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include "SimulationDataFormat/MCGenStatus.h" +#include "SimulationDataFormat/MCGenProperties.h" #include "SimulationDataFormat/ParticleStatus.h" #include "Generators/GeneratorTGenerator.h" #include diff --git a/Generators/src/GeneratorsLinkDef.h b/Generators/src/GeneratorsLinkDef.h index 7e0021aa2dbb3..0d42b2ce505b6 100644 --- a/Generators/src/GeneratorsLinkDef.h +++ b/Generators/src/GeneratorsLinkDef.h @@ -54,6 +54,7 @@ #pragma link C++ class o2::eventgen::GeneratorFromO2KineParam + ; #pragma link C++ class o2::conf::ConfigurableParamHelper < o2::eventgen::GeneratorFromO2KineParam> + ; #pragma link C++ class o2::eventgen::PrimaryGenerator + ; +#pragma link C++ class o2::eventgen::PrimaryGeneratorParam + ; #pragma link C++ enum o2::eventgen::EVertexDistribution; #pragma link C++ class o2::eventgen::TriggerExternalParam + ; diff --git a/Generators/src/PrimaryGenerator.cxx b/Generators/src/PrimaryGenerator.cxx index 2b6b883802666..d3c6c90ebbc54 100644 --- a/Generators/src/PrimaryGenerator.cxx +++ b/Generators/src/PrimaryGenerator.cxx @@ -12,9 +12,11 @@ /// \author R+Preghenella - June 2017 #include "Generators/PrimaryGenerator.h" +#include #include "Generators/Generator.h" #include "SimConfig/InteractionDiamondParam.h" #include "SimulationDataFormat/MCEventHeader.h" +#include "SimulationDataFormat/MCGenProperties.h" #include "DataFormatsCalibration/MeanVertexObject.h" #include "DetectorsBase/Stack.h" #include @@ -56,6 +58,11 @@ Bool_t PrimaryGenerator::Init() LOG(info) << "Initialising primary generator"; + // set generator ID and description + auto& params = PrimaryGeneratorParam::Instance(); + setGeneratorId(params.id); + setGeneratorDescription(params.description); + /** embedding **/ if (mEmbedTree) { LOG(info) << "Embedding into: " << mEmbedFile->GetName() @@ -76,7 +83,11 @@ Bool_t PrimaryGenerator::GenerateEvent(FairGenericStack* pStack) /** normal generation if no embedding **/ if (!mEmbedTree) { fixInteractionVertex(); // <-- always fixes vertex outside of FairROOT - return FairPrimaryGenerator::GenerateEvent(pStack); + auto ret = FairPrimaryGenerator::GenerateEvent(pStack); + if (ret) { + setGeneratorInformation(); + } + return ret; } /** this is for embedding **/ @@ -105,6 +116,7 @@ Bool_t PrimaryGenerator::GenerateEvent(FairGenericStack* pStack) o2event->setEmbeddingFileName(mEmbedFile->GetName()); o2event->setEmbeddingEventIndex(mEmbedIndex); } + setGeneratorInformation(); /** increment embedding counter **/ mEmbedIndex++; @@ -337,6 +349,17 @@ Bool_t PrimaryGenerator::embedInto(TString fname) return kTRUE; } +/*****************************************************************/ + +void PrimaryGenerator::setGeneratorInformation() +{ + auto o2event = dynamic_cast(fEvent); + if (o2event) { + o2event->putInfo(o2::mcgenid::GeneratorProperty::GENERATORID, mGeneratorId); + o2event->putInfo(o2::mcgenid::GeneratorProperty::GENERATORDESCRIPTION, mGeneratorDescription); + } +} + /*****************************************************************/ /*****************************************************************/ diff --git a/Generators/src/PrimaryGeneratorParam.cxx b/Generators/src/PrimaryGeneratorParam.cxx new file mode 100644 index 0000000000000..86a47bb0f5d3c --- /dev/null +++ b/Generators/src/PrimaryGeneratorParam.cxx @@ -0,0 +1,13 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Generators/PrimaryGeneratorParam.h" +O2ParamImpl(o2::eventgen::PrimaryGeneratorParam); From aefad0ce566e5dde45b1cf1a26b6d077a081606b Mon Sep 17 00:00:00 2001 From: Benedikt Volkel Date: Mon, 10 Jul 2023 14:58:21 +0200 Subject: [PATCH 2/3] Be consistent with Run1 and Run2 * rename cocktail to subGenerator everywhere * a cocktail should stay a cocktail of different generators * remove comment in AnalysisDataModel --- .../SimulationDataFormat/MCGenProperties.h | 20 ++++---- DataFormats/simulation/test/testMCGenId.cxx | 51 +++++++++---------- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 2 +- .../include/Framework/AnalysisDataModel.h | 7 ++- Generators/include/Generators/Generator.h | 14 ++--- Generators/src/Generator.cxx | 18 +++---- 6 files changed, 54 insertions(+), 58 deletions(-) diff --git a/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h b/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h index e9ebf8c3a81a4..e6816d639cd75 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h +++ b/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h @@ -86,8 +86,8 @@ class GeneratorProperty typedef const char* Property; static constexpr Property GENERATORID{"generator_id"}; static constexpr Property GENERATORDESCRIPTION{"generator_description"}; - static constexpr Property COCKTAILID{"cocktail_id"}; - static constexpr Property COCKTAILDESCRIPTIONMAP{"gcocktail_description_map"}; + static constexpr Property SUBGENERATORID{"subgenerator_id"}; + static constexpr Property SUBGENERATORDESCRIPTIONMAP{"subgenerator_description_map"}; }; // internal structure to allow convenient manipulation of properties as bits on an int to (dis)entangle HepMC and specific generator status codes @@ -95,18 +95,18 @@ union MCGenIdEncoding { MCGenIdEncoding() : fullEncoding(0) {} MCGenIdEncoding(int enc) : fullEncoding(enc) {} // To be backward-compatible, only set transport to 1 if hepmc status is 1 - MCGenIdEncoding(int generatorId, int sourceId, int cocktailId = -1) : generatorId(generatorId), sourceId(sourceId), cocktailId(cocktailId) {} + MCGenIdEncoding(int generatorId, int sourceId, int subGeneratorId = -1) : generatorId(generatorId), sourceId(sourceId), subGeneratorId(subGeneratorId) {} short fullEncoding; struct { - short generatorId : 5; // an additional identifier for a generator which can be set by the user - short sourceId : 5; // ID used in embedding scenarios - short cocktailId : 6; // reserved bits for future encodings, for instance to identify single cocktail constituents of a generator + short generatorId : 7; // an additional identifier for a generator which can be set by the user + short sourceId : 4; // ID used in embedding scenarios + short subGeneratorId : 5; // sub generator ID in case a generator implements some additional logic }; }; -inline short getEncodedGenId(int generatorId, int sourceId, int cocktailId = -1) +inline short getEncodedGenId(int generatorId, int sourceId, int subGeneratorId = -1) { - return MCGenIdEncoding(generatorId, sourceId, cocktailId).fullEncoding; + return MCGenIdEncoding(generatorId, sourceId, subGeneratorId).fullEncoding; } inline int getGeneratorId(short encoded) @@ -119,9 +119,9 @@ inline int getSourceId(short encoded) return static_cast(MCGenIdEncoding(encoded).sourceId); } -inline int getCocktailId(short encoded) +inline int getSubGeneratorId(short encoded) { - return static_cast(MCGenIdEncoding(encoded).cocktailId); + return static_cast(MCGenIdEncoding(encoded).subGeneratorId); } } // namespace mcgenid diff --git a/DataFormats/simulation/test/testMCGenId.cxx b/DataFormats/simulation/test/testMCGenId.cxx index 4c90d4e4cf8f9..eeacf5c21853d 100644 --- a/DataFormats/simulation/test/testMCGenId.cxx +++ b/DataFormats/simulation/test/testMCGenId.cxx @@ -14,7 +14,6 @@ #define BOOST_TEST_DYN_LINK #include #include "SimulationDataFormat/MCGenProperties.h" -#include "TRandom.h" using namespace o2::mcgenid; @@ -23,32 +22,28 @@ BOOST_AUTO_TEST_CASE(MCGenId_test) // create 2 vectors each with some random integers constexpr size_t length{100}; constexpr int low{-2}; - constexpr int high{16}; - - // initialise the seed (could be anything) - gRandom->SetSeed(); - - for (size_t i = 0; i < length; i++) { - // draw random integers - auto sourceId = static_cast(gRandom->Uniform(low, high)); - auto generatorId = static_cast(gRandom->Uniform(low, high)); - auto cocktailId = static_cast(gRandom->Uniform(low, high)); - - // encode them - auto encoded = getEncodedGenId(generatorId, sourceId, cocktailId); - - // decode them - auto sourceIdAfter = getSourceId(encoded); - auto generatorIdAfter = getGeneratorId(encoded); - auto cocktailIdAfter = getCocktailId(encoded); - - std::cout << "SourceID: " << sourceId << " ==> " << sourceIdAfter << "\n" - << "generatorId: " << generatorId << " ==> " << generatorIdAfter << "\n" - << "cocktailId: " << cocktailId << " ==> " << cocktailIdAfter << "\n"; - - // check if original and decoded numbers are the same - BOOST_CHECK(sourceIdAfter == sourceId); - BOOST_CHECK(generatorIdAfter == generatorId); - BOOST_CHECK(cocktailId == cocktailIdAfter); + constexpr int highGenerator{64}; + constexpr int highSubGenerator{16}; + constexpr int highSource{8}; + + for (int sourceId = 0; sourceId < highSource; sourceId++) { + for (int generatorId = 0; generatorId < highGenerator; generatorId++) { + for (int subGeneratorId = 0; subGeneratorId < highSubGenerator; subGeneratorId++) { + auto encoded = getEncodedGenId(generatorId, sourceId, subGeneratorId); + // decode them + auto sourceIdAfter = getSourceId(encoded); + auto generatorIdAfter = getGeneratorId(encoded); + auto subGeneratorIdAfter = getSubGeneratorId(encoded); + + std::cout << "SourceID: " << sourceId << " ==> " << sourceIdAfter << "\n" + << "generatorId: " << generatorId << " ==> " << generatorIdAfter << "\n" + << "subGeneratorId: " << subGeneratorId << " ==> " << subGeneratorIdAfter << "\n"; + + // check if original and decoded numbers are the same + BOOST_CHECK(sourceIdAfter == sourceId); + BOOST_CHECK(generatorIdAfter == generatorId); + BOOST_CHECK(subGeneratorId == subGeneratorIdAfter); + } + } } } diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 68023aed1b637..08ed518741814 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -1842,7 +1842,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto& header = mcReader->getMCEventHeader(sourceID, eventID); bool isValid{}; mcCollisionsCursor(bcID, - o2::mcgenid::getEncodedGenId(header.getInfo(o2::mcgenid::GeneratorProperty::GENERATORID, isValid), header.getInfo(o2::mcgenid::GeneratorProperty::COCKTAILID, isValid), sourceID), + o2::mcgenid::getEncodedGenId(header.getInfo(o2::mcgenid::GeneratorProperty::GENERATORID, isValid), sourceID, header.getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid)), truncateFloatFraction(header.GetX(), mCollisionPosition), truncateFloatFraction(header.GetY(), mCollisionPosition), truncateFloatFraction(header.GetZ(), mCollisionPosition), diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index 71ff91f961368..1b6538f998686 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -1270,7 +1270,6 @@ using Run2BCInfo = Run2BCInfos::iterator; namespace mccollision { DECLARE_SOA_INDEX_COLUMN(BC, bc); //! BC index -// TODO enum to be added to O2 DECLARE_SOA_COLUMN(GeneratorsID, generatorsID, short); //! disentangled generator IDs should be accessed from dynamic columns using getGenId, getCocktailId and getSourceId DECLARE_SOA_COLUMN(PosX, posX, float); //! X vertex position in cm DECLARE_SOA_COLUMN(PosY, posY, float); //! Y vertex position in cm @@ -1278,10 +1277,10 @@ DECLARE_SOA_COLUMN(PosZ, posZ, float); //! Z vertex positi DECLARE_SOA_COLUMN(T, t, float); //! Collision time relative to given bc in ns DECLARE_SOA_COLUMN(Weight, weight, float); //! MC weight DECLARE_SOA_COLUMN(ImpactParameter, impactParameter, float); //! Impact parameter for A-A -DECLARE_SOA_DYNAMIC_COLUMN(GetGenId, getGenId, //! The global generator ID which might have been assigned by the user +DECLARE_SOA_DYNAMIC_COLUMN(GetGeneratorId, getGeneratorId, //! The global generator ID which might have been assigned by the user [](short generatorsID) -> int { return o2::mcgenid::getGeneratorId(generatorsID); }); -DECLARE_SOA_DYNAMIC_COLUMN(GetCocktailId, getCocktailId, //! A specific cocktail ID in case the generator consisted of multiple cocktail constituents - [](short generatorsID) -> int { return o2::mcgenid::getCocktailId(generatorsID); }); +DECLARE_SOA_DYNAMIC_COLUMN(GetSubGeneratorId, getSubGeneratorId, //! A specific sub-generator ID in case the generator has some sub-generator logic + [](short generatorsID) -> int { return o2::mcgenid::getSubGeneratorId(generatorsID); }); DECLARE_SOA_DYNAMIC_COLUMN(GetSourceId, getSourceId, //! The source ID to differentiate between signals and background in an embedding simulation [](short generatorsID) -> int { return o2::mcgenid::getSourceId(generatorsID); }); diff --git a/Generators/include/Generators/Generator.h b/Generators/include/Generators/Generator.h index b0650114b2d31..884fa153275cd 100644 --- a/Generators/include/Generators/Generator.h +++ b/Generators/include/Generators/Generator.h @@ -111,11 +111,11 @@ class Generator : public FairGenerator Bool_t triggerEvent(); /** to handle cocktail constituents **/ - void addCocktailConstituent(int cocktailId, std::string const& cocktailDescription) + void addSubGenerator(int subGeneratorId, std::string const& subGeneratorDescription) { - mCocktailIdToDesc.insert({cocktailId, cocktailDescription}); + mSubGeneratorsIdToDesc.insert({subGeneratorId, subGeneratorDescription}); } - void notifyCocktailConstituent(int cocktailId) { mCocktailId = cocktailId; } + void notifySubGenerator(int subGeneratorId) { mSubGeneratorId = subGeneratorId; } /** generator interface **/ void* mInterface = nullptr; @@ -145,10 +145,12 @@ class Generator : public FairGenerator Double_t mBoost; private: - void updateCocktailInformation(o2::dataformats::MCEventHeader* header) const; + void updateSubGeneratorInformation(o2::dataformats::MCEventHeader* header) const; - std::unordered_map mCocktailIdToDesc; - int mCocktailId = -1; + // collect an ID and a short description of sub-generator entities + std::unordered_map mSubGeneratorsIdToDesc; + // the current ID of the sub-generator used in the current event (if applicable) + int mSubGeneratorId = -1; ClassDefOverride(Generator, 2); diff --git a/Generators/src/Generator.cxx b/Generators/src/Generator.cxx index 8d6a767b2cb12..a179acd740198 100644 --- a/Generators/src/Generator.cxx +++ b/Generators/src/Generator.cxx @@ -70,8 +70,8 @@ Bool_t /** clear particle vector **/ mParticles.clear(); - /** reset the cocktail ID **/ - mCocktailId = -1; + /** reset the sub-generator ID **/ + mSubGeneratorId = -1; /** generate event **/ if (!generateEvent()) { @@ -83,11 +83,11 @@ Bool_t return kFALSE; } - if (mCocktailIdToDesc.empty() && mCocktailId > -1) { + if (mSubGeneratorsIdToDesc.empty() && mSubGeneratorId > -1) { return kFALSE; } - if (!mCocktailIdToDesc.empty() && mCocktailId < 0) { + if (!mSubGeneratorsIdToDesc.empty() && mSubGeneratorId < 0) { return kFALSE; } @@ -113,7 +113,7 @@ Bool_t return kFALSE; } updateHeader(o2header); - updateCocktailInformation(o2header); + updateSubGeneratorInformation(o2header); /** success **/ return kTRUE; @@ -220,13 +220,13 @@ Bool_t /*****************************************************************/ -void Generator::updateCocktailInformation(o2::dataformats::MCEventHeader* header) const +void Generator::updateSubGeneratorInformation(o2::dataformats::MCEventHeader* header) const { - if (mCocktailId < 0) { + if (mSubGeneratorId < 0) { return; } - header->putInfo(o2::mcgenid::GeneratorProperty::COCKTAILID, mCocktailId); - header->putInfo>(o2::mcgenid::GeneratorProperty::COCKTAILDESCRIPTIONMAP, mCocktailIdToDesc); + header->putInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, mSubGeneratorId); + header->putInfo>(o2::mcgenid::GeneratorProperty::SUBGENERATORDESCRIPTIONMAP, mSubGeneratorsIdToDesc); } /*****************************************************************/ From 66bc61ce65db36567b83705847a936d93a038030 Mon Sep 17 00:00:00 2001 From: Benedikt Volkel Date: Tue, 11 Jul 2023 13:05:32 +0200 Subject: [PATCH 3/3] Adjust ID ranges * generator ID from 0 to 127 (included) * sub-generator ID from -1 to 30 (included) * source ID from 0 to 15 (included) --- .../SimulationDataFormat/MCGenProperties.h | 17 +++++++++-------- DataFormats/simulation/test/testMCGenId.cxx | 17 +++++++++-------- Generators/include/Generators/Generator.h | 5 +---- Generators/src/Generator.cxx | 10 ++++++++++ 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h b/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h index e6816d639cd75..1a4f86cc98122 100644 --- a/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h +++ b/DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h @@ -90,27 +90,28 @@ class GeneratorProperty static constexpr Property SUBGENERATORDESCRIPTIONMAP{"subgenerator_description_map"}; }; -// internal structure to allow convenient manipulation of properties as bits on an int to (dis)entangle HepMC and specific generator status codes +// internal structure to allow encoding of generator IDs and map different numbers to a single short union MCGenIdEncoding { MCGenIdEncoding() : fullEncoding(0) {} MCGenIdEncoding(int enc) : fullEncoding(enc) {} - // To be backward-compatible, only set transport to 1 if hepmc status is 1 - MCGenIdEncoding(int generatorId, int sourceId, int subGeneratorId = -1) : generatorId(generatorId), sourceId(sourceId), subGeneratorId(subGeneratorId) {} + MCGenIdEncoding(int generatorId, int sourceId, int subGeneratorId) : generatorId(generatorId), sourceId(sourceId), subGeneratorId(subGeneratorId) {} short fullEncoding; struct { - short generatorId : 7; // an additional identifier for a generator which can be set by the user - short sourceId : 4; // ID used in embedding scenarios - short subGeneratorId : 5; // sub generator ID in case a generator implements some additional logic + unsigned short generatorId : 7; // an additional identifier for a generator which can be set by the user + unsigned short sourceId : 4; // ID used in embedding scenarios + unsigned short subGeneratorId : 5; // sub generator ID in case a generator implements some additional logic }; }; inline short getEncodedGenId(int generatorId, int sourceId, int subGeneratorId = -1) { - return MCGenIdEncoding(generatorId, sourceId, subGeneratorId).fullEncoding; + + return MCGenIdEncoding(generatorId, sourceId, subGeneratorId + 1).fullEncoding; } inline int getGeneratorId(short encoded) { + return static_cast(MCGenIdEncoding(encoded).generatorId); } @@ -121,7 +122,7 @@ inline int getSourceId(short encoded) inline int getSubGeneratorId(short encoded) { - return static_cast(MCGenIdEncoding(encoded).subGeneratorId); + return static_cast(MCGenIdEncoding(encoded).subGeneratorId) - 1; } } // namespace mcgenid diff --git a/DataFormats/simulation/test/testMCGenId.cxx b/DataFormats/simulation/test/testMCGenId.cxx index eeacf5c21853d..246268ac78d52 100644 --- a/DataFormats/simulation/test/testMCGenId.cxx +++ b/DataFormats/simulation/test/testMCGenId.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#define BOOST_TEST_MODULE Test MCGenStatus class +#define BOOST_TEST_MODULE Test MCGenId class #define BOOST_TEST_MAIN #define BOOST_TEST_DYN_LINK #include @@ -19,16 +19,17 @@ using namespace o2::mcgenid; BOOST_AUTO_TEST_CASE(MCGenId_test) { - // create 2 vectors each with some random integers - constexpr size_t length{100}; - constexpr int low{-2}; - constexpr int highGenerator{64}; - constexpr int highSubGenerator{16}; - constexpr int highSource{8}; + // possible generator IDs range from 0 to 127 (included) + constexpr int highGenerator{128}; + // possible sub-generator IDs range from -1 to 30 (included) + constexpr int highSubGenerator{31}; + // possible soufce IDs range from 0 to 15 (included) + constexpr int highSource{16}; + // test all combinations for (int sourceId = 0; sourceId < highSource; sourceId++) { for (int generatorId = 0; generatorId < highGenerator; generatorId++) { - for (int subGeneratorId = 0; subGeneratorId < highSubGenerator; subGeneratorId++) { + for (int subGeneratorId = -1; subGeneratorId < highSubGenerator; subGeneratorId++) { auto encoded = getEncodedGenId(generatorId, sourceId, subGeneratorId); // decode them auto sourceIdAfter = getSourceId(encoded); diff --git a/Generators/include/Generators/Generator.h b/Generators/include/Generators/Generator.h index 884fa153275cd..3b3e056efe3ae 100644 --- a/Generators/include/Generators/Generator.h +++ b/Generators/include/Generators/Generator.h @@ -111,10 +111,7 @@ class Generator : public FairGenerator Bool_t triggerEvent(); /** to handle cocktail constituents **/ - void addSubGenerator(int subGeneratorId, std::string const& subGeneratorDescription) - { - mSubGeneratorsIdToDesc.insert({subGeneratorId, subGeneratorDescription}); - } + void addSubGenerator(int subGeneratorId, std::string const& subGeneratorDescription); void notifySubGenerator(int subGeneratorId) { mSubGeneratorId = subGeneratorId; } /** generator interface **/ diff --git a/Generators/src/Generator.cxx b/Generators/src/Generator.cxx index a179acd740198..90f0d2dd3a5df 100644 --- a/Generators/src/Generator.cxx +++ b/Generators/src/Generator.cxx @@ -220,6 +220,16 @@ Bool_t /*****************************************************************/ +void Generator::addSubGenerator(int subGeneratorId, std::string const& subGeneratorDescription) +{ + if (mSubGeneratorId < 0) { + LOG(fatal) << "Sub-generator IDs must be >= 0, instead, passed value is " << subGeneratorId; + } + mSubGeneratorsIdToDesc.insert({subGeneratorId, subGeneratorDescription}); +} + +/*****************************************************************/ + void Generator::updateSubGeneratorInformation(o2::dataformats::MCEventHeader* header) const { if (mSubGeneratorId < 0) {