Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-22 07:55:45

0001 
0002 #include "JEventProcessorPODIO.h"
0003 
0004 #include <JANA/JApplication.h>
0005 #include <JANA/JApplicationFwd.h>
0006 #include <JANA/Services/JParameterManager.h>
0007 #include <JANA/Utils/JTypeInfo.h>
0008 #include <fmt/core.h>
0009 #include <fmt/format.h>
0010 #include <podio/CollectionBase.h>
0011 #include <podio/Frame.h>
0012 #include <podio/ROOTWriter.h>
0013 #include <algorithm>
0014 #include <exception>
0015 #include <functional>
0016 #include <iterator>
0017 #include <regex>
0018 #include <sstream>
0019 #include <stdexcept>
0020 
0021 #include "services/log/Log_service.h"
0022 
0023 JEventProcessorPODIO::JEventProcessorPODIO() {
0024   SetTypeName(NAME_OF_THIS); // Provide JANA with this class's name
0025 
0026   japp->SetDefaultParameter("podio:output_file", m_output_file,
0027                             "Name of EDM4hep/podio output file to write to. Setting this will "
0028                             "cause the output file to be created and written to.");
0029 
0030   // Allow user to set PODIO:OUTPUT_FILE to "1" to specify using the default name.
0031   if (m_output_file == "1") {
0032     auto* param = japp->GetJParameterManager()->FindParameter("podio:output_file");
0033     if (param != nullptr) {
0034       param->SetValue(param->GetDefault());
0035       m_output_file = param->GetDefault();
0036     }
0037   }
0038 
0039   // Get the output directory path for creating a second copy of the output file at the end of processing.
0040   // (this is duplicating similar functionality in Juggler/Gaudi so assume it is useful).
0041   japp->SetDefaultParameter("podio:output_file_copy_dir", m_output_file_copy_dir,
0042                             "Directory name to make an additional copy of the output file to. Copy "
0043                             "will be done at end of processing. Default is empty string which "
0044                             "means do not make a copy. No check is made on path existing.");
0045 
0046   // Get the list of output collections to include/exclude
0047   std::vector<std::string> output_collections = {
0048       // Header and other metadata
0049       "EventHeader",
0050 
0051       // Truth record
0052       "MCParticles",
0053       "MCBeamElectrons",
0054       "MCBeamProtons",
0055       "MCScatteredElectrons",
0056       "MCScatteredProtons",
0057       "MCParticlesHeadOnFrameNoBeamFX",
0058 
0059       // Central tracking hits combined
0060       "CentralTrackerTruthSeeds",
0061       "CentralTrackingRecHits",
0062       "CentralTrackingRawHitAssociations",
0063       "CentralTrackSeedingResults",
0064       "CentralTrackerMeasurements",
0065 
0066       // Si tracker hits
0067       "SiBarrelTrackerRecHits",
0068       "SiBarrelVertexRecHits",
0069       "SiEndcapTrackerRecHits",
0070 
0071       "SiBarrelRawHits",
0072       "SiBarrelVertexRawHits",
0073       "SiEndcapTrackerRawHits",
0074 
0075       "SiBarrelHits",
0076       "VertexBarrelHits",
0077       "TrackerEndcapHits",
0078 
0079       "SiBarrelRawHitAssociations",
0080       "SiBarrelVertexRawHitAssociations",
0081       "SiEndcapTrackerRawHitAssociations",
0082 
0083       // TOF
0084       "TOFBarrelRecHits",
0085       "TOFEndcapRecHits",
0086 
0087       "TOFBarrelRawHits",
0088       "TOFEndcapRawHits",
0089 
0090       "TOFBarrelHits",
0091       "TOFBarrelClusterHits",
0092       "TOFBarrelADCTDC",
0093       "TOFEndcapHits",
0094 
0095       "TOFEndcapSharedHits",
0096       "TOFEndcapADCTDC",
0097 
0098       "TOFBarrelRawHitAssociations",
0099       "TOFEndcapRawHitAssociations",
0100 
0101       "CombinedTOFTruthSeededParticleIDs",
0102       "CombinedTOFParticleIDs",
0103 
0104       // DRICH
0105       "DRICHRawHits",
0106       "DRICHRawHitsAssociations",
0107       "DRICHAerogelTracks",
0108       "DRICHGasTracks",
0109       "DRICHAerogelIrtCherenkovParticleID",
0110       "DRICHGasIrtCherenkovParticleID",
0111       "DRICHTruthSeededParticleIDs",
0112       "DRICHParticleIDs",
0113 
0114       // PFRICH
0115       "RICHEndcapNRawHits",
0116       "RICHEndcapNRawHitsAssociations",
0117       "RICHEndcapNTruthSeededParticleIDs",
0118       "RICHEndcapNParticleIDs",
0119 
0120       // MPGD
0121       "MPGDBarrelRecHits",
0122       "OuterMPGDBarrelRecHits",
0123       "BackwardMPGDEndcapRecHits",
0124       "ForwardMPGDEndcapRecHits",
0125 
0126       "MPGDBarrelRawHits",
0127       "OuterMPGDBarrelRawHits",
0128       "BackwardMPGDEndcapRawHits",
0129       "ForwardMPGDEndcapRawHits",
0130 
0131       "MPGDBarrelHits",
0132       "OuterMPGDBarrelHits",
0133       "BackwardMPGDEndcapHits",
0134       "ForwardMPGDEndcapHits",
0135 
0136       "MPGDBarrelRawHitAssociations",
0137       "OuterMPGDBarrelRawHitAssociations",
0138       "BackwardMPGDEndcapRawHitAssociations",
0139       "ForwardMPGDEndcapRawHitAssociations",
0140 
0141       // LOWQ2 hits
0142       "TaggerTrackerHits",
0143       "TaggerTrackerSharedHits",
0144       "TaggerTrackerHitPulses",
0145       "TaggerTrackerCombinedPulses",
0146       "TaggerTrackerCombinedPulsesWithNoise",
0147       "TaggerTrackerRawHits",
0148       "TaggerTrackerRawHitAssociations",
0149       "TaggerTrackerM1L0ClusterPositions",
0150       "TaggerTrackerM1L1ClusterPositions",
0151       "TaggerTrackerM1L2ClusterPositions",
0152       "TaggerTrackerM1L3ClusterPositions",
0153       "TaggerTrackerM2L0ClusterPositions",
0154       "TaggerTrackerM2L1ClusterPositions",
0155       "TaggerTrackerM2L2ClusterPositions",
0156       "TaggerTrackerM2L3ClusterPositions",
0157       "TaggerTrackerM1LocalTracks",
0158       "TaggerTrackerM2LocalTracks",
0159       "TaggerTrackerM1LocalTrackAssociations",
0160       "TaggerTrackerM2LocalTrackAssociations",
0161       "TaggerTrackerLocalTracks",
0162       "TaggerTrackerLocalTrackAssociations",
0163       "TaggerTrackerReconstructedParticles",
0164       "TaggerTrackerReconstructedParticleAssociations",
0165 
0166       // Forward & Far forward hits
0167       "B0TrackerTruthSeeds",
0168       "B0TrackerRecHits",
0169       "B0TrackerRawHits",
0170       "B0TrackerHits",
0171       "B0TrackerRawHitAssociations",
0172       "B0TrackerSeedingResults",
0173       "B0TrackerMeasurements",
0174 
0175       "ForwardRomanPotRecHits",
0176       "ForwardOffMTrackerRecHits",
0177 
0178       "ForwardRomanPotRecParticles",
0179       "ForwardOffMRecParticles",
0180 
0181       "ForwardRomanPotRawHits",
0182       "ForwardRomanPotRawHitAssociations",
0183       "ForwardOffMTrackerRawHits",
0184       "ForwardOffMTrackerRawHitAssociations",
0185 
0186       // Reconstructed data
0187       "GeneratedParticles",
0188       "GeneratedBreitFrameParticles",
0189       "ReconstructedParticles",
0190       "ReconstructedParticleAssociations",
0191       "ReconstructedTruthSeededChargedParticles",
0192       "ReconstructedTruthSeededChargedParticleAssociations",
0193       "ReconstructedChargedRealPIDParticles",
0194       "ReconstructedChargedRealPIDParticleIDs",
0195       "ReconstructedChargedParticles",
0196       "ReconstructedChargedParticleAssociations",
0197       "MCScatteredElectronAssociations",    // Remove if/when used internally
0198       "MCNonScatteredElectronAssociations", // Remove if/when used internally
0199       "ReconstructedBreitFrameParticles",
0200 
0201       // Central tracking
0202       "CentralTrackSegments",
0203       "CentralTrackVertices",
0204       "CentralCKFTruthSeededTrajectories",
0205       "CentralCKFTruthSeededTracks",
0206       "CentralCKFTruthSeededTrackAssociations",
0207       "CentralCKFTruthSeededTrackParameters",
0208       "CentralCKFTrajectories",
0209       "CentralCKFTracks",
0210       "CentralCKFTrackAssociations",
0211       "CentralCKFTrackParameters",
0212       // tracking properties - true seeding
0213       "CentralCKFTruthSeededTrajectoriesUnfiltered",
0214       "CentralCKFTruthSeededTracksUnfiltered",
0215       "CentralCKFTruthSeededTrackUnfilteredAssociations",
0216       "CentralCKFTruthSeededTrackParametersUnfiltered",
0217       // tracking properties - realistic seeding
0218       "CentralCKFTrajectoriesUnfiltered",
0219       "CentralCKFTracksUnfiltered",
0220       "CentralCKFTrackUnfilteredAssociations",
0221       "CentralCKFTrackParametersUnfiltered",
0222 
0223       // B0 tracking
0224       "B0TrackerCKFTruthSeededTrajectories",
0225       "B0TrackerCKFTruthSeededTracks",
0226       "B0TrackerCKFTruthSeededTrackAssociations",
0227       "B0TrackerCKFTruthSeededTrackParameters",
0228       "B0TrackerCKFTrajectories",
0229       "B0TrackerCKFTracks",
0230       "B0TrackerCKFTrackAssociations",
0231       "B0TrackerCKFTrackParameters",
0232       // tracking properties - true seeding
0233       "B0TrackerCKFTruthSeededTrajectoriesUnfiltered",
0234       "B0TrackerCKFTruthSeededTracksUnfiltered",
0235       "B0TrackerCKFTruthSeededTrackUnfilteredAssociations",
0236       "B0TrackerCKFTruthSeededTrackParametersUnfiltered",
0237       // tracking properties - realistic seeding
0238       "B0TrackerCKFTrajectoriesUnfiltered",
0239       "B0TrackerCKFTrackParametersUnfiltered",
0240       "B0TrackerCKFTracksUnfiltered",
0241       "B0TrackerCKFTrackUnfilteredAssociations",
0242 
0243       "CentralAndB0TrackVertices",
0244 
0245       // Inclusive kinematics
0246       "InclusiveKinematicsDA",
0247       "InclusiveKinematicsJB",
0248       "InclusiveKinematicsML",
0249       "InclusiveKinematicsSigma",
0250       "InclusiveKinematicseSigma", // Deprecated, use ESigma
0251       "InclusiveKinematicsESigma",
0252       "InclusiveKinematicsElectron",
0253       "InclusiveKinematicsTruth",
0254       "GeneratedJets",
0255       "GeneratedChargedJets",
0256       "GeneratedCentauroJets",
0257       "ReconstructedJets",
0258       "ReconstructedChargedJets",
0259       "ReconstructedCentauroJets",
0260       "ReconstructedElectrons",
0261       "ScatteredElectronsTruth",
0262       "ScatteredElectronsEMinusPz",
0263       "PrimaryVertices",
0264       "BarrelClusters",
0265       "HadronicFinalState",
0266 
0267       // Track projections
0268       "CalorimeterTrackProjections",
0269 
0270       // Ecal stuff
0271       "EcalEndcapNRawHits",
0272       "EcalEndcapNRecHits",
0273       "EcalEndcapNTruthClusters",
0274       "EcalEndcapNTruthClusterAssociations",
0275       "EcalEndcapNClusters",
0276       "EcalEndcapNClusterAssociations",
0277       "EcalEndcapNSplitMergeClusters",
0278       "EcalEndcapNSplitMergeClusterAssociations",
0279       "EcalEndcapPRawHits",
0280       "EcalEndcapPRecHits",
0281       "EcalEndcapPTruthClusters",
0282       "EcalEndcapPTruthClusterAssociations",
0283       "EcalEndcapPClusters",
0284       "EcalEndcapPClusterAssociations",
0285       "EcalEndcapPSplitMergeClusters",
0286       "EcalEndcapPSplitMergeClusterAssociations",
0287       "EcalBarrelClusters",
0288       "EcalBarrelClusterAssociations",
0289       "EcalBarrelTruthClusters",
0290       "EcalBarrelTruthClusterAssociations",
0291       "EcalBarrelImagingRawHits",
0292       "EcalBarrelImagingRecHits",
0293       "EcalBarrelImagingClusters",
0294       "EcalBarrelImagingClusterAssociations",
0295       "EcalBarrelScFiPAttenuatedHits",
0296       "EcalBarrelScFiPAttenuatedHitContributions",
0297       "EcalBarrelScFiNAttenuatedHits",
0298       "EcalBarrelScFiNAttenuatedHitContributions",
0299       "EcalBarrelScFiRawHits",
0300       "EcalBarrelScFiPPulses",
0301       "EcalBarrelScFiNPulses",
0302       "EcalBarrelScFiPCombinedPulses",
0303       "EcalBarrelScFiNCombinedPulses",
0304       "EcalBarrelScFiPCombinedPulsesWithNoise",
0305       "EcalBarrelScFiNCombinedPulsesWithNoise",
0306       "EcalBarrelScFiRecHits",
0307       "EcalBarrelScFiClusters",
0308       "EcalBarrelScFiClusterAssociations",
0309       "EcalLumiSpecRawHits",
0310       "EcalLumiSpecRecHits",
0311       "EcalLumiSpecTruthClusters",
0312       "EcalLumiSpecTruthClusterAssociations",
0313       "EcalLumiSpecClusters",
0314       "EcalLumiSpecClusterAssociations",
0315       "HcalEndcapNRawHits",
0316       "HcalEndcapNRecHits",
0317       "HcalEndcapNMergedHits",
0318       "HcalEndcapNClusters",
0319       "HcalEndcapNClusterAssociations",
0320       "HcalEndcapNSplitMergeClusters",
0321       "HcalEndcapNSplitMergeClusterAssociations",
0322       "HcalEndcapPInsertRawHits",
0323       "HcalEndcapPInsertRecHits",
0324       "HcalEndcapPInsertMergedHits",
0325       "HcalEndcapPInsertClusters",
0326       "HcalEndcapPInsertClusterAssociations",
0327       "LFHCALRawHits",
0328       "LFHCALRecHits",
0329       "LFHCALClusters",
0330       "LFHCALClusterAssociations",
0331       "LFHCALSplitMergeClusters",
0332       "LFHCALSplitMergeClusterAssociations",
0333       "HcalBarrelRawHits",
0334       "HcalBarrelRecHits",
0335       "HcalBarrelMergedHits",
0336       "HcalBarrelClusters",
0337       "HcalBarrelClusterAssociations",
0338       "HcalBarrelSplitMergeClusters",
0339       "HcalBarrelSplitMergeClusterAssociations",
0340       "B0ECalRawHits",
0341       "B0ECalRecHits",
0342       "B0ECalClusters",
0343       "B0ECalClusterAssociations",
0344       "HcalEndcapNTruthClusters",
0345       "HcalEndcapNTruthClusterAssociations",
0346       "HcalBarrelTruthClusters",
0347       "HcalBarrelTruthClusterAssociations",
0348 
0349       //ZDC Ecal
0350       "EcalFarForwardZDCRawHits",
0351       "EcalFarForwardZDCRecHits",
0352       "EcalFarForwardZDCClusters",
0353       "EcalFarForwardZDCClusterAssociations",
0354       "EcalFarForwardZDCTruthClusters",
0355       "EcalFarForwardZDCTruthClusterAssociations",
0356 
0357       //ZDC HCal
0358       "HcalFarForwardZDCRawHits",
0359       "HcalFarForwardZDCRecHits",
0360       "HcalFarForwardZDCSubcellHits",
0361       "HcalFarForwardZDCClusters",
0362       "HcalFarForwardZDCClusterAssociations",
0363       "HcalFarForwardZDCClustersBaseline",
0364       "HcalFarForwardZDCClusterAssociationsBaseline",
0365       "HcalFarForwardZDCTruthClusters",
0366       "HcalFarForwardZDCTruthClusterAssociations",
0367       "ReconstructedFarForwardZDCNeutrals",
0368       "ReconstructedFarForwardZDCLambdas",
0369       "ReconstructedFarForwardZDCLambdaDecayProductsCM",
0370 
0371       // DIRC
0372       "DIRCRawHits",
0373       "DIRCTruthSeededParticleIDs",
0374       "DIRCParticleIDs",
0375 
0376       "B0ECalRawHitAssociations",
0377       "EcalBarrelScFiRawHitAssociations",
0378       "EcalBarrelImagingRawHitAssociations",
0379       "HcalBarrelRawHitAssociations",
0380       "EcalEndcapNRawHitAssociations",
0381       "HcalEndcapNRawHitAssociations",
0382       "EcalEndcapPRawHitAssociations",
0383       "HcalEndcapPInsertRawHitAssociations",
0384       "LFHCALRawHitAssociations",
0385       "EcalLumiSpecRawHitAssociations",
0386       "EcalFarForwardZDCRawHitAssociations",
0387       "HcalFarForwardZDCRawHitAssociations",
0388       "EcalEndcapPTrackClusterMatches",
0389       "LFHCALTrackClusterMatches",
0390       "HcalEndcapPInsertClusterMatches",
0391       "EcalBarrelTrackClusterMatches",
0392       "HcalBarrelTrackClusterMatches",
0393       "EcalEndcapNTrackClusterMatches",
0394       "HcalEndcapNTrackClusterMatches",
0395 
0396   };
0397   std::vector<std::string> output_exclude_collections; // need to get as vector, then convert to set
0398   std::string output_include_collections = "DEPRECATED";
0399   japp->SetDefaultParameter("podio:output_include_collections", output_include_collections,
0400                             "DEPRECATED. Use podio:output_collections instead.");
0401   if (output_include_collections != "DEPRECATED") {
0402     output_collections.clear();
0403     JParameterManager::Parse(output_include_collections, output_collections);
0404     m_output_include_collections_set = true;
0405   }
0406   japp->SetDefaultParameter(
0407       "podio:output_collections", output_collections,
0408       "Comma separated list of collection names to write out. If not set, all collections will be "
0409       "written (including ones from input file). Don't set this and use "
0410       "PODIO:OUTPUT_EXCLUDE_COLLECTIONS to write everything except a selection.");
0411   japp->SetDefaultParameter("podio:output_exclude_collections", output_exclude_collections,
0412                             "Comma separated list of collection names to not write out.");
0413   japp->SetDefaultParameter(
0414       "podio:print_collections", m_collections_to_print,
0415       "Comma separated list of collection names to print to screen, e.g. for debugging.");
0416 
0417   m_output_collections =
0418       std::set<std::string>(output_collections.begin(), output_collections.end());
0419   m_output_exclude_collections =
0420       std::set<std::string>(output_exclude_collections.begin(), output_exclude_collections.end());
0421 }
0422 
0423 void JEventProcessorPODIO::Init() {
0424 
0425   auto* app = GetApplication();
0426   m_log     = app->GetService<Log_service>()->logger("JEventProcessorPODIO");
0427   m_writer  = std::make_unique<podio::ROOTWriter>(m_output_file);
0428   // TODO: NWB: Verify that output file is writable NOW, rather than after event processing completes.
0429   //       I definitely don't trust PODIO to do this for me.
0430 
0431   if (m_output_include_collections_set) {
0432     m_log->error("The podio:output_include_collections was provided, but is deprecated. Use "
0433                  "podio:output_collections instead.");
0434     throw std::runtime_error("The podio:output_include_collections was provided, but is "
0435                              "deprecated. Use podio:output_collections instead.");
0436   }
0437 }
0438 
0439 void JEventProcessorPODIO::FindCollectionsToWrite(const std::shared_ptr<const JEvent>& event) {
0440 
0441   // Set up the set of collections_to_write.
0442   std::vector<std::string> all_collections = event->GetAllCollectionNames();
0443 
0444   if (m_output_collections.empty()) {
0445     // User has not specified an include list, so we include _all_ PODIO collections present in the first event.
0446     for (const std::string& col : all_collections) {
0447       if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) {
0448         m_collections_to_write.push_back(col);
0449         m_log->info("Persisting collection '{}'", col);
0450       }
0451     }
0452   } else {
0453     m_log->debug("Persisting podio types from includes list");
0454 
0455     // We match up the include list with what is actually present in the event
0456     std::set<std::string> all_collections_set =
0457         std::set<std::string>(all_collections.begin(), all_collections.end());
0458 
0459     // Turn regexes among output collections into actual collection names
0460     std::set<std::string> matching_collections_set;
0461     std::vector<std::regex> output_collections_regex(m_output_collections.size());
0462     std::ranges::transform(m_output_collections, output_collections_regex.begin(),
0463                            [](const std::string& r) { return std::regex(r); });
0464     std::ranges::copy_if(all_collections_set,
0465                          std::inserter(matching_collections_set, matching_collections_set.end()),
0466                          [&](const std::string& c) {
0467                            return std::ranges::any_of(
0468                                output_collections_regex,
0469 
0470                                [&](const std::regex& r) { return std::regex_match(c, r); });
0471                          });
0472 
0473     for (const auto& col : matching_collections_set) {
0474       if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) {
0475         // Included and not excluded
0476         if (all_collections_set.find(col) == all_collections_set.end()) {
0477           // Included, but not a valid PODIO type
0478           m_log->warn("Explicitly included collection '{}' not present in factory set, omitting.",
0479                       col);
0480         } else {
0481           // Included, not excluded, and a valid PODIO type
0482           m_collections_to_write.push_back(col);
0483           m_log->info("Persisting collection '{}'", col);
0484         }
0485       }
0486     }
0487   }
0488 }
0489 
0490 void JEventProcessorPODIO::Process(const std::shared_ptr<const JEvent>& event) {
0491 
0492   // Find all collections to write from the first event
0493   std::call_once(m_is_first_event, &JEventProcessorPODIO::FindCollectionsToWrite, this, event);
0494 
0495   // Print the contents of some collections, just for debugging purposes
0496   // Do this before writing just in case writing crashes
0497   if (!m_collections_to_print.empty()) {
0498     m_log->info("========================================");
0499     m_log->info("JEventProcessorPODIO: Event {}", event->GetEventNumber());
0500     ;
0501   }
0502   for (const auto& coll_name : m_collections_to_print) {
0503     m_log->info("------------------------------");
0504     m_log->info("{}", coll_name);
0505     try {
0506       const auto* coll_ptr = event->GetCollectionBase(coll_name);
0507       if (coll_ptr == nullptr) {
0508         m_log->info("missing");
0509       } else {
0510         std::stringstream ss;
0511         coll_ptr->print(ss);
0512         m_log->info(ss.str());
0513       }
0514     } catch (std::exception& e) {
0515       m_log->info("missing");
0516     }
0517   }
0518 
0519   m_log->trace("==================================");
0520   m_log->trace("Event #{}", event->GetEventNumber());
0521 
0522   // Make sure that all factories get called that need to be written into the frame.
0523   // We need to do this for _all_ factories unless we've constrained it by using includes/excludes.
0524   // Note that all collections need to be present in the first event, as podio::RootFrameWriter constrains us to write one event at a time, so there
0525   // is no way to add a new branch after the first event.
0526 
0527   // If we get an exception below while trying to add a factory for any
0528   // reason then mark that factory as bad and don't try running it again.
0529   // This is motivated by trying to write EcalBarrelSciGlass objects for
0530   // data simulated using the imaging calorimeter. In that case, it will
0531   // always throw an exception, but DD4hep also prints its own error message.
0532   // Thus, to prevent that error message every event, we must avoid calling
0533   // it.
0534 
0535   // Activate factories.
0536   std::vector<std::string> successful_collections;
0537   std::set<std::string> failed_collections;
0538   for (const std::string& coll : m_collections_to_write) {
0539     try {
0540       m_log->trace("Ensuring factory for collection '{}' has been called.", coll);
0541       const auto* coll_ptr = event->GetCollectionBase(coll);
0542       if (coll_ptr == nullptr) {
0543         // If a collection is missing from the frame, the podio root writer will segfault.
0544         // To avoid this, we treat this as a failing collection and omit from this point onwards.
0545         // However, this code path is expected to be unreachable because any missing collection will be
0546         // replaced with an empty collection in JFactoryPodioTFixed::Create.
0547         if (!failed_collections.contains(coll)) {
0548           m_log->error("Omitting PODIO collection '{}' because it is null", coll);
0549           failed_collections.insert(coll);
0550         }
0551       } else {
0552         m_log->trace("Including PODIO collection '{}'", coll);
0553         successful_collections.push_back(coll);
0554       }
0555     } catch (std::exception& e) {
0556       // Limit printing warning to just once per factory
0557       if (!failed_collections.contains(coll)) {
0558         m_log->error("Omitting PODIO collection '{}' due to exception: {}.", coll, e.what());
0559         failed_collections.insert(coll);
0560       }
0561     }
0562   }
0563 
0564   // Frame will contain data from all Podio factories that have been triggered,
0565   // including by the `event->GetCollectionBase(coll);` above.
0566   // Note that collections MUST be present in frame. If a collection is null, the writer will segfault.
0567   const auto* frame = event->GetSingle<podio::Frame>();
0568   {
0569     std::lock_guard<std::mutex> lock(m_mutex);
0570     m_writer->writeFrame(*frame, "events", m_collections_to_write);
0571   }
0572 }
0573 
0574 void JEventProcessorPODIO::Finish() {
0575   if (m_output_include_collections_set) {
0576     m_log->error("The podio:output_include_collections was provided, but is deprecated. Use "
0577                  "podio:output_collections instead.");
0578     throw std::runtime_error("The podio:output_include_collections was provided, but is "
0579                              "deprecated. Use podio:output_collections instead.");
0580   }
0581 
0582   m_writer->finish();
0583 }