From 79f06fc6d19cd5aa53b85b4b92ed5faf5b7cec51 Mon Sep 17 00:00:00 2001 From: xjules Date: Tue, 13 Nov 2018 16:59:59 +0100 Subject: [PATCH 1/6] First version of extrapolation in the resample function. TODO: Need to make tests in cpp. The first test in python sketched. --- lib/ecl/ecl_sum.cpp | 58 +++++++++---------- .../tests/ecl_sum_alloc_resampled_test.cpp | 4 +- lib/include/ert/ecl/ecl_sum.hpp | 2 +- python/ecl/summary/ecl_sum.py | 6 +- python/tests/ecl_tests/test_sum_statoil.py | 30 ++++++++++ 5 files changed, 63 insertions(+), 37 deletions(-) diff --git a/lib/ecl/ecl_sum.cpp b/lib/ecl/ecl_sum.cpp index 4bb9a4c70b..71bf4686b8 100644 --- a/lib/ecl/ecl_sum.cpp +++ b/lib/ecl/ecl_sum.cpp @@ -779,39 +779,21 @@ const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const /*****************************************************************/ -ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * _times) { +ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * _times, const bool lower_extrapolation, const bool upper_extrapolation) { time_t start_time = ecl_sum_get_data_start(ecl_sum); time_t end_time = ecl_sum_get_end_time(ecl_sum); time_t input_t0 = time_t_vector_get_first( _times ); - time_t_vector_type * times = time_t_vector_alloc(0,0); /* - This is a temporary hack - the time argument used for resampling are - internally clamped to the [start, end] interval of the simulation; however - when outputting the original time values from the input argument _times is - used. - - The real fix for this is to update the complete time interpolation code to - return something sensible when the time arguments are outside of simulation - time range. + If lower and / or upper extrapolation is set to true it makes sure that resampling returns the first / last value of the simulation + if set to false, we jus throw exception */ - for (int i=0; i < time_t_vector_size(_times); i++) { - time_t t = time_t_vector_iget(_times, i); - if (t < start_time) - t = start_time; - - if (t > end_time) - t = end_time; - - time_t_vector_append(times, t); - } - - if ( time_t_vector_get_first(times) < start_time ) + if ( !lower_extrapolation && time_t_vector_get_first(_times) < start_time ) return NULL; - if ( time_t_vector_get_last(times) > ecl_sum_get_end_time(ecl_sum) ) + if ( !upper_extrapolation && time_t_vector_get_last(_times) > end_time) return NULL; - if ( !time_t_vector_is_sorted(times, false) ) + if ( !time_t_vector_is_sorted(_times, false) ) return NULL; const int * grid_dims = ecl_smspec_get_grid_dims(ecl_sum->smspec); @@ -840,13 +822,28 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_sum_vector_type * ecl_sum_vector = ecl_sum_vector_alloc(ecl_sum, true); double_vector_type * data = double_vector_alloc( ecl_sum_vector_get_size(ecl_sum_vector) , 0); - - for (int report_step = 0; report_step < time_t_vector_size(times); report_step++) { - time_t t = time_t_vector_iget(times, report_step); + for (int report_step = 0; report_step < time_t_vector_size(_times); report_step++) { time_t input_t = time_t_vector_iget(_times, report_step); - - /* Look up interpolated data in the original case. */ - ecl_sum_get_interp_vector( ecl_sum, t, ecl_sum_vector, data); + if (input_t < start_time) { + //clamping to the first value for t < start_time or if rate that derivative is 0 + for (int i=0; i < ecl_sum_vector_get_size(ecl_sum_vector); i++) { + double value = 0; + if (!ecl_sum_vector_iget_is_rate(ecl_sum_vector, i)) + value = ecl_sum_iget_first_value(ecl_sum,i); + double_vector_iset(data, i , value ); + } + } else if (input_t > end_time) { + //clamping to the last value for t > end_time or if is it a rate than derivative is 0 + for (int i=0; i < ecl_sum_vector_get_size(ecl_sum_vector); i++) { + double value = 0; + if (!ecl_sum_vector_iget_is_rate(ecl_sum_vector, i)) + value = ecl_sum_iget_last_value(ecl_sum,i); + double_vector_iset(data, i , value); + } + } else { + /* Look up interpolated data in the original case. */ + ecl_sum_get_interp_vector( ecl_sum, input_t, ecl_sum_vector, data); + } /* Add timestep corresponding to the interpolated data in the resampled case. */ ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum_resampled , report_step , input_t - input_t0); @@ -858,7 +855,6 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * } double_vector_free( data ); ecl_sum_vector_free( ecl_sum_vector ); - time_t_vector_free(times); return ecl_sum_resampled; } diff --git a/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp b/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp index 7eb7423bdb..379b985064 100644 --- a/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp +++ b/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp @@ -37,7 +37,7 @@ void test_correct_time_vector() { time_t_vector_append(t, util_make_date_utc( 4,1,2010 )); time_t_vector_append(t, util_make_date_utc( 6,1,2010 )); time_t_vector_append(t, util_make_date_utc( 8,1,2010 )); - ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_resample(ecl_sum, "kk", t); + ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_resample(ecl_sum, "kk", t, false, false); test_assert_int_equal( ecl_sum_get_report_time(ecl_sum_resampled, 2) , util_make_date_utc( 6,1,2010 )); const ecl_smspec_type * smspec_resampled = ecl_sum_get_smspec(ecl_sum_resampled); @@ -63,7 +63,7 @@ void test_not_sorted() { time_t_vector_append(t, util_make_date_utc( 1,1,2010 )); time_t_vector_append(t, util_make_date_utc( 3,1,2010 )); time_t_vector_append(t, util_make_date_utc( 2,1,2010 )); - test_assert_NULL( ecl_sum_alloc_resample( ecl_sum, "kk", t) ); + test_assert_NULL( ecl_sum_alloc_resample( ecl_sum, "kk", t, false, false) ); time_t_vector_free(t); ecl_sum_free(ecl_sum); } diff --git a/lib/include/ert/ecl/ecl_sum.hpp b/lib/include/ert/ecl/ecl_sum.hpp index a66529fb45..2bf1cd0b28 100644 --- a/lib/include/ert/ecl/ecl_sum.hpp +++ b/lib/include/ert/ecl/ecl_sum.hpp @@ -93,7 +93,7 @@ typedef struct ecl_sum_struct ecl_sum_type; ecl_sum_type * ecl_sum_fread_alloc_case(const char * , const char * key_join_string); ecl_sum_type * ecl_sum_fread_alloc_case__(const char * input_file , const char * key_join_string , bool include_restart); ecl_sum_type * ecl_sum_fread_alloc_case2__(const char * , const char * key_join_string , bool include_restart, bool lazy_load, int file_options); - ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times); + ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times, const bool lower_extrapolation, const bool upper_extrapolation); bool ecl_sum_case_exists( const char * input_file ); /* Accessor functions : */ diff --git a/python/ecl/summary/ecl_sum.py b/python/ecl/summary/ecl_sum.py index ee6f187d8b..a00c209d67 100644 --- a/python/ecl/summary/ecl_sum.py +++ b/python/ecl/summary/ecl_sum.py @@ -90,7 +90,7 @@ class EclSum(BaseCClass): _fread_alloc = EclPrototype("void* ecl_sum_fread_alloc(char*, stringlist, char*, bool)", bind=False) _create_restart_writer = EclPrototype("ecl_sum_obj ecl_sum_alloc_restart_writer2(char*, char*, int, bool, bool, char*, time_t, bool, int, int, int)", bind = False) _create_writer = EclPrototype("ecl_sum_obj ecl_sum_alloc_writer(char*, bool, bool, char*, time_t, bool, int, int, int)", bind = False) - _resample = EclPrototype("ecl_sum_obj ecl_sum_alloc_resample( ecl_sum, char*, time_t_vector)") + _resample = EclPrototype("ecl_sum_obj ecl_sum_alloc_resample( ecl_sum, char*, time_t_vector, bool, bool)") _iiget = EclPrototype("double ecl_sum_iget(ecl_sum, int, int)") _free = EclPrototype("void ecl_sum_free(ecl_sum)") _data_length = EclPrototype("int ecl_sum_get_data_length(ecl_sum)") @@ -1481,8 +1481,8 @@ def export_csv(self, filename, keys=None, date_format="%Y-%m-%d", sep=";"): - def resample(self, new_case_name, time_points): - new_case = self._resample(new_case_name, time_points) + def resample(self, new_case_name, time_points, lower_extrapolation=False, upper_extrapolation=False): + new_case = self._resample(new_case_name, time_points, lower_extrapolation, upper_extrapolation) if new_case is None: raise ValueError("Failed to create new resampled case:{}".format(new_case_name)) diff --git a/python/tests/ecl_tests/test_sum_statoil.py b/python/tests/ecl_tests/test_sum_statoil.py index 477d5135e3..9d95d5ed83 100755 --- a/python/tests/ecl_tests/test_sum_statoil.py +++ b/python/tests/ecl_tests/test_sum_statoil.py @@ -525,6 +525,36 @@ def test_resample(self): for time_index,t in enumerate(time_points): self.assertFloatEqual(resampled.iget( key, time_index), self.ecl_sum.get_interp_direct( key, t)) + def test_resample_extrapolate(self): + time_points = TimeVector() + start_time = self.ecl_sum.get_data_start_time() - CTime(60) + end_time = self.ecl_sum.get_end_time() + CTime(60) + 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, lower_extrapolation=True, upper_extrapolation=True ) + + 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.assertFalse( delta.total_seconds() <= 1 ) + + key_not_rate = "WOPT:OP_1" + for time_index,t in enumerate(time_points): + self.assertFloatEqual(resampled.iget( key_not_rate, time_index), self.ecl_sum.get_interp_direct( key_not_rate, t)) + + key_rate = "WOPR:OP_1" + for time_index,t in enumerate(time_points[1:-1]): + self.assertFloatEqual(resampled.iget( key_rate, time_index), self.ecl_sum.get_interp_direct( key_rate, t)) + + for time_index,t in enumerate([time_points[0],time_points[-1]]): + self.assertFloatEqual(resampled.iget( key_rate, time_index), 0) + def test_summary_units(self): self.assertEqual(self.ecl_sum.unit_system, EclUnitTypeEnum.ECL_METRIC_UNITS) From a717323b795c773cb769df315f0b786f5521926a Mon Sep 17 00:00:00 2001 From: xjules Date: Wed, 14 Nov 2018 15:51:01 +0100 Subject: [PATCH 2/6] Fixing naming of _times to times and error in datetime. --- lib/ecl/ecl_sum.cpp | 14 +++++++------- lib/include/ert/ecl/ecl_sum.hpp | 2 +- python/tests/ecl_tests/test_sum_statoil.py | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/ecl/ecl_sum.cpp b/lib/ecl/ecl_sum.cpp index 71bf4686b8..ddca132b7e 100644 --- a/lib/ecl/ecl_sum.cpp +++ b/lib/ecl/ecl_sum.cpp @@ -779,21 +779,21 @@ const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const /*****************************************************************/ -ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * _times, const bool lower_extrapolation, const bool upper_extrapolation) { +ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times, bool lower_extrapolation, bool upper_extrapolation) { time_t start_time = ecl_sum_get_data_start(ecl_sum); time_t end_time = ecl_sum_get_end_time(ecl_sum); - time_t input_t0 = time_t_vector_get_first( _times ); + time_t input_t0 = time_t_vector_get_first( times ); /* If lower and / or upper extrapolation is set to true it makes sure that resampling returns the first / last value of the simulation if set to false, we jus throw exception */ - if ( !lower_extrapolation && time_t_vector_get_first(_times) < start_time ) + if ( !lower_extrapolation && time_t_vector_get_first(times) < start_time ) return NULL; - if ( !upper_extrapolation && time_t_vector_get_last(_times) > end_time) + if ( !upper_extrapolation && time_t_vector_get_last(times) > end_time) return NULL; - if ( !time_t_vector_is_sorted(_times, false) ) + if ( !time_t_vector_is_sorted(times, false) ) return NULL; const int * grid_dims = ecl_smspec_get_grid_dims(ecl_sum->smspec); @@ -822,8 +822,8 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_sum_vector_type * ecl_sum_vector = ecl_sum_vector_alloc(ecl_sum, true); double_vector_type * data = double_vector_alloc( ecl_sum_vector_get_size(ecl_sum_vector) , 0); - for (int report_step = 0; report_step < time_t_vector_size(_times); report_step++) { - time_t input_t = time_t_vector_iget(_times, report_step); + for (int report_step = 0; report_step < time_t_vector_size(times); report_step++) { + time_t input_t = time_t_vector_iget(times, report_step); if (input_t < start_time) { //clamping to the first value for t < start_time or if rate that derivative is 0 for (int i=0; i < ecl_sum_vector_get_size(ecl_sum_vector); i++) { diff --git a/lib/include/ert/ecl/ecl_sum.hpp b/lib/include/ert/ecl/ecl_sum.hpp index 2bf1cd0b28..c5bbdd6239 100644 --- a/lib/include/ert/ecl/ecl_sum.hpp +++ b/lib/include/ert/ecl/ecl_sum.hpp @@ -93,7 +93,7 @@ typedef struct ecl_sum_struct ecl_sum_type; ecl_sum_type * ecl_sum_fread_alloc_case(const char * , const char * key_join_string); ecl_sum_type * ecl_sum_fread_alloc_case__(const char * input_file , const char * key_join_string , bool include_restart); ecl_sum_type * ecl_sum_fread_alloc_case2__(const char * , const char * key_join_string , bool include_restart, bool lazy_load, int file_options); - ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times, const bool lower_extrapolation, const bool upper_extrapolation); + ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times, bool lower_extrapolation, bool upper_extrapolation); bool ecl_sum_case_exists( const char * input_file ); /* Accessor functions : */ diff --git a/python/tests/ecl_tests/test_sum_statoil.py b/python/tests/ecl_tests/test_sum_statoil.py index 9d95d5ed83..5255053cf1 100755 --- a/python/tests/ecl_tests/test_sum_statoil.py +++ b/python/tests/ecl_tests/test_sum_statoil.py @@ -527,8 +527,8 @@ def test_resample(self): def test_resample_extrapolate(self): time_points = TimeVector() - start_time = self.ecl_sum.get_data_start_time() - CTime(60) - end_time = self.ecl_sum.get_end_time() + CTime(60) + start_time = self.ecl_sum.get_data_start_time() - datetime.timedelta(seconds=60) + end_time = self.ecl_sum.get_end_time() + datetime.timedelta(seconds=60) delta = end_time - start_time N = 25 time_points.initRange( CTime(start_time), From b05a0f5ab65f84811d3f4cf1195d5816f6053bc0 Mon Sep 17 00:00:00 2001 From: xjules Date: Fri, 23 Nov 2018 15:05:41 +0100 Subject: [PATCH 3/6] update to resampling function (using access via nodes). Adding test function in c, python test in progress (crashes) --- lib/ecl/ecl_sum.cpp | 45 ++++++++++--------- .../tests/ecl_sum_alloc_resampled_test.cpp | 44 +++++++++++++++--- python/tests/ecl_tests/test_sum_statoil.py | 31 ------------- 3 files changed, 63 insertions(+), 57 deletions(-) diff --git a/lib/ecl/ecl_sum.cpp b/lib/ecl/ecl_sum.cpp index ddca132b7e..d963072cb6 100644 --- a/lib/ecl/ecl_sum.cpp +++ b/lib/ecl/ecl_sum.cpp @@ -782,16 +782,17 @@ const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times, bool lower_extrapolation, bool upper_extrapolation) { time_t start_time = ecl_sum_get_data_start(ecl_sum); time_t end_time = ecl_sum_get_end_time(ecl_sum); - time_t input_t0 = time_t_vector_get_first( times ); - + time_t input_start = time_t_vector_get_first( times ); + time_t input_end = time_t_vector_get_last( times ); + /* If lower and / or upper extrapolation is set to true it makes sure that resampling returns the first / last value of the simulation if set to false, we jus throw exception */ - if ( !lower_extrapolation && time_t_vector_get_first(times) < start_time ) + if ( !lower_extrapolation && input_start < start_time ) return NULL; - if ( !upper_extrapolation && time_t_vector_get_last(times) > end_time) + if ( !upper_extrapolation && input_end > end_time) return NULL; if ( !time_t_vector_is_sorted(times, false) ) return NULL; @@ -803,21 +804,21 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * if ( util_string_equal(smspec_node_get_unit(node), "DAYS" ) ) time_in_days = true; - ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_writer( ecl_case , ecl_sum->fmt_case , ecl_sum->unified , ecl_sum->key_join_string , start_time , time_in_days , grid_dims[0] , grid_dims[1] , grid_dims[2] ); - - + //create elc_sum_resampled with TIME node only + ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_writer( ecl_case , ecl_sum->fmt_case , ecl_sum->unified , ecl_sum->key_join_string , input_start , time_in_days , grid_dims[0] , grid_dims[1] , grid_dims[2] ); + //add remaining nodes for (int i = 0; i < ecl_smspec_num_nodes(ecl_sum->smspec); i++) { const smspec_node_type * node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, i); - if (util_string_equal(smspec_node_get_gen_key1(node), "TIME")) - continue; - + if (util_string_equal(smspec_node_get_keyword(node), "TIME")) + continue; ecl_sum_add_smspec_node( ecl_sum_resampled, node ); } /* The SMSPEC header structure has been completely initialized, it is time to start filling it up with data. + */ ecl_sum_vector_type * ecl_sum_vector = ecl_sum_vector_alloc(ecl_sum, true); double_vector_type * data = double_vector_alloc( ecl_sum_vector_get_size(ecl_sum_vector) , 0); @@ -825,20 +826,22 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * for (int report_step = 0; report_step < time_t_vector_size(times); report_step++) { time_t input_t = time_t_vector_iget(times, report_step); if (input_t < start_time) { - //clamping to the first value for t < start_time or if rate that derivative is 0 - for (int i=0; i < ecl_sum_vector_get_size(ecl_sum_vector); i++) { + //clamping to the first value for t < start_time or if it is a rate than derivative is 0 + for (int i=1; i < ecl_smspec_num_nodes(ecl_sum->smspec); i++) { double value = 0; - if (!ecl_sum_vector_iget_is_rate(ecl_sum_vector, i)) - value = ecl_sum_iget_first_value(ecl_sum,i); - double_vector_iset(data, i , value ); + const smspec_node_type * node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, i); + if (!smspec_node_is_rate(node)) + value = ecl_sum_iget_first_value(ecl_sum,i-1); + double_vector_iset(data, i-1, value ); } } else if (input_t > end_time) { - //clamping to the last value for t > end_time or if is it a rate than derivative is 0 - for (int i=0; i < ecl_sum_vector_get_size(ecl_sum_vector); i++) { + //clamping to the last value for t > end_time or if it is a rate than derivative is 0 + for (int i=1; i < ecl_smspec_num_nodes(ecl_sum->smspec); i++) { double value = 0; - if (!ecl_sum_vector_iget_is_rate(ecl_sum_vector, i)) - value = ecl_sum_iget_last_value(ecl_sum,i); - double_vector_iset(data, i , value); + const smspec_node_type * node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, i); + if (!smspec_node_is_rate(node)) + value = ecl_sum_iget_last_value(ecl_sum,i-1); + double_vector_iset(data, i-1, value ); } } else { /* Look up interpolated data in the original case. */ @@ -846,7 +849,7 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * } /* Add timestep corresponding to the interpolated data in the resampled case. */ - ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum_resampled , report_step , input_t - input_t0); + ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum_resampled , report_step , input_t - input_start); for (int data_index = 0; data_index < ecl_sum_vector_get_size(ecl_sum_vector); data_index++) { double value = double_vector_iget(data,data_index); int params_index = data_index + 1; // The +1 shift is because the first element in the tstep is time value. diff --git a/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp b/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp index 379b985064..aed41a8e50 100644 --- a/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp +++ b/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp @@ -57,6 +57,41 @@ void test_correct_time_vector() { ecl_sum_free(ecl_sum); } + +void test_resample_extrapolate_rate() { + + ecl_sum_type * ecl_sum = test_alloc_ecl_sum(); + + time_t_vector_type * t = time_t_vector_alloc( 0 , 0 ); + time_t_vector_append(t, util_make_date_utc( 1,1,2009 )); + time_t_vector_append(t, util_make_date_utc( 4,1,2010 )); + time_t_vector_append(t, util_make_date_utc( 12,1,2010 )); + + ecl_sum_type * ecl_sum_resampled = ecl_sum_alloc_resample(ecl_sum, "kk", t, true, true); + + + const ecl_smspec_type * smspec_resampled = ecl_sum_get_smspec(ecl_sum_resampled); + const smspec_node_type * node1 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 1); + const smspec_node_type * node2 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 2); + const smspec_node_type * node3 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 3); + + + //testing extrapolation for rate wrt. 3 dates: lower, inside and upper + test_assert_double_equal(0, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 1, 1, 2009), node3)); + test_assert_double_equal(10.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 4, 1, 2010), node3)); + test_assert_double_equal(0, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 12, 1, 2010), node3)); + + //testing extrapolation for variable wrt. 3 dates: lower, inside and upper + test_assert_double_equal(0, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 1, 1, 2009 ), node1) ); + test_assert_double_equal(2.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 4, 1,2010 ), node1) ); + test_assert_double_equal(9.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 12, 1,2010 ), node1) ); + + + ecl_sum_free(ecl_sum_resampled); + time_t_vector_free(t); + ecl_sum_free(ecl_sum); +} + void test_not_sorted() { ecl_sum_type * ecl_sum = test_alloc_ecl_sum(); time_t_vector_type * t = time_t_vector_alloc( 0 , 0 ); @@ -70,10 +105,9 @@ void test_not_sorted() { int main() { - fprintf(stderr,"The ecl_sum resample code is currently broken - this should be fizxed\n"); - exit(0); - // test_correct_time_vector(); - // test_not_sorted(); - // return 0; + test_correct_time_vector(); + test_resample_extrapolate_rate(); + test_not_sorted(); + return 0; } diff --git a/python/tests/ecl_tests/test_sum_statoil.py b/python/tests/ecl_tests/test_sum_statoil.py index 5255053cf1..91cd727d53 100755 --- a/python/tests/ecl_tests/test_sum_statoil.py +++ b/python/tests/ecl_tests/test_sum_statoil.py @@ -525,37 +525,6 @@ def test_resample(self): for time_index,t in enumerate(time_points): self.assertFloatEqual(resampled.iget( key, time_index), self.ecl_sum.get_interp_direct( key, t)) - def test_resample_extrapolate(self): - time_points = TimeVector() - start_time = self.ecl_sum.get_data_start_time() - datetime.timedelta(seconds=60) - end_time = self.ecl_sum.get_end_time() + datetime.timedelta(seconds=60) - 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, lower_extrapolation=True, upper_extrapolation=True ) - - 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.assertFalse( delta.total_seconds() <= 1 ) - - key_not_rate = "WOPT:OP_1" - for time_index,t in enumerate(time_points): - self.assertFloatEqual(resampled.iget( key_not_rate, time_index), self.ecl_sum.get_interp_direct( key_not_rate, t)) - - key_rate = "WOPR:OP_1" - for time_index,t in enumerate(time_points[1:-1]): - self.assertFloatEqual(resampled.iget( key_rate, time_index), self.ecl_sum.get_interp_direct( key_rate, t)) - - for time_index,t in enumerate([time_points[0],time_points[-1]]): - self.assertFloatEqual(resampled.iget( key_rate, time_index), 0) - - def test_summary_units(self): self.assertEqual(self.ecl_sum.unit_system, EclUnitTypeEnum.ECL_METRIC_UNITS) From b24de7842785310ea3d9a13936093f86f0c5c30d Mon Sep 17 00:00:00 2001 From: xjules Date: Fri, 23 Nov 2018 15:27:51 +0100 Subject: [PATCH 4/6] Removing unused node2 in resample test --- lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp b/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp index aed41a8e50..c7ad9dc56e 100644 --- a/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp +++ b/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp @@ -72,7 +72,6 @@ void test_resample_extrapolate_rate() { const ecl_smspec_type * smspec_resampled = ecl_sum_get_smspec(ecl_sum_resampled); const smspec_node_type * node1 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 1); - const smspec_node_type * node2 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 2); const smspec_node_type * node3 = ecl_smspec_iget_node_w_params_index(smspec_resampled, 3); From 5985965db004a9e436519d12e24945b2056d1749 Mon Sep 17 00:00:00 2001 From: xjules Date: Tue, 27 Nov 2018 09:43:24 +0100 Subject: [PATCH 5/6] Fix python resample test in test_sum. --- lib/ecl/ecl_sum.cpp | 10 +++---- python/tests/ecl_tests/test_sum.py | 46 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/lib/ecl/ecl_sum.cpp b/lib/ecl/ecl_sum.cpp index d963072cb6..4132bb5e3e 100644 --- a/lib/ecl/ecl_sum.cpp +++ b/lib/ecl/ecl_sum.cpp @@ -780,15 +780,15 @@ const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times, bool lower_extrapolation, bool upper_extrapolation) { + /* + If lower and / or upper extrapolation is set to true it makes sure that resampling returns the first / last value of the simulation + or in the case of derivate / rate then it gets zero. if these are set to false, we jus throw exception + */ + time_t start_time = ecl_sum_get_data_start(ecl_sum); time_t end_time = ecl_sum_get_end_time(ecl_sum); time_t input_start = time_t_vector_get_first( times ); time_t input_end = time_t_vector_get_last( times ); - - /* - If lower and / or upper extrapolation is set to true it makes sure that resampling returns the first / last value of the simulation - if set to false, we jus throw exception - */ if ( !lower_extrapolation && input_start < start_time ) return NULL; diff --git a/python/tests/ecl_tests/test_sum.py b/python/tests/ecl_tests/test_sum.py index b29c8e0da9..8394def5b7 100644 --- a/python/tests/ecl_tests/test_sum.py +++ b/python/tests/ecl_tests/test_sum.py @@ -585,3 +585,49 @@ def test_directory_conflict(self): case.fwrite() os.mkdir("UNITS") case2 = EclSum("./UNITS") + + + def test_resample_extrapolate(self): + """ + Test resampling of summary with extrapolate option of lower and upper boundaries enabled + Note: When performing resampling on cp_simple3 test case, it fails to duplicate node 251 so suing mocked ecl_sum instead + path = os.path.join(self.TESTDATA_ROOT, "local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3") + ecl_sum = EclSum( path, lazy_load=True ) + """ + from ecl.util.util import TimeVector, CTime + + time_points = TimeVector() + ecl_sum = create_case(data_start=datetime.date(2010, 1, 1)) + 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)) From 97e4fca9fa7f2673124b9589e7f5c4a8a4d766dc Mon Sep 17 00:00:00 2001 From: xjules Date: Tue, 27 Nov 2018 12:26:27 +0100 Subject: [PATCH 6/6] Important fix: make us of smspec_node_get_params_index and test fix --- lib/ecl/ecl_sum.cpp | 8 ++++---- lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp | 2 +- python/tests/ecl_tests/test_sum.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/ecl/ecl_sum.cpp b/lib/ecl/ecl_sum.cpp index 4132bb5e3e..7c59bb2ec9 100644 --- a/lib/ecl/ecl_sum.cpp +++ b/lib/ecl/ecl_sum.cpp @@ -831,8 +831,8 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * double value = 0; const smspec_node_type * node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, i); if (!smspec_node_is_rate(node)) - value = ecl_sum_iget_first_value(ecl_sum,i-1); - double_vector_iset(data, i-1, value ); + value = ecl_sum_iget_first_value(ecl_sum, smspec_node_get_params_index(node)); + double_vector_iset(data, i-1, value); } } else if (input_t > end_time) { //clamping to the last value for t > end_time or if it is a rate than derivative is 0 @@ -840,8 +840,8 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * double value = 0; const smspec_node_type * node = ecl_smspec_iget_node_w_node_index(ecl_sum->smspec, i); if (!smspec_node_is_rate(node)) - value = ecl_sum_iget_last_value(ecl_sum,i-1); - double_vector_iset(data, i-1, value ); + value = ecl_sum_iget_last_value(ecl_sum, smspec_node_get_params_index(node)); + double_vector_iset(data, i-1, value); } } else { /* Look up interpolated data in the original case. */ diff --git a/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp b/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp index c7ad9dc56e..3e98fbf65d 100644 --- a/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp +++ b/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp @@ -83,7 +83,7 @@ void test_resample_extrapolate_rate() { //testing extrapolation for variable wrt. 3 dates: lower, inside and upper test_assert_double_equal(0, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 1, 1, 2009 ), node1) ); test_assert_double_equal(2.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 4, 1,2010 ), node1) ); - test_assert_double_equal(9.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 12, 1,2010 ), node1) ); + test_assert_double_equal(6.000, ecl_sum_get_from_sim_time( ecl_sum_resampled, util_make_date_utc( 12, 1,2010 ), node1) ); ecl_sum_free(ecl_sum_resampled); diff --git a/python/tests/ecl_tests/test_sum.py b/python/tests/ecl_tests/test_sum.py index 4f2a28b85a..40ddc883ac 100644 --- a/python/tests/ecl_tests/test_sum.py +++ b/python/tests/ecl_tests/test_sum.py @@ -625,7 +625,7 @@ def test_directory_conflict(self): def test_resample_extrapolate(self): """ Test resampling of summary with extrapolate option of lower and upper boundaries enabled - Note: When performing resampling on cp_simple3 test case, it fails to duplicate node 251 so suing mocked ecl_sum instead + Note: When performing resampling on cp_simple3 test case, it fails to duplicate node 251 so using mocked ecl_sum instead path = os.path.join(self.TESTDATA_ROOT, "local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3") ecl_sum = EclSum( path, lazy_load=True ) """