diff --git a/README.md b/README.md index 5b0f3aee5..e5bf720c8 100644 --- a/README.md +++ b/README.md @@ -39,12 +39,18 @@ A generic event data model for future HEP collider experiments. | [MCRecoTrackerHitPlaneAssociation](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L644) | [MCRecoCaloParticleAssociation](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L653) | [MCRecoClusterParticleAssociation](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L662) | | [MCRecoTrackParticleAssociation](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L671) | [RecoParticleVertexAssociation](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L680) | | -**Interfaces** +**Generator related (meta-)data** | | | | |-|-|-| -| [TrackerHit](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L787) | | | +| [GeneratorEventParameters](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L790) | | | +| [GeneratorPdfInfo](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L807) | | | + +**Interfaces** +| | | | +|-|-|-| +| [TrackerHit](https://github.com/key4hep/EDM4hep/blob/main/edm4hep.yaml#L818) | | | The tests and examples in the `tests` directory show how to read, write, and use these types in your code. diff --git a/doc/GeneratorInfo.md b/doc/GeneratorInfo.md new file mode 100644 index 000000000..02da37bb7 --- /dev/null +++ b/doc/GeneratorInfo.md @@ -0,0 +1,35 @@ +# Dealing with Generator (meta-)data + +EDM4hep provides data types and helper functions to handle the storage of generator meta data, both at run and event level. + +## Storing and retrieving run level information +At run level, information about generator tools (name, version, description) are being stored. They can be written via + + +```cpp + #include "edm4hep/GeneratorToolInfo.h" + // ... + // write some generator tool info into the run + auto toolInfo = edm4hep::GeneratorToolInfo(); + auto toolInfos = std::vector(); + toolInfo.name = "something"; + toolInfo.version = "v1"; + toolInfo.description = "some tool"; + toolInfos.emplace_back(std::move(toolInfo)); + + edm4hep::utils::putGenToolInfos(run, toolInfos); +``` + +and read-back via: + +```cpp + #include "edm4hep/GeneratorToolInfo.h" + // ... + auto toolInfos = edm4hep::utils::getGenToolInfos(run); + +``` + +### Storing and retrieving event specific generator parameters and PDF information + +For storing information about event level parameters of generators one can use the type `GeneratorEventParameters`. +For storing information about PDFs, one can use the type `GeneratorPdfInfo`. diff --git a/edm4hep.yaml b/edm4hep.yaml index 44f115510..eb823226c 100644 --- a/edm4hep.yaml +++ b/edm4hep.yaml @@ -783,6 +783,37 @@ datatypes: OneToOneRelations: - edm4hep::Track track // the corresponding track + + #===== Generator related data ===== + + #---------- GeneratorEventParameters + edm4hep::GeneratorEventParameters: + Description: "Generator event parameters" + Author: "EDM4hep authors" + Members: + - double eventScale // event scale + - double alphaQED // alpha_QED + - double alphaQCD // alpha_QCD + - int signalProcessId // id of signal process + - double sqrts [GeV] // sqrt(s) + VectorMembers: + - double crossSections [pb] // list of cross sections + - double crossSectionErrors [pb] // list of cross section errors + OneToManyRelations: + - edm4hep::MCParticle signalVertex // List of initial state MCParticle that are the source of the hard interaction + + + #---------- GeneratorPdfInfo + edm4hep::GeneratorPdfInfo: + Description: "Generator pdf information" + Author: "EDM4hep authors" + Members: + - std::array partonId // Parton PDG id + - std::array lhapdfId // LHAPDF PDF id (see https://lhapdf.hepforge.org/pdfsets.html) + - std::array x // Parton momentum fraction + - std::array xf // PDF value + - double scale [GeV] // Factorisation scale + interfaces: edm4hep::TrackerHit: Description: "Tracker hit interface class" diff --git a/include/edm4hep/Constants.h b/include/edm4hep/Constants.h index ddd7dd415..ef769a004 100644 --- a/include/edm4hep/Constants.h +++ b/include/edm4hep/Constants.h @@ -37,6 +37,14 @@ namespace labels { static constexpr const char* PIDParameterNames = "ParameterNames"; static constexpr const char* PIDAlgoName = "AlgoName"; static constexpr const char* PIDAlgoType = "AlgoType"; + + // Parameter names for Generator level metadata + static constexpr const char* GeneratorToolVersions = "GeneratorToolVersions"; + static constexpr const char* GeneratorToolNames = "GeneratorToolNames"; + static constexpr const char* GeneratorToolDescriptions = "GeneratorToolDescriptions"; + static constexpr const char* GeneratorEventParameters = "GeneratorEventParameters"; + static constexpr const char* GeneratorPdfInfo = "GeneratorPdfInfo"; + static constexpr const char* GeneratorWeightNames = "GeneratorWeightNames"; } // namespace labels DEPRECATED_LABEL(CellIDEncoding, CellIDEncoding); diff --git a/include/edm4hep/GeneratorToolInfo.h b/include/edm4hep/GeneratorToolInfo.h new file mode 100644 index 000000000..71dc91124 --- /dev/null +++ b/include/edm4hep/GeneratorToolInfo.h @@ -0,0 +1,88 @@ +#ifndef EDM4HEP_GENERATORTOOLINFO_H +#define EDM4HEP_GENERATORTOOLINFO_H + +#include "edm4hep/Constants.h" +#include "podio/Frame.h" +#include +#include + +namespace edm4hep { + +/// Meta information class to group information about the used generator (tools) +/// to create a file +/// +/// @note Since this is all rather loosely coupled and stored via podio Frame +/// parameters, use of the @ref getGenToolInfos and @ref putGenToolInfos utility +/// functions for retrieval, resp. storage of this information is crucial to +/// ensure consistent information. +struct GeneratorToolInfo { + std::string name{}; ///< The name of the tool + std::string version{}; ///< The version of the tool + std::string description{}; ///< A brief description of the tool + + /// Construct a generator tool info object with all empty fields + GeneratorToolInfo() = default; + + /// Construct a complete tool info object from all ingredients + /// + /// @param name The name of the tool + /// @param version The version of the tool + /// @param description The brief description of the tool + GeneratorToolInfo(const std::string& name, const std::string& version, const std::string& description) : + name(name), version(version), description(description){}; +}; + +namespace utils { + + /// Get all the generator tool infos that are available from the passed + /// (metadata) frame. + /// + /// Tries to retrieve all meta information that are available and that have + /// been stored via the @ref putGenToolInfos function. + /// + /// @param frame The (metadata) frame that should be queried for the + /// information + /// + /// @returns The GeneratorToolInfo that were found in the Frame. If none ar + /// found an empty vector will be returned. + const inline std::vector getGenToolInfos(const podio::Frame& frame) { + using namespace edm4hep::labels; + auto toolInfos = std::vector(); + const auto names = + frame.getParameter>(GeneratorToolNames).value_or(std::vector{}); + const auto versions = + frame.getParameter>(GeneratorToolVersions).value_or(std::vector{}); + const auto descriptions = + frame.getParameter>(GeneratorToolDescriptions).value_or(std::vector{}); + for (unsigned int i = 0; i < names.size(); ++i) { + toolInfos.emplace_back(names[i], versions[i], descriptions[i]); + } + return toolInfos; + }; + + /// Put the generator tool meta information into a (metadata) frame + /// + /// In order to guarantee consistent storage and retrieval of these metadata + /// it is necessary to use this utility function. + /// + /// @param frame The (metadata) Frame into which the generator tool info should go + /// @param toolInfos The generator tool infos that should be stored + void inline putGenToolInfos(podio::Frame& frame, const std::vector& toolInfos) { + auto names = std::vector(); + auto versions = std::vector(); + auto descriptions = std::vector(); + for (auto& toolInfo : toolInfos) { + names.push_back(toolInfo.name); + versions.push_back(toolInfo.version); + descriptions.push_back(toolInfo.description); + } + + using namespace edm4hep::labels; + frame.putParameter(GeneratorToolNames, std::move(names)); + frame.putParameter(GeneratorToolVersions, std::move(versions)); + frame.putParameter(GeneratorToolDescriptions, std::move(descriptions)); + }; +} // namespace utils +} // namespace edm4hep + +#endif // EDM4HEP_GENERATORTOOLINFO_H diff --git a/test/read_events.h b/test/read_events.h index d3a71d5ae..ea805483c 100644 --- a/test/read_events.h +++ b/test/read_events.h @@ -3,6 +3,9 @@ // test data model #include "edm4hep/CaloHitContributionCollection.h" +#include "edm4hep/GeneratorEventParametersCollection.h" +#include "edm4hep/GeneratorPdfInfoCollection.h" +#include "edm4hep/GeneratorToolInfo.h" #include "edm4hep/MCParticleCollection.h" #include "edm4hep/RawTimeSeriesCollection.h" #include "edm4hep/SimCalorimeterHitCollection.h" @@ -16,6 +19,27 @@ // STL #include +void processRun(const podio::Frame& run) { + //=============================================================================== + // get generator tool info from the run + auto toolInfos = edm4hep::utils::getGenToolInfos(run); + auto toolinfo = toolInfos[0]; + if (toolinfo.name != "something") + throw std::runtime_error("toolinfo.name != 'something'"); + if (toolinfo.version != "v1") + throw std::runtime_error("toolinfo.version != 'v1'"); + if (toolinfo.description != "some tool") + throw std::runtime_error("toolinfo.description != 'some tool'"); + + //=============================================================================== + // get generator weight names + auto weightNames = run.getParameter>(edm4hep::labels::GeneratorWeightNames).value(); + if (weightNames[0] != "oneWeight") + throw std::runtime_error("weightNames[0] != 'oneWeight'"); + if (weightNames[1] != "anotherWeight") + throw std::runtime_error("weightNames[1] != 'anotherWeight'"); +} + void processEvent(const podio::Frame& event) { auto& mcps = event.get("MCParticles"); auto& sths = event.get("SimTrackerHits"); @@ -232,6 +256,17 @@ void processEvent(const podio::Frame& event) { throw std::runtime_error("Collection 'TrackerHitPlanes' should be present"); } + //=============================================================================== + // check the generator meta data + auto& genParametersCollection = + event.get(edm4hep::labels::GeneratorEventParameters); + auto genParam = genParametersCollection[0]; + if (genParam.getEventScale() != 23) + throw std::runtime_error("Event_scale != 23"); + + auto& generatorPdfInfoCollection = event.get(edm4hep::labels::GeneratorPdfInfo); + auto genPdfInfo = generatorPdfInfoCollection[0]; + // //=============================================================================== // if( sccons.isValid() ){ // } else { @@ -251,6 +286,9 @@ void read_events(const std::string& filename) { ReaderT reader; reader.openFile(filename); + const auto run = podio::Frame(reader.readNextEntry("runs")); + processRun(run); + unsigned nEvents = reader.getEntries("events"); for (unsigned i = 0; i < nEvents; ++i) { std::cout << "reading event " << i << std::endl; diff --git a/test/write_events.h b/test/write_events.h index e80d5c6f2..9eaa2ebe6 100644 --- a/test/write_events.h +++ b/test/write_events.h @@ -2,7 +2,11 @@ #define EDM4HEP_TEST_WRITE_EVENTS_H // Data model + #include "edm4hep/CaloHitContributionCollection.h" +#include "edm4hep/GeneratorEventParametersCollection.h" +#include "edm4hep/GeneratorPdfInfoCollection.h" +#include "edm4hep/GeneratorToolInfo.h" #include "edm4hep/MCParticleCollection.h" #include "edm4hep/RawTimeSeriesCollection.h" #include "edm4hep/SimCalorimeterHitCollection.h" @@ -28,6 +32,7 @@ void write(std::string outfilename) { for (unsigned i = 0; i < nevents; ++i) { std::cout << " --- processing event " << i << std::endl; auto event = podio::Frame(); + auto run = podio::Frame(); // place the following generator event to the MCParticle collection // @@ -108,6 +113,47 @@ void write(std::string outfilename) { } } + //=============================================================================== + // write some generator event data + auto genParametersCollection = edm4hep::GeneratorEventParametersCollection(); + auto genParam = genParametersCollection.create(); + genParam.setEventScale(23); + genParam.setAlphaQED(1 / 127); + genParam.setAlphaQCD(0.1); + genParam.setSignalProcessId(42); + genParam.setSqrts(90); + genParam.addToCrossSections(10); + genParam.addToCrossSectionErrors(3); + genParam.addToSignalVertex(mcp1); + genParam.addToSignalVertex(mcp2); + event.put(std::move(genParametersCollection), edm4hep::labels::GeneratorEventParameters); + + auto genPdfInfoCollection = edm4hep::GeneratorPdfInfoCollection(); + auto genPdfInfo = genPdfInfoCollection.create(); + genPdfInfo.setPartonId(1, 2); + genPdfInfo.setLhapdfId({20, 20}); + genPdfInfo.setX({0.5, 0.5}); + genPdfInfo.setXf({0.5, 0.5}); + genPdfInfo.setScale(23); + event.put(std::move(genPdfInfoCollection), edm4hep::labels::GeneratorPdfInfo); + + //=============================================================================== + // write some generator tool info into the run + auto toolInfos = std::vector(); + auto toolInfo = edm4hep::GeneratorToolInfo(); + toolInfo.name = "something"; + toolInfo.version = "v1"; + toolInfo.description = "some tool"; + toolInfos.emplace_back(std::move(toolInfo)); + edm4hep::utils::putGenToolInfos(run, toolInfos); + + //=============================================================================== + // write some generator weightname info into the run + auto weightNames = std::vector(); + weightNames.emplace_back("oneWeight"); + weightNames.emplace_back("anotherWeight"); + run.putParameter(edm4hep::labels::GeneratorWeightNames, std::move(weightNames)); + // fixme: should this become a utility function ? //------------------------------------------------------------- @@ -237,6 +283,7 @@ void write(std::string outfilename) { event.putParameter("EventType", "test"); writer.writeFrame(event, "events"); + writer.writeFrame(run, "runs"); } writer.finish(); diff --git a/tools/include/edm4hep2json.hxx b/tools/include/edm4hep2json.hxx index 0849453de..2ff0faba0 100644 --- a/tools/include/edm4hep2json.hxx +++ b/tools/include/edm4hep2json.hxx @@ -6,6 +6,8 @@ #include "edm4hep/CalorimeterHitCollection.h" #include "edm4hep/ClusterCollection.h" #include "edm4hep/EventHeaderCollection.h" +#include "edm4hep/GeneratorEventParametersCollection.h" +#include "edm4hep/GeneratorPdfInfoCollection.h" #include "edm4hep/MCParticleCollection.h" #include "edm4hep/ParticleIDCollection.h" #include "edm4hep/RawCalorimeterHitCollection.h" @@ -154,6 +156,12 @@ nlohmann::json processEvent(const podio::Frame& frame, std::vector& insertIntoJson>(jsonDict, coll, collList[i]); } else if (coll->getTypeName() == "podio::UserDataCollection") { insertIntoJson>(jsonDict, coll, collList[i]); + } + // Generator (meta-)data + else if (coll->getTypeName() == "podio::GeneratorParametersCollection") { + insertIntoJson(jsonDict, coll, collList[i]); + } else if (coll->getTypeName() == "podio::GeneratorPdfInfoCollection") { + insertIntoJson(jsonDict, coll, collList[i]); } else { std::cout << "WARNING: Collection type not recognized!\n" << " " << coll->getTypeName() << "\n";