File indexing completed on 2025-01-18 10:17:38
0001
0002
0003
0004
0005 #pragma once
0006
0007 #include <JANA/JObject.h>
0008 #include <JANA/JException.h>
0009 #include <JANA/JFactoryT.h>
0010 #include <JANA/JFactorySet.h>
0011 #include <JANA/JLogger.h>
0012 #include <JANA/JVersion.h>
0013
0014 #include <JANA/Utils/JEventLevel.h>
0015 #include <JANA/Utils/JTypeInfo.h>
0016 #include <JANA/Utils/JCpuInfo.h>
0017 #include <JANA/Utils/JCallGraphRecorder.h>
0018 #include <JANA/Utils/JCallGraphEntryMaker.h>
0019 #include <JANA/Utils/JInspector.h>
0020
0021 #include <vector>
0022 #include <cstddef>
0023 #include <memory>
0024 #include <atomic>
0025
0026 #if JANA2_HAVE_PODIO
0027 #include <JANA/Podio/JFactoryPodioT.h>
0028 namespace podio {
0029 class CollectionBase;
0030 }
0031 #endif
0032
0033 class JApplication;
0034 class JEventSource;
0035
0036
0037 class JEvent : public std::enable_shared_from_this<JEvent> {
0038
0039 private:
0040 JApplication* mApplication = nullptr;
0041 int32_t mRunNumber = 0;
0042 uint64_t mEventNumber = 0;
0043 mutable JFactorySet* mFactorySet = nullptr;
0044 mutable JCallGraphRecorder mCallGraph;
0045 mutable JInspector mInspector;
0046 bool mUseDefaultTags = false;
0047 std::map<std::string, std::string> mDefaultTags;
0048 JEventSource* mEventSource = nullptr;
0049 bool mIsBarrierEvent = false;
0050 bool mIsWarmedUp = false;
0051
0052
0053 std::vector<std::pair<JEventLevel, JEvent*>> mParents;
0054 std::atomic_int mReferenceCount {1};
0055 int64_t mEventIndex = -1;
0056
0057 #if JANA2_HAVE_PODIO
0058 std::map<std::string, JFactory*> mPodioFactories;
0059 #endif
0060
0061
0062 public:
0063 JEvent();
0064 explicit JEvent(JApplication* app);
0065 virtual ~JEvent();
0066
0067 void SetFactorySet(JFactorySet* aFactorySet);
0068 void SetRunNumber(int32_t aRunNumber){mRunNumber = aRunNumber;}
0069 void SetEventNumber(uint64_t aEventNumber){mEventNumber = aEventNumber;}
0070 void SetJApplication(JApplication* app){mApplication = app;}
0071 void SetJEventSource(JEventSource* aSource){mEventSource = aSource;}
0072 void SetDefaultTags(std::map<std::string, std::string> aDefaultTags){mDefaultTags=aDefaultTags; mUseDefaultTags = !mDefaultTags.empty();}
0073 void SetSequential(bool isSequential) {mIsBarrierEvent = isSequential;}
0074
0075 JFactorySet* GetFactorySet() const { return mFactorySet; }
0076 int32_t GetRunNumber() const {return mRunNumber;}
0077 uint64_t GetEventNumber() const {return mEventNumber;}
0078 JApplication* GetJApplication() const {return mApplication;}
0079 JEventSource* GetJEventSource() const {return mEventSource; }
0080 JCallGraphRecorder* GetJCallGraphRecorder() const {return &mCallGraph;}
0081 JInspector* GetJInspector() const {return &mInspector;}
0082 void Inspect() const { mInspector.Loop();}
0083 bool GetSequential() const {return mIsBarrierEvent;}
0084 bool IsWarmedUp() { return mIsWarmedUp; }
0085
0086
0087 JEventLevel GetLevel() const { return mFactorySet->GetLevel(); }
0088 void SetLevel(JEventLevel level) { mFactorySet->SetLevel(level); }
0089 void SetEventIndex(int event_index) { mEventIndex = event_index; }
0090 int64_t GetEventIndex() const { return mEventIndex; }
0091
0092 bool HasParent(JEventLevel level) const;
0093 const JEvent& GetParent(JEventLevel level) const;
0094 void SetParent(JEvent* parent);
0095 JEvent* ReleaseParent(JEventLevel level);
0096 void Release();
0097
0098
0099 void Clear();
0100 void Finish();
0101
0102 JFactory* GetFactory(const std::string& object_name, const std::string& tag) const;
0103 std::vector<JFactory*> GetAllFactories() const;
0104
0105
0106 template<class T> JFactoryT<T>* GetFactory(const std::string& tag = "", bool throw_on_missing=false) const;
0107 template<class T> std::vector<JFactoryT<T>*> GetFactoryAll(bool throw_on_missing = false) const;
0108
0109
0110 template<class T> JFactoryT<T>* GetSingle(const T* &t, const char *tag="", bool exception_if_not_one=true) const;
0111 template<class T> JFactoryT<T>* Get(const T** item, const std::string& tag="") const;
0112 template<class T> JFactoryT<T>* Get(std::vector<const T*> &vec, const std::string& tag = "", bool strict=true) const;
0113 template<class T> void GetAll(std::vector<const T*> &vec) const;
0114
0115
0116 template<class T> const T* GetSingle(const std::string& tag = "") const;
0117 template<class T> const T* GetSingleStrict(const std::string& tag = "") const;
0118 template<class T> std::vector<const T*> Get(const std::string& tag = "", bool strict=true) const;
0119 template<class T> typename JFactoryT<T>::PairType GetIterators(const std::string& aTag = "") const;
0120 template<class T> std::vector<const T*> GetAll() const;
0121 template<class T> std::map<std::pair<std::string,std::string>,std::vector<T*>> GetAllChildren() const;
0122
0123
0124 template <class T> JFactoryT<T>* Insert(T* item, const std::string& aTag = "") const;
0125 template <class T> JFactoryT<T>* Insert(const std::vector<T*>& items, const std::string& tag = "") const;
0126
0127
0128 #if JANA2_HAVE_PODIO
0129 std::vector<std::string> GetAllCollectionNames() const;
0130 const podio::CollectionBase* GetCollectionBase(std::string name, bool throw_on_missing=true) const;
0131 template <typename T> const typename JFactoryPodioT<T>::CollectionT* GetCollection(std::string name, bool throw_on_missing=true) const;
0132 template <typename T> JFactoryPodioT<T>* InsertCollection(typename JFactoryPodioT<T>::CollectionT&& collection, std::string name);
0133 template <typename T> JFactoryPodioT<T>* InsertCollectionAlreadyInFrame(const podio::CollectionBase* collection, std::string name);
0134 #endif
0135
0136
0137 };
0138
0139
0140
0141
0142 template<class T>
0143 inline JFactoryT<T>* JEvent::GetFactory(const std::string& tag, bool throw_on_missing) const
0144 {
0145 std::string resolved_tag = tag;
0146 if (mUseDefaultTags && tag.empty()) {
0147 auto defaultTag = mDefaultTags.find(JTypeInfo::demangle<T>());
0148 if (defaultTag != mDefaultTags.end()) resolved_tag = defaultTag->second;
0149 }
0150 auto factory = mFactorySet->GetFactory<T>(resolved_tag);
0151 if (factory == nullptr) {
0152 if (throw_on_missing) {
0153 JException ex("Could not find JFactoryT<" + JTypeInfo::demangle<T>() + "> with tag=" + tag);
0154 ex.show_stacktrace = false;
0155 throw ex;
0156 }
0157 };
0158 return factory;
0159 }
0160
0161
0162
0163
0164
0165 template<class T>
0166 inline std::vector<JFactoryT<T>*> JEvent::GetFactoryAll(bool throw_on_missing) const {
0167 auto factories = mFactorySet->GetAllFactories<T>();
0168 if (factories.size() == 0) {
0169 if (throw_on_missing) {
0170 JException ex("Could not find any JFactoryT<" + JTypeInfo::demangle<T>() + "> (from any tag)");
0171 ex.show_stacktrace = false;
0172 throw ex;
0173 }
0174 };
0175 return factories;
0176 }
0177
0178
0179
0180
0181 template<class T>
0182 JFactoryT<T>* JEvent::GetSingle(const T* &t, const char *tag, bool exception_if_not_one) const
0183 {
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 std::vector<const T*> v;
0197 auto fac = GetFactory<T>(tag, true);
0198 JCallGraphEntryMaker cg_entry(mCallGraph, fac);
0199 Get(v, tag);
0200 if(v.size()!=1){
0201 t = NULL;
0202 if(exception_if_not_one) throw v.size();
0203 }
0204 t = v[0];
0205 return fac;
0206 }
0207
0208
0209
0210
0211
0212
0213
0214
0215 template<class T>
0216 JFactoryT<T>* JEvent::Get(const T** destination, const std::string& tag) const
0217 {
0218 auto factory = GetFactory<T>(tag, true);
0219 JCallGraphEntryMaker cg_entry(mCallGraph, factory);
0220 auto iterators = factory->CreateAndGetData(this->shared_from_this());
0221 if (std::distance(iterators.first, iterators.second) == 0) {
0222 *destination = nullptr;
0223 }
0224 else {
0225 *destination = *iterators.first;
0226 }
0227 return factory;
0228 }
0229
0230
0231 template<class T>
0232 JFactoryT<T>* JEvent::Get(std::vector<const T*>& destination, const std::string& tag, bool strict) const
0233 {
0234 auto factory = GetFactory<T>(tag, strict);
0235 if (factory == nullptr) return nullptr;
0236 JCallGraphEntryMaker cg_entry(mCallGraph, factory);
0237 auto iterators = factory->CreateAndGetData(this->shared_from_this());
0238 for (auto it=iterators.first; it!=iterators.second; it++) {
0239 destination.push_back(*it);
0240 }
0241 return factory;
0242 }
0243
0244
0245
0246 template<class T>
0247 void JEvent::GetAll(std::vector<const T*>& destination) const {
0248 auto factories = GetFactoryAll<T>(true);
0249 for (auto factory : factories) {
0250 auto iterators = factory->CreateAndGetData(this->shared_from_this());
0251 for (auto it = iterators.first; it != iterators.second; it++) {
0252 destination.push_back(*it);
0253 }
0254 }
0255 }
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 template<class T> const T* JEvent::GetSingle(const std::string& tag) const {
0269 auto factory = GetFactory<T>(tag, true);
0270 JCallGraphEntryMaker cg_entry(mCallGraph, factory);
0271 auto iterators = factory->CreateAndGetData(this->shared_from_this());
0272 if (std::distance(iterators.first, iterators.second) == 0) {
0273 return nullptr;
0274 }
0275 return *iterators.first;
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286 template<class T> const T* JEvent::GetSingleStrict(const std::string& tag) const {
0287 auto factory = GetFactory<T>(tag, true);
0288 JCallGraphEntryMaker cg_entry(mCallGraph, factory);
0289 auto iterators = factory->CreateAndGetData(this->shared_from_this());
0290 if (std::distance(iterators.first, iterators.second) == 0) {
0291 JException ex("GetSingle failed due to missing %d", NAME_OF(T));
0292 ex.show_stacktrace = false;
0293 throw ex;
0294 }
0295 else if (std::distance(iterators.first, iterators.second) > 1) {
0296 JException ex("GetSingle failed due to too many %d", NAME_OF(T));
0297 ex.show_stacktrace = false;
0298 throw ex;
0299 }
0300 return *iterators.first;
0301 }
0302
0303
0304 template<class T>
0305 std::vector<const T*> JEvent::Get(const std::string& tag, bool strict) const {
0306
0307 auto factory = GetFactory<T>(tag, strict);
0308 std::vector<const T*> vec;
0309 if (factory == nullptr) return vec;
0310 JCallGraphEntryMaker cg_entry(mCallGraph, factory);
0311 auto iters = factory->CreateAndGetData(this->shared_from_this());
0312 for (auto it=iters.first; it!=iters.second; ++it) {
0313 vec.push_back(*it);
0314 }
0315 return vec;
0316 }
0317
0318 template<class T>
0319 typename JFactoryT<T>::PairType JEvent::GetIterators(const std::string& tag) const {
0320 auto factory = GetFactory<T>(tag, true);
0321 JCallGraphEntryMaker cg_entry(mCallGraph, factory);
0322 auto iters = factory->CreateAndGetData(this->shared_from_this());
0323 return iters;
0324 }
0325
0326
0327 template<class T>
0328 std::vector<const T*> JEvent::GetAll() const {
0329 std::vector<const T*> vec;
0330 auto factories = GetFactoryAll<T>(true);
0331
0332 for (auto factory : factories) {
0333 auto iters = factory->CreateAndGetData(this->shared_from_this());
0334 std::vector<const T*> vec;
0335 for (auto it = iters.first; it != iters.second; ++it) {
0336 vec.push_back(*it);
0337 }
0338 }
0339 return vec;
0340 }
0341
0342
0343
0344
0345
0346
0347 template<class S>
0348 std::map<std::pair<std::string, std::string>, std::vector<S*>> JEvent::GetAllChildren() const {
0349 std::map<std::pair<std::string, std::string>, std::vector<S*>> results;
0350 for (JFactory* factory : mFactorySet->GetAllFactories()) {
0351 auto val = factory->GetAs<S>();
0352 if (!val.empty()) {
0353 auto key = std::make_pair(factory->GetObjectName(), factory->GetTag());
0354 results.insert(std::make_pair(key, val));
0355 }
0356 }
0357 return results;
0358 }
0359
0360
0361
0362
0363
0364
0365
0366 template <class T>
0367 inline JFactoryT<T>* JEvent::Insert(T* item, const std::string& tag) const {
0368
0369 std::string resolved_tag = tag;
0370 if (mUseDefaultTags && tag.empty()) {
0371 auto defaultTag = mDefaultTags.find(JTypeInfo::demangle<T>());
0372 if (defaultTag != mDefaultTags.end()) resolved_tag = defaultTag->second;
0373 }
0374 auto factory = mFactorySet->GetFactory<T>(resolved_tag);
0375 if (factory == nullptr) {
0376 factory = new JFactoryT<T>;
0377 factory->SetTag(tag);
0378 factory->SetLevel(mFactorySet->GetLevel());
0379 mFactorySet->Add(factory);
0380 }
0381 factory->Insert(item);
0382 factory->SetInsertOrigin( mCallGraph.GetInsertDataOrigin() );
0383 return factory;
0384 }
0385
0386 template <class T>
0387 inline JFactoryT<T>* JEvent::Insert(const std::vector<T*>& items, const std::string& tag) const {
0388
0389 std::string resolved_tag = tag;
0390 if (mUseDefaultTags && tag.empty()) {
0391 auto defaultTag = mDefaultTags.find(JTypeInfo::demangle<T>());
0392 if (defaultTag != mDefaultTags.end()) resolved_tag = defaultTag->second;
0393 }
0394 auto factory = mFactorySet->GetFactory<T>(resolved_tag);
0395 if (factory == nullptr) {
0396 factory = new JFactoryT<T>;
0397 factory->SetTag(tag);
0398 factory->SetLevel(mFactorySet->GetLevel());
0399 mFactorySet->Add(factory);
0400 }
0401 for (T* item : items) {
0402 factory->Insert(item);
0403 }
0404 factory->SetStatus(JFactory::Status::Inserted);
0405 factory->SetCreationStatus(JFactory::CreationStatus::Inserted);
0406 factory->SetInsertOrigin( mCallGraph.GetInsertDataOrigin() );
0407 return factory;
0408 }
0409
0410
0411
0412 #if JANA2_HAVE_PODIO
0413
0414 inline std::vector<std::string> JEvent::GetAllCollectionNames() const {
0415 std::vector<std::string> keys;
0416 for (auto pair : mPodioFactories) {
0417 keys.push_back(pair.first);
0418 }
0419 return keys;
0420 }
0421
0422 inline const podio::CollectionBase* JEvent::GetCollectionBase(std::string name, bool throw_on_missing) const {
0423 auto it = mPodioFactories.find(name);
0424 if (it == mPodioFactories.end()) {
0425 if (throw_on_missing) {
0426 throw JException("No factory with tag '%s' found", name.c_str());
0427 }
0428 else {
0429 return nullptr;
0430 }
0431 }
0432 JFactoryPodio* factory = dynamic_cast<JFactoryPodio*>(it->second);
0433 if (factory == nullptr) {
0434
0435 throw JException("Factory with tag '%s' does not inherit from JFactoryPodio!", name.c_str());
0436 }
0437 JCallGraphEntryMaker cg_entry(mCallGraph, it->second);
0438 it->second->Create(this->shared_from_this());
0439 return factory->GetCollection();
0440 }
0441
0442
0443 template <typename T>
0444 const typename JFactoryPodioT<T>::CollectionT* JEvent::GetCollection(std::string name, bool throw_on_missing) const {
0445 JFactoryT<T>* factory = GetFactory<T>(name, throw_on_missing);
0446 if (factory == nullptr) {
0447 return nullptr;
0448 }
0449 JFactoryPodioT<T>* typed_factory = dynamic_cast<JFactoryPodioT<T>*>(factory);
0450 if (typed_factory == nullptr) {
0451 throw JException("Factory must inherit from JFactoryPodioT in order to use JEvent::GetCollection()");
0452 }
0453 JCallGraphEntryMaker cg_entry(mCallGraph, typed_factory);
0454 typed_factory->Create(this->shared_from_this());
0455 return static_cast<const typename JFactoryPodioT<T>::CollectionT*>(typed_factory->GetCollection());
0456 }
0457
0458
0459 template <typename T>
0460 JFactoryPodioT<T>* JEvent::InsertCollection(typename JFactoryPodioT<T>::CollectionT&& collection, std::string name) {
0461
0462
0463 auto frame = GetOrCreateFrame(shared_from_this());
0464 const auto& owned_collection = frame->put(std::move(collection), name);
0465 return InsertCollectionAlreadyInFrame<T>(&owned_collection, name);
0466 }
0467
0468
0469 template <typename T>
0470 JFactoryPodioT<T>* JEvent::InsertCollectionAlreadyInFrame(const podio::CollectionBase* collection, std::string name) {
0471
0472
0473
0474
0475 const auto* typed_collection = dynamic_cast<const typename T::collection_type*>(collection);
0476 if (typed_collection == nullptr) {
0477 throw JException("Attempted to insert a collection of the wrong type! name='%s', expected type='%s', actual type='%s'",
0478 name.c_str(), JTypeInfo::demangle<typename T::collection_type>().c_str(), collection->getDataTypeName().data());
0479 }
0480
0481
0482 if (mUseDefaultTags && name.empty()) {
0483 auto defaultTag = mDefaultTags.find(JTypeInfo::demangle<T>());
0484 if (defaultTag != mDefaultTags.end()) name = defaultTag->second;
0485 }
0486
0487
0488 JFactoryT<T>* factory = mFactorySet->GetFactory<T>(name);
0489 if (factory == nullptr) {
0490 factory = new JFactoryPodioT<T>();
0491 factory->SetTag(name);
0492 factory->SetLevel(GetLevel());
0493 mFactorySet->Add(factory);
0494
0495 auto it = mPodioFactories.find(name);
0496 if (it != mPodioFactories.end()) {
0497 throw JException("InsertCollection failed because tag '%s' is not unique", name.c_str());
0498 }
0499 mPodioFactories[name] = factory;
0500 }
0501
0502
0503 if (factory->GetStatus() == JFactory::Status::Inserted ||
0504 factory->GetStatus() == JFactory::Status::Processed) {
0505
0506 throw JException("PODIO collections can only be inserted once, but factory with tag '%s' already has data", name.c_str());
0507 }
0508
0509
0510
0511 JFactoryPodioT<T>* typed_factory = dynamic_cast<JFactoryPodioT<T>*>(factory);
0512 if (typed_factory == nullptr) {
0513 throw JException("Factory must inherit from JFactoryPodioT in order to use JEvent::GetCollection()");
0514 }
0515
0516 typed_factory->SetCollectionAlreadyInFrame(typed_collection);
0517 typed_factory->SetInsertOrigin( mCallGraph.GetInsertDataOrigin() );
0518 return typed_factory;
0519 }
0520
0521 #endif
0522
0523
0524