File indexing completed on 2026-01-09 09:30:01
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
0020 #include "services/log/Log_service.h"
0021
0022 JEventProcessorPODIO::JEventProcessorPODIO() {
0023 SetTypeName(NAME_OF_THIS);
0024
0025 japp->SetDefaultParameter("podio:output_file", m_output_file,
0026 "Name of EDM4hep/podio output file to write to. Setting this will "
0027 "cause the output file to be created and written to.");
0028
0029
0030 if (m_output_file == "1") {
0031 auto* param = japp->GetJParameterManager()->FindParameter("podio:output_file");
0032 if (param != nullptr) {
0033 param->SetValue(param->GetDefault());
0034 m_output_file = param->GetDefault();
0035 }
0036 }
0037
0038
0039
0040 japp->SetDefaultParameter("podio:output_file_copy_dir", m_output_file_copy_dir,
0041 "Directory name to make an additional copy of the output file to. Copy "
0042 "will be done at end of processing. Default is empty string which "
0043 "means do not make a copy. No check is made on path existing.");
0044
0045
0046 std::vector<std::string> output_collections = {
0047
0048 "EventHeader",
0049
0050
0051 "MCParticles",
0052 "MCBeamElectrons",
0053 "MCBeamProtons",
0054 "MCScatteredElectrons",
0055 "MCScatteredProtons",
0056 "MCParticlesHeadOnFrameNoBeamFX",
0057
0058
0059 "CentralTrackerTruthSeeds",
0060 "CentralTrackingRecHits",
0061 "CentralTrackingRawHitAssociations",
0062 "CentralTrackSeedingResults",
0063 "CentralTrackerMeasurements",
0064
0065
0066 "SiBarrelTrackerRecHits",
0067 "SiBarrelVertexRecHits",
0068 "SiEndcapTrackerRecHits",
0069
0070 "SiBarrelRawHits",
0071 "SiBarrelVertexRawHits",
0072 "SiEndcapTrackerRawHits",
0073
0074 "SiBarrelHits",
0075 "VertexBarrelHits",
0076 "TrackerEndcapHits",
0077
0078 "SiBarrelRawHitAssociations",
0079 "SiBarrelVertexRawHitAssociations",
0080 "SiEndcapTrackerRawHitAssociations",
0081
0082
0083 "TOFBarrelRecHits",
0084 "TOFEndcapRecHits",
0085
0086 "TOFBarrelRawHits",
0087 "TOFEndcapRawHits",
0088
0089 "TOFBarrelHits",
0090 "TOFBarrelClusterHits",
0091 "TOFBarrelADCTDC",
0092 "TOFEndcapHits",
0093
0094 "TOFEndcapSharedHits",
0095 "TOFEndcapADCTDC",
0096
0097 "TOFBarrelRawHitAssociations",
0098 "TOFEndcapRawHitAssociations",
0099
0100 "CombinedTOFTruthSeededParticleIDs",
0101 "CombinedTOFParticleIDs",
0102
0103
0104 "DRICHRawHits",
0105 "DRICHRawHitsAssociations",
0106 "DRICHAerogelTracks",
0107 "DRICHGasTracks",
0108 "DRICHAerogelIrtCherenkovParticleID",
0109 "DRICHGasIrtCherenkovParticleID",
0110 "DRICHTruthSeededParticleIDs",
0111 "DRICHParticleIDs",
0112
0113
0114 "RICHEndcapNRawHits",
0115 "RICHEndcapNRawHitsAssociations",
0116 "RICHEndcapNTruthSeededParticleIDs",
0117 "RICHEndcapNParticleIDs",
0118
0119
0120 "MPGDBarrelRecHits",
0121 "OuterMPGDBarrelRecHits",
0122 "BackwardMPGDEndcapRecHits",
0123 "ForwardMPGDEndcapRecHits",
0124
0125 "MPGDBarrelRawHits",
0126 "OuterMPGDBarrelRawHits",
0127 "BackwardMPGDEndcapRawHits",
0128 "ForwardMPGDEndcapRawHits",
0129
0130 "MPGDBarrelHits",
0131 "OuterMPGDBarrelHits",
0132 "BackwardMPGDEndcapHits",
0133 "ForwardMPGDEndcapHits",
0134
0135 "MPGDBarrelRawHitAssociations",
0136 "OuterMPGDBarrelRawHitAssociations",
0137 "BackwardMPGDEndcapRawHitAssociations",
0138 "ForwardMPGDEndcapRawHitAssociations",
0139
0140
0141 "TaggerTrackerHits",
0142 "TaggerTrackerSharedHits",
0143 "TaggerTrackerHitPulses",
0144 "TaggerTrackerCombinedPulses",
0145 "TaggerTrackerCombinedPulsesWithNoise",
0146 "TaggerTrackerRawHits",
0147 "TaggerTrackerRawHitAssociations",
0148 "TaggerTrackerM1L0ClusterPositions",
0149 "TaggerTrackerM1L1ClusterPositions",
0150 "TaggerTrackerM1L2ClusterPositions",
0151 "TaggerTrackerM1L3ClusterPositions",
0152 "TaggerTrackerM2L0ClusterPositions",
0153 "TaggerTrackerM2L1ClusterPositions",
0154 "TaggerTrackerM2L2ClusterPositions",
0155 "TaggerTrackerM2L3ClusterPositions",
0156 "TaggerTrackerM1LocalTracks",
0157 "TaggerTrackerM2LocalTracks",
0158 "TaggerTrackerM1LocalTrackAssociations",
0159 "TaggerTrackerM2LocalTrackAssociations",
0160 "TaggerTrackerLocalTracks",
0161 "TaggerTrackerLocalTrackAssociations",
0162 "TaggerTrackerReconstructedParticles",
0163 "TaggerTrackerReconstructedParticleAssociations",
0164
0165
0166 "B0TrackerTruthSeeds",
0167 "B0TrackerRecHits",
0168 "B0TrackerRawHits",
0169 "B0TrackerHits",
0170 "B0TrackerRawHitAssociations",
0171 "B0TrackerSeedingResults",
0172 "B0TrackerMeasurements",
0173
0174 "ForwardRomanPotRecHits",
0175 "ForwardOffMTrackerRecHits",
0176
0177 "ForwardRomanPotRecParticles",
0178 "ForwardRomanPotStaticRecParticles",
0179 "ForwardOffMRecParticles",
0180
0181 "ForwardRomanPotRawHits",
0182 "ForwardRomanPotRawHitAssociations",
0183 "ForwardOffMTrackerRawHits",
0184 "ForwardOffMTrackerRawHitAssociations",
0185
0186
0187 "GeneratedParticles",
0188 "GeneratedBreitFrameParticles",
0189 "ReconstructedParticles",
0190 "ReconstructedParticleAssociations",
0191 "ReconstructedTruthSeededChargedParticles",
0192 "ReconstructedTruthSeededChargedParticleAssociations",
0193 "ReconstructedChargedRealPIDParticles",
0194 "ReconstructedChargedRealPIDParticleIDs",
0195 "ReconstructedChargedParticles",
0196 "ReconstructedChargedParticleAssociations",
0197 "MCScatteredElectronAssociations",
0198 "MCNonScatteredElectronAssociations",
0199 "ReconstructedBreitFrameParticles",
0200
0201
0202 "CentralTrackSegments",
0203 "CentralTrackVertices",
0204 "CentralCKFTruthSeededTrajectories",
0205 "CentralCKFTruthSeededTracks",
0206 "CentralCKFTruthSeededTrackAssociations",
0207 "CentralCKFTruthSeededTrackParameters",
0208 "CentralCKFTrajectories",
0209 "CentralCKFTracks",
0210 "CentralCKFTrackAssociations",
0211 "CentralCKFTrackParameters",
0212
0213 "CentralCKFTruthSeededTrajectoriesUnfiltered",
0214 "CentralCKFTruthSeededTracksUnfiltered",
0215 "CentralCKFTruthSeededTrackUnfilteredAssociations",
0216 "CentralCKFTruthSeededTrackParametersUnfiltered",
0217
0218 "CentralCKFTrajectoriesUnfiltered",
0219 "CentralCKFTracksUnfiltered",
0220 "CentralCKFTrackUnfilteredAssociations",
0221 "CentralCKFTrackParametersUnfiltered",
0222
0223
0224 "B0TrackerCKFTruthSeededTrajectories",
0225 "B0TrackerCKFTruthSeededTracks",
0226 "B0TrackerCKFTruthSeededTrackAssociations",
0227 "B0TrackerCKFTruthSeededTrackParameters",
0228 "B0TrackerCKFTrajectories",
0229 "B0TrackerCKFTracks",
0230 "B0TrackerCKFTrackAssociations",
0231 "B0TrackerCKFTrackParameters",
0232
0233 "B0TrackerCKFTruthSeededTrajectoriesUnfiltered",
0234 "B0TrackerCKFTruthSeededTracksUnfiltered",
0235 "B0TrackerCKFTruthSeededTrackUnfilteredAssociations",
0236 "B0TrackerCKFTruthSeededTrackParametersUnfiltered",
0237
0238 "B0TrackerCKFTrajectoriesUnfiltered",
0239 "B0TrackerCKFTrackParametersUnfiltered",
0240 "B0TrackerCKFTracksUnfiltered",
0241 "B0TrackerCKFTrackUnfilteredAssociations",
0242
0243 "CentralAndB0TrackVertices",
0244
0245
0246 "InclusiveKinematicsDA",
0247 "InclusiveKinematicsJB",
0248 "InclusiveKinematicsML",
0249 "InclusiveKinematicsSigma",
0250 "InclusiveKinematicseSigma",
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 "SecondaryVerticesHelix",
0265 "BarrelClusters",
0266 "HadronicFinalState",
0267
0268
0269 "CalorimeterTrackProjections",
0270
0271
0272 "EcalEndcapNRawHits",
0273 "EcalEndcapNRecHits",
0274 "EcalEndcapNTruthClusters",
0275 "EcalEndcapNTruthClusterAssociations",
0276 "EcalEndcapNClusters",
0277 "EcalEndcapNClusterAssociations",
0278 "EcalEndcapNSplitMergeClusters",
0279 "EcalEndcapNSplitMergeClusterAssociations",
0280 "EcalEndcapPRawHits",
0281 "EcalEndcapPRecHits",
0282 "EcalEndcapPTruthClusters",
0283 "EcalEndcapPTruthClusterAssociations",
0284 "EcalEndcapPClusters",
0285 "EcalEndcapPClusterAssociations",
0286 "EcalEndcapPSplitMergeClusters",
0287 "EcalEndcapPSplitMergeClusterAssociations",
0288 "EcalBarrelClusters",
0289 "EcalBarrelClusterAssociations",
0290 "EcalBarrelTruthClusters",
0291 "EcalBarrelTruthClusterAssociations",
0292 "EcalBarrelImagingRawHits",
0293 "EcalBarrelImagingRecHits",
0294 "EcalBarrelImagingClusters",
0295 "EcalBarrelImagingClusterAssociations",
0296 "EcalBarrelScFiPAttenuatedHits",
0297 "EcalBarrelScFiPAttenuatedHitContributions",
0298 "EcalBarrelScFiNAttenuatedHits",
0299 "EcalBarrelScFiNAttenuatedHitContributions",
0300 "EcalBarrelScFiRawHits",
0301 "EcalBarrelScFiPPulses",
0302 "EcalBarrelScFiNPulses",
0303 "EcalBarrelScFiPCombinedPulses",
0304 "EcalBarrelScFiNCombinedPulses",
0305 "EcalBarrelScFiPCombinedPulsesWithNoise",
0306 "EcalBarrelScFiNCombinedPulsesWithNoise",
0307 "EcalBarrelScFiRecHits",
0308 "EcalBarrelScFiClusters",
0309 "EcalBarrelScFiClusterAssociations",
0310 "EcalLumiSpecRawHits",
0311 "EcalLumiSpecRecHits",
0312 "EcalLumiSpecTruthClusters",
0313 "EcalLumiSpecTruthClusterAssociations",
0314 "EcalLumiSpecClusters",
0315 "EcalLumiSpecClusterAssociations",
0316 "HcalEndcapNRawHits",
0317 "HcalEndcapNRecHits",
0318 "HcalEndcapNMergedHits",
0319 "HcalEndcapNClusters",
0320 "HcalEndcapNClusterAssociations",
0321 "HcalEndcapNSplitMergeClusters",
0322 "HcalEndcapNSplitMergeClusterAssociations",
0323 "HcalEndcapPInsertRawHits",
0324 "HcalEndcapPInsertRecHits",
0325 "HcalEndcapPInsertMergedHits",
0326 "HcalEndcapPInsertClusters",
0327 "HcalEndcapPInsertClusterAssociations",
0328 "LFHCALRawHits",
0329 "LFHCALRecHits",
0330 "LFHCALClusters",
0331 "LFHCALClusterAssociations",
0332 "LFHCALSplitMergeClusters",
0333 "LFHCALSplitMergeClusterAssociations",
0334 "HcalBarrelRawHits",
0335 "HcalBarrelRecHits",
0336 "HcalBarrelMergedHits",
0337 "HcalBarrelClusters",
0338 "HcalBarrelClusterAssociations",
0339 "HcalBarrelSplitMergeClusters",
0340 "HcalBarrelSplitMergeClusterAssociations",
0341 "B0ECalRawHits",
0342 "B0ECalRecHits",
0343 "B0ECalClusters",
0344 "B0ECalClusterAssociations",
0345 "HcalEndcapNTruthClusters",
0346 "HcalEndcapNTruthClusterAssociations",
0347 "HcalBarrelTruthClusters",
0348 "HcalBarrelTruthClusterAssociations",
0349
0350
0351 "EcalFarForwardZDCRawHits",
0352 "EcalFarForwardZDCRecHits",
0353 "EcalFarForwardZDCClusters",
0354 "EcalFarForwardZDCClusterAssociations",
0355 "EcalFarForwardZDCTruthClusters",
0356 "EcalFarForwardZDCTruthClusterAssociations",
0357
0358
0359 "HcalFarForwardZDCRawHits",
0360 "HcalFarForwardZDCRecHits",
0361 "HcalFarForwardZDCSubcellHits",
0362 "HcalFarForwardZDCClusters",
0363 "HcalFarForwardZDCClusterAssociations",
0364 "HcalFarForwardZDCClustersBaseline",
0365 "HcalFarForwardZDCClusterAssociationsBaseline",
0366 "HcalFarForwardZDCTruthClusters",
0367 "HcalFarForwardZDCTruthClusterAssociations",
0368 "ReconstructedFarForwardZDCNeutrals",
0369 "ReconstructedFarForwardZDCLambdas",
0370 "ReconstructedFarForwardZDCLambdaDecayProductsCM",
0371
0372
0373 "DIRCRawHits",
0374 "DIRCTruthSeededParticleIDs",
0375 "DIRCParticleIDs",
0376
0377 "B0ECalRawHitAssociations",
0378 "EcalBarrelScFiRawHitAssociations",
0379 "EcalBarrelImagingRawHitAssociations",
0380 "HcalBarrelRawHitAssociations",
0381 "EcalEndcapNRawHitAssociations",
0382 "HcalEndcapNRawHitAssociations",
0383 "EcalEndcapPRawHitAssociations",
0384 "HcalEndcapPInsertRawHitAssociations",
0385 "LFHCALRawHitAssociations",
0386 "EcalLumiSpecRawHitAssociations",
0387 "EcalFarForwardZDCRawHitAssociations",
0388 "HcalFarForwardZDCRawHitAssociations",
0389 "EcalEndcapPTrackClusterMatches",
0390 "LFHCALTrackClusterMatches",
0391 "HcalEndcapPInsertClusterMatches",
0392 "EcalBarrelTrackClusterMatches",
0393 "HcalBarrelTrackClusterMatches",
0394 "EcalEndcapNTrackClusterMatches",
0395 "HcalEndcapNTrackClusterMatches",
0396
0397 };
0398 std::vector<std::string> output_exclude_collections;
0399 japp->SetDefaultParameter(
0400 "podio:output_collections", output_collections,
0401 "Comma separated list of collection names to write out. If not set, all collections will be "
0402 "written (including ones from input file). Don't set this and use "
0403 "PODIO:OUTPUT_EXCLUDE_COLLECTIONS to write everything except a selection.");
0404 japp->SetDefaultParameter("podio:output_exclude_collections", output_exclude_collections,
0405 "Comma separated list of collection names to not write out.");
0406 japp->SetDefaultParameter(
0407 "podio:print_collections", m_collections_to_print,
0408 "Comma separated list of collection names to print to screen, e.g. for debugging.");
0409
0410 m_output_collections =
0411 std::set<std::string>(output_collections.begin(), output_collections.end());
0412 m_output_exclude_collections =
0413 std::set<std::string>(output_exclude_collections.begin(), output_exclude_collections.end());
0414 }
0415
0416 void JEventProcessorPODIO::Init() {
0417
0418 auto* app = GetApplication();
0419 m_log = app->GetService<Log_service>()->logger("JEventProcessorPODIO");
0420 m_writer = std::make_unique<podio::ROOTWriter>(m_output_file);
0421 }
0422
0423 void JEventProcessorPODIO::FindCollectionsToWrite(const std::shared_ptr<const JEvent>& event) {
0424
0425
0426 std::vector<std::string> all_collections = event->GetAllCollectionNames();
0427
0428 if (m_output_collections.empty()) {
0429
0430 for (const std::string& col : all_collections) {
0431 if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) {
0432 m_collections_to_write.push_back(col);
0433 m_log->debug("Persisting collection '{}'", col);
0434 }
0435 }
0436 } else {
0437 m_log->debug("Persisting podio types from includes list");
0438
0439
0440 std::set<std::string> all_collections_set =
0441 std::set<std::string>(all_collections.begin(), all_collections.end());
0442
0443
0444 std::set<std::string> matching_collections_set;
0445 std::vector<std::regex> output_collections_regex(m_output_collections.size());
0446 std::ranges::transform(m_output_collections, output_collections_regex.begin(),
0447 [](const std::string& r) { return std::regex(r); });
0448 std::ranges::copy_if(all_collections_set,
0449 std::inserter(matching_collections_set, matching_collections_set.end()),
0450 [&](const std::string& c) {
0451 return std::ranges::any_of(
0452 output_collections_regex,
0453
0454 [&](const std::regex& r) { return std::regex_match(c, r); });
0455 });
0456
0457 for (const auto& col : matching_collections_set) {
0458 if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) {
0459
0460 if (all_collections_set.find(col) == all_collections_set.end()) {
0461
0462 m_log->warn("Explicitly included collection '{}' not present in factory set, omitting.",
0463 col);
0464 } else {
0465
0466 m_collections_to_write.push_back(col);
0467 m_log->info("Persisting collection '{}'", col);
0468 }
0469 }
0470 }
0471 }
0472 }
0473
0474 void JEventProcessorPODIO::Process(const std::shared_ptr<const JEvent>& event) {
0475
0476
0477 std::call_once(m_is_first_event, &JEventProcessorPODIO::FindCollectionsToWrite, this, event);
0478
0479
0480
0481 if (!m_collections_to_print.empty()) {
0482 m_log->info("========================================");
0483 m_log->info("JEventProcessorPODIO: Event {}", event->GetEventNumber());
0484 ;
0485 }
0486 for (const auto& coll_name : m_collections_to_print) {
0487 m_log->info("------------------------------");
0488 m_log->info("{}", coll_name);
0489 try {
0490 const auto* coll_ptr = event->GetCollectionBase(coll_name);
0491 if (coll_ptr == nullptr) {
0492 m_log->info("missing");
0493 } else {
0494 std::stringstream ss;
0495 coll_ptr->print(ss);
0496 m_log->info(ss.str());
0497 }
0498 } catch (std::exception& e) {
0499 m_log->info("missing");
0500 }
0501 }
0502
0503 m_log->trace("==================================");
0504 m_log->trace("Event #{}", event->GetEventNumber());
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520 std::vector<std::string> successful_collections;
0521 std::set<std::string> failed_collections;
0522 for (const std::string& coll : m_collections_to_write) {
0523 try {
0524 m_log->trace("Ensuring factory for collection '{}' has been called.", coll);
0525 const auto* coll_ptr = event->GetCollectionBase(coll);
0526 if (coll_ptr == nullptr) {
0527
0528
0529
0530
0531 if (!failed_collections.contains(coll)) {
0532 m_log->error("Omitting PODIO collection '{}' because it is null", coll);
0533 failed_collections.insert(coll);
0534 }
0535 } else {
0536 m_log->trace("Including PODIO collection '{}'", coll);
0537 successful_collections.push_back(coll);
0538 }
0539 } catch (std::exception& e) {
0540
0541 if (!failed_collections.contains(coll)) {
0542 m_log->error("Omitting PODIO collection '{}' due to exception: {}.", coll, e.what());
0543 failed_collections.insert(coll);
0544 }
0545 }
0546 }
0547
0548
0549
0550
0551 const auto* frame = event->GetSingle<podio::Frame>();
0552 {
0553 std::lock_guard<std::mutex> lock(m_mutex);
0554 m_writer->writeFrame(*frame, "events", m_collections_to_write);
0555 }
0556 }
0557
0558 void JEventProcessorPODIO::Finish() { m_writer->finish(); }