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);
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 "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 "BarrelClusters",
0265 "HadronicFinalState",
0266
0267
0268 "CalorimeterTrackProjections",
0269
0270
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
0350 "EcalFarForwardZDCRawHits",
0351 "EcalFarForwardZDCRecHits",
0352 "EcalFarForwardZDCClusters",
0353 "EcalFarForwardZDCClusterAssociations",
0354 "EcalFarForwardZDCTruthClusters",
0355 "EcalFarForwardZDCTruthClusterAssociations",
0356
0357
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
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;
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
0429
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
0442 std::vector<std::string> all_collections = event->GetAllCollectionNames();
0443
0444 if (m_output_collections.empty()) {
0445
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
0456 std::set<std::string> all_collections_set =
0457 std::set<std::string>(all_collections.begin(), all_collections.end());
0458
0459
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
0476 if (all_collections_set.find(col) == all_collections_set.end()) {
0477
0478 m_log->warn("Explicitly included collection '{}' not present in factory set, omitting.",
0479 col);
0480 } else {
0481
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
0493 std::call_once(m_is_first_event, &JEventProcessorPODIO::FindCollectionsToWrite, this, event);
0494
0495
0496
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
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
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
0544
0545
0546
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
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
0565
0566
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 }