CMS 3D CMS Logo

EventSetupProvider.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Framework
00004 // Module:      EventSetupProvider
00005 // 
00006 // Description: <one line class summary>
00007 //
00008 // Implementation:
00009 //     <Notes on implementation>
00010 //
00011 // Author:      Chris Jones
00012 // Created:     Thu Mar 24 16:27:14 EST 2005
00013 //
00014 
00015 // system include files
00016 #include "boost/bind.hpp"
00017 #include <algorithm>
00018 
00019 // user include files
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 // constants, enums and typedefs
00032 //
00033 
00034 //
00035 // static data member definitions
00036 //
00037 
00038 //
00039 // constructors and destructor
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 {
00048 }
00049 
00050 // EventSetupProvider::EventSetupProvider(const EventSetupProvider& rhs)
00051 // {
00052 //    // do actual copying here;
00053 // }
00054 
00055 EventSetupProvider::~EventSetupProvider()
00056 {
00057 }
00058 
00059 //
00060 // assignment operators
00061 //
00062 // const EventSetupProvider& EventSetupProvider::operator=(const EventSetupProvider& rhs)
00063 // {
00064 //   //An exception safe implementation is
00065 //   EventSetupProvider temp(rhs);
00066 //   swap(rhs);
00067 //
00068 //   return *this;
00069 // }
00070 
00071 //
00072 // member functions
00073 //
00074 void 
00075 EventSetupProvider::insert(const EventSetupRecordKey& iKey, std::auto_ptr<EventSetupRecordProvider> iProvider)
00076 {
00077    boost::shared_ptr<EventSetupRecordProvider> temp(iProvider.release());
00078    providers_[iKey] = temp;
00079    //temp->addRecordTo(*this);
00080 }
00081 
00082 void 
00083 EventSetupProvider::add(boost::shared_ptr<DataProxyProvider> iProvider)
00084 {
00085    mustFinishConfiguration_ = true;
00086    assert(&(*iProvider) != 0);
00087    typedef std::set<EventSetupRecordKey> Keys;
00088    const Keys recordsUsing = iProvider->usingRecords();
00089 
00090    for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
00091        itKey != itKeyEnd;
00092        ++itKey) {
00093       Providers::iterator itFound = providers_.find(*itKey);
00094       if(providers_.end() == itFound) {
00095          //create a provider for this record
00096          insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
00097          itFound = providers_.find(*itKey);
00098       }
00099       itFound->second->add(iProvider);
00100    }
00101 }
00102 
00103 
00104 void 
00105 EventSetupProvider::add(boost::shared_ptr<EventSetupRecordIntervalFinder> iFinder)
00106 {
00107    mustFinishConfiguration_ = true;
00108    assert(&(*iFinder) != 0);
00109    finders_->push_back(iFinder);
00110 }
00111 
00112 typedef std::map<EventSetupRecordKey, boost::shared_ptr<EventSetupRecordProvider> > Providers;
00113 typedef std::map<EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap> RecordToPreferred;
00115 static
00116 void 
00117 preferEverything(const ComponentDescription& iComponent,
00118                  const Providers& iProviders,
00119                  RecordToPreferred& iReturnValue)
00120 {
00121    //need to get our hands on the actual DataProxyProvider
00122    bool foundProxyProvider = false;
00123    for(Providers::const_iterator itProvider = iProviders.begin(), itProviderEnd = iProviders.end();
00124        itProvider!= itProviderEnd;
00125        ++itProvider) {
00126       std::set<ComponentDescription> components = itProvider->second->proxyProviderDescriptions();
00127       if(components.find(iComponent)!= components.end()) {
00128          boost::shared_ptr<DataProxyProvider> proxyProv = 
00129          itProvider->second->proxyProvider(*(components.find(iComponent)));
00130          assert(proxyProv.get());
00131          
00132          std::set<EventSetupRecordKey> records = proxyProv->usingRecords();
00133          for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
00134              itRecordEnd = records.end();
00135              itRecord != itRecordEnd;
00136              ++itRecord){
00137             const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(*itRecord);
00138             if(!keyedProxies.empty()){
00139                //add them to our output
00140                EventSetupRecordProvider::DataToPreferredProviderMap& dataToProviderMap =
00141                iReturnValue[*itRecord];
00142                
00143                for(DataProxyProvider::KeyedProxies::const_iterator itProxy = keyedProxies.begin(),
00144                    itProxyEnd = keyedProxies.end();
00145                    itProxy != itProxyEnd;
00146                    ++itProxy) {
00147                   EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
00148                   dataToProviderMap.find(itProxy->first);
00149                   if(itFind != dataToProviderMap.end()){
00150                      throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
00151                      <<itProxy->first.type().name()<<" \""<<itProxy->first.name().value()<<"\""
00152                      <<"\n the providers are "
00153                      <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
00154                      <<"\n 2) type="<<iComponent.type_<<" label=\""<<iComponent.label_<<"\""
00155                      <<"\nPlease modify configuration so only one is preferred";
00156                   }
00157                   dataToProviderMap.insert(std::make_pair(itProxy->first,iComponent));
00158                }
00159             }
00160          }
00161          foundProxyProvider=true;
00162          break;
00163       }
00164    }
00165    if(!foundProxyProvider) {
00166       throw cms::Exception("ESPreferNoProvider")<<"Could not make type=\""<<iComponent.type_
00167       <<"\" label=\""<<iComponent.label_<<"\" a preferred Provider."<<
00168       "\n  Please check spelling of name, or that it was loaded into the job.";
00169    }
00170 }
00171 static
00172 RecordToPreferred determinePreferred(const EventSetupProvider::PreferredProviderInfo* iInfo, 
00173                                      const Providers& iProviders)
00174 {
00175    using namespace edm::eventsetup;
00176    RecordToPreferred returnValue;
00177    if(0 != iInfo){
00178       for(EventSetupProvider::PreferredProviderInfo::const_iterator itInfo = iInfo->begin(),
00179           itInfoEnd = iInfo->end();
00180           itInfo != itInfoEnd;
00181           ++itInfo) {
00182          if(itInfo->second.empty()) {
00183             //want everything
00184             preferEverything(itInfo->first, iProviders, returnValue);
00185          } else {
00186             for(EventSetupProvider::RecordToDataMap::const_iterator itRecData = itInfo->second.begin(),
00187                 itRecDataEnd = itInfo->second.end();
00188                 itRecData != itRecDataEnd;
00189                 ++itRecData) {
00190                std::string recordName= itRecData->first;
00191                EventSetupRecordKey recordKey(eventsetup::EventSetupRecordKey::TypeTag::findType(recordName));
00192                if(recordKey.type() == eventsetup::EventSetupRecordKey::TypeTag()) {
00193                   throw cms::Exception("ESPreferUnknownRecord") <<"Unknown record \""<<recordName
00194                   <<"\" used in es_prefer statement for type="
00195                   <<itInfo->first.type_<<" label=\""<<itInfo->first.label_
00196                   <<"\"\n Please check spelling.";
00197                   //record not found
00198                }
00199                //See if the ProxyProvider provides something for this Record
00200                Providers::const_iterator itRecordProvider = iProviders.find(recordKey);
00201                assert(itRecordProvider != iProviders.end());
00202                
00203                std::set<ComponentDescription> components = itRecordProvider->second->proxyProviderDescriptions();
00204                std::set<ComponentDescription>::iterator itProxyProv = components.find(itInfo->first);
00205                if(itProxyProv == components.end()){
00206                   throw cms::Exception("ESPreferWrongRecord")<<"The type="<<itInfo->first.type_<<" label=\""<<
00207                   itInfo->first.label_<<"\" does not provide data for the Record "<<recordName;
00208                }
00209                //Does it data type exist?
00210                eventsetup::TypeTag datumType = eventsetup::TypeTag::findType(itRecData->second.first);
00211                if(datumType == eventsetup::TypeTag()) {
00212                   //not found
00213                   throw cms::Exception("ESPreferWrongDataType")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
00214                   itInfo->first.label_<<"\" has the unknown data type \""<<itRecData->second.first<<"\""
00215                   <<"\n Please check spelling";
00216                }
00217                eventsetup::DataKey datumKey(datumType, itRecData->second.second.c_str());
00218                
00219                //Does the proxyprovider make this?
00220                boost::shared_ptr<DataProxyProvider> proxyProv = 
00221                   itRecordProvider->second->proxyProvider(*itProxyProv);
00222                const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(recordKey);
00223                if(std::find_if(keyedProxies.begin(), keyedProxies.end(), 
00224                                 boost::bind(std::equal_to<DataKey>(), datumKey, boost::bind(&DataProxyProvider::KeyedProxies::value_type::first,_1))) ==
00225                    keyedProxies.end()){
00226                   throw cms::Exception("ESPreferWrongData")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
00227                   itInfo->first.label_<<"\" specifies the data item \n"
00228                   <<"  type=\""<<itRecData->second.first<<"\" label=\""<<itRecData->second.second<<"\""
00229                   <<"  which is not provided.  Please check spelling.";
00230                }
00231                
00232                EventSetupRecordProvider::DataToPreferredProviderMap& dataToProviderMap
00233                   =returnValue[recordKey];
00234                //has another provider already been specified?
00235                if(dataToProviderMap.end() != dataToProviderMap.find(datumKey)) {
00236                   EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
00237                   dataToProviderMap.find(datumKey);
00238                   throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
00239                   <<datumKey.type().name()<<" \""<<datumKey.name().value()<<"\""
00240                   <<"\n the providers are "
00241                   <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
00242                   <<"\n 2) type="<<itProxyProv->type_<<" label=\""<<itProxyProv->label_<<"\""
00243                   <<"\nPlease modify configuration so only one is preferred";
00244                }
00245                dataToProviderMap.insert(std::make_pair(datumKey,*itProxyProv));
00246             }
00247          }
00248       }
00249    }
00250    return returnValue;
00251 }
00252 
00253 void
00254 EventSetupProvider::finishConfiguration()
00255 {
00256    //we delayed adding finders to the system till here so that everything would be loaded first
00257    for(std::vector<boost::shared_ptr<EventSetupRecordIntervalFinder> >::iterator itFinder=finders_->begin(),
00258        itEnd = finders_->end();
00259        itFinder != itEnd;
00260        ++itFinder) {
00261       typedef std::set<EventSetupRecordKey> Keys;
00262       const Keys recordsUsing = (*itFinder)->findingForRecords();
00263       
00264       for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
00265           itKey != itKeyEnd;
00266           ++itKey) {
00267          Providers::iterator itFound = providers_.find(*itKey);
00268          if(providers_.end() == itFound) {
00269             //create a provider for this record
00270             insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
00271             itFound = providers_.find(*itKey);
00272          }
00273          itFound->second->addFinder(*itFinder);
00274       }      
00275    }
00276    //we've transfered our ownership so this is no longer needed
00277    finders_.reset();
00278    
00279    
00280    //used for the case where no preferred Providers have been specified for the Record
00281    static const EventSetupRecordProvider::DataToPreferredProviderMap kEmptyMap;
00282    
00283    RecordToPreferred recordToPreferred = determinePreferred(preferredProviderInfo_.get(),providers_);
00284    //For each Provider, find all the Providers it depends on.  If a dependent Provider
00285    // can not be found pass in an empty list
00286    //CHANGE: now allow for missing Providers
00287    for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
00288         itProvider != itProviderEnd;
00289         ++itProvider) {
00290       const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
00291       RecordToPreferred::const_iterator itRecordFound = recordToPreferred.find(itProvider->first);
00292       if(itRecordFound != recordToPreferred.end()) {
00293          preferredInfo = &(itRecordFound->second);
00294       }
00295       //Give it our list of preferred 
00296       itProvider->second->usePreferred(*preferredInfo);
00297       
00298       std::set<EventSetupRecordKey> records = itProvider->second->dependentRecords();
00299       if(records.size() != 0) {
00300          std::string missingRecords;
00301          std::vector<boost::shared_ptr<EventSetupRecordProvider> > depProviders;
00302          depProviders.reserve(records.size());
00303          bool foundAllProviders = true;
00304          for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
00305               itRecordEnd = records.end();
00306               itRecord != itRecordEnd;
00307               ++itRecord) {
00308             Providers::iterator itFound = providers_.find(*itRecord);
00309             if(itFound == providers_.end()) {
00310                foundAllProviders = false;
00311                if(missingRecords.size() == 0) {
00312                  missingRecords = itRecord->name();
00313                } else {
00314                  missingRecords += ", ";
00315                  missingRecords += itRecord->name();
00316                }
00317                //break;
00318             } else {
00319                depProviders.push_back(itFound->second);
00320             }
00321          }
00322          
00323          if(!foundAllProviders) {
00324             edm::LogInfo("EventSetupDependency")<<"The EventSetup record "<<itProvider->second->key().name()
00325             <<" depends on at least one Record \n ("<<missingRecords<<") which is not present in the job."
00326            "\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.";
00327 
00328             //depProviders.clear();
00329            //NOTE: should provide a warning
00330          }
00331           
00332          itProvider->second->setDependentProviders(depProviders);
00333       }
00334    }
00335    mustFinishConfiguration_ = false;
00336    
00337 }
00338 typedef std::map<EventSetupRecordKey, boost::shared_ptr<EventSetupRecordProvider> > Providers;
00339 typedef Providers::iterator Itr;
00340 static
00341 void
00342 findDependents(const EventSetupRecordKey& iKey,
00343                Itr itBegin,
00344                Itr itEnd,
00345                std::vector<boost::shared_ptr<EventSetupRecordProvider> >& oDependents)
00346 {
00347   
00348   for(Itr it = itBegin; it != itEnd; ++it) {
00349     //does it depend on the record in question?
00350     const std::set<EventSetupRecordKey>& deps = it->second->dependentRecords();
00351     if(deps.end() != deps.find(iKey)) {
00352       oDependents.push_back(it->second);
00353       //now see who is dependent on this record since they will be indirectly dependent on iKey
00354       findDependents(it->first, itBegin, itEnd, oDependents);
00355     }
00356   }
00357 }
00358                
00359 void 
00360 EventSetupProvider::resetRecordPlusDependentRecords(const EventSetupRecordKey& iKey)
00361 {
00362   Providers::iterator itFind = providers_.find(iKey);
00363   if(itFind == providers_.end()) {
00364     return;
00365   }
00366 
00367   
00368   std::vector<boost::shared_ptr<EventSetupRecordProvider> > dependents;
00369   findDependents(iKey, providers_.begin(), providers_.end(), dependents);
00370 
00371   dependents.erase(std::unique(dependents.begin(),dependents.end()), dependents.end());
00372   
00373   itFind->second->resetProxies();
00374   for_all(dependents,
00375                 boost::bind(&EventSetupRecordProvider::resetProxies,
00376                             _1));
00377 }
00378 
00379 //
00380 // const member functions
00381 //
00382 EventSetup const&
00383 EventSetupProvider::eventSetupForInstance(const IOVSyncValue& iValue)
00384 {
00385    eventSetup_.setIOVSyncValue(iValue);
00386 
00387    eventSetup_.clear();
00388    if(mustFinishConfiguration_) {
00389       const_cast<EventSetupProvider*>(this)->finishConfiguration();
00390    }
00391 
00392    for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
00393         itProvider != itProviderEnd;
00394         ++itProvider) {
00395       itProvider->second->addRecordToIfValid(*this, iValue);
00396    }
00397    
00398    return eventSetup_;
00399 
00400    
00401 }
00402 namespace {
00403    struct InsertAll : public std::unary_function< const std::set<ComponentDescription>&, void>{
00404       
00405       typedef std::set<ComponentDescription> Set;
00406       Set* container_;
00407       InsertAll(Set& iSet) : container_(&iSet) {}
00408       void operator()(const Set& iSet) {
00409          container_->insert(iSet.begin(), iSet.end());
00410       }
00411    };
00412 }
00413 std::set<ComponentDescription> 
00414 EventSetupProvider::proxyProviderDescriptions() const
00415 {
00416    using boost::bind;
00417    typedef std::set<ComponentDescription> Set;
00418    Set descriptions;
00419 
00420    for_all(providers_,
00421                  bind(InsertAll(descriptions),
00422                       bind(&EventSetupRecordProvider::proxyProviderDescriptions,
00423                            bind(&Providers::value_type::second,_1))));
00424                        
00425    return descriptions;
00426 }
00427 
00428 //
00429 // static member functions
00430 //
00431    }
00432 }

Generated on Tue Jun 9 17:35:59 2009 for CMSSW by  doxygen 1.5.4