** Warning **
Issuing rollback() due to DESTROY without explicit disconnect() of DBD::mysql::db handle dbname=lxr_eic at /usr/local/share/lxr/lxr-2.3.7/lib/LXR/Common.pm line 1161, <GEN243> line 1.
Last-Modified: Fri, 10 Jul 2025 08:58:11 GMT
Content-Type: text/html; charset=utf-8
/master/EICrecon/src/services/io/podio/JEventSourcePODIO.cc
File indexing completed on 2025-07-10 07:55:36
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/Utils /JTypeInfo.h >
0014 #include <TFile.h >
0015 #include <TObject.h >
0016 #include <fmt/core.h >
0017 #include <fmt/ostream.h >
0018 #include <podio/CollectionBase.h >
0019 #include <podio/Frame.h >
0020 #include <podio/podioVersion.h >
0021 #include <algorithm>
0022 #include <exception>
0023 #include <iostream>
0024 #include <map>
0025 #include <memory>
0026 #include <utility>
0027 #include <vector>
0028
0029
0030 #include "services/io/podio/datamodel_glue.h "
0031 #include "services/io/podio/datamodel_includes.h" // IWYU pragma: keep
0032 #include "services/log/Log_service.h "
0033
0034
0035 template <> struct fmt ::formatter <podio ::version ::Version > : ostream_formatter {};
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 )
0053 : m_event (event ), m_collection_name (collection_name ){};
0054
0055 template <typename T > 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 JEventSourcePODIO ::JEventSourcePODIO (std ::string resource_name , JApplication * app )
0070 : JEventSource (resource_name , app ) {
0071 SetTypeName (NAME_OF_THIS );
0072 #if JANA_NEW_CALLBACK_STYLE
0073 SetCallbackStyle (CallbackStyle ::ExpertMode );
0074 #endif
0075
0076
0077 m_log = GetApplication ()->GetService <Log_service >()->logger ("JEventSourcePODIO" );
0078
0079
0080
0081
0082
0083 GetApplication ()->SetDefaultParameter ("podio:run_forever" , m_run_forever ,
0084 "set to true to recycle through events continuously" );
0085
0086 bool print_type_table = false ;
0087 GetApplication ()->SetDefaultParameter ("podio:print_type_table" , print_type_table ,
0088 "Print list of collection names and their types" );
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 m_log ->info ("Closing Event Source for {}" , GetResourceName ());
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 m_reader .openFile (GetResourceName ());
0132
0133 auto version = m_reader .currentFileVersion ();
0134 bool version_mismatch = version .major > podio ::version ::build_version .major ;
0135 version_mismatch |= (version .major == podio ::version ::build_version .major ) &&
0136 (version .minor > podio ::version ::build_version .minor );
0137 if (version_mismatch ) {
0138 std ::stringstream ss ;
0139 ss << "Mismatch in PODIO versions! " << version << " > " << podio ::version ::build_version ;
0140
0141
0142 }
0143
0144 m_log ->info ("PODIO version: file={} (executable={})" , version , podio ::version ::build_version );
0145
0146 Nevents_in_file = m_reader .getEntries ("events" );
0147 m_log ->info ("Opened PODIO Frame file \"{}\" with {} events" , GetResourceName (),
0148 Nevents_in_file );
0149
0150 if (print_type_table ) {
0151 PrintCollectionTypeTable ();
0152 }
0153
0154 } catch (std ::exception & e ) {
0155 m_log ->error (e .what ());
0156 throw JException (fmt ::format ("Problem opening file \"{}\"" , GetResourceName ()));
0157 }
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167 void JEventSourcePODIO ::Close () {
0168
0169
0170 }
0171
0172
0173
0174
0175
0176
0177
0178
0179 #if JANA_NEW_CALLBACK_STYLE
0180 JEventSourcePODIO ::Result JEventSourcePODIO ::Emit (JEvent & event ) {
0181 #else
0182 void JEventSourcePODIO ::GetEvent (std ::shared_ptr <JEvent > _event ) {
0183 auto & event = *_event ;
0184 #endif
0185
0186
0187
0188
0189
0190 if (Nevents_read >= Nevents_in_file ) {
0191 if (m_run_forever ) {
0192 Nevents_read = 0;
0193 } else {
0194 #if JANA_NEW_CALLBACK_STYLE
0195 return Result ::FailureFinished ;
0196 #else
0197 throw RETURN_STATUS ::kNO_MORE_EVENTS ;
0198 #endif
0199 }
0200 }
0201
0202 auto frame_data = m_reader .readEntry ("events" , Nevents_read );
0203 auto frame = std ::make_unique <podio ::Frame >(std ::move (frame_data ));
0204
0205 if (m_use_event_headers ) {
0206 const auto & event_headers = frame ->get <edm4hep ::EventHeaderCollection >("EventHeader" );
0207 if (event_headers .size () != 1) {
0208 m_log ->warn ("Missing or bad event headers: Entry {} contains {} items, but 1 expected. Will "
0209 "not use event and run numbers from header" ,
0210 Nevents_read , event_headers .size ());
0211 m_use_event_headers = false ;
0212 } else {
0213 event .SetEventNumber (event_headers [0].getEventNumber ());
0214 event .SetRunNumber (event_headers [0].getRunNumber ());
0215 }
0216 }
0217
0218
0219 VisitPodioCollection <InsertingVisitor > visit ;
0220 for (const std ::string & coll_name : frame ->getAvailableCollections ()) {
0221 const podio ::CollectionBase * collection = frame ->get (coll_name );
0222 InsertingVisitor visitor (event , coll_name );
0223 visit (visitor , *collection );
0224 }
0225
0226 event .Insert (frame .release ());
0227 Nevents_read += 1;
0228 #if JANA_NEW_CALLBACK_STYLE
0229 return Result ::Success ;
0230 #endif
0231 }
0232
0233
0234
0235
0236 std ::string JEventSourcePODIO ::GetDescription () {
0237
0238
0239 return "PODIO root file (Frames, podio >= v0.16.3)" ;
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 template <>
0255 double JEventSourceGeneratorT <JEventSourcePODIO >::CheckOpenable (std ::string resource_name ) {
0256
0257
0258
0259
0260 if (resource_name .find (".root" ) == std ::string ::npos ) {
0261 return 0.0;
0262 }
0263
0264
0265
0266 std ::unique_ptr <TFile > file = std ::unique_ptr <TFile >{TFile ::Open (resource_name .c_str ())};
0267 if (!file || file ->IsZombie ()) {
0268 return 0.0;
0269 }
0270
0271
0272 TObject * tree = file ->Get ("podio_metadata" );
0273 if (tree == nullptr) {
0274 return 0.0;
0275 }
0276 return 0.03;
0277 }
0278
0279
0280
0281
0282
0283
0284
0285
0286 void JEventSourcePODIO ::PrintCollectionTypeTable () {
0287
0288
0289 auto frame_data = m_reader .readEntry ("events" , 0);
0290 auto frame = std ::make_unique <podio ::Frame >(std ::move (frame_data ));
0291
0292 std ::map <std ::string , std ::string > collectionNames ;
0293 std ::size_t max_name_len = 0;
0294 std ::size_t max_type_len = 0;
0295
0296
0297
0298 for (const std ::string & name : frame ->getAvailableCollections ()) {
0299 const podio ::CollectionBase * coll = frame ->get (name );
0300 const auto type = coll ->getTypeName ();
0301 max_name_len = std ::max (max_name_len , name .length ());
0302 max_type_len = std ::max (max_type_len , type .length ());
0303 collectionNames [name ] = std ::string (type );
0304 }
0305
0306
0307 std ::cout << std ::endl ;
0308 std ::cout << "Available Collections" << std ::endl ;
0309 std ::cout << std ::endl ;
0310 std ::cout << "Collection Name"
0311 << std ::string (max_name_len + 2 - std ::string ("Collection Name" ).length (), ' ' )
0312 << "Data Type" << std ::endl ;
0313 std ::cout << std ::string (max_name_len , '-' ) << " " << std ::string (max_name_len , '-' )
0314 << std ::endl ;
0315 for (auto & [name , type ] : collectionNames ) {
0316 std ::cout << name + std ::string (max_name_len + 2 - name .length (), ' ' );
0317 std ::cout << type << std ::endl ;
0318 }
0319 std ::cout << std ::endl ;
0320 }