File indexing completed on 2023-10-25 09:39:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <iostream>
0015
0016
0017 #include "DataFormats/FWLite/interface/MultiChainEvent.h"
0018 #include "DataFormats/Common/interface/EDProductGetter.h"
0019 #include "DataFormats/FWLite/interface/Handle.h"
0020 #include "DataFormats/Common/interface/TriggerResults.h"
0021 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0022 #include "FWCore/Common/interface/TriggerResultsByName.h"
0023
0024 #include <algorithm>
0025
0026 namespace fwlite {
0027
0028 namespace internal {
0029
0030 class MultiProductGetter : public edm::EDProductGetter {
0031 public:
0032 MultiProductGetter(MultiChainEvent const* iEvent) : event_(iEvent) {}
0033
0034 edm::WrapperBase const* getIt(edm::ProductID const& iID) const override { return event_->getByProductID(iID); }
0035
0036 std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> getThinnedProduct(
0037 edm::ProductID const& pid, unsigned int key) const override {
0038 return event_->getThinnedProduct(pid, key);
0039 }
0040
0041 void getThinnedProducts(edm::ProductID const& pid,
0042 std::vector<edm::WrapperBase const*>& foundContainers,
0043 std::vector<unsigned int>& keys) const override {
0044 event_->getThinnedProducts(pid, foundContainers, keys);
0045 }
0046
0047 edm::OptionalThinnedKey getThinnedKeyFrom(edm::ProductID const& parent,
0048 unsigned int key,
0049 edm::ProductID const& thinned) const override {
0050 return event_->getThinnedKeyFrom(parent, key, thinned);
0051 }
0052
0053 private:
0054 unsigned int transitionIndex_() const override { return 0U; }
0055
0056 MultiChainEvent const* event_;
0057 };
0058 }
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 MultiChainEvent::MultiChainEvent(std::vector<std::string> const& iFileNames1,
0072 std::vector<std::string> const& iFileNames2,
0073 bool useSecFileMapSorted) {
0074 event1_ = std::make_shared<ChainEvent>(iFileNames1);
0075 event2_ = std::make_shared<ChainEvent>(iFileNames2);
0076
0077 getter_ = std::make_shared<internal::MultiProductGetter>(this);
0078
0079 if (event1_->size() == 0) {
0080 std::cout << "------------------------------------------------------------------------" << std::endl;
0081 std::cout << "WARNING! MultiChainEvent: all primary files have zero events." << std::endl;
0082 std::cout << "Trying to access the events may lead to a crash. " << std::endl;
0083 std::cout << "------------------------------------------------------------------------" << std::endl;
0084 } else {
0085 event1_->setGetter(getter_);
0086 event2_->setGetter(getter_);
0087 }
0088
0089 useSecFileMapSorted_ = useSecFileMapSorted;
0090
0091 if (!useSecFileMapSorted_) {
0092 std::cout << "------------------------------------------------------------------------" << std::endl;
0093 std::cout << "WARNING! What you are about to do may be very slow." << std::endl;
0094 std::cout << "The 2-file solution in FWLite works with very simple assumptions." << std::endl;
0095 std::cout << "It will linearly search through the files in the secondary file list for Products." << std::endl;
0096 std::cout << "There are speed improvements available to make this run faster." << std::endl;
0097 std::cout << "***If your secondary files are sorted with a run-range within a file, (almost always the case) "
0098 << std::endl;
0099 std::cout << "***please use the option useSecFileMapSorted=true in this constructor. " << std::endl;
0100 std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, true);" << std::endl;
0101 std::cout << "------------------------------------------------------------------------" << std::endl;
0102 }
0103
0104 if (useSecFileMapSorted_) {
0105 std::cout << "------------------------------------------------------------------------" << std::endl;
0106 std::cout << "This MultiChainEvent is now creating a (run_range)_2 ---> file_index_2 map" << std::endl;
0107 std::cout << "for the 2-file solution. " << std::endl;
0108 std::cout
0109 << "This is assuming the files you are giving me are sorted by run,event pairs within each secondary file."
0110 << std::endl;
0111 std::cout << "If this is not true (rarely the case), set this option to false." << std::endl;
0112 std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, false);" << std::endl;
0113 std::cout << "------------------------------------------------------------------------" << std::endl;
0114
0115
0116
0117
0118 TFile* lastFile = nullptr;
0119 std::pair<event_id_range, Long64_t> eventRange;
0120 bool firstFile = true;
0121
0122 bool foundAny = false;
0123
0124 for (event2_->toBegin(); !event2_->atEnd(); ++(*event2_)) {
0125
0126 if (lastFile != event2_->getTFile()) {
0127
0128
0129 if (!firstFile) {
0130 foundAny = true;
0131 event_id_range toAdd = eventRange.first;
0132 secFileMapSorted_[toAdd] = eventRange.second;
0133 }
0134
0135 eventRange.first.first = event2_->event()->id();
0136 lastFile = event2_->getTFile();
0137 }
0138
0139
0140
0141 else {
0142 eventRange.first.second = event2_->event()->id();
0143 eventRange.second = event2_->eventIndex();
0144 }
0145 firstFile = false;
0146 }
0147
0148
0149 if (foundAny) {
0150 event_id_range toAdd = eventRange.first;
0151 secFileMapSorted_[toAdd] = eventRange.second;
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 }
0169 }
0170
0171
0172
0173
0174
0175
0176 MultiChainEvent::~MultiChainEvent() {}
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194 const MultiChainEvent& MultiChainEvent::operator++() {
0195 event1_->operator++();
0196 return *this;
0197 }
0198
0199
0200 bool MultiChainEvent::to(Long64_t iIndex) { return event1_->to(iIndex); }
0201
0202
0203 bool MultiChainEvent::to(edm::EventID id) { return to(id.run(), id.luminosityBlock(), id.event()); }
0204
0205
0206 bool MultiChainEvent::to(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event) {
0207 return event1_->to(run, lumi, event);
0208 }
0209
0210
0211 bool MultiChainEvent::to(edm::RunNumber_t run, edm::EventNumber_t event) { return to(run, 0U, event); }
0212
0213
0214 bool MultiChainEvent::toSec(Long64_t iIndex) { return event2_->to(iIndex); }
0215
0216
0217 bool MultiChainEvent::toSec(const edm::EventID& id) {
0218
0219 if (event2_->event_->to(id)) {
0220
0221 return true;
0222 }
0223
0224
0225
0226 for (sec_file_range_index_map::const_iterator mBegin = secFileMapSorted_.begin(),
0227 mEnd = secFileMapSorted_.end(),
0228 mit = mBegin;
0229 mit != mEnd;
0230 ++mit) {
0231 if (id < mit->first.first || id > mit->first.second) {
0232
0233
0234 continue;
0235 }
0236
0237
0238
0239
0240
0241 event2_->switchToFile(mit->second);
0242
0243 if (event2_->to(id)) {
0244
0245 return true;
0246 }
0247
0248
0249
0250 }
0251
0252
0253
0254
0255 if (event2_->to(id)) {
0256 return true;
0257 }
0258
0259
0260 throw cms::Exception("ProductNotFound")
0261 << "Cannot find id " << id.run() << ", " << id.event() << " in secondary list. Exiting." << std::endl;
0262
0263 return false;
0264 }
0265
0266
0267 bool MultiChainEvent::toSec(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event) {
0268 return toSec(edm::EventID(run, lumi, event));
0269 }
0270
0271
0272
0273 bool MultiChainEvent::toSec(edm::RunNumber_t run, edm::EventNumber_t event) {
0274 return toSec(edm::EventID(run, 0U, event));
0275 }
0276
0277
0278 const MultiChainEvent& MultiChainEvent::toBegin() {
0279 event1_->toBegin();
0280 return *this;
0281 }
0282
0283
0284
0285
0286 std::string const MultiChainEvent::getBranchNameFor(std::type_info const& iType,
0287 char const* iModule,
0288 char const* iInstance,
0289 char const* iProcess) const {
0290 return event1_->getBranchNameFor(iType, iModule, iInstance, iProcess);
0291 }
0292
0293 std::vector<edm::BranchDescription> const& MultiChainEvent::getBranchDescriptions() const {
0294 return event1_->getBranchDescriptions();
0295 }
0296
0297 std::vector<std::string> const& MultiChainEvent::getProcessHistory() const { return event1_->getProcessHistory(); }
0298
0299 edm::ProcessHistory const& MultiChainEvent::processHistory() const { return event1_->processHistory(); }
0300
0301 edm::EventAuxiliary const& MultiChainEvent::eventAuxiliary() const { return event1_->eventAuxiliary(); }
0302
0303 bool MultiChainEvent::getByLabel(std::type_info const& iType,
0304 char const* iModule,
0305 char const* iInstance,
0306 char const* iProcess,
0307 void* iValue) const {
0308 bool ret1 = event1_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
0309 if (!ret1) {
0310 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
0311 bool ret2 = event2_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
0312 if (!ret2)
0313 return false;
0314 }
0315 return true;
0316 }
0317
0318 bool MultiChainEvent::getByTokenImp(edm::EDGetToken iToken, edm::WrapperBase const*& iValue) const {
0319 bool ret1 = event1_->getByTokenImp(iToken, iValue);
0320 if (!ret1) {
0321 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
0322 bool ret2 = event2_->getByTokenImp(iToken, iValue);
0323 if (!ret2)
0324 return false;
0325 }
0326 return true;
0327 }
0328
0329 edm::WrapperBase const* MultiChainEvent::getByProductID(edm::ProductID const& iID) const {
0330
0331 edm::WrapperBase const* edp = event1_->getByProductID(iID);
0332
0333 if (edp == nullptr) {
0334 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
0335 edp = event2_->getByProductID(iID);
0336 }
0337 return edp;
0338 }
0339
0340 std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> MultiChainEvent::getThinnedProduct(
0341 edm::ProductID const& pid, unsigned int key) const {
0342
0343 auto edp = event1_->getThinnedProduct(pid, key);
0344
0345 if (not edp.has_value()) {
0346 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
0347 edp = event2_->getThinnedProduct(pid, key);
0348 }
0349 return edp;
0350 }
0351
0352 void MultiChainEvent::getThinnedProducts(edm::ProductID const& pid,
0353 std::vector<edm::WrapperBase const*>& wrappers,
0354 std::vector<unsigned int>& keys) const {
0355
0356 event1_->getThinnedProducts(pid, wrappers, keys);
0357
0358 if (std::find(wrappers.begin(), wrappers.end(), nullptr) != wrappers.end()) {
0359 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
0360 event2_->getThinnedProducts(pid, wrappers, keys);
0361 }
0362 }
0363
0364 edm::OptionalThinnedKey MultiChainEvent::getThinnedKeyFrom(edm::ProductID const& parent,
0365 unsigned int key,
0366 edm::ProductID const& thinned) const {
0367
0368 auto edp = event1_->getThinnedKeyFrom(parent, key, thinned);
0369
0370 if (std::holds_alternative<std::monostate>(edp)) {
0371 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
0372 edp = event2_->getThinnedKeyFrom(parent, key, thinned);
0373 }
0374 return edp;
0375 }
0376
0377 bool MultiChainEvent::isValid() const { return event1_->isValid(); }
0378 MultiChainEvent::operator bool() const { return *event1_; }
0379
0380 bool MultiChainEvent::atEnd() const { return event1_->atEnd(); }
0381
0382 Long64_t MultiChainEvent::size() const { return event1_->size(); }
0383
0384 edm::TriggerNames const& MultiChainEvent::triggerNames(edm::TriggerResults const& triggerResults) const {
0385 edm::TriggerNames const* names = triggerNames_(triggerResults);
0386 if (names != nullptr)
0387 return *names;
0388
0389 event1_->fillParameterSetRegistry();
0390 names = triggerNames_(triggerResults);
0391 if (names != nullptr)
0392 return *names;
0393
0394
0395
0396 event2_->to(event1_->id());
0397 event2_->fillParameterSetRegistry();
0398 names = triggerNames_(triggerResults);
0399 if (names != nullptr)
0400 return *names;
0401
0402 throw cms::Exception("TriggerNamesNotFound") << "TriggerNames not found in ParameterSet registry";
0403 return *names;
0404 }
0405
0406 edm::TriggerResultsByName MultiChainEvent::triggerResultsByName(edm::TriggerResults const& triggerResults) const {
0407 edm::TriggerNames const* names = triggerNames_(triggerResults);
0408
0409 if (names == nullptr) {
0410 event1_->fillParameterSetRegistry();
0411 names = triggerNames_(triggerResults);
0412 }
0413
0414 if (names == nullptr) {
0415 event2_->to(event1_->id());
0416 event2_->fillParameterSetRegistry();
0417 names = triggerNames_(triggerResults);
0418 }
0419
0420 return edm::TriggerResultsByName(&triggerResults, names);
0421 }
0422
0423 edm::ParameterSet const* MultiChainEvent::parameterSet(edm::ParameterSetID const& psID) const {
0424 auto pset = event1_->parameterSet(psID);
0425 if (nullptr == pset) {
0426 pset = event2_->parameterSet(psID);
0427 }
0428 return pset;
0429 }
0430
0431
0432
0433 void MultiChainEvent::throwProductNotFoundException(std::type_info const& iType,
0434 char const* iModule,
0435 char const* iInstance,
0436 char const* iProcess) {
0437 ChainEvent::throwProductNotFoundException(iType, iModule, iInstance, iProcess);
0438 }
0439 }