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