File indexing completed on 2025-12-09 09:21:10
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);
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
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
0040
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
0047 std::vector<std::string> output_collections = {
0048
0049 "EventHeader",
0050
0051
0052 "MCParticles",
0053 "MCBeamElectrons",
0054 "MCBeamProtons",
0055 "MCScatteredElectrons",
0056 "MCScatteredProtons",
0057 "MCParticlesHeadOnFrameNoBeamFX",
0058
0059
0060 "CentralTrackerTruthSeeds",
0061 "CentralTrackingRecHits",
0062 "CentralTrackingRawHitAssociations",
0063 "CentralTrackSeedingResults",
0064 "CentralTrackerMeasurements",
0065
0066
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
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
0105 "DRICHRawHits",
0106 "DRICHRawHitsAssociations",
0107 "DRICHAerogelTracks",
0108 "DRICHGasTracks",
0109 "DRICHAerogelIrtCherenkovParticleID",
0110 "DRICHGasIrtCherenkovParticleID",
0111 "DRICHTruthSeededParticleIDs",
0112 "DRICHParticleIDs",
0113
0114
0115 "RICHEndcapNRawHits",
0116 "RICHEndcapNRawHitsAssociations",
0117 "RICHEndcapNTruthSeededParticleIDs",
0118 "RICHEndcapNParticleIDs",
0119
0120
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
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
0167 "B0TrackerTruthSeeds",
0168 "B0TrackerRecHits",
0169 "B0TrackerRawHits",
0170 "B0TrackerHits",
0171 "B0TrackerRawHitAssociations",
0172 "B0TrackerSeedingResults",
0173 "B0TrackerMeasurements",
0174
0175 "ForwardRomanPotRecHits",
0176 "ForwardOffMTrackerRecHits",
0177
0178 "ForwardRomanPotRecParticles",
0179 "ForwardRomanPotStaticRecParticles",
0180 "ForwardOffMRecParticles",
0181
0182 "ForwardRomanPotRawHits",
0183 "ForwardRomanPotRawHitAssociations",
0184 "ForwardOffMTrackerRawHits",
0185 "ForwardOffMTrackerRawHitAssociations",
0186
0187
0188 "GeneratedParticles",
0189 "GeneratedBreitFrameParticles",
0190 "ReconstructedParticles",
0191 "ReconstructedParticleAssociations",
0192 "ReconstructedTruthSeededChargedParticles",
0193 "ReconstructedTruthSeededChargedParticleAssociations",
0194 "ReconstructedChargedRealPIDParticles",
0195 "ReconstructedChargedRealPIDParticleIDs",
0196 "ReconstructedChargedParticles",
0197 "ReconstructedChargedParticleAssociations",
0198 "MCScatteredElectronAssociations",
0199 "MCNonScatteredElectronAssociations",
0200 "ReconstructedBreitFrameParticles",
0201
0202
0203 "CentralTrackSegments",
0204 "CentralTrackVertices",
0205 "CentralCKFTruthSeededTrajectories",
0206 "CentralCKFTruthSeededTracks",
0207 "CentralCKFTruthSeededTrackAssociations",
0208 "CentralCKFTruthSeededTrackParameters",
0209 "CentralCKFTrajectories",
0210 "CentralCKFTracks",
0211 "CentralCKFTrackAssociations",
0212 "CentralCKFTrackParameters",
0213
0214 "CentralCKFTruthSeededTrajectoriesUnfiltered",
0215 "CentralCKFTruthSeededTracksUnfiltered",
0216 "CentralCKFTruthSeededTrackUnfilteredAssociations",
0217 "CentralCKFTruthSeededTrackParametersUnfiltered",
0218
0219 "CentralCKFTrajectoriesUnfiltered",
0220 "CentralCKFTracksUnfiltered",
0221 "CentralCKFTrackUnfilteredAssociations",
0222 "CentralCKFTrackParametersUnfiltered",
0223
0224
0225 "B0TrackerCKFTruthSeededTrajectories",
0226 "B0TrackerCKFTruthSeededTracks",
0227 "B0TrackerCKFTruthSeededTrackAssociations",
0228 "B0TrackerCKFTruthSeededTrackParameters",
0229 "B0TrackerCKFTrajectories",
0230 "B0TrackerCKFTracks",
0231 "B0TrackerCKFTrackAssociations",
0232 "B0TrackerCKFTrackParameters",
0233
0234 "B0TrackerCKFTruthSeededTrajectoriesUnfiltered",
0235 "B0TrackerCKFTruthSeededTracksUnfiltered",
0236 "B0TrackerCKFTruthSeededTrackUnfilteredAssociations",
0237 "B0TrackerCKFTruthSeededTrackParametersUnfiltered",
0238
0239 "B0TrackerCKFTrajectoriesUnfiltered",
0240 "B0TrackerCKFTrackParametersUnfiltered",
0241 "B0TrackerCKFTracksUnfiltered",
0242 "B0TrackerCKFTrackUnfilteredAssociations",
0243
0244 "CentralAndB0TrackVertices",
0245
0246
0247 "InclusiveKinematicsDA",
0248 "InclusiveKinematicsJB",
0249 "InclusiveKinematicsML",
0250 "InclusiveKinematicsSigma",
0251 "InclusiveKinematicseSigma",
0252 "InclusiveKinematicsESigma",
0253 "InclusiveKinematicsElectron",
0254 "InclusiveKinematicsTruth",
0255 "GeneratedJets",
0256 "GeneratedChargedJets",
0257 "GeneratedCentauroJets",
0258 "ReconstructedJets",
0259 "ReconstructedChargedJets",
0260 "ReconstructedCentauroJets",
0261 "ReconstructedElectrons",
0262 "ScatteredElectronsTruth",
0263 "ScatteredElectronsEMinusPz",
0264 "PrimaryVertices",
0265 "SecondaryVerticesHelix",
0266 "BarrelClusters",
0267 "HadronicFinalState",
0268
0269
0270 "CalorimeterTrackProjections",
0271
0272
0273 "EcalEndcapNRawHits",
0274 "EcalEndcapNRecHits",
0275 "EcalEndcapNTruthClusters",
0276 "EcalEndcapNTruthClusterAssociations",
0277 "EcalEndcapNClusters",
0278 "EcalEndcapNClusterAssociations",
0279 "EcalEndcapNSplitMergeClusters",
0280 "EcalEndcapNSplitMergeClusterAssociations",
0281 "EcalEndcapPRawHits",
0282 "EcalEndcapPRecHits",
0283 "EcalEndcapPTruthClusters",
0284 "EcalEndcapPTruthClusterAssociations",
0285 "EcalEndcapPClusters",
0286 "EcalEndcapPClusterAssociations",
0287 "EcalEndcapPSplitMergeClusters",
0288 "EcalEndcapPSplitMergeClusterAssociations",
0289 "EcalBarrelClusters",
0290 "EcalBarrelClusterAssociations",
0291 "EcalBarrelTruthClusters",
0292 "EcalBarrelTruthClusterAssociations",
0293 "EcalBarrelImagingRawHits",
0294 "EcalBarrelImagingRecHits",
0295 "EcalBarrelImagingClusters",
0296 "EcalBarrelImagingClusterAssociations",
0297 "EcalBarrelScFiPAttenuatedHits",
0298 "EcalBarrelScFiPAttenuatedHitContributions",
0299 "EcalBarrelScFiNAttenuatedHits",
0300 "EcalBarrelScFiNAttenuatedHitContributions",
0301 "EcalBarrelScFiRawHits",
0302 "EcalBarrelScFiPPulses",
0303 "EcalBarrelScFiNPulses",
0304 "EcalBarrelScFiPCombinedPulses",
0305 "EcalBarrelScFiNCombinedPulses",
0306 "EcalBarrelScFiPCombinedPulsesWithNoise",
0307 "EcalBarrelScFiNCombinedPulsesWithNoise",
0308 "EcalBarrelScFiRecHits",
0309 "EcalBarrelScFiClusters",
0310 "EcalBarrelScFiClusterAssociations",
0311 "EcalLumiSpecRawHits",
0312 "EcalLumiSpecRecHits",
0313 "EcalLumiSpecTruthClusters",
0314 "EcalLumiSpecTruthClusterAssociations",
0315 "EcalLumiSpecClusters",
0316 "EcalLumiSpecClusterAssociations",
0317 "HcalEndcapNRawHits",
0318 "HcalEndcapNRecHits",
0319 "HcalEndcapNMergedHits",
0320 "HcalEndcapNClusters",
0321 "HcalEndcapNClusterAssociations",
0322 "HcalEndcapNSplitMergeClusters",
0323 "HcalEndcapNSplitMergeClusterAssociations",
0324 "HcalEndcapPInsertRawHits",
0325 "HcalEndcapPInsertRecHits",
0326 "HcalEndcapPInsertMergedHits",
0327 "HcalEndcapPInsertClusters",
0328 "HcalEndcapPInsertClusterAssociations",
0329 "LFHCALRawHits",
0330 "LFHCALRecHits",
0331 "LFHCALClusters",
0332 "LFHCALClusterAssociations",
0333 "LFHCALSplitMergeClusters",
0334 "LFHCALSplitMergeClusterAssociations",
0335 "HcalBarrelRawHits",
0336 "HcalBarrelRecHits",
0337 "HcalBarrelMergedHits",
0338 "HcalBarrelClusters",
0339 "HcalBarrelClusterAssociations",
0340 "HcalBarrelSplitMergeClusters",
0341 "HcalBarrelSplitMergeClusterAssociations",
0342 "B0ECalRawHits",
0343 "B0ECalRecHits",
0344 "B0ECalClusters",
0345 "B0ECalClusterAssociations",
0346 "HcalEndcapNTruthClusters",
0347 "HcalEndcapNTruthClusterAssociations",
0348 "HcalBarrelTruthClusters",
0349 "HcalBarrelTruthClusterAssociations",
0350
0351
0352 "EcalFarForwardZDCRawHits",
0353 "EcalFarForwardZDCRecHits",
0354 "EcalFarForwardZDCClusters",
0355 "EcalFarForwardZDCClusterAssociations",
0356 "EcalFarForwardZDCTruthClusters",
0357 "EcalFarForwardZDCTruthClusterAssociations",
0358
0359
0360 "HcalFarForwardZDCRawHits",
0361 "HcalFarForwardZDCRecHits",
0362 "HcalFarForwardZDCSubcellHits",
0363 "HcalFarForwardZDCClusters",
0364 "HcalFarForwardZDCClusterAssociations",
0365 "HcalFarForwardZDCClustersBaseline",
0366 "HcalFarForwardZDCClusterAssociationsBaseline",
0367 "HcalFarForwardZDCTruthClusters",
0368 "HcalFarForwardZDCTruthClusterAssociations",
0369 "ReconstructedFarForwardZDCNeutrals",
0370 "ReconstructedFarForwardZDCLambdas",
0371 "ReconstructedFarForwardZDCLambdaDecayProductsCM",
0372
0373
0374 "DIRCRawHits",
0375 "DIRCTruthSeededParticleIDs",
0376 "DIRCParticleIDs",
0377
0378 "B0ECalRawHitAssociations",
0379 "EcalBarrelScFiRawHitAssociations",
0380 "EcalBarrelImagingRawHitAssociations",
0381 "HcalBarrelRawHitAssociations",
0382 "EcalEndcapNRawHitAssociations",
0383 "HcalEndcapNRawHitAssociations",
0384 "EcalEndcapPRawHitAssociations",
0385 "HcalEndcapPInsertRawHitAssociations",
0386 "LFHCALRawHitAssociations",
0387 "EcalLumiSpecRawHitAssociations",
0388 "EcalFarForwardZDCRawHitAssociations",
0389 "HcalFarForwardZDCRawHitAssociations",
0390 "EcalEndcapPTrackClusterMatches",
0391 "LFHCALTrackClusterMatches",
0392 "HcalEndcapPInsertClusterMatches",
0393 "EcalBarrelTrackClusterMatches",
0394 "HcalBarrelTrackClusterMatches",
0395 "EcalEndcapNTrackClusterMatches",
0396 "HcalEndcapNTrackClusterMatches",
0397
0398 };
0399 std::vector<std::string> output_exclude_collections;
0400 std::string output_include_collections = "DEPRECATED";
0401 japp->SetDefaultParameter("podio:output_include_collections", output_include_collections,
0402 "DEPRECATED. Use podio:output_collections instead.");
0403 if (output_include_collections != "DEPRECATED") {
0404 output_collections.clear();
0405 JParameterManager::Parse(output_include_collections, output_collections);
0406 m_output_include_collections_set = true;
0407 }
0408 japp->SetDefaultParameter(
0409 "podio:output_collections", output_collections,
0410 "Comma separated list of collection names to write out. If not set, all collections will be "
0411 "written (including ones from input file). Don't set this and use "
0412 "PODIO:OUTPUT_EXCLUDE_COLLECTIONS to write everything except a selection.");
0413 japp->SetDefaultParameter("podio:output_exclude_collections", output_exclude_collections,
0414 "Comma separated list of collection names to not write out.");
0415 japp->SetDefaultParameter(
0416 "podio:print_collections", m_collections_to_print,
0417 "Comma separated list of collection names to print to screen, e.g. for debugging.");
0418
0419 m_output_collections =
0420 std::set<std::string>(output_collections.begin(), output_collections.end());
0421 m_output_exclude_collections =
0422 std::set<std::string>(output_exclude_collections.begin(), output_exclude_collections.end());
0423 }
0424
0425 void JEventProcessorPODIO::Init() {
0426
0427 auto* app = GetApplication();
0428 m_log = app->GetService<Log_service>()->logger("JEventProcessorPODIO");
0429 m_writer = std::make_unique<podio::ROOTWriter>(m_output_file);
0430
0431
0432
0433 if (m_output_include_collections_set) {
0434 m_log->error("The podio:output_include_collections was provided, but is deprecated. Use "
0435 "podio:output_collections instead.");
0436 throw std::runtime_error("The podio:output_include_collections was provided, but is "
0437 "deprecated. Use podio:output_collections instead.");
0438 }
0439 }
0440
0441 void JEventProcessorPODIO::FindCollectionsToWrite(const std::shared_ptr<const JEvent>& event) {
0442
0443
0444 std::vector<std::string> all_collections = event->GetAllCollectionNames();
0445
0446 if (m_output_collections.empty()) {
0447
0448 for (const std::string& col : all_collections) {
0449 if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) {
0450 m_collections_to_write.push_back(col);
0451 m_log->debug("Persisting collection '{}'", col);
0452 }
0453 }
0454 } else {
0455 m_log->debug("Persisting podio types from includes list");
0456
0457
0458 std::set<std::string> all_collections_set =
0459 std::set<std::string>(all_collections.begin(), all_collections.end());
0460
0461
0462 std::set<std::string> matching_collections_set;
0463 std::vector<std::regex> output_collections_regex(m_output_collections.size());
0464 std::ranges::transform(m_output_collections, output_collections_regex.begin(),
0465 [](const std::string& r) { return std::regex(r); });
0466 std::ranges::copy_if(all_collections_set,
0467 std::inserter(matching_collections_set, matching_collections_set.end()),
0468 [&](const std::string& c) {
0469 return std::ranges::any_of(
0470 output_collections_regex,
0471
0472 [&](const std::regex& r) { return std::regex_match(c, r); });
0473 });
0474
0475 for (const auto& col : matching_collections_set) {
0476 if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) {
0477
0478 if (all_collections_set.find(col) == all_collections_set.end()) {
0479
0480 m_log->warn("Explicitly included collection '{}' not present in factory set, omitting.",
0481 col);
0482 } else {
0483
0484 m_collections_to_write.push_back(col);
0485 m_log->info("Persisting collection '{}'", col);
0486 }
0487 }
0488 }
0489 }
0490 }
0491
0492 void JEventProcessorPODIO::Process(const std::shared_ptr<const JEvent>& event) {
0493
0494
0495 std::call_once(m_is_first_event, &JEventProcessorPODIO::FindCollectionsToWrite, this, event);
0496
0497
0498
0499 if (!m_collections_to_print.empty()) {
0500 m_log->info("========================================");
0501 m_log->info("JEventProcessorPODIO: Event {}", event->GetEventNumber());
0502 ;
0503 }
0504 for (const auto& coll_name : m_collections_to_print) {
0505 m_log->info("------------------------------");
0506 m_log->info("{}", coll_name);
0507 try {
0508 const auto* coll_ptr = event->GetCollectionBase(coll_name);
0509 if (coll_ptr == nullptr) {
0510 m_log->info("missing");
0511 } else {
0512 std::stringstream ss;
0513 coll_ptr->print(ss);
0514 m_log->info(ss.str());
0515 }
0516 } catch (std::exception& e) {
0517 m_log->info("missing");
0518 }
0519 }
0520
0521 m_log->trace("==================================");
0522 m_log->trace("Event #{}", event->GetEventNumber());
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538 std::vector<std::string> successful_collections;
0539 std::set<std::string> failed_collections;
0540 for (const std::string& coll : m_collections_to_write) {
0541 try {
0542 m_log->trace("Ensuring factory for collection '{}' has been called.", coll);
0543 const auto* coll_ptr = event->GetCollectionBase(coll);
0544 if (coll_ptr == nullptr) {
0545
0546
0547
0548
0549 if (!failed_collections.contains(coll)) {
0550 m_log->error("Omitting PODIO collection '{}' because it is null", coll);
0551 failed_collections.insert(coll);
0552 }
0553 } else {
0554 m_log->trace("Including PODIO collection '{}'", coll);
0555 successful_collections.push_back(coll);
0556 }
0557 } catch (std::exception& e) {
0558
0559 if (!failed_collections.contains(coll)) {
0560 m_log->error("Omitting PODIO collection '{}' due to exception: {}.", coll, e.what());
0561 failed_collections.insert(coll);
0562 }
0563 }
0564 }
0565
0566
0567
0568
0569 const auto* frame = event->GetSingle<podio::Frame>();
0570 {
0571 std::lock_guard<std::mutex> lock(m_mutex);
0572 m_writer->writeFrame(*frame, "events", m_collections_to_write);
0573 }
0574 }
0575
0576 void JEventProcessorPODIO::Finish() {
0577 if (m_output_include_collections_set) {
0578 m_log->error("The podio:output_include_collections was provided, but is deprecated. Use "
0579 "podio:output_collections instead.");
0580 throw std::runtime_error("The podio:output_include_collections was provided, but is "
0581 "deprecated. Use podio:output_collections instead.");
0582 }
0583
0584 m_writer->finish();
0585 }