File indexing completed on 2025-11-08 09:23:22
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 "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 std::string output_include_collections = "DEPRECATED";
0400 japp->SetDefaultParameter("podio:output_include_collections", output_include_collections,
0401 "DEPRECATED. Use podio:output_collections instead.");
0402 if (output_include_collections != "DEPRECATED") {
0403 output_collections.clear();
0404 JParameterManager::Parse(output_include_collections, output_collections);
0405 m_output_include_collections_set = true;
0406 }
0407 japp->SetDefaultParameter(
0408 "podio:output_collections", output_collections,
0409 "Comma separated list of collection names to write out. If not set, all collections will be "
0410 "written (including ones from input file). Don't set this and use "
0411 "PODIO:OUTPUT_EXCLUDE_COLLECTIONS to write everything except a selection.");
0412 japp->SetDefaultParameter("podio:output_exclude_collections", output_exclude_collections,
0413 "Comma separated list of collection names to not write out.");
0414 japp->SetDefaultParameter(
0415 "podio:print_collections", m_collections_to_print,
0416 "Comma separated list of collection names to print to screen, e.g. for debugging.");
0417
0418 m_output_collections =
0419 std::set<std::string>(output_collections.begin(), output_collections.end());
0420 m_output_exclude_collections =
0421 std::set<std::string>(output_exclude_collections.begin(), output_exclude_collections.end());
0422 }
0423
0424 void JEventProcessorPODIO::Init() {
0425
0426 auto* app = GetApplication();
0427 m_log = app->GetService<Log_service>()->logger("JEventProcessorPODIO");
0428 m_writer = std::make_unique<podio::ROOTWriter>(m_output_file);
0429
0430
0431
0432 if (m_output_include_collections_set) {
0433 m_log->error("The podio:output_include_collections was provided, but is deprecated. Use "
0434 "podio:output_collections instead.");
0435 throw std::runtime_error("The podio:output_include_collections was provided, but is "
0436 "deprecated. Use podio:output_collections instead.");
0437 }
0438 }
0439
0440 void JEventProcessorPODIO::FindCollectionsToWrite(const std::shared_ptr<const JEvent>& event) {
0441
0442
0443 std::vector<std::string> all_collections = event->GetAllCollectionNames();
0444
0445 if (m_output_collections.empty()) {
0446
0447 for (const std::string& col : all_collections) {
0448 if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) {
0449 m_collections_to_write.push_back(col);
0450 m_log->debug("Persisting collection '{}'", col);
0451 }
0452 }
0453 } else {
0454 m_log->debug("Persisting podio types from includes list");
0455
0456
0457 std::set<std::string> all_collections_set =
0458 std::set<std::string>(all_collections.begin(), all_collections.end());
0459
0460
0461 std::set<std::string> matching_collections_set;
0462 std::vector<std::regex> output_collections_regex(m_output_collections.size());
0463 std::ranges::transform(m_output_collections, output_collections_regex.begin(),
0464 [](const std::string& r) { return std::regex(r); });
0465 std::ranges::copy_if(all_collections_set,
0466 std::inserter(matching_collections_set, matching_collections_set.end()),
0467 [&](const std::string& c) {
0468 return std::ranges::any_of(
0469 output_collections_regex,
0470
0471 [&](const std::regex& r) { return std::regex_match(c, r); });
0472 });
0473
0474 for (const auto& col : matching_collections_set) {
0475 if (m_output_exclude_collections.find(col) == m_output_exclude_collections.end()) {
0476
0477 if (all_collections_set.find(col) == all_collections_set.end()) {
0478
0479 m_log->warn("Explicitly included collection '{}' not present in factory set, omitting.",
0480 col);
0481 } else {
0482
0483 m_collections_to_write.push_back(col);
0484 m_log->info("Persisting collection '{}'", col);
0485 }
0486 }
0487 }
0488 }
0489 }
0490
0491 void JEventProcessorPODIO::Process(const std::shared_ptr<const JEvent>& event) {
0492
0493
0494 std::call_once(m_is_first_event, &JEventProcessorPODIO::FindCollectionsToWrite, this, event);
0495
0496
0497
0498 if (!m_collections_to_print.empty()) {
0499 m_log->info("========================================");
0500 m_log->info("JEventProcessorPODIO: Event {}", event->GetEventNumber());
0501 ;
0502 }
0503 for (const auto& coll_name : m_collections_to_print) {
0504 m_log->info("------------------------------");
0505 m_log->info("{}", coll_name);
0506 try {
0507 const auto* coll_ptr = event->GetCollectionBase(coll_name);
0508 if (coll_ptr == nullptr) {
0509 m_log->info("missing");
0510 } else {
0511 std::stringstream ss;
0512 coll_ptr->print(ss);
0513 m_log->info(ss.str());
0514 }
0515 } catch (std::exception& e) {
0516 m_log->info("missing");
0517 }
0518 }
0519
0520 m_log->trace("==================================");
0521 m_log->trace("Event #{}", event->GetEventNumber());
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537 std::vector<std::string> successful_collections;
0538 std::set<std::string> failed_collections;
0539 for (const std::string& coll : m_collections_to_write) {
0540 try {
0541 m_log->trace("Ensuring factory for collection '{}' has been called.", coll);
0542 const auto* coll_ptr = event->GetCollectionBase(coll);
0543 if (coll_ptr == nullptr) {
0544
0545
0546
0547
0548 if (!failed_collections.contains(coll)) {
0549 m_log->error("Omitting PODIO collection '{}' because it is null", coll);
0550 failed_collections.insert(coll);
0551 }
0552 } else {
0553 m_log->trace("Including PODIO collection '{}'", coll);
0554 successful_collections.push_back(coll);
0555 }
0556 } catch (std::exception& e) {
0557
0558 if (!failed_collections.contains(coll)) {
0559 m_log->error("Omitting PODIO collection '{}' due to exception: {}.", coll, e.what());
0560 failed_collections.insert(coll);
0561 }
0562 }
0563 }
0564
0565
0566
0567
0568 const auto* frame = event->GetSingle<podio::Frame>();
0569 {
0570 std::lock_guard<std::mutex> lock(m_mutex);
0571 m_writer->writeFrame(*frame, "events", m_collections_to_write);
0572 }
0573 }
0574
0575 void JEventProcessorPODIO::Finish() {
0576 if (m_output_include_collections_set) {
0577 m_log->error("The podio:output_include_collections was provided, but is deprecated. Use "
0578 "podio:output_collections instead.");
0579 throw std::runtime_error("The podio:output_include_collections was provided, but is "
0580 "deprecated. Use podio:output_collections instead.");
0581 }
0582
0583 m_writer->finish();
0584 }