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 __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 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 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)
def create_synthetic_refcase(case_name: pathlib.Path, schedule: Schedule, nx: int = 1, ny: int = 1, nz: int = 1): """ This function creates a synthetic simulation output in order to please ERT, which uses it for mapping the dates to report step. Args: case_name: Case name for synthetic case schedule: FlowNet Schedule instance nx: Number of grid blocks in the x-direction ny: Number of grid blocks in the y-direction nz: Number of grid blocks in the z-direction Returns: Nothing """ datetimes = schedule.get_dates() numdates = [date2num(date) for date in datetimes] start_time = CTime._timegm( # pylint: disable=protected-access 0, 0, 0, datetimes[0].day, datetimes[0].month, datetimes[0].year) eclsum = EclSum.writer(str(case_name), start_time, nx, ny, nz) vectors = [] for well in schedule.get_wells(): vectors.append(["WOPR", well, 0, "Sm3/day"]) vectors.append(["WWPR", well, 0, "Sm3/day"]) vectors.append(["WGOR", well, 0, "Sm3/day"]) vectors.append(["WBHP", well, 0, "Sm3/day"]) for vector in vectors: # pylint: disable=no-member EclSum.addVariable(eclsum, vector[0], vector[1], vector[2], vector[3]) for report_step, _ in enumerate(numdates): # pylint: disable=no-member if report_step == 0: tstep = EclSum.addTStep(eclsum, 1, numdates[report_step] - numdates[0]) else: tstep = EclSum.addTStep(eclsum, report_step, numdates[report_step] - numdates[0]) for vector in vectors: tstep[f"{vector[0]}:{vector[1]}"] = 0 EclSum.fwrite(eclsum)
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 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 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 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()) 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 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 restart_view(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))
def test_comparison(self): t0 = CTime(0) t1 = CTime(0) t2 = CTime(1) self.assertTrue(t0 == t1) self.assertFalse(t0 != t1) with self.assertRaises(TypeError): t0 != 0.5 self.assertFalse(t0 < t1) self.assertTrue(t0 < t2) with self.assertRaises(TypeError): t0 < 0.5 self.assertTrue(t0 <= t1) self.assertTrue(t0 <= t2) with self.assertRaises(TypeError): t0 <= 0.5 self.assertFalse(t0 > t1) self.assertFalse(t0 > t2) with self.assertRaises(TypeError): t0 > 0.5 self.assertTrue(t0 >= t1) self.assertFalse(t0 >= t2) with self.assertRaises(TypeError): t0 >= 0.5 t3 = CTime(date(2050, 1, 1)) t4 = CTime(date(2060, 1, 1)) self.assertTrue(t1 < t3) self.assertTrue(t3 < t4) t5 = CTime(t4) self.assertTrue(t4 == t5)
def get_date(self): """ The date when this RFT/PLT/... was recorded. """ ct = CTime(self._get_date()) return ct.date()
def get_interp_direct(self, key, date): if not isinstance(date, CTime): date = CTime(date) return self._get_general_var_from_sim_time(date, key)
def __contains__(self, time): index = self._lookup_time(CTime(time)) if index >= 0: return True else: return False
def get_sim_date(self): ct = CTime( self._get_sim_time( ) ) return ct.datetime( )
def test_resample_extrapolate(self): """ Test resampling of summary with extrapolate option of lower and upper boundaries enabled """ from ecl.util.util import TimeVector, CTime time_points = TimeVector() path = os.path.join(self.TESTDATA_ROOT, "local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3") ecl_sum = EclSum(path, lazy_load=True) start_time = ecl_sum.get_data_start_time() - datetime.timedelta( seconds=86400) end_time = ecl_sum.get_end_time() + datetime.timedelta(seconds=86400) 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 = ecl_sum.resample( "OUTPUT_CASE", time_points, lower_extrapolation=True, upper_extrapolation=True, ) for key in ecl_sum.keys(): self.assertIn(key, resampled) self.assertEqual( ecl_sum.get_data_start_time() - datetime.timedelta(seconds=86400), resampled.get_data_start_time(), ) key_not_rate = "FOPT" for time_index, t in enumerate(time_points): if t < ecl_sum.get_data_start_time(): self.assertFloatEqual( resampled.iget(key_not_rate, time_index), ecl_sum._get_first_value(key_not_rate), ) elif t > ecl_sum.get_end_time(): self.assertFloatEqual( resampled.iget(key_not_rate, time_index), ecl_sum.get_last_value(key_not_rate), ) else: self.assertFloatEqual( resampled.iget(key_not_rate, time_index), ecl_sum.get_interp_direct(key_not_rate, t), ) key_rate = "FOPR" for time_index, t in enumerate(time_points): if t < ecl_sum.get_data_start_time(): self.assertFloatEqual(resampled.iget(key_rate, time_index), 0) elif t > ecl_sum.get_end_time(): self.assertFloatEqual(resampled.iget(key_rate, time_index), 0) else: self.assertFloatEqual( resampled.iget(key_rate, time_index), ecl_sum.get_interp_direct(key_rate, t), )
def test_conversion(self): t = CTime(0) self.assertEqual(t.value(), 0) self.assertEqual(t.ctime(), 0) self.assertEqual(t.time(), time.gmtime(0))
def get_end_time(self): """ A Python datetime instance with the last loaded time. """ return CTime(self._get_end_date()).datetime()
def __init__(self, config_content=None, config_dict=None): if config_content is not None and config_dict is not None: raise ValueError( "Error: EclConfig can not be instantiated with multiple config objects" ) c_ptr = None if config_dict is None: c_ptr = self._alloc(config_content) if config_dict is not None: # ECLBASE_KEY have_eclbase = config_dict.get(ConfigKeys.ECLBASE) is not None # DATA_FILE_KEY data_file = config_dict.get(ConfigKeys.DATA_FILE) if data_file is not None: data_file = os.path.realpath(data_file) if not os.path.isfile(data_file): raise ValueError("Error: data file is not a file") # GRID_KEY grid = None grid_file = config_dict.get(ConfigKeys.GRID) if grid_file is not None: grid_file = os.path.realpath(grid_file) if not os.path.isfile(grid_file): raise ValueError("Error: grid file is not a file") grid = EclGrid.load_from_file(grid_file) # REFCASE_KEY refcase_default = config_dict.get(ConfigKeys.REFCASE) if refcase_default is not None: refcase_default = os.path.realpath(refcase_default) # REFCASE_LIST_KEY refcase_list = StringList() for refcase in config_dict.get(ConfigKeys.REFCASE_LIST, []): refcase_list.append(refcase) # INIT_SECTION_KEY init_section = config_dict.get(ConfigKeys.INIT_SECITON) # END_DATE_KEY end_date = CTime( datetime.strptime( config_dict.get(ConfigKeys.END_DATE, "31/12/1969"), "%d/%m/%Y")) # SCHEDULE_PREDICTION_FILE_KEY schedule_prediction_file = config_dict.get( ConfigKeys.SCHEDULE_PREDICTION_FILE) c_ptr = self._alloc_full(have_eclbase, data_file, grid, refcase_default, refcase_list, init_section, end_date, schedule_prediction_file) if grid is not None: grid.convertToCReference(None) if c_ptr: super(EclConfig, self).__init__(c_ptr) else: raise RuntimeError( 'Internal error: Failed constructing EclConfig!')
def __len__(self): return self._get_size(None, CTime(-1))
def get_interp_row(self, key_list, sim_time, invalid_value=-1): ctime = CTime(sim_time) data = DoubleVector(initial_size=len(key_list), default_value=invalid_value) EclSum._get_interp_vector(self, ctime, key_list, data) return data
def time_range(self, start=None, end=None, interval="1Y", num_timestep=None, extend_end=True): """Will create a vector of timepoints based on the current case. By default the timepoints will be regularly sampled based on the interval given by the @interval string. Alternatively the total number of timesteps can be specified, if the @num_timestep option is specified that will take presedence. """ (num, timeUnit) = TimeVector.parseTimeUnit(interval) if start is None: start = self.getDataStartTime() else: if isinstance(start, datetime.date): start = datetime.datetime(start.year, start.month, start.day, 0, 0, 0) if start < self.getDataStartTime(): start = self.getDataStartTime() if end is None: end = self.getEndTime() else: if isinstance(end, datetime.date): end = datetime.datetime(end.year, end.month, end.day, 0, 0, 0) if end > self.getEndTime(): end = self.getEndTime() if end < start: raise ValueError("Invalid time interval start after end") if not num_timestep is None: return TimeVector.create_linear(CTime(start), CTime(end), num_timestep) range_start = start range_end = end if not timeUnit == "d": year1 = start.year year2 = end.year month1 = start.month month2 = end.month day1 = start.day day2 = end.day if extend_end: if timeUnit == 'm': if day2 > 1: month2 += 1 if month2 == 13: year2 += 1 month2 = 1 elif timeUnit == "y": month1 = 1 if year2 > 1 or day2 > 1: year2 += 1 month2 = 1 day1 = 1 day2 = 1 range_start = datetime.date(year1, month1, day1) range_end = datetime.date(year2, month2, day2) trange = TimeVector.createRegular(range_start, range_end, interval) # If the simulation does not start at the first of the month # the start value will be before the simulation start; we # manually shift the first element in the trange to the start # value; the same for the end of list. if trange[-1] < end: if extend_end: trange.appendTime(num, timeUnit) else: trange.append(end) data_start = self.getDataStartTime() if trange[0] < data_start: trange[0] = CTime(data_start) return trange
def get_date(self): """ The date when this RFT/PLT/... was recorded. """ ct = CTime(self._get_date( )) return ct.date()
def get_report_time(self, report): """ Will return the datetime corresponding to the report_step @report. """ return CTime(self._get_report_time(report)).date()
def __init__(self, config_content=None, config_dict=None): if config_content is not None and config_dict is not None: raise ValueError( "Error: EclConfig can not be instantiated with multiple config objects" ) c_ptr = None if config_dict is None: c_ptr = self._alloc(config_content) if config_dict is not None: # ECLBASE_KEY have_eclbase = config_dict.get(ConfigKeys.ECLBASE) is not None # DATA_FILE_KEY data_file = config_dict.get(ConfigKeys.DATA_FILE) if data_file is not None: data_file = os.path.realpath(data_file) if not os.path.isfile(data_file): raise ValueError("Error: data file is not a file") # GRID_KEY grid = None grid_file = config_dict.get(ConfigKeys.GRID) if grid_file is not None: grid_file = os.path.realpath(grid_file) if not os.path.isfile(grid_file): raise ValueError("Error: grid file is not a file") grid = EclGrid.load_from_file(grid_file) # REFCASE_KEY refcase_default = config_dict.get(ConfigKeys.REFCASE) if refcase_default is not None: refcase_default = os.path.realpath(refcase_default) # REFCASE_LIST_KEY refcase_list = StringList() for refcase in config_dict.get(ConfigKeys.REFCASE_LIST, []): refcase_list.append(refcase) # END_DATE_KEY try: end_date = CTime( datetime.strptime( config_dict.get(ConfigKeys.END_DATE, "1969-12-31"), "%Y-%m-%d")) except ValueError: print( "Deprecation warning: The date format DD/MM/YYYY is deprecated, " "and its support will be removed in a future release. " "Please use ISO date format YYYY-MM-DD.") end_date = CTime( datetime.strptime( config_dict.get(ConfigKeys.END_DATE, "31/12/1969"), "%d/%m/%Y")) # SCHEDULE_PREDICTION_FILE_KEY schedule_prediction_file = config_dict.get( ConfigKeys.SCHEDULE_PREDICTION_FILE) c_ptr = self._alloc_full( have_eclbase, data_file, grid, refcase_default, refcase_list, end_date, schedule_prediction_file, ) if grid is not None: grid.convertToCReference(None) if c_ptr: super().__init__(c_ptr) else: raise RuntimeError( "Internal error: Failed constructing EclConfig!")
def end_date(self): """ The date of the last (loaded) time step. """ return CTime(self._get_end_date()).date()
def __init__(self, name, type_string, date, days): c_ptr = self._alloc(name, type_string, CTime(date), days) super(EclRFT, self).__init__(c_ptr)
def get_sim_date(self): ct = CTime( self._get_sim_time( ) ) return ct.datetime( )