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::EDProduct const*
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
00054 MultiChainEvent::MultiChainEvent(const std::vector<std::string>& iFileNames1,
00055 const std::vector<std::string>& iFileNames2,
00056 bool useSecFileMapSorted)
00057 {
00058 event1_ = boost::shared_ptr<ChainEvent> ( new ChainEvent( iFileNames1 ) );
00059 event2_ = boost::shared_ptr<ChainEvent> ( new ChainEvent( iFileNames2 ) );
00060
00061 getter_ = boost::shared_ptr<internal::MultiProductGetter>( new internal::MultiProductGetter( this) );
00062
00063 event1_->setGetter( getter_ );
00064 event2_->setGetter( getter_ );
00065
00066 useSecFileMapSorted_ = useSecFileMapSorted;
00067
00068 if ( !useSecFileMapSorted_ ) {
00069 std::cout << "------------------------------------------------------------------------" << std::endl;
00070 std::cout << "WARNING! What you are about to do may be very slow." << std::endl;
00071 std::cout << "The 2-file solution in FWLite works with very simple assumptions." << std::endl;
00072 std::cout << "It will linearly search through the files in the secondary file list for Products." << std::endl;
00073 std::cout << "There are speed improvements available to make this run faster." << std::endl;
00074 std::cout << "***If your secondary files are sorted with a run-range within a file, (almost always the case) " << std::endl;
00075 std::cout << "***please use the option useSecFileMapSorted=true in this constructor. " << std::endl;
00076 std::cout << " > usage: MultiChainEvent( primaryFiles, secondaryFiles, true);" << std::endl;
00077 std::cout << "------------------------------------------------------------------------" << std::endl;
00078
00079 }
00080
00081 if ( useSecFileMapSorted_ ) {
00082
00083 std::cout << "------------------------------------------------------------------------" << std::endl;
00084 std::cout << "This MultiChainEvent is now creating a (run_range)_2 ---> file_index_2 map" << std::endl;
00085 std::cout << "for the 2-file solution. " << std::endl;
00086 std::cout << "This is assuming the files you are giving me are sorted by run,event pairs within each secondary file." << std::endl;
00087 std::cout << "If this is not true (rarely the case), set this option to false." << std::endl;
00088 std::cout << " > usage: MultiChainEvent( primaryFiles, secondaryFiles, false);" << std::endl;
00089 std::cout << "------------------------------------------------------------------------" << std::endl;
00090
00091
00092
00093
00094
00095 TFile * lastFile = 0;
00096 std::pair<event_id_range,Long64_t> eventRange;
00097 bool firstFile = true;
00098
00099 bool foundAny = false;
00100
00101 for( event2_->toBegin();
00102 ! event2_->atEnd();
00103 ++(*event2_)) {
00104
00105 if ( lastFile != event2_->getTFile() ) {
00106
00107
00108
00109 if ( !firstFile ) {
00110 foundAny = true;
00111 event_id_range toAdd = eventRange.first;
00112 secFileMapSorted_[ toAdd ] = eventRange.second;
00113 }
00114
00115 eventRange.first.first = event2_->event()->id();
00116 lastFile = event2_->getTFile();
00117 }
00118
00119
00120
00121 else {
00122 eventRange.first.second = event2_->event()->id();
00123 eventRange.second = event2_->eventIndex();
00124 }
00125 firstFile = false;
00126 }
00127
00128
00129 if ( foundAny ) {
00130 event_id_range toAdd = eventRange.first;
00131 secFileMapSorted_[ toAdd ] = eventRange.second;
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
00157 MultiChainEvent::~MultiChainEvent()
00158 {
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 const MultiChainEvent&
00178 MultiChainEvent::operator++()
00179 {
00180 event1_->operator++();
00181 return *this;
00182 }
00183
00185 bool
00186 MultiChainEvent::to(Long64_t iIndex)
00187 {
00188 return event1_->to( iIndex );
00189 }
00190
00191
00193 bool
00194 MultiChainEvent::to(edm::EventID id)
00195 {
00196 return to(id.run(), id.luminosityBlock(), id.event());
00197 }
00198
00200 bool
00201 MultiChainEvent::to(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event)
00202 {
00203 return event1_->to( run, lumi, event );
00204 }
00205
00207 bool
00208 MultiChainEvent::to(edm::RunNumber_t run, edm::EventNumber_t event)
00209 {
00210 return to( run, 0U, event );
00211 }
00212
00213
00215 bool
00216 MultiChainEvent::toSec(Long64_t iIndex)
00217 {
00218 return event2_->to( iIndex );
00219 }
00220
00221
00222 bool
00223 MultiChainEvent::toSec (const edm::EventID &id)
00224 {
00225
00226 if ( event2_->event_->to( id ) )
00227 {
00228
00229 return true;
00230 }
00231
00232
00233
00234 for ( sec_file_range_index_map::const_iterator mBegin =
00235 secFileMapSorted_.begin(),
00236 mEnd = secFileMapSorted_.end(),
00237 mit = mBegin;
00238 mit != mEnd;
00239 ++mit )
00240 {
00241 if ( id < mit->first.first || id > mit->first.second )
00242 {
00243
00244
00245 continue;
00246 }
00247
00248
00249
00250
00251
00252 event2_->switchToFile( mit->second );
00253
00254 if (event2_->to( id ))
00255 {
00256
00257 return true;
00258 }
00259
00260
00261
00262 }
00263
00264
00265
00266
00267 if (event2_->to(id))
00268 {
00269 return true;
00270 }
00271
00272
00273 throw cms::Exception("ProductNotFound") << "Cannot find id "
00274 << id.run() << ", "
00275 << id.event()
00276 << " in secondary list. Exiting."
00277 << std::endl;
00278
00279 return false;
00280 }
00281
00283 bool
00284 MultiChainEvent::toSec(edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi, edm::EventNumber_t event)
00285 {
00286 return toSec( edm::EventID( run, lumi, event) );
00287 }
00288
00289
00291 bool
00292 MultiChainEvent::toSec(edm::RunNumber_t run, edm::EventNumber_t event)
00293 {
00294 return toSec( edm::EventID( run, 0U, event) );
00295 }
00296
00297
00298 const MultiChainEvent&
00299 MultiChainEvent::toBegin()
00300 {
00301 event1_->toBegin();
00302 return *this;
00303 }
00304
00305
00306
00307
00308 const std::string
00309 MultiChainEvent::getBranchNameFor(const std::type_info& iType,
00310 const char* iModule,
00311 const char* iInstance,
00312 const char* iProcess) const
00313 {
00314 return event1_->getBranchNameFor(iType,iModule,iInstance,iProcess);
00315 }
00316
00317 const std::vector<edm::BranchDescription>&
00318 MultiChainEvent::getBranchDescriptions() const
00319 {
00320 return event1_->getBranchDescriptions();
00321 }
00322
00323 const std::vector<std::string>&
00324 MultiChainEvent::getProcessHistory() const
00325 {
00326 return event1_->getProcessHistory();
00327 }
00328
00329 edm::ProcessHistory const&
00330 MultiChainEvent::processHistory() const
00331 {
00332 return event1_->processHistory();
00333 }
00334
00335 edm::EventAuxiliary const&
00336 MultiChainEvent::eventAuxiliary() const
00337 {
00338 return event1_->eventAuxiliary();
00339 }
00340
00341 bool
00342 MultiChainEvent::getByLabel(const std::type_info& iType,
00343 const char* iModule,
00344 const char* iInstance,
00345 const char* 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 edm::EDProduct const* MultiChainEvent::getByProductID(edm::ProductID const&iID) const
00358 {
00359
00360 edm::EDProduct const * prod = event1_->getByProductID(iID);
00361
00362 if ( 0 == prod ) {
00363 (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
00364 prod = event2_->getByProductID(iID);
00365 if ( 0 == prod ) {
00366 throw cms::Exception("ProductNotFound") << "Cannot find product " << iID;
00367 }
00368 }
00369 return prod;
00370 }
00371
00372
00373 bool
00374 MultiChainEvent::isValid() const
00375 {
00376 return event1_->isValid();
00377 }
00378 MultiChainEvent::operator bool() const
00379 {
00380 return *event1_;
00381 }
00382
00383 bool
00384 MultiChainEvent::atEnd() const
00385 {
00386 return event1_->atEnd();
00387 }
00388
00389 Long64_t
00390 MultiChainEvent::size() const
00391 {
00392 return event1_->size();
00393 }
00394
00395 edm::TriggerNames const&
00396 MultiChainEvent::triggerNames(edm::TriggerResults const& triggerResults) const
00397 {
00398 edm::TriggerNames const* names = triggerNames_(triggerResults);
00399 if (names != 0) return *names;
00400
00401 event1_->fillParameterSetRegistry();
00402 names = triggerNames_(triggerResults);
00403 if (names != 0) return *names;
00404
00405
00406
00407 event2_->to( event1_->id() );
00408 event2_->fillParameterSetRegistry();
00409 names = triggerNames_(triggerResults);
00410 if (names != 0) return *names;
00411
00412 throw cms::Exception("TriggerNamesNotFound")
00413 << "TriggerNames not found in ParameterSet registry";
00414 return *names;
00415 }
00416
00417 edm::TriggerResultsByName
00418 MultiChainEvent::triggerResultsByName(std::string const& process) const {
00419
00420 fwlite::Handle<edm::TriggerResults> hTriggerResults;
00421 hTriggerResults.getByLabel(*this,"TriggerResults","",process.c_str());
00422 if ( !hTriggerResults.isValid()) {
00423 return edm::TriggerResultsByName(0,0);
00424 }
00425
00426 edm::TriggerNames const* names = triggerNames_(*hTriggerResults);
00427
00428 if (names == 0) {
00429 event1_->fillParameterSetRegistry();
00430 names = triggerNames_(*hTriggerResults);
00431 }
00432
00433 if (names == 0) {
00434 event2_->to( event1_->id() );
00435 event2_->fillParameterSetRegistry();
00436 names = triggerNames_(*hTriggerResults);
00437 }
00438
00439 return edm::TriggerResultsByName(hTriggerResults.product(), names);
00440 }
00441
00442
00443
00444
00445 void
00446 MultiChainEvent::throwProductNotFoundException(const std::type_info& iType,
00447 const char* iModule,
00448 const char* iInstance,
00449 const char* iProcess) {
00450 ChainEvent::throwProductNotFoundException(iType,iModule,iInstance,iProcess);
00451 }
00452 }