CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DependentRecordIntervalFinder.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Framework
4 // Class : DependentRecordIntervalFinder
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Author: Chris Jones
10 // Created: Sat Apr 30 19:37:22 EDT 2005
11 // $Id: DependentRecordIntervalFinder.cc,v 1.13 2010/12/17 19:33:53 chrjones Exp $
12 //
13 
14 // system include files
15 
16 // user include files
19 
20 //
21 // constants, enums and typedefs
22 //
23 namespace edm {
24  namespace eventsetup {
25 //
26 // static data member definitions
27 //
28 
29 //
30 // constructors and destructor
31 //
33  providers_()
34 {
36 }
37 
38 // DependentRecordIntervalFinder::DependentRecordIntervalFinder(const DependentRecordIntervalFinder& rhs)
39 // {
40 // // do actual copying here;
41 // }
42 
44 {
45 }
46 
47 //
48 // assignment operators
49 //
50 // const DependentRecordIntervalFinder& DependentRecordIntervalFinder::operator=(const DependentRecordIntervalFinder& rhs)
51 // {
52 // //An exception safe implementation is
53 // DependentRecordIntervalFinder temp(rhs);
54 // swap(rhs);
55 //
56 // return *this;
57 // }
58 
59 //
60 // member functions
61 //
62 void
63 DependentRecordIntervalFinder::addProviderWeAreDependentOn(boost::shared_ptr<EventSetupRecordProvider> iProvider)
64 {
65  providers_.push_back(iProvider);
66 }
67 
68 void
69 DependentRecordIntervalFinder::setAlternateFinder(boost::shared_ptr<EventSetupRecordIntervalFinder> iOther)
70 {
71  alternate_ = iOther;
72 }
73 
74 void
76  const IOVSyncValue& iTime,
77  ValidityInterval& oInterval)
78 {
79  //NOTE: oInterval is the last value that was used so if nothing changed do not modify oInterval
80 
81  //I am assuming that an invalidTime is always less then the first valid time
83  if(providers_.size() == 0 && alternate_.get() == 0 ) {
85  return;
86  }
87  bool haveAValidDependentRecord = false;
88  bool allRecordsValid = true;
90 
91  if (alternate_.get() != 0) {
92  ValidityInterval test = alternate_->findIntervalFor(iKey, iTime);
93  if ( test != ValidityInterval::invalidInterval() ) {
94  haveAValidDependentRecord =true;
95  newInterval = test;
96  }
97  }
98  bool intervalsWereComparible = true;
99  for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
100  itProvider != itProviderEnd;
101  ++itProvider) {
102  if((*itProvider)->setValidityIntervalFor(iTime)) {
103  haveAValidDependentRecord=true;
104  ValidityInterval providerInterval = (*itProvider)->validityInterval();
105  if( (!newInterval.first().comparable(providerInterval.first())) ||
106  (!newInterval.last().comparable(providerInterval.last()))) {
107  intervalsWereComparible=false;
108  break;
109  }
110  if(newInterval.first() < providerInterval.first()) {
111  newInterval.setFirst(providerInterval.first());
112  }
113  if(newInterval.last() > providerInterval.last()) {
114  newInterval.setLast(providerInterval.last());
115  }
116  } else {
117  allRecordsValid = false;
118  }
119  }
120  if(intervalsWereComparible) {
121  if(!haveAValidDependentRecord) {
122  //If no Finder has no valid time, then this record is also invalid for this time
123  newInterval = ValidityInterval::invalidInterval();
124  }
125  if(!allRecordsValid) {
126  //since some of the dependent providers do not have a valid IOV for this syncvalue
127  // we do not know what the true end IOV is. Therefore we must make it open ended
128  // so that we can check each time to see if those providers become valid.
130  }
131  oInterval = newInterval;
132  return;
133  }
134  //handle the case where some providers use time and others use run/lumi/event
135  // in this case all we can do is find an IOV which changed since last time
136  // and use its start time to do the synching and use an 'invalid' end time
137  // so the system always checks back to see if something has changed
138  if (previousIOVs_.empty()) {
139  std::vector<ValidityInterval> tmp(providers_.size(),ValidityInterval());
140  previousIOVs_.swap(tmp);
141  }
142 
143  //I'm using an heuristic to pick a reasonable starting point for the IOV. The idea is to
144  // assume that lumi sections are 23 seconds long and therefore if we take a difference between
145  // iTime and the beginning of a changed IOV we can pick the changed IOV with the start time
146  // closest to iTime. This doesn't have to be perfect, we just want to reduce the dependency
147  // on provider order to make the jobs more deterministic
148 
149  bool hadChangedIOV = false;
150  //both start at the smallest value
151  EventID closestID;
152  Timestamp closestTimeStamp(0);
153  std::vector<ValidityInterval>::iterator itIOVs = previousIOVs_.begin();
154  for(Providers::iterator itProvider = providers_.begin(), itProviderEnd = providers_.end();
155  itProvider != itProviderEnd;
156  ++itProvider, ++itIOVs) {
157  if((*itProvider)->setValidityIntervalFor(iTime)) {
158  ValidityInterval providerInterval = (*itProvider)->validityInterval();
159  if(*itIOVs != providerInterval) {
160  hadChangedIOV = true;
161  if(providerInterval.first().time().value() == 0) {
162  //this is a run/lumi based one
163  if( closestID < providerInterval.first().eventID()) {
164  closestID = providerInterval.first().eventID();
165  }
166  } else {
167  if(closestTimeStamp < providerInterval.first().time()) {
168  closestTimeStamp = providerInterval.first().time();
169  }
170  }
171  *itIOVs = providerInterval;
172  }
173  }
174  }
175  if(hadChangedIOV) {
176  if(closestID.run() !=0) {
177  if(closestTimeStamp.value() == 0) {
178  //no time
180  } else {
181  if(closestID.run() == iTime.eventID().run()) {
182  //can compare time to lumi
183  const unsigned long long kLumiTimeLength = 23;
184 
185  if( (iTime.eventID().luminosityBlock() - closestID.luminosityBlock())*kLumiTimeLength <
186  iTime.time().unixTime() - closestTimeStamp.unixTime() ) {
187  //closestID was closer
189  } else {
190  oInterval = ValidityInterval(IOVSyncValue(closestTimeStamp), IOVSyncValue::invalidIOVSyncValue());
191  }
192  } else {
193  //since we don't know how to change run # into time we can't compare
194  // so if we have a time just use it
195  oInterval = ValidityInterval(IOVSyncValue(closestTimeStamp), IOVSyncValue::invalidIOVSyncValue());
196  }
197  }
198  } else {
199  oInterval = ValidityInterval( IOVSyncValue(closestTimeStamp), IOVSyncValue::invalidIOVSyncValue());
200  }
201  }
202 }
203 
204 //
205 // const member functions
206 //
207 
208 //
209 // static member functions
210 //
211  }
212 }
RunNumber_t run() const
Definition: EventID.h:42
void setFirst(const IOVSyncValue &iTime)
const EventID & eventID() const
Definition: IOVSyncValue.h:42
static const IOVSyncValue & endOfTime()
Definition: IOVSyncValue.cc:97
std::pair< Time_t, Time_t > ValidityInterval
Definition: Time.h:19
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:43
const IOVSyncValue & last() const
static const IOVSyncValue & beginOfTime()
boost::shared_ptr< EventSetupRecordIntervalFinder > alternate_
unsigned int unixTime() const
Time in seconds since January 1, 1970.
Definition: Timestamp.h:39
void setLast(const IOVSyncValue &iTime)
void addProviderWeAreDependentOn(boost::shared_ptr< EventSetupRecordProvider >)
TimeValue_t value() const
Definition: Timestamp.cc:72
virtual void setIntervalFor(const EventSetupRecordKey &, const IOVSyncValue &, ValidityInterval &)
void setAlternateFinder(boost::shared_ptr< EventSetupRecordIntervalFinder >)
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
static const ValidityInterval & invalidInterval()
const Timestamp & time() const
Definition: IOVSyncValue.h:44
const IOVSyncValue & first() const
bool comparable(const IOVSyncValue &iOther) const
Definition: IOVSyncValue.h:69
void findingRecordWithKey(const eventsetup::EventSetupRecordKey &)
static const IOVSyncValue & invalidIOVSyncValue()
Definition: IOVSyncValue.cc:92