CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EventSetupProvider.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Framework
4 // Module: EventSetupProvider
5 //
6 // Description: <one line class summary>
7 //
8 // Implementation:
9 // <Notes on implementation>
10 //
11 // Author: Chris Jones
12 // Created: Thu Mar 24 16:27:14 EST 2005
13 //
14 
15 // system include files
16 #include "boost/bind.hpp"
17 #include <algorithm>
18 
19 // user include files
28 
29 namespace edm {
30  namespace eventsetup {
31 //
32 // constants, enums and typedefs
33 //
34 
35 //
36 // static data member definitions
37 //
38 
39 //
40 // constructors and destructor
41 //
43 eventSetup_(),
44 providers_(),
45 mustFinishConfiguration_(true),
46 preferredProviderInfo_((0!=iInfo) ? (new PreferredProviderInfo(*iInfo)): 0),
47 finders_(new std::vector<boost::shared_ptr<EventSetupRecordIntervalFinder> >() ),
48 dataProviders_(new std::vector<boost::shared_ptr<DataProxyProvider> >() )
49 {
50 }
51 
52 // EventSetupProvider::EventSetupProvider(const EventSetupProvider& rhs)
53 // {
54 // // do actual copying here;
55 // }
56 
58 {
59 }
60 
61 //
62 // assignment operators
63 //
64 // const EventSetupProvider& EventSetupProvider::operator=(const EventSetupProvider& rhs)
65 // {
66 // //An exception safe implementation is
67 // EventSetupProvider temp(rhs);
68 // swap(rhs);
69 //
70 // return *this;
71 // }
72 
73 //
74 // member functions
75 //
76 void
77 EventSetupProvider::insert(const EventSetupRecordKey& iKey, std::auto_ptr<EventSetupRecordProvider> iProvider)
78 {
79  boost::shared_ptr<EventSetupRecordProvider> temp(iProvider.release());
80  providers_[iKey] = temp;
81  //temp->addRecordTo(*this);
82 }
83 
84 void
85 EventSetupProvider::add(boost::shared_ptr<DataProxyProvider> iProvider)
86 {
88  assert(&(*iProvider) != 0);
89  dataProviders_->push_back(iProvider);
90 }
91 
92 
93 void
94 EventSetupProvider::add(boost::shared_ptr<EventSetupRecordIntervalFinder> iFinder)
95 {
97  assert(&(*iFinder) != 0);
98  finders_->push_back(iFinder);
99 }
100 
101 typedef std::map<EventSetupRecordKey, boost::shared_ptr<EventSetupRecordProvider> > Providers;
102 typedef std::map<EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap> RecordToPreferred;
104 static
105 void
107  const Providers& iProviders,
108  RecordToPreferred& iReturnValue)
109 {
110  //need to get our hands on the actual DataProxyProvider
111  bool foundProxyProvider = false;
112  for(Providers::const_iterator itProvider = iProviders.begin(), itProviderEnd = iProviders.end();
113  itProvider!= itProviderEnd;
114  ++itProvider) {
115  std::set<ComponentDescription> components = itProvider->second->proxyProviderDescriptions();
116  if(components.find(iComponent)!= components.end()) {
117  boost::shared_ptr<DataProxyProvider> proxyProv =
118  itProvider->second->proxyProvider(*(components.find(iComponent)));
119  assert(proxyProv.get());
120 
121  std::set<EventSetupRecordKey> records = proxyProv->usingRecords();
122  for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
123  itRecordEnd = records.end();
124  itRecord != itRecordEnd;
125  ++itRecord){
126  const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(*itRecord);
127  if(!keyedProxies.empty()){
128  //add them to our output
130  iReturnValue[*itRecord];
131 
132  for(DataProxyProvider::KeyedProxies::const_iterator itProxy = keyedProxies.begin(),
133  itProxyEnd = keyedProxies.end();
134  itProxy != itProxyEnd;
135  ++itProxy) {
136  EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
137  dataToProviderMap.find(itProxy->first);
138  if(itFind != dataToProviderMap.end()){
139  throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
140  <<itProxy->first.type().name()<<" \""<<itProxy->first.name().value()<<"\""
141  <<"\n the providers are "
142  <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
143  <<"\n 2) type="<<iComponent.type_<<" label=\""<<iComponent.label_<<"\""
144  <<"\nPlease modify configuration so only one is preferred";
145  }
146  dataToProviderMap.insert(std::make_pair(itProxy->first,iComponent));
147  }
148  }
149  }
150  foundProxyProvider=true;
151  break;
152  }
153  }
154  if(!foundProxyProvider) {
155  throw cms::Exception("ESPreferNoProvider")<<"Could not make type=\""<<iComponent.type_
156  <<"\" label=\""<<iComponent.label_<<"\" a preferred Provider."<<
157  "\n Please check spelling of name, or that it was loaded into the job.";
158  }
159 }
160 static
162  const Providers& iProviders)
163 {
164  using namespace edm::eventsetup;
165  RecordToPreferred returnValue;
166  if(0 != iInfo){
167  for(EventSetupProvider::PreferredProviderInfo::const_iterator itInfo = iInfo->begin(),
168  itInfoEnd = iInfo->end();
169  itInfo != itInfoEnd;
170  ++itInfo) {
171  if(itInfo->second.empty()) {
172  //want everything
173  preferEverything(itInfo->first, iProviders, returnValue);
174  } else {
175  for(EventSetupProvider::RecordToDataMap::const_iterator itRecData = itInfo->second.begin(),
176  itRecDataEnd = itInfo->second.end();
177  itRecData != itRecDataEnd;
178  ++itRecData) {
179  std::string recordName= itRecData->first;
181  if(recordKey.type() == eventsetup::EventSetupRecordKey::TypeTag()) {
182  throw cms::Exception("ESPreferUnknownRecord") <<"Unknown record \""<<recordName
183  <<"\" used in es_prefer statement for type="
184  <<itInfo->first.type_<<" label=\""<<itInfo->first.label_
185  <<"\"\n Please check spelling.";
186  //record not found
187  }
188  //See if the ProxyProvider provides something for this Record
189  Providers::const_iterator itRecordProvider = iProviders.find(recordKey);
190  assert(itRecordProvider != iProviders.end());
191 
192  std::set<ComponentDescription> components = itRecordProvider->second->proxyProviderDescriptions();
193  std::set<ComponentDescription>::iterator itProxyProv = components.find(itInfo->first);
194  if(itProxyProv == components.end()){
195  throw cms::Exception("ESPreferWrongRecord")<<"The type="<<itInfo->first.type_<<" label=\""<<
196  itInfo->first.label_<<"\" does not provide data for the Record "<<recordName;
197  }
198  //Does it data type exist?
199  eventsetup::TypeTag datumType = eventsetup::TypeTag::findType(itRecData->second.first);
200  if(datumType == eventsetup::TypeTag()) {
201  //not found
202  throw cms::Exception("ESPreferWrongDataType")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
203  itInfo->first.label_<<"\" has the unknown data type \""<<itRecData->second.first<<"\""
204  <<"\n Please check spelling";
205  }
206  eventsetup::DataKey datumKey(datumType, itRecData->second.second.c_str());
207 
208  //Does the proxyprovider make this?
209  boost::shared_ptr<DataProxyProvider> proxyProv =
210  itRecordProvider->second->proxyProvider(*itProxyProv);
211  const DataProxyProvider::KeyedProxies& keyedProxies = proxyProv->keyedProxies(recordKey);
212  if(std::find_if(keyedProxies.begin(), keyedProxies.end(),
213  boost::bind(std::equal_to<DataKey>(), datumKey, boost::bind(&DataProxyProvider::KeyedProxies::value_type::first,_1))) ==
214  keyedProxies.end()){
215  throw cms::Exception("ESPreferWrongData")<<"The es_prefer statement for type="<<itInfo->first.type_<<" label=\""<<
216  itInfo->first.label_<<"\" specifies the data item \n"
217  <<" type=\""<<itRecData->second.first<<"\" label=\""<<itRecData->second.second<<"\""
218  <<" which is not provided. Please check spelling.";
219  }
220 
222  =returnValue[recordKey];
223  //has another provider already been specified?
224  if(dataToProviderMap.end() != dataToProviderMap.find(datumKey)) {
225  EventSetupRecordProvider::DataToPreferredProviderMap::iterator itFind =
226  dataToProviderMap.find(datumKey);
227  throw cms::Exception("ESPreferConflict") <<"Two providers have been set to be preferred for\n"
228  <<datumKey.type().name()<<" \""<<datumKey.name().value()<<"\""
229  <<"\n the providers are "
230  <<"\n 1) type="<<itFind->second.type_<<" label=\""<<itFind->second.label_<<"\""
231  <<"\n 2) type="<<itProxyProv->type_<<" label=\""<<itProxyProv->label_<<"\""
232  <<"\nPlease modify configuration so only one is preferred";
233  }
234  dataToProviderMap.insert(std::make_pair(datumKey,*itProxyProv));
235  }
236  }
237  }
238  }
239  return returnValue;
240 }
241 
242 void
244 {
245  //we delayed adding finders to the system till here so that everything would be loaded first
246  for(std::vector<boost::shared_ptr<EventSetupRecordIntervalFinder> >::iterator itFinder=finders_->begin(),
247  itEnd = finders_->end();
248  itFinder != itEnd;
249  ++itFinder) {
250  typedef std::set<EventSetupRecordKey> Keys;
251  const Keys recordsUsing = (*itFinder)->findingForRecords();
252 
253  for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
254  itKey != itKeyEnd;
255  ++itKey) {
256  Providers::iterator itFound = providers_.find(*itKey);
257  if(providers_.end() == itFound) {
258  //create a provider for this record
259  insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
260  itFound = providers_.find(*itKey);
261  }
262  itFound->second->addFinder(*itFinder);
263  }
264  }
265  //we've transfered our ownership so this is no longer needed
266  finders_.reset();
267 
268  //Now handle providers since sources can also be finders and the sources can delay registering
269  // their Records and therefore could delay setting up their Proxies
270  typedef std::set<EventSetupRecordKey> Keys;
271  for(std::vector<boost::shared_ptr<DataProxyProvider> >::iterator itProvider=dataProviders_->begin(),
272  itEnd = dataProviders_->end();
273  itProvider != itEnd;
274  ++itProvider) {
275 
276  const Keys recordsUsing = (*itProvider)->usingRecords();
277 
278  for(Keys::const_iterator itKey = recordsUsing.begin(), itKeyEnd = recordsUsing.end();
279  itKey != itKeyEnd;
280  ++itKey) {
281  Providers::iterator itFound = providers_.find(*itKey);
282  if(providers_.end() == itFound) {
283  //create a provider for this record
284  insert(*itKey, EventSetupRecordProviderFactoryManager::instance().makeRecordProvider(*itKey));
285  itFound = providers_.find(*itKey);
286  }
287  itFound->second->add(*itProvider);
288  }
289  }
290  dataProviders_.reset();
291 
292  //used for the case where no preferred Providers have been specified for the Record
294 
296  //For each Provider, find all the Providers it depends on. If a dependent Provider
297  // can not be found pass in an empty list
298  //CHANGE: now allow for missing Providers
299  for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
300  itProvider != itProviderEnd;
301  ++itProvider) {
302  const EventSetupRecordProvider::DataToPreferredProviderMap* preferredInfo = &kEmptyMap;
303  RecordToPreferred::const_iterator itRecordFound = recordToPreferred.find(itProvider->first);
304  if(itRecordFound != recordToPreferred.end()) {
305  preferredInfo = &(itRecordFound->second);
306  }
307  //Give it our list of preferred
308  itProvider->second->usePreferred(*preferredInfo);
309 
310  std::set<EventSetupRecordKey> records = itProvider->second->dependentRecords();
311  if(records.size() != 0) {
312  std::string missingRecords;
313  std::vector<boost::shared_ptr<EventSetupRecordProvider> > depProviders;
314  depProviders.reserve(records.size());
315  bool foundAllProviders = true;
316  for(std::set<EventSetupRecordKey>::iterator itRecord = records.begin(),
317  itRecordEnd = records.end();
318  itRecord != itRecordEnd;
319  ++itRecord) {
320  Providers::iterator itFound = providers_.find(*itRecord);
321  if(itFound == providers_.end()) {
322  foundAllProviders = false;
323  if(missingRecords.size() == 0) {
324  missingRecords = itRecord->name();
325  } else {
326  missingRecords += ", ";
327  missingRecords += itRecord->name();
328  }
329  //break;
330  } else {
331  depProviders.push_back(itFound->second);
332  }
333  }
334 
335  if(!foundAllProviders) {
336  edm::LogInfo("EventSetupDependency")<<"The EventSetup record "<<itProvider->second->key().name()
337  <<" depends on at least one Record \n ("<<missingRecords<<") which is not present in the job."
338  "\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.";
339 
340  //depProviders.clear();
341  //NOTE: should provide a warning
342  }
343 
344  itProvider->second->setDependentProviders(depProviders);
345  }
346  }
347  mustFinishConfiguration_ = false;
348 
349 }
350 typedef std::map<EventSetupRecordKey, boost::shared_ptr<EventSetupRecordProvider> > Providers;
351 typedef Providers::iterator Itr;
352 static
353 void
355  Itr itBegin,
356  Itr itEnd,
357  std::vector<boost::shared_ptr<EventSetupRecordProvider> >& oDependents)
358 {
359 
360  for(Itr it = itBegin; it != itEnd; ++it) {
361  //does it depend on the record in question?
362  const std::set<EventSetupRecordKey>& deps = it->second->dependentRecords();
363  if(deps.end() != deps.find(iKey)) {
364  oDependents.push_back(it->second);
365  //now see who is dependent on this record since they will be indirectly dependent on iKey
366  findDependents(it->first, itBegin, itEnd, oDependents);
367  }
368  }
369 }
370 
371 void
373 {
374  Providers::iterator itFind = providers_.find(iKey);
375  if(itFind == providers_.end()) {
376  return;
377  }
378 
379 
380  std::vector<boost::shared_ptr<EventSetupRecordProvider> > dependents;
381  findDependents(iKey, providers_.begin(), providers_.end(), dependents);
382 
383  dependents.erase(std::unique(dependents.begin(),dependents.end()), dependents.end());
384 
385  itFind->second->resetProxies();
386  for_all(dependents,
388  _1));
389 }
390 
391 void
393 {
394  for(Providers::iterator it=providers_.begin(), itEnd = providers_.end();
395  it != itEnd;
396  ++it) {
397  it->second->resetProxies();
398  }
399 }
400 
401 
402 void
404  iRecord.setEventSetup(&eventSetup_);
405  eventSetup_.add(iRecord);
406 }
407 
408 //
409 // const member functions
410 //
411 EventSetup const&
413 {
415 
416  eventSetup_.clear();
418  const_cast<EventSetupProvider*>(this)->finishConfiguration();
419  }
420 
421  for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
422  itProvider != itProviderEnd;
423  ++itProvider) {
424  itProvider->second->addRecordToIfValid(*this, iValue);
425  }
426 
427  return eventSetup_;
428 
429 
430 }
431 namespace {
432  struct InsertAll : public std::unary_function< const std::set<ComponentDescription>&, void>{
433 
434  typedef std::set<ComponentDescription> Set;
436  InsertAll(Set& iSet) : container_(&iSet) {}
437  void operator()(const Set& iSet) {
438  container_->insert(iSet.begin(), iSet.end());
439  }
440  };
441 }
442 std::set<ComponentDescription>
444 {
445  using boost::bind;
446  typedef std::set<ComponentDescription> Set;
447  Set descriptions;
448 
450  bind(InsertAll(descriptions),
452  bind(&Providers::value_type::second,_1))));
453  if(dataProviders_.get()) {
454  for(std::vector<boost::shared_ptr<DataProxyProvider> >::const_iterator it = dataProviders_->begin(),
455  itEnd = dataProviders_->end();
456  it != itEnd;
457  ++it) {
458  descriptions.insert((*it)->description());
459  }
460 
461  }
462 
463  return descriptions;
464 }
465 
466 //
467 // static member functions
468 //
469  }
470 }
EventSetup const & eventSetupForInstance(IOVSyncValue const &)
std::map< DataKey, ComponentDescription > DataToPreferredProviderMap
std::auto_ptr< PreferredProviderInfo > preferredProviderInfo_
EventSetupProvider(PreferredProviderInfo const *iInfo=0)
std::auto_ptr< std::vector< boost::shared_ptr< EventSetupRecordIntervalFinder > > > finders_
void forceCacheClear()
Used when testing that all code properly updates on IOV changes of all Records.
std::map< EventSetupRecordKey, boost::shared_ptr< EventSetupRecordProvider > > Providers
void resetRecordPlusDependentRecords(EventSetupRecordKey const &)
Used when we need to force a Record to reset all its proxies.
void insert(std::auto_ptr< T > iRecordProvider)
std::map< EventSetupRecordKey, EventSetupRecordProvider::DataToPreferredProviderMap > RecordToPreferred
void addRecordToEventSetup(EventSetupRecord &iRecord)
std::auto_ptr< std::vector< boost::shared_ptr< DataProxyProvider > > > dataProviders_
std::map< ComponentDescription, RecordToDataMap > PreferredProviderInfo
void add(boost::shared_ptr< DataProxyProvider >)
Func for_all(ForwardSequence &s, Func f)
wrapper for std::for_each
Definition: Algorithms.h:16
U second(std::pair< T, U > const &p)
std::vector< std::pair< DataKey, boost::shared_ptr< DataProxy > > > KeyedProxies
static void findDependents(const EventSetupRecordKey &iKey, Itr itBegin, Itr itEnd, std::vector< boost::shared_ptr< EventSetupRecordProvider > > &oDependents)
bool first
Definition: L1TdeRCT.cc:94
static RecordToPreferred determinePreferred(const EventSetupProvider::PreferredProviderInfo *iInfo, const Providers &iProviders)
static void preferEverything(const ComponentDescription &iComponent, const Providers &iProviders, RecordToPreferred &iReturnValue)
find everything made by a DataProxyProvider and add it to the &#39;preferred&#39; list
std::vector< size_type > Keys
void add(const eventsetup::EventSetupRecord &iRecord)
Definition: EventSetup.cc:81
heterocontainer::HCTypeTag TypeTag
std::set< ComponentDescription > proxyProviderDescriptions() const
return information on which DataProxyProviders are supplying information
void setIOVSyncValue(const IOVSyncValue &)
Definition: EventSetup.cc:62
void setEventSetup(EventSetup const *iEventSetup)
std::set< ComponentDescription > proxyProviderDescriptions() const
void resetProxies()
This will clear the cache&#39;s of all the Proxies so that next time they are called they will run...
Set * container_
Providers::iterator Itr
static HCTypeTag findType(char const *iTypeName)
find a type based on the types name, if not found will return default HCTypeTag
Definition: HCTypeTag.cc:129