From a84d26cf1286dcdf840feb0d7b82caf03b1076dc Mon Sep 17 00:00:00 2001 From: benedikt-voelkel Date: Wed, 19 Jul 2023 13:11:13 +0200 Subject: [PATCH 1/3] Introduce proper generator IDs (#11509) * 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 * Be consistent with Run1 and Run2 * rename cocktail to subGenerator everywhere * a cocktail should stay a cocktail of different generators * remove comment in AnalysisDataModel * 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) --------- Co-authored-by: Benedikt Volkel --- DataFormats/simulation/CMakeLists.txt | 5 ++ .../{MCGenStatus.h => MCGenProperties.h} | 55 ++++++++++++++++++- .../include/SimulationDataFormat/MCTrack.h | 2 +- .../include/SimulationDataFormat/MCUtils.h | 4 +- DataFormats/simulation/src/MCUtils.cxx | 2 +- DataFormats/simulation/test/testMCGenId.cxx | 50 +++++++++++++++++ .../simulation/test/testMCGenStatus.cxx | 2 +- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 5 +- .../include/Framework/AnalysisDataModel.h | 12 +++- Generators/CMakeLists.txt | 10 ++-- Generators/include/Generators/Generator.h | 27 ++++++--- .../Generators/GeneratorExternalParam.h | 2 +- .../include/Generators/PrimaryGenerator.h | 12 +++- .../Generators/PrimaryGeneratorParam.h | 37 +++++++++++++ Generators/src/Generator.cxx | 35 +++++++++++- 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, 277 insertions(+), 31 deletions(-) rename DataFormats/simulation/include/SimulationDataFormat/{MCGenStatus.h => MCGenProperties.h} (58%) 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 d7d048879a7a9..678e7229c4b49 100644 --- a/DataFormats/simulation/CMakeLists.txt +++ b/DataFormats/simulation/CMakeLists.txt @@ -83,3 +83,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 58% rename from DataFormats/simulation/include/SimulationDataFormat/MCGenStatus.h rename to DataFormats/simulation/include/SimulationDataFormat/MCGenProperties.h index 09b2b51c8e483..1a4f86cc98122 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,57 @@ 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 SUBGENERATORID{"subgenerator_id"}; + static constexpr Property SUBGENERATORDESCRIPTIONMAP{"subgenerator_description_map"}; +}; + +// 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) {} + MCGenIdEncoding(int generatorId, int sourceId, int subGeneratorId) : generatorId(generatorId), sourceId(sourceId), subGeneratorId(subGeneratorId) {} + short fullEncoding; + struct { + 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 + 1).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 getSubGeneratorId(short encoded) +{ + return static_cast(MCGenIdEncoding(encoded).subGeneratorId) - 1; +} + +} // namespace mcgenid + } // namespace o2 #endif diff --git a/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h b/DataFormats/simulation/include/SimulationDataFormat/MCTrack.h index df387e5526fa9..4cde4fa627084 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..246268ac78d52 --- /dev/null +++ b/DataFormats/simulation/test/testMCGenId.cxx @@ -0,0 +1,50 @@ +// 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 MCGenId class +#define BOOST_TEST_MAIN +#define BOOST_TEST_DYN_LINK +#include +#include "SimulationDataFormat/MCGenProperties.h" + +using namespace o2::mcgenid; + +BOOST_AUTO_TEST_CASE(MCGenId_test) +{ + // 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 = -1; 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/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 52f5bb76bf323..6600b415bf9a7 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" @@ -1882,10 +1883,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), 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 3d44a5b756d06..1b6538f998686 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; @@ -1270,14 +1270,20 @@ 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); //! +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(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(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); }); + } // 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..3b3e056efe3ae 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,10 @@ class Generator : public FairGenerator Bool_t boostEvent(); Bool_t triggerEvent(); + /** to handle cocktail constituents **/ + void addSubGenerator(int subGeneratorId, std::string const& subGeneratorDescription); + void notifySubGenerator(int subGeneratorId) { mSubGeneratorId = subGeneratorId; } + /** generator interface **/ void* mInterface = nullptr; std::string mInterfaceName; @@ -136,7 +141,15 @@ class Generator : public FairGenerator /** lorentz boost data members **/ Double_t mBoost; - ClassDefOverride(Generator, 1); + private: + void updateSubGeneratorInformation(o2::dataformats::MCEventHeader* header) const; + + // 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); }; /** 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..90f0d2dd3a5df 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 sub-generator ID **/ + mSubGeneratorId = -1; + /** generate event **/ if (!generateEvent()) { return kFALSE; @@ -80,6 +83,14 @@ Bool_t return kFALSE; } + if (mSubGeneratorsIdToDesc.empty() && mSubGeneratorId > -1) { + return kFALSE; + } + + if (!mSubGeneratorsIdToDesc.empty() && mSubGeneratorId < 0) { + return kFALSE; + } + /** trigger event **/ if (triggerEvent()) { mTriggerOkHook(mParticles, mReadEventCounter); @@ -102,6 +113,7 @@ Bool_t return kFALSE; } updateHeader(o2header); + updateSubGeneratorInformation(o2header); /** success **/ return kTRUE; @@ -206,6 +218,27 @@ Bool_t return triggered; } +/*****************************************************************/ + +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) { + return; + } + header->putInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, mSubGeneratorId); + header->putInfo>(o2::mcgenid::GeneratorProperty::SUBGENERATORDESCRIPTIONMAP, mSubGeneratorsIdToDesc); +} + /*****************************************************************/ /*****************************************************************/ 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 dfcf7de6f94e0..1cdbe78f9549e 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 33b40cdc443a00fbeea7906d36b2ce7be17f5371 Mon Sep 17 00:00:00 2001 From: Benedikt Volkel Date: Fri, 21 Jul 2023 09:51:21 +0200 Subject: [PATCH 2/3] Avoid warnings when looking for MCEventHeader info in particular avoid problem retrieving info 'subgenerator_id': no such key --- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 6600b415bf9a7..857df09b4b8d4 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -1885,8 +1885,12 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) // use generators' names for generatorIDs (?) auto& header = mcReader->getMCEventHeader(sourceID, eventID); bool isValid{}; + int subGeneratorId{-1}; + if (header.hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + subGeneratorId = header.getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + } mcCollisionsCursor(bcID, - o2::mcgenid::getEncodedGenId(header.getInfo(o2::mcgenid::GeneratorProperty::GENERATORID, isValid), sourceID, header.getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid)), + o2::mcgenid::getEncodedGenId(header.getInfo(o2::mcgenid::GeneratorProperty::GENERATORID, isValid), sourceID, subGeneratorId), truncateFloatFraction(header.GetX(), mCollisionPosition), truncateFloatFraction(header.GetY(), mCollisionPosition), truncateFloatFraction(header.GetZ(), mCollisionPosition), From ef711e598050dc6f80515a8a2feb994f38968ca4 Mon Sep 17 00:00:00 2001 From: Fabio Catalano Date: Wed, 18 Oct 2023 16:05:57 +0200 Subject: [PATCH 3/3] Fix typo in subGenerator check --- Generators/src/Generator.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Generators/src/Generator.cxx b/Generators/src/Generator.cxx index 90f0d2dd3a5df..99a00f154c268 100644 --- a/Generators/src/Generator.cxx +++ b/Generators/src/Generator.cxx @@ -222,7 +222,7 @@ Bool_t void Generator::addSubGenerator(int subGeneratorId, std::string const& subGeneratorDescription) { - if (mSubGeneratorId < 0) { + if (subGeneratorId < 0) { LOG(fatal) << "Sub-generator IDs must be >= 0, instead, passed value is " << subGeneratorId; } mSubGeneratorsIdToDesc.insert({subGeneratorId, subGeneratorDescription});