00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "DataFormats/FWLite/interface/MultiChainEvent.h"
00017 #include "DataFormats/Common/interface/EDProductGetter.h"
00018 #include "DataFormats/FWLite/interface/Handle.h"
00019 #include "DataFormats/Common/interface/TriggerResults.h"
00020 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00021 #include "FWCore/Common/interface/TriggerResultsByName.h"
00022
00023 namespace fwlite {
00024
00025 namespace internal {
00026
00027 class MultiProductGetter : public edm::EDProductGetter {
00028 public:
00029 MultiProductGetter(MultiChainEvent const* iEvent) : event_(iEvent) {}
00030
00031 virtual edm::WrapperHolder
00032 getIt(edm::ProductID const& iID) const {
00033
00034 return event_->getByProductID(iID);
00035 }
00036 private:
00037 MultiChainEvent const* event_;
00038
00039 };
00040 }
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 MultiChainEvent::MultiChainEvent(std::vector<std::string> const& iFileNames1,
00054 std::vector<std::string> const& iFileNames2,
00055 bool useSecFileMapSorted)
00056 {
00057 event1_ = boost::shared_ptr<ChainEvent> (new ChainEvent(iFileNames1));
00058 event2_ = boost::shared_ptr<ChainEvent> (new ChainEvent(iFileNames2));
00059
00060 getter_ = boost::shared_ptr<internal::MultiProductGetter>(new internal::MultiProductGetter(this));
00061
00062 event1_->setGetter(getter_);
00063 event2_->setGetter(getter_);
00064
00065 useSecFileMapSorted_ = useSecFileMapSorted;
00066
00067 if (!useSecFileMapSorted_) {
00068 std::cout << "------------------------------------------------------------------------" << std::endl;
00069 std::cout << "WARNING! What you are about to do may be very slow." << std::endl;
00070 std::cout << "The 2-file solution in FWLite works with very simple assumptions." << std::endl;
00071 std::cout << "It will linearly search through the files in the secondary file list for Products." << std::endl;
00072 std::cout << "There are speed improvements available to make this run faster." << std::endl;
00073 std::cout << "***If your secondary files are sorted with a run-range within a file, (almost always the case) " << std::endl;
00074 std::cout << "***please use the option useSecFileMapSorted=true in this constructor. " << std::endl;
00075 std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, true);" << std::endl;
00076 std::cout << "------------------------------------------------------------------------" << std::endl;
00077
00078 }
00079
00080 if (useSecFileMapSorted_) {
00081
00082 std::cout << "------------------------------------------------------------------------" << std::endl;
00083 std::cout << "This MultiChainEvent is now creating a (run_range)_2 ---> file_index_2 map" << std::endl;
00084 std::cout << "for the 2-file solution. " << std::endl;
00085 std::cout << "This is assuming the files you are giving me are sorted by run,event pairs within each secondary file." << std::endl;
00086 std::cout << "If this is not true (rarely the case), set this option to false." << std::endl;
00087 std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, false);" << std::endl;
00088 std::cout << "------------------------------------------------------------------------" << std::endl;
00089
00090
00091
00092
00093
00094 TFile * lastFile = 0;
00095 std::pair<event_id_range,Long64_t> eventRange;
00096 bool firstFile = true;
00097
00098 bool foundAny = false;
00099
00100 for(event2_->toBegin();
00101 ! event2_->atEnd();
00102 ++(*event2_)) {
00103
00104 if (lastFile != event2_->getTFile()) {
00105
00106
00107
00108 if (!firstFile) {
00109 foundAny = true;
00110 event_id_range toAdd = eventRange.first;
00111 secFileMapSorted_[ toAdd ] = eventRange.second;
00112 }
00113
00114 eventRange.first.first = event2_->event()->id();
00115 lastFile = event2_->getTFile();
00116 }
00117
00118
00119
00120 else {
00121 eventRange.first.second = event2_->event()->id();
00122 eventRange.second = event2_->eventIndex();
00123 }
00124 firstFile = false;
00125 }
00126
00127
00128 if (foundAny) {
00129 event_id_range toAdd = eventRange.first;
00130 secFileMapSorted_[ toAdd ] = eventRange.second;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 }
00148
00149 }
00150
00151
00152
00153
00154
00155
00156 MultiChainEvent::~MultiChainEvent()
00157 {
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 const MultiChainEvent&
00177 MultiChainEvent::operator++()
00178 {
00179 event1_->operator++();
00180 return *this;
00181 }
00182
00184 bool
00185 MultiChainEvent::to(Long64_t iIndex)
00186 {
00187 return event1_->to(iIndex);
00188 }
00189
00190
00192 bool
00193 MultiChainEvent::to(edm::EventID id)
00194 {
00195 return to(id.run(), id.luminosityBlock(), id.event());
00196 }
00197
00199 bool
00200 MultiChainEvent::to(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event)
00201 {
00202 return event1_->to(run, lumi, event);
00203 }
00204
00206 bool
00207 MultiChainEvent::to(edm::RunNumber_t run, edm::EventNumber_t event)
00208 {
00209 return to(run, 0U, event);
00210 }
00211
00212
00214 bool
00215 MultiChainEvent::toSec(Long64_t iIndex)
00216 {
00217 return event2_->to(iIndex);
00218 }
00219
00220
00221 bool
00222 MultiChainEvent::toSec (const edm::EventID &id)
00223 {
00224
00225 if (event2_->event_->to(id))
00226 {
00227
00228 return true;
00229 }
00230
00231
00232
00233 for (sec_file_range_index_map::const_iterator mBegin =
00234 secFileMapSorted_.begin(),
00235 mEnd = secFileMapSorted_.end(),
00236 mit = mBegin;
00237 mit != mEnd;
00238 ++mit)
00239 {
00240 if (id < mit->first.first || id > mit->first.second)
00241 {
00242
00243
00244 continue;
00245 }
00246
00247
00248
00249
00250
00251 event2_->switchToFile(mit->second);
00252
00253 if (event2_->to(id))
00254 {
00255
00256 return true;
00257 }
00258
00259
00260
00261 }
00262
00263
00264
00265
00266 if (event2_->to(id))
00267 {
00268 return true;
00269 }
00270
00271
00272 throw cms::Exception("ProductNotFound") << "Cannot find id "
00273 << id.run() << ", "
00274 << id.event()
00275 << " in secondary list. Exiting."
00276 << std::endl;
00277
00278 return false;
00279 }
00280
00282 bool
00283 MultiChainEvent::toSec(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event)
00284 {
00285 return toSec(edm::EventID(run, lumi, event));
00286 }
00287
00288
00290 bool
00291 MultiChainEvent::toSec(edm::RunNumber_t run, edm::EventNumber_t event)
00292 {
00293 return toSec(edm::EventID(run, 0U, event));
00294 }
00295
00296
00297 const MultiChainEvent&
00298 MultiChainEvent::toBegin()
00299 {
00300 event1_->toBegin();
00301 return *this;
00302 }
00303
00304
00305
00306
00307 std::string const
00308 MultiChainEvent::getBranchNameFor(std::type_info const& iType,
00309 char const* iModule,
00310 char const* iInstance,
00311 char const* iProcess) const
00312 {
00313 return event1_->getBranchNameFor(iType,iModule,iInstance,iProcess);
00314 }
00315
00316 std::vector<edm::BranchDescription> const&
00317 MultiChainEvent::getBranchDescriptions() const
00318 {
00319 return event1_->getBranchDescriptions();
00320 }
00321
00322 std::vector<std::string> const&
00323 MultiChainEvent::getProcessHistory() const
00324 {
00325 return event1_->getProcessHistory();
00326 }
00327
00328 edm::ProcessHistory const&
00329 MultiChainEvent::processHistory() const
00330 {
00331 return event1_->processHistory();
00332 }
00333
00334 edm::EventAuxiliary const&
00335 MultiChainEvent::eventAuxiliary() const
00336 {
00337 return event1_->eventAuxiliary();
00338 }
00339
00340 bool
00341 MultiChainEvent::getByLabel(
00342 std::type_info const& iType,
00343 char const* iModule,
00344 char const* iInstance,
00345 char const* iProcess,
00346 void* iValue) const
00347 {
00348 bool ret1 = event1_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
00349 if (!ret1) {
00350 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
00351 bool ret2 = event2_->getByLabel(iType,iModule,iInstance,iProcess,iValue);
00352 if (!ret2) return false;
00353 }
00354 return true;
00355 }
00356
00357 bool
00358 MultiChainEvent::getByLabel(
00359 std::type_info const& iType,
00360 char const* iModule,
00361 char const* iInstance,
00362 char const* iProcess,
00363 edm::WrapperHolder& holder) const {
00364 bool ret1 = event1_->getByLabel(iType, iModule, iInstance, iProcess, holder);
00365 if(!ret1) {
00366 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
00367 bool ret2 = event2_->getByLabel(iType, iModule, iInstance, iProcess, holder);
00368 if(!ret2) return false;
00369 }
00370 return true;
00371 }
00372
00373 edm::WrapperHolder MultiChainEvent::getByProductID(edm::ProductID const&iID) const
00374 {
00375
00376 edm::WrapperHolder edp = event1_->getByProductID(iID);
00377
00378 if (!edp.isValid()) {
00379 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
00380 edp = event2_->getByProductID(iID);
00381 if (!edp.isValid()) {
00382 throw cms::Exception("ProductNotFound") << "Cannot find product " << iID;
00383 }
00384 }
00385 return edp;
00386 }
00387
00388
00389 bool
00390 MultiChainEvent::isValid() const
00391 {
00392 return event1_->isValid();
00393 }
00394 MultiChainEvent::operator bool() const
00395 {
00396 return *event1_;
00397 }
00398
00399 bool
00400 MultiChainEvent::atEnd() const
00401 {
00402 return event1_->atEnd();
00403 }
00404
00405 Long64_t
00406 MultiChainEvent::size() const
00407 {
00408 return event1_->size();
00409 }
00410
00411 edm::TriggerNames const&
00412 MultiChainEvent::triggerNames(edm::TriggerResults const& triggerResults) const
00413 {
00414 edm::TriggerNames const* names = triggerNames_(triggerResults);
00415 if (names != 0) return *names;
00416
00417 event1_->fillParameterSetRegistry();
00418 names = triggerNames_(triggerResults);
00419 if (names != 0) return *names;
00420
00421
00422
00423 event2_->to(event1_->id());
00424 event2_->fillParameterSetRegistry();
00425 names = triggerNames_(triggerResults);
00426 if (names != 0) return *names;
00427
00428 throw cms::Exception("TriggerNamesNotFound")
00429 << "TriggerNames not found in ParameterSet registry";
00430 return *names;
00431 }
00432
00433 edm::TriggerResultsByName
00434 MultiChainEvent::triggerResultsByName(std::string const& process) const {
00435
00436 fwlite::Handle<edm::TriggerResults> hTriggerResults;
00437 hTriggerResults.getByLabel(*this,"TriggerResults","",process.c_str());
00438 if (!hTriggerResults.isValid()) {
00439 return edm::TriggerResultsByName(0,0);
00440 }
00441
00442 edm::TriggerNames const* names = triggerNames_(*hTriggerResults);
00443
00444 if (names == 0) {
00445 event1_->fillParameterSetRegistry();
00446 names = triggerNames_(*hTriggerResults);
00447 }
00448
00449 if (names == 0) {
00450 event2_->to(event1_->id());
00451 event2_->fillParameterSetRegistry();
00452 names = triggerNames_(*hTriggerResults);
00453 }
00454
00455 return edm::TriggerResultsByName(hTriggerResults.product(), names);
00456 }
00457
00458
00459
00460
00461 void
00462 MultiChainEvent::throwProductNotFoundException(std::type_info const& iType,
00463 char const* iModule,
00464 char const* iInstance,
00465 char const* iProcess) {
00466 ChainEvent::throwProductNotFoundException(iType,iModule,iInstance,iProcess);
00467 }
00468 }