def createRegular(cls, start, end, deltaString): """ The last element in the vector will be <= end; i.e. if the question of whether the range is closed in the upper end depends on the commensurability of the [start,end] interval and the delta: createRegular(0 , 10 , delta=3) => [0,3,6,9] createRegular(0 , 10 , delta=2) => [0,2,4,6,8,10] """ start = CTime(start) end = CTime(end) if start > end: raise ValueError("The time interval is invalid start is after end") (num, timeUnit) = cls.parseTimeUnit(deltaString) timeVector = TimeVector() currentTime = start while currentTime <= end: ct = CTime(currentTime) timeVector.append(ct) currentTime = timeVector.nextTime(num, timeUnit) return timeVector
def iget_date(self, time_index): """ Returns the simulation date for element nr @time_index. """ long_time = self._iget_sim_time(time_index) ct = CTime(long_time) return ct.datetime()
def test_range(self): d1 = date(2000, 1, 1) dt1 = datetime(2000, 1, 1, 0, 0, 0) c1 = CTime(d1) d0 = date(1999, 1, 1) dt0 = datetime(1999, 1, 1, 0, 0, 0) c0 = CTime(d0) d2 = date(2001, 1, 1) dt2 = datetime(2001, 1, 1, 0, 0, 0) c2 = CTime(d2) self.assertTrue(d0 <= c1 < dt2) self.assertTrue(c0 <= c1 < d2) self.assertTrue(dt0 <= c1 < c2) self.assertFalse(d1 <= c0 < dt2) self.assertFalse(c1 <= c0 < d2) self.assertFalse(dt1 <= c0 < c2) self.assertTrue(d0 <= c0 < dt2) self.assertTrue(c0 <= c0 < d2) self.assertTrue(dt0 <= c0 < c2) self.assertFalse(d0 <= c2 < dt2) self.assertFalse(c0 <= c2 < d2) self.assertFalse(dt0 <= c2 < c2) self.assertTrue(d0 <= c2 <= dt2) self.assertTrue(c0 <= c2 <= d2) self.assertTrue(dt0 <= c2 <= c2)
def iget_restart_sim_time(self, index): """ Will locate restart block nr @index and return the true time as a datetime instance. """ ct = CTime(self._iget_restart_time(index)) return ct.datetime()
def test_creation(self): t0 = CTime(0) t2 = CTime(datetime(1970, 1, 1)) self.assertEqual(t0, t2) t3 = CTime(date(1970, 1, 1)) self.assertEqual(t0, t3) with self.assertRaises(NotImplementedError): CTime("string")
def __init__(self, default_value=None, initial_size=0): if default_value is None: super(TimeVector, self).__init__(CTime(0), initial_size) else: try: default = CTime(default_value) except: raise ValueError( "default value invalid - must be type ctime() or date/datetime" ) super(TimeVector, self).__init__(default, initial_size)
def test_math(self): c1 = CTime(date(2000, 1, 1)) c2 = CTime(date(2000, 1, 1)) c3 = CTime(date(2000, 1, 1)) c3 += c1 self.assertTrue(isinstance(c3, CTime)) c4 = c1 * 1.0 self.assertTrue(isinstance(c4, CTime)) self.assertTrue(isinstance(c1 + c2, CTime)) self.assertEqual((c1 + c2) * 0.5, date(2000, 1, 1))
def test_c_time(self): delta = 0 c_time = CTime(0) py_time = datetime(1970, 1, 1) self.assertEqual(str(c_time), py_time.strftime("%Y-%m-%d %H:%M:%S%z")) date_time = CTime(py_time) self.assertEqual(c_time, date_time) date_time_after = CTime(datetime(1970, 1, 1, 1, 0, 5)) self.assertTrue(date_time_after > date_time)
def get_start_time(self): """ A Python datetime instance with the start time. See start_date() for further details. """ return CTime(self._get_start_date()).datetime()
def get_interp(self, key, days=None, date=None): """ Will lookup vector @key at time given by @days or @date. Requiers exactly one input argument @days or @date; will raise exception ValueError if this is not satisfied. The method will check that the time argument is within the time limits of the simulation; if else the method will raise exception ValueError. Also available as method get_interp() on the EclSumVector class. """ self.assertKeyValid(key) if days is None and date is None: raise ValueError("Must supply either days or date") if days is None: t = CTime(date) if self.check_sim_time(t): return self._get_general_var_from_sim_time(t, key) else: raise ValueError( "date:%s is outside range of simulation data" % date) elif date is None: if self._check_sim_days(days): return self._get_general_var_from_sim_days(days, key) else: raise ValueError( "days:%s is outside range of simulation: [%g,%g]" % (days, self.first_day, self.sim_length)) else: raise ValueError("Must supply either days or date")
def assert_ecl_config(self, ecl_config, config_data, working_dir): self.assert_same_config_file( config_data["DATA_FILE"], ecl_config.getDataFile(), working_dir ) self.assertEqual( CTime(config_data["START"]), ecl_config.getStartDate() ) self.assertEqual( config_data["ECLBASE"], ecl_config.getEclBase() ) for extension in ["SMSPEC", "UNSMRY"]: self.assert_same_config_file( config_data["REFCASE"] + "." + extension, ecl_config.getRefcaseName() + "." + extension, working_dir ) self.assert_same_config_file( config_data["GRID"], ecl_config.get_gridfile(), working_dir )
def check_sim_time(self, date): """ Will check if the input date is in the time span [sim_start, sim_end]. """ if not isinstance(date, CTime): date = CTime(date) return self._check_sim_time(date)
def dump_csv_line(self, time, keywords, pfile): """ Will dump a csv formatted line of the keywords in @keywords, evaluated at the intertpolated time @time. @pfile should point to an open Python file handle. """ cfile = CFILE(pfile) ctime = CTime(time) EclSum._dump_csv_line(self, ctime, keywords, cfile)
def update(self, index, time): if self._try_update(index, CTime(time)): return True else: if self.isStrict(): raise Exception("Tried to update with inconsistent value") else: return False
def get_headers(self): """ Returns a list of two tuples (well_name , date) for the whole file. """ header_list = [] for i in (range(self._get_size( None , CTime(-1)))): rft = self.iget( i ) header_list.append( (rft.getWellName() , rft.getDate()) ) return header_list
def get_data_start_time(self): """The first date we have data for. Thiw will mostly be equal to getStartTime(), but in the case of restarts, where the case we have restarted from is not found, this time will be later than the true start of the field. """ return CTime(self._get_data_start()).datetime()
def blocked_production(self, totalKey, timeRange): node = self.smspec_node(totalKey) if node.isTotal(): total = DoubleVector() for t in timeRange: if t < CTime(self.start_time): total.append(0) elif t >= CTime(self.end_time): total.append(self.get_last_value(totalKey)) else: total.append(self.get_interp(totalKey, date=t)) tmp = total << 1 total.pop() return tmp - total else: raise TypeError( "The blockedProduction method must be called with one of the TOTAL keys like e.g. FOPT or GWIT" )
def __init__(self, filename, start_time): if os.path.isfile(filename): c_ptr = self._parse(filename, CTime(start_time)) super(SchedFile, self).__init__(c_ptr) if not c_ptr: err_msg = 'start_time = "%s", filename = "%s"' % ( str(start_time), str(filename)) raise ValueError('Unable to construct SchedFile with %s.' % err_msg) else: raise IOError('No such file "%s"' % filename)
def has_sim_time(self, dtime): """ Checks if the current EclFile has data for time @dtime. The implementation goes through all the INTEHEAD headers in the EclFile, i.e. it can be fooled (and probably crash and burn) if the EclFile instance in question is has INTEHEAD keyword(s), but is still not a restart file. The @dtime argument should be a normal python datetime instance. """ return self._has_sim_time(CTime(dtime))
def start_date(self): """ A Python date instance with the start date. The start time is taken from the SMSPEC file, and in case not all timesteps have been loaded, e.g. for a restarted case, the returned start_date might be different from the datetime of the first (loaded) timestep. """ ct = self._get_start_date() return CTime(ct).date()
def get(self , well_name , date ): """ Will look up the RFT object corresponding to @well and @date. Raise Exception if not found. """ if self.size( well = well_name , date = date) == 0: raise KeyError("No RFT for well:%s at %s" % (well_name , date)) rft = self._get_rft( well_name , CTime( date )) rft.setParent( self ) return rft
def lookupTime(self, time, tolerance_seconds_before=0, tolerance_seconds_after=0): """Will look up the report step corresponding to input @time. If the tolerance arguments tolerance_seconds_before and tolerance_seconds_after have the default value zero we require an exact match between input time argument and the content of the time map. If the tolerance arguments are supplied the function will search through the time_map for the report step closest to the time argument, which satisfies the tolerance criteria. With the call: lookupTime( datetime.date(2010,1,10) , 3600*24 , 3600*7) We will find the report step in the date interval 2010,1,9 - 2010,1,17 which is closest to 2010,1,10. The tolerance limits are inclusive. If no report step satisfying the criteria is found a ValueError exception will be raised. """ if tolerance_seconds_before == 0 and tolerance_seconds_after == 0: index = self._lookup_time(CTime(time)) else: index = self._lookup_time_with_tolerance(CTime(time), tolerance_seconds_before, tolerance_seconds_after) if index >= 0: return index else: raise ValueError( "The time:%s was not found in the time_map instance" % time)
def size(self, well=None, date=None): """ The number of elements in EclRFTFile container. By default the size() method will return the total number of RFTs/PLTs in the container, but by specifying the optional arguments date and/or well the function will only count the number of well measurements matching that time or well name. The well argument can contain wildcards. rftFile = ecl.EclRFTFile( "ECLIPSE.RFT" ) print "Total number of RFTs : %d" % rftFile.size( ) print "RFTs matching OP* : %d" % rftFile.size( well = "OP*" ) print "RFTs at 01/01/2010 : %d" % rftFile.size( date = datetime.date( 2010 , 1 , 1 )) """ if date: cdate = CTime( date ) else: cdate = CTime( -1 ) return self._get_size( well , cdate)
def test_time_vector(self): time_vector = TimeVector() time1 = CTime(datetime.datetime(2013, 8, 13, 0, 0, 0)) time2 = CTime(datetime.datetime(2013, 8, 13, 1, 0, 0)) time_vector.setDefault(time2) time_vector.append(time1) time_vector[2] = time2 self.assertEqual(time_vector[0], time1) self.assertEqual(time_vector[1], time2) self.assertEqual(time_vector[2], time2) tv1 = TimeVector(default_value=datetime.date(2000, 1, 1), initial_size=2) self.assertEqual(tv1[0], datetime.date(2000, 1, 1)) tv2 = TimeVector() tv2.append(time2) print(tv2)
def test_resample(self): time_points = TimeVector() start_time = self.ecl_sum.get_data_start_time() end_time = self.ecl_sum.get_end_time() delta = end_time - start_time N = 25 time_points.initRange( CTime(start_time), CTime(end_time), CTime(int(delta.total_seconds()/(N - 1)))) time_points.append(CTime(end_time)) resampled = self.ecl_sum.resample( "OUTPUT_CASE", time_points ) for key in self.ecl_sum.keys(): self.assertIn( key, resampled ) self.assertEqual(self.ecl_sum.get_data_start_time(), resampled.get_data_start_time()) delta = self.ecl_sum.get_end_time() - resampled.get_end_time() self.assertTrue( delta.total_seconds() <= 1 ) keys = ["FOPT", "FOPR", "BPR:15,28,1", "WGOR:OP_1"] for key in keys: for time_index,t in enumerate(time_points): self.assertFloatEqual(resampled.iget( key, time_index), self.ecl_sum.get_interp_direct( key, t))
def get_report(self, date=None, days=None): """ Will return the report step corresponding to input @date or @days. If the input argument does not correspond to any report steps the function will return -1. Observe that the function requires strict equality. """ if date: if days: raise ValueError("Must supply either days or date") step = self._get_report_step_from_time(CTime(date)) elif days: step = self._get_report_step_from_days(days) return step
def get_interp_vector(self, key, days_list=None, date_list=None): """ Will return numpy vector with interpolated values. Requiers exactly one input argument @days or @date; will raise exception ValueError if this is not satisfied. The method will check that the time arguments are within the time limits of the simulation; if else the method will raise exception ValueError. Also available as method get_interp_vector() on the EclSumVector class. """ self.assertKeyValid(key) if days_list: if date_list: raise ValueError("Must supply either days_list or date_list") else: vector = numpy.zeros(len(days_list)) sim_length = self.sim_length sim_start = self.first_day index = 0 for days in days_list: if (days >= sim_start) and (days <= sim_length): vector[index] = self._get_general_var_from_sim_days( days, key) else: raise ValueError("Invalid days value") index += 1 elif date_list: start_time = self.data_start end_time = self.end_date vector = numpy.zeros(len(date_list)) index = 0 for date in date_list: ct = CTime(date) if start_time <= ct <= end_time: vector[index] = self._get_general_var_from_sim_time( ct, key) else: raise ValueError("Invalid date value") index += 1 else: raise ValueError("Must supply either days_list or date_list") return vector
def test_slicing(self): dv = DoubleVector(initial_size=10) for i in range(10): dv[i] = 1.0 / (1 + i) self.dotest_slicing(dv) iv = IntVector(initial_size=10) for i in range(10): iv[i] = i**3 self.dotest_slicing(iv) bv = BoolVector(initial_size=10) for i in range(0, 10, 3): bv[i] = True self.dotest_slicing(bv) tv = TimeVector(initial_size=10) for i in range(10): tv[i] = CTime(datetime.datetime(2016, 12, i + 3, 0, 0, 0)) self.dotest_slicing(tv)
def restartView(self , seqnum_index = None, report_step = None , sim_time = None , sim_days = None): if report_step is None: report_step = -1 if sim_time is None: sim_time = -1 if sim_days is None: sim_days = -1 if seqnum_index is None: seqnum_index = -1 view = self._restart_view( seqnum_index , report_step , CTime( sim_time ) , sim_days ) if view is None: raise ValueError("No such restart block could be identiefied") view.setParent( parent = self ) return view
def restart_get_kw(self, kw_name, dtime, copy=False): """Will return EclKW @kw_name from restart file at time @dtime. This function assumes that the current EclFile instance represents a restart file. It will then look for keyword @kw_name exactly at the time @dtime; @dtime is a datetime instance: file = EclFile( "ECLIPSE.UNRST" ) swat2010 = file.restart_get_kw( "SWAT" , datetime.datetime( 2000 , 1 , 1 )) By default the returned kw instance is a reference to the ecl_kw still contained in the EclFile instance; i.e. the kw will become a dangling reference if the EclFile instance goes out of scope. If the optional argument @copy is True the returned kw will be a true copy. If the file does not have the keyword at the specified time the function will raise IndexError(); if the file does not have the keyword at all - KeyError will be raised. """ index = self._get_restart_index(CTime(dtime)) if index >= 0: if self.num_named_kw(kw_name) > index: kw = self.iget_named_kw(kw_name, index) if copy: return EclKW.copy(kw) else: return kw else: if self.has_kw(kw_name): raise IndexError('Does not have keyword "%s" at time:%s.' % (kw_name, dtime)) else: raise KeyError('Keyword "%s" not recognized.' % kw_name) else: raise IndexError('Does not have keyword "%s" at time:%s.' % (kw_name, dtime))