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