Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 07:53:16

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsExamples/Io/HepMC3/HepMC3Util.hpp"
0010 
0011 #include "Acts/Utilities/ScopedTimer.hpp"
0012 
0013 #include <stdexcept>
0014 
0015 #include <HepMC3/GenEvent.h>
0016 #include <HepMC3/GenParticle.h>
0017 #include <HepMC3/GenVertex.h>
0018 
0019 namespace ActsExamples {
0020 
0021 namespace {
0022 template <typename T>
0023 void mergeEventsImpl(HepMC3::GenEvent& event, std::span<T> genEvents,
0024                      const Acts::Logger& logger) {
0025   Acts::AveragingScopedTimer mergeTimer("Merging HepMC3 events", logger(),
0026                                         Acts::Logging::DEBUG);
0027 
0028   std::vector<std::shared_ptr<HepMC3::GenParticle>> particles;
0029 
0030   // Loop once to find the total size we'll need
0031   std::size_t nParticles = 0;
0032   std::size_t nVertices = 0;
0033   for (const auto& genEvent : genEvents) {
0034     nParticles += genEvent->particles().size();
0035     nVertices += genEvent->vertices().size();
0036   }
0037 
0038   event.reserve(nParticles, nVertices);
0039 
0040   for (const auto& genEvent : genEvents) {
0041     auto sample = mergeTimer.sample();
0042     particles.clear();
0043     particles.reserve(genEvent->particles().size());
0044 
0045     auto copyAttributes = [&](const auto& src, auto& dst) {
0046       for (const auto& attr : src.attribute_names()) {
0047         auto value = src.attribute_as_string(attr);
0048         dst.add_attribute(attr,
0049                           std::make_shared<HepMC3::StringAttribute>(value));
0050       }
0051     };
0052 
0053     copyAttributes(*genEvent, event);
0054 
0055     // Add to combined event
0056     for (const auto& srcParticle : genEvent->particles()) {
0057       if (srcParticle->id() - 1 != static_cast<int>(particles.size())) {
0058         throw std::runtime_error("Particle id is not consecutive");
0059       }
0060       auto particle = std::make_shared<HepMC3::GenParticle>();
0061       particle->set_momentum(srcParticle->momentum());
0062       particle->set_generated_mass(srcParticle->generated_mass());
0063       particle->set_pid(srcParticle->pid());
0064       particle->set_status(srcParticle->status());
0065 
0066       particles.push_back(particle);
0067       event.add_particle(particle);
0068 
0069       copyAttributes(*srcParticle, *particle);
0070     }
0071 
0072     for (const auto& srcVertex : genEvent->vertices()) {
0073       auto vertex = std::make_shared<HepMC3::GenVertex>(srcVertex->position());
0074       vertex->set_status(srcVertex->status());
0075 
0076       event.add_vertex(vertex);
0077 
0078       copyAttributes(*srcVertex, *vertex);
0079 
0080       for (const auto& srcParticle : srcVertex->particles_in()) {
0081         const auto& particle = particles.at(srcParticle->id() - 1);
0082         vertex->add_particle_in(particle);
0083       }
0084       for (const auto& srcParticle : srcVertex->particles_out()) {
0085         const auto& particle = particles.at(srcParticle->id() - 1);
0086         vertex->add_particle_out(particle);
0087       }
0088     }
0089   }
0090 }
0091 }  // namespace
0092 
0093 void HepMC3Util::mergeEvents(HepMC3::GenEvent& event,
0094                              std::span<const HepMC3::GenEvent*> genEvents,
0095                              const Acts::Logger& logger) {
0096   mergeEventsImpl(event, genEvents, logger);
0097 }
0098 
0099 void HepMC3Util::mergeEvents(
0100     HepMC3::GenEvent& event,
0101     std::span<std::shared_ptr<const HepMC3::GenEvent>> genEvents,
0102     const Acts::Logger& logger) {
0103   mergeEventsImpl(event, genEvents, logger);
0104 }
0105 
0106 std::string_view HepMC3Util::compressionExtension(Compression compression) {
0107   switch (compression) {
0108     using enum Compression;
0109     case none:
0110       return "";
0111     case zlib:
0112       return ".gz";
0113     case lzma:
0114       return ".xz";
0115     case bzip2:
0116       return ".bz2";
0117     case zstd:
0118       return ".zst";
0119     default:
0120       throw std::invalid_argument{"Unknown compression value"};
0121   }
0122 }
0123 
0124 std::span<const HepMC3Util::Compression>
0125 HepMC3Util::availableCompressionModes() {
0126   using enum Compression;
0127   static const auto values = []() -> std::vector<HepMC3Util::Compression> {
0128     return {
0129         none,
0130 #ifdef HEPMC3_Z_SUPPORT
0131         zlib,
0132 #endif
0133 #ifdef HEPMC3_LZMA_SUPPORT
0134         lzma,
0135 #endif
0136 #ifdef HEPMC3_BZ2_SUPPORT
0137         bzip2,
0138 #endif
0139 #ifdef HEPMC3_ZSTD_SUPPORT
0140         zstd,
0141 #endif
0142     };
0143   }();
0144   return values;
0145 }
0146 
0147 std::ostream& HepMC3Util::operator<<(std::ostream& os,
0148                                      HepMC3Util::Compression compression) {
0149   switch (compression) {
0150     using enum HepMC3Util::Compression;
0151     case none:
0152       return os << "none";
0153     case zlib:
0154       return os << "zlib";
0155     case lzma:
0156       return os << "lzma";
0157     case bzip2:
0158       return os << "bzip2";
0159     case zstd:
0160       return os << "zstd";
0161     default:
0162       throw std::invalid_argument{"Unknown compression value"};
0163   }
0164 }
0165 
0166 std::ostream& HepMC3Util::operator<<(std::ostream& os,
0167                                      HepMC3Util::Format format) {
0168   switch (format) {
0169     using enum HepMC3Util::Format;
0170     case ascii:
0171       return os << "ascii";
0172     case root:
0173       return os << "root";
0174     default:
0175       throw std::invalid_argument{"Unknown format value"};
0176   }
0177 }
0178 
0179 std::span<const HepMC3Util::Format> HepMC3Util::availableFormats() {
0180   using enum Format;
0181   static const auto values = []() -> std::vector<HepMC3Util::Format> {
0182     return {
0183         ascii,
0184 #ifdef HEPMC3_ROOT_SUPPORT
0185         root,
0186 #endif
0187     };
0188   }();
0189   return values;
0190 }
0191 
0192 HepMC3Util::Format HepMC3Util::formatFromFilename(std::string_view filename) {
0193   using enum Format;
0194 
0195   for (auto compression : availableCompressionModes()) {
0196     auto ext = compressionExtension(compression);
0197 
0198     if (filename.ends_with(".hepmc3" + std::string(ext)) ||
0199         filename.ends_with(".hepmc" + std::string(ext))) {
0200       return ascii;
0201     }
0202   }
0203   if (filename.ends_with(".root")) {
0204     return root;
0205   }
0206 
0207   throw std::invalid_argument{"Unknown format extension: " +
0208                               std::string{filename}};
0209 }
0210 
0211 }  // namespace ActsExamples