00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "boost/bind.hpp"
00017 #include <algorithm>
00018
00019
00020 #include "FWCore/Framework/interface/EventSetupProvider.h"
00021 #include "FWCore/Framework/interface/EventSetupRecordProvider.h"
00022 #include "FWCore/Framework/interface/EventSetupRecordProviderFactoryManager.h"
00023 #include "FWCore/Framework/interface/EventSetupRecord.h"
00024 #include "FWCore/Framework/interface/DataProxyProvider.h"
00025 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
00026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00027 #include "FWCore/Utilities/interface/Algorithms.h"
00028
00029 namespace edm {
00030 namespace eventsetup {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 EventSetupProvider::EventSetupProvider(const PreferredProviderInfo* iInfo) :
00043 eventSetup_(),
00044 providers_(),
00045 mustFinishConfiguration_(true),
00046 preferredProviderInfo_((0!=iInfo) ? (new PreferredProviderInfo(*iInfo)): 0),
00047 finders_(new std::vector<boost::shared_ptr<EventSetupRecordIntervalFinder> >() ),
00048 dataProviders_(new std::vector<boost::shared_ptr<DataProxyProvider> >() )
00049 {
00050 }
00051
00052
00053
00054
00055
00056
00057 EventSetupProvider::~EventSetupProvider()
00058 {
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 void
00077 EventSetupProvider::insert(const EventSetupRecordKey& iKey, std::auto_ptr<EventSetupRecordProvider> iProvider)
00078 {
00079 boost::shared_ptr<EventSetupRecordProvider> temp(iProvider.release());
00080 providers_[iKey] = temp;
00081
00082 }
00083
00084 void
00085 EventSetupProvider::add(boost::shared_ptr<DataProxyProvider> iProvider)
00086 {
00087 mustFinishConfiguration_ = true;
00088 assert(&(*iProvider) != 0);
00089 dataProviders_->push_back(iProvider);
00090 }
00091
00092
00093 void
00094 EventSetupProvider::add(boost::shared_ptr<EventSetupRecordIntervalFinder> iFinder)
00095 {
00096 mustFinishConfiguration_ = true;
00097 assert(&(*iFinder) != 0);
00098 finders_->push_back(iFinder);
00099 }
00100
00101 typedef std::map<EventSetupRecordKey, boost::shared_ptr<EventSetupRecordProvider> > Providers;
00102 typedef std::map<EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap> RecordToPreferred;
00104 static
00105 void
00106 preferEverything(const ComponentDescription& iComponent,
00107 const Providers& iProviders,
00108 RecordToPreferred& iReturnValue)
00109 {
00110
00111 bool foundProxyProvider = false;
00112 for(Providers::const_iterator itProvider = iProviders.begin(), itProviderEnd = iProviders.end();
00113 itProvider!= itProviderEnd;
00114 ++itProvider) {
00115 std::set<ComponentDescription> components = itProvider->second->proxyProviderDescriptions();
00116 if(components.find(iComponent)!= components.end()) {
00117 boost::shared_ptr<DataProxyProvider> proxyProv =
00118 itProvider->second->proxyProvider(*(components.find(iComponent)));
00119 assert(proxyProv.get());
00120
00121 std::set<EventSetupRecordKey> records = proxyProv->usingRecords();
00122 for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
00123 itRecordEnd = records.end();
00124 itRecord != itRecordEnd;
00125 ++itRecord){
00126 const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(*itRecord);
00127 if(!keyedProxies.empty()){
00128
00129 EventSetupRecordProvider::DataToPreferredProviderMap& dataToProviderMap =
00130 iReturnValue[*itRecord];
00131
00132 for(DataProxyProvider::KeyedProxies::const_iterator itProxy = keyedProxies.begin(),
00133 itProxyEnd = keyedProxies.end();
00134 itProxy != itProxyEnd;
00135 ++itProxy) {
00136 EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
00137 dataToProviderMap.find(itProxy->first);
00138 if(itFind != dataToProviderMap.end()){
00139 throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
00140 <<itProxy->first.type().name()<<" \""<<itProxy->first.name().value()<<"\""
00141 <<"\n the providers are "
00142 <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
00143 <<"\n 2) type="<<iComponent.type_<<" label=\""<<iComponent.label_<<"\""
00144 <<"\nPlease modify configuration so only one is preferred";
00145 }
00146 dataToProviderMap.insert(std::make_pair(itProxy->first,iComponent));
00147 }
00148 }
00149 }
00150 foundProxyProvider=true;
00151 break;
00152 }
00153 }
00154 if(!foundProxyProvider) {
00155 throw cms::Exception("ESPreferNoProvider")<<"Could not make type=\""<<iComponent.type_
00156 <<"\" label=\""<<iComponent.label_<<"\" a preferred Provider."<<
00157 "\n Please check spelling of name, or that it was loaded into the job.";
00158 }
00159 }
00160 static
00161 RecordToPreferred determinePreferred(const EventSetupProvider::PreferredProviderInfo* iInfo,
00162 const Providers& iProviders)
00163 {
00164 using namespace edm::eventsetup;
00165 RecordToPreferred returnValue;
00166 if(0 != iInfo){
00167 for(EventSetupProvider::PreferredProviderInfo::const_iterator itInfo = iInfo->begin(),
00168 itInfoEnd = iInfo->end();
00169 itInfo != itInfoEnd;
00170 ++itInfo) {
00171 if(itInfo->second.empty()) {
00172
00173 preferEverything(itInfo->first, iProviders, returnValue);
00174 } else {
00175 for(EventSetupProvider::RecordToDataMap::const_iterator itRecData = itInfo->second.begin(),
00176 itRecDataEnd = itInfo->second.end();
00177 itRecData != itRecDataEnd;
00178 ++itRecData) {
00179 std::string recordName= itRecData->first;
00180 EventSetupRecordKey recordKey(eventsetup::EventSetupRecordKey::TypeTag::findType(recordName));
00181 if(recordKey.type() == eventsetup::EventSetupRecordKey::TypeTag()) {
00182 throw cms::Exception("ESPreferUnknownRecord") <<"Unknown record \""<<recordName
00183 <<"\" used in es_prefer statement for type="
00184 <<itInfo->first.type_<<" label=\""<<itInfo->first.label_
00185 <<"\"\n Please check spelling.";
00186
00187 }
00188
00189 Providers::const_iterator itRecordProvider = iProviders.find(recordKey);
00190 assert(itRecordProvider != iProviders.end());
00191
00192 std::set<ComponentDescription> components = itRecordProvider->second->proxyProviderDescriptions();
00193 std::set<ComponentDescription>::iterator itProxyProv = components.find(itInfo->first);
00194 if(itProxyProv == components.end()){
00195 throw cms::Exception("ESPreferWrongRecord")<<"The type="<<itInfo->first.type_<<" label=\""<<
00196 itInfo->first.label_<<"\" does not provide data for the Record "<<recordName;
00197 }
00198
00199 eventsetup::TypeTag datumType = eventsetup::TypeTag::findType(itRecData->second.first);
00200 if(datumType == eventsetup::TypeTag()) {
00201
00202 throw cms::Exception("ESPreferWrongDataType")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
00203 itInfo->first.label_<<"\" has the unknown data type \""<<itRecData->second.first<<"\""
00204 <<"\n Please check spelling";
00205 }
00206 eventsetup::DataKey datumKey(datumType, itRecData->second.second.c_str());
00207
00208
00209 boost::shared_ptr<DataProxyProvider> proxyProv =
00210 itRecordProvider->second->proxyProvider(*itProxyProv);
00211 const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(recordKey);
00212 if(std::find_if(keyedProxies.begin(), keyedProxies.end(),
00213 boost::bind(std::equal_to<DataKey>(), datumKey, boost::bind(&DataProxyProvider::KeyedProxies::value_type::first,_1))) ==
00214 keyedProxies.end()){
00215 throw cms::Exception("ESPreferWrongData")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
00216 itInfo->first.label_<<"\" specifies the data item \n"
00217 <<" type=\""<<itRecData->second.first<<"\" label=\""<<itRecData->second.second<<"\""
00218 <<" which is not provided. Please check spelling.";
00219 }
00220
00221 EventSetupRecordProvider::DataToPreferredProviderMap& dataToProviderMap
00222 =returnValue[recordKey];
00223
00224 if(dataToProviderMap.end() != dataToProviderMap.find(datumKey)) {
00225 EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
00226 dataToProviderMap.find(datumKey);
00227 throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
00228 <<datumKey.type().name()<<" \""<<datumKey.name().value()<<"\""
00229 <<"\n the providers are "
00230 <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
00231 <<"\n 2) type="<<itProxyProv->type_<<" label=\""<<itProxyProv->label_<<"\""
00232 <<"\nPlease modify configuration so only one is preferred";
00233 }
00234 dataToProviderMap.insert(std::make_pair(datumKey,*itProxyProv));
00235 }
00236 }
00237 }
00238 }
00239 return returnValue;
00240 }
00241
00242 void
00243 EventSetupProvider::finishConfiguration()
00244 {
00245
00246 for(std::vector<boost::shared_ptr<EventSetupRecordIntervalFinder> >::iterator itFinder=finders_->begin(),
00247 itEnd = finders_->end();
00248 itFinder != itEnd;
00249 ++itFinder) {
00250 typedef std::set<EventSetupRecordKey> Keys;
00251 const Keys recordsUsing = (*itFinder)->findingForRecords();
00252
00253 for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
00254 itKey != itKeyEnd;
00255 ++itKey) {
00256 Providers::iterator itFound = providers_.find(*itKey);
00257 if(providers_.end() == itFound) {
00258
00259 insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
00260 itFound = providers_.find(*itKey);
00261 }
00262 itFound->second->addFinder(*itFinder);
00263 }
00264 }
00265
00266 finders_.reset();
00267
00268
00269
00270 typedef std::set<EventSetupRecordKey> Keys;
00271 for(std::vector<boost::shared_ptr<DataProxyProvider> >::iterator itProvider=dataProviders_->begin(),
00272 itEnd = dataProviders_->end();
00273 itProvider != itEnd;
00274 ++itProvider) {
00275
00276 const Keys recordsUsing = (*itProvider)->usingRecords();
00277
00278 for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
00279 itKey != itKeyEnd;
00280 ++itKey) {
00281 Providers::iterator itFound = providers_.find(*itKey);
00282 if(providers_.end() == itFound) {
00283
00284 insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
00285 itFound = providers_.find(*itKey);
00286 }
00287 itFound->second->add(*itProvider);
00288 }
00289 }
00290 dataProviders_.reset();
00291
00292
00293 static const EventSetupRecordProvider::DataToPreferredProviderMap kEmptyMap;
00294
00295 RecordToPreferred recordToPreferred = determinePreferred(preferredProviderInfo_.get(),providers_);
00296
00297
00298
00299 for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
00300 itProvider != itProviderEnd;
00301 ++itProvider) {
00302 const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
00303 RecordToPreferred::const_iterator itRecordFound = recordToPreferred.find(itProvider->first);
00304 if(itRecordFound != recordToPreferred.end()) {
00305 preferredInfo = &(itRecordFound->second);
00306 }
00307
00308 itProvider->second->usePreferred(*preferredInfo);
00309
00310 std::set<EventSetupRecordKey> records = itProvider->second->dependentRecords();
00311 if(records.size() != 0) {
00312 std::string missingRecords;
00313 std::vector<boost::shared_ptr<EventSetupRecordProvider> > depProviders;
00314 depProviders.reserve(records.size());
00315 bool foundAllProviders = true;
00316 for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
00317 itRecordEnd = records.end();
00318 itRecord != itRecordEnd;
00319 ++itRecord) {
00320 Providers::iterator itFound = providers_.find(*itRecord);
00321 if(itFound == providers_.end()) {
00322 foundAllProviders = false;
00323 if(missingRecords.size() == 0) {
00324 missingRecords = itRecord->name();
00325 } else {
00326 missingRecords += ", ";
00327 missingRecords += itRecord->name();
00328 }
00329
00330 } else {
00331 depProviders.push_back(itFound->second);
00332 }
00333 }
00334
00335 if(!foundAllProviders) {
00336 edm::LogInfo("EventSetupDependency")<<"The EventSetup record "<<itProvider->second->key().name()
00337 <<" depends on at least one Record \n ("<<missingRecords<<") which is not present in the job."
00338 "\n This may lead to an exception begin thrown during event processing.\n If no exception occurs during the job than it is usually safe to ignore this message.";
00339
00340
00341
00342 }
00343
00344 itProvider->second->setDependentProviders(depProviders);
00345 }
00346 }
00347 mustFinishConfiguration_ = false;
00348
00349 }
00350 typedef std::map<EventSetupRecordKey, boost::shared_ptr<EventSetupRecordProvider> > Providers;
00351 typedef Providers::iterator Itr;
00352 static
00353 void
00354 findDependents(const EventSetupRecordKey& iKey,
00355 Itr itBegin,
00356 Itr itEnd,
00357 std::vector<boost::shared_ptr<EventSetupRecordProvider> >& oDependents)
00358 {
00359
00360 for(Itr it = itBegin; it != itEnd; ++it) {
00361
00362 const std::set<EventSetupRecordKey>& deps = it->second->dependentRecords();
00363 if(deps.end() != deps.find(iKey)) {
00364 oDependents.push_back(it->second);
00365
00366 findDependents(it->first, itBegin, itEnd, oDependents);
00367 }
00368 }
00369 }
00370
00371 void
00372 EventSetupProvider::resetRecordPlusDependentRecords(const EventSetupRecordKey& iKey)
00373 {
00374 Providers::iterator itFind = providers_.find(iKey);
00375 if(itFind == providers_.end()) {
00376 return;
00377 }
00378
00379
00380 std::vector<boost::shared_ptr<EventSetupRecordProvider> > dependents;
00381 findDependents(iKey, providers_.begin(), providers_.end(), dependents);
00382
00383 dependents.erase(std::unique(dependents.begin(),dependents.end()), dependents.end());
00384
00385 itFind->second->resetProxies();
00386 for_all(dependents,
00387 boost::bind(&EventSetupRecordProvider::resetProxies,
00388 _1));
00389 }
00390
00391 void
00392 EventSetupProvider::forceCacheClear()
00393 {
00394 for(Providers::iterator it=providers_.begin(), itEnd = providers_.end();
00395 it != itEnd;
00396 ++it) {
00397 it->second->resetProxies();
00398 }
00399 }
00400
00401
00402 void
00403 EventSetupProvider::addRecordToEventSetup(EventSetupRecord& iRecord) {
00404 iRecord.setEventSetup(&eventSetup_);
00405 eventSetup_.add(iRecord);
00406 }
00407
00408
00409
00410
00411 EventSetup const&
00412 EventSetupProvider::eventSetupForInstance(const IOVSyncValue& iValue)
00413 {
00414 eventSetup_.setIOVSyncValue(iValue);
00415
00416 eventSetup_.clear();
00417 if(mustFinishConfiguration_) {
00418 const_cast<EventSetupProvider*>(this)->finishConfiguration();
00419 }
00420
00421 for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
00422 itProvider != itProviderEnd;
00423 ++itProvider) {
00424 itProvider->second->addRecordToIfValid(*this, iValue);
00425 }
00426
00427 return eventSetup_;
00428
00429
00430 }
00431 namespace {
00432 struct InsertAll : public std::unary_function< const std::set<ComponentDescription>&, void>{
00433
00434 typedef std::set<ComponentDescription> Set;
00435 Set* container_;
00436 InsertAll(Set& iSet) : container_(&iSet) {}
00437 void operator()(const Set& iSet) {
00438 container_->insert(iSet.begin(), iSet.end());
00439 }
00440 };
00441 }
00442 std::set<ComponentDescription>
00443 EventSetupProvider::proxyProviderDescriptions() const
00444 {
00445 using boost::bind;
00446 typedef std::set<ComponentDescription> Set;
00447 Set descriptions;
00448
00449 for_all(providers_,
00450 bind(InsertAll(descriptions),
00451 bind(&EventSetupRecordProvider::proxyProviderDescriptions,
00452 bind(&Providers::value_type::second,_1))));
00453 if(dataProviders_.get()) {
00454 for(std::vector<boost::shared_ptr<DataProxyProvider> >::const_iterator it = dataProviders_->begin(),
00455 itEnd = dataProviders_->end();
00456 it != itEnd;
00457 ++it) {
00458 descriptions.insert((*it)->description());
00459 }
00460
00461 }
00462
00463 return descriptions;
00464 }
00465
00466
00467
00468
00469 }
00470 }