Warning, file /EICrecon/src/services/io/podio/JEventSourcePODIO.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008 #include "JEventSourcePODIO.h"
0009
0010 #include <JANA/JApplication.h>
0011 #include <JANA/JEvent.h>
0012 #include <JANA/JException.h>
0013 #include <JANA/JLogger.h>
0014 #include <JANA/Utils/JTypeInfo.h>
0015 #include <TFile.h>
0016 #include <TObject.h>
0017 #include <fmt/color.h>
0018 #include <fmt/core.h>
0019 #include <fmt/format.h>
0020 #include <podio/CollectionBase.h>
0021 #include <podio/Frame.h>
0022 #include <podio/podioVersion.h>
0023 #include <algorithm>
0024 #include <cstdlib>
0025 #include <exception>
0026 #include <filesystem>
0027 #include <iostream>
0028 #include <map>
0029 #include <utility>
0030 #include <vector>
0031
0032
0033 #include "services/io/podio/datamodel_glue.h"
0034 #include "services/io/podio/datamodel_includes.h" // IWYU pragma: keep
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 struct InsertingVisitor {
0049 JEvent& m_event;
0050 const std::string& m_collection_name;
0051
0052 InsertingVisitor(JEvent& event, const std::string& collection_name) : m_event(event), m_collection_name(collection_name){};
0053
0054 template <typename T>
0055 void operator() (const T& collection) {
0056
0057 using ContentsT = decltype(collection[0]);
0058 m_event.InsertCollectionAlreadyInFrame<ContentsT>(&collection, m_collection_name);
0059 }
0060 };
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 JEventSourcePODIO::JEventSourcePODIO(std::string resource_name, JApplication* app) : JEventSource(resource_name, app) {
0071 SetTypeName(NAME_OF_THIS);
0072
0073
0074
0075
0076
0077 GetApplication()->SetDefaultParameter(
0078 "podio:run_forever",
0079 m_run_forever,
0080 "set to true to recycle through events continuously"
0081 );
0082
0083 bool print_type_table = false;
0084 GetApplication()->SetDefaultParameter(
0085 "podio:print_type_table",
0086 print_type_table,
0087 "Print list of collection names and their types"
0088 );
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 }
0109
0110
0111
0112
0113 JEventSourcePODIO::~JEventSourcePODIO() {
0114 LOG << "Closing Event Source for " << GetResourceName() << LOG_END;
0115 }
0116
0117
0118
0119
0120
0121
0122 void JEventSourcePODIO::Open() {
0123
0124 bool print_type_table = GetApplication()->GetParameterValue<bool>("podio:print_type_table");
0125
0126
0127
0128
0129 try {
0130
0131
0132 if( ! std::filesystem::exists(GetResourceName()) ){
0133
0134
0135
0136 auto mess = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),"ERROR: ");
0137 mess += fmt::format(fmt::emphasis::bold, "file: {} does not exist!", GetResourceName());
0138 std::cerr << std::endl << std::endl << mess << std::endl << std::endl;
0139 std::_Exit(EXIT_FAILURE);
0140 }
0141
0142 m_reader.openFile( GetResourceName() );
0143
0144 auto version = m_reader.currentFileVersion();
0145 bool version_mismatch = version.major > podio::version::build_version.major;
0146 version_mismatch |= (version.major == podio::version::build_version.major) && (version.minor>podio::version::build_version.minor);
0147 if( version_mismatch ) {
0148 std::stringstream ss;
0149 ss << "Mismatch in PODIO versions! " << version << " > " << podio::version::build_version;
0150
0151
0152 }
0153
0154 LOG << "PODIO version: file=" << version << " (executable=" << podio::version::build_version << ")" << LOG_END;
0155
0156 Nevents_in_file = m_reader.getEntries("events");
0157 LOG << "Opened PODIO Frame file \"" << GetResourceName() << "\" with " << Nevents_in_file << " events" << LOG_END;
0158
0159 if( print_type_table ) PrintCollectionTypeTable();
0160
0161 }catch (std::exception &e ){
0162 LOG_ERROR(default_cerr_logger) << e.what() << LOG_END;
0163 throw JException( fmt::format( "Problem opening file \"{}\"", GetResourceName() ) );
0164 }
0165
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175 void JEventSourcePODIO::Close() {
0176
0177
0178 }
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 void JEventSourcePODIO::GetEvent(std::shared_ptr<JEvent> event) {
0189
0190
0191
0192
0193
0194 if( Nevents_read >= Nevents_in_file ) {
0195 if( m_run_forever ){
0196 Nevents_read = 0;
0197 }else{
0198
0199
0200 throw RETURN_STATUS::kNO_MORE_EVENTS;
0201 }
0202 }
0203
0204 auto frame_data = m_reader.readEntry("events", Nevents_read);
0205 auto frame = std::make_unique<podio::Frame>(std::move(frame_data));
0206
0207 const auto& event_headers = frame->get<edm4hep::EventHeaderCollection>("EventHeader");
0208 if (event_headers.size() != 1) {
0209 throw JException("Bad event headers: Entry %d contains %d items, but 1 expected.", Nevents_read, event_headers.size());
0210 }
0211 event->SetEventNumber(event_headers[0].getEventNumber());
0212 event->SetRunNumber(event_headers[0].getRunNumber());
0213
0214
0215 VisitPodioCollection<InsertingVisitor> visit;
0216 for (const std::string& coll_name : frame->getAvailableCollections()) {
0217 const podio::CollectionBase* collection = frame->get(coll_name);
0218 InsertingVisitor visitor(*event, coll_name);
0219 visit(visitor, *collection);
0220 }
0221
0222 event->Insert(frame.release());
0223 Nevents_read += 1;
0224 }
0225
0226
0227
0228
0229 std::string JEventSourcePODIO::GetDescription() {
0230
0231
0232 return "PODIO root file (Frames, podio >= v0.16.3)";
0233 }
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 template <>
0248 double JEventSourceGeneratorT<JEventSourcePODIO>::CheckOpenable(std::string resource_name) {
0249
0250
0251
0252
0253 if (resource_name.find(".root") == std::string::npos ) return 0.0;
0254
0255
0256
0257 std::unique_ptr<TFile> file = std::make_unique<TFile>(resource_name.c_str());
0258 if (!file || file->IsZombie()) return 0.0;
0259
0260
0261 TObject* tree = file->Get("podio_metadata");
0262 if (tree == nullptr) return 0.0;
0263 return 0.03;
0264 }
0265
0266
0267
0268
0269
0270
0271
0272
0273 void JEventSourcePODIO::PrintCollectionTypeTable(void) {
0274
0275
0276 auto frame_data = m_reader.readEntry("events", 0);
0277 auto frame = std::make_unique<podio::Frame>(std::move(frame_data));
0278
0279 std::map<std::string, std::string> collectionNames;
0280 size_t max_name_len = 0;
0281 size_t max_type_len = 0;
0282
0283
0284
0285 for (const std::string& name : frame->getAvailableCollections()) {
0286 const podio::CollectionBase* coll = frame->get(name);
0287 const auto type = coll->getTypeName();
0288 max_name_len = std::max(max_name_len, name.length());
0289 max_type_len = std::max(max_type_len, type.length());
0290 collectionNames[name] = std::string(type);
0291 }
0292
0293
0294 std::cout << std::endl;
0295 std::cout << "Available Collections" << std::endl;
0296 std::cout << std::endl;
0297 std::cout << "Collection Name" << std::string(max_name_len + 2 - std::string("Collection Name").length(), ' ')
0298 << "Data Type" << std::endl;
0299 std::cout << std::string(max_name_len, '-') << " " << std::string(max_name_len, '-') << std::endl;
0300 for (auto &[name, type] : collectionNames) {
0301 std::cout << name + std::string(max_name_len + 2 - name.length(), ' ');
0302 std::cout << type << std::endl;
0303 }
0304 std::cout << std::endl;
0305
0306 }