void obs_vector_load_from_SUMMARY_OBSERVATION(obs_vector_type * obs_vector , const conf_instance_type * conf_instance , const history_type * history, ensemble_config_type * ensemble_config) { if(!conf_instance_is_of_class(conf_instance, "SUMMARY_OBSERVATION")) util_abort("%s: internal error. expected \"SUMMARY_OBSERVATION\" instance, got \"%s\".\n", __func__, conf_instance_get_class_name_ref(conf_instance) ); { double obs_value = conf_instance_get_item_value_double(conf_instance, "VALUE" ); double obs_error = conf_instance_get_item_value_double(conf_instance, "ERROR" ); double min_error = conf_instance_get_item_value_double(conf_instance, "ERROR_MIN"); const char * error_mode = conf_instance_get_item_value_ref( conf_instance, "ERROR_MODE"); const char * sum_key = conf_instance_get_item_value_ref( conf_instance, "KEY" ); const char * obs_key = conf_instance_get_name_ref(conf_instance); int size = history_get_last_restart( history ); int obs_restart_nr = __conf_instance_get_restart_nr(conf_instance , obs_key , history , size); if (obs_restart_nr == 0) { int day,month,year; time_t start_time = history_get_time_t_from_restart_nr( history , 0 ); util_set_date_values( start_time , &day , &month , &year); fprintf(stderr,"** ERROR: It is unfortunately not possible to use summary observations from the\n"); fprintf(stderr," start of the simulation. Problem with observation:%s at %02d/%02d/%4d\n",obs_key , day,month,year); exit(1); } { if (strcmp( error_mode , "REL") == 0) obs_error *= obs_value; else if (strcmp( error_mode , "RELMIN") == 0) obs_error = util_double_max( min_error , obs_error * obs_value ); obs_vector_add_summary_obs( obs_vector , obs_restart_nr , sum_key , obs_key , obs_value , obs_error , NULL , 0); } } }
static int __conf_instance_get_restart_nr(const conf_instance_type * conf_instance, const char * obs_key , time_map_type * time_map , bool prefer_restart) { int obs_restart_nr = -1; /* To shut up compiler warning. */ if(conf_instance_has_item(conf_instance, "RESTART")) { obs_restart_nr = conf_instance_get_item_value_int(conf_instance, "RESTART"); if (obs_restart_nr > time_map_get_last_step( time_map)) util_abort("%s: Observation %s occurs at restart %i, but history file has only %i restarts.\n", __func__, obs_key, obs_restart_nr, time_map_get_last_step( time_map )); } else { time_t obs_time = time_map_get_start_time( time_map ); if(conf_instance_has_item(conf_instance, "DATE")) { obs_time = conf_instance_get_item_value_time_t(conf_instance, "DATE" ); if (prefer_restart) obs_vector_prefer_RESTART_warning(); } else if (conf_instance_has_item(conf_instance, "DAYS")) { double days = conf_instance_get_item_value_double(conf_instance, "DAYS"); util_inplace_forward_days_utc( &obs_time , days ); if (prefer_restart) obs_vector_prefer_RESTART_warning(); } else if (conf_instance_has_item(conf_instance, "HOURS")) { double hours = conf_instance_get_item_value_double(conf_instance, "HOURS"); util_inplace_forward_seconds_utc( &obs_time , hours * 3600 ); if (prefer_restart) obs_vector_prefer_RESTART_warning(); } else util_abort("%s: Internal error. Invalid conf_instance?\n", __func__); obs_restart_nr = time_map_lookup_time_with_tolerance( time_map , obs_time , 30 , 30 ); } if (obs_restart_nr < 0) util_abort("%s: Failed to look up restart nr correctly \n",__func__); return obs_restart_nr; }
obs_vector_type * obs_vector_alloc_from_GENERAL_OBSERVATION(const conf_instance_type * conf_instance , const history_type * history, const ensemble_config_type * ensemble_config) { if(!conf_instance_is_of_class(conf_instance, "GENERAL_OBSERVATION")) util_abort("%s: internal error. expected \"GENERAL_OBSERVATION\" instance, got \"%s\".\n", __func__, conf_instance_get_class_name_ref(conf_instance) ); const char * obs_key = conf_instance_get_name_ref(conf_instance); const char * state_kw = conf_instance_get_item_value_ref( conf_instance, "DATA" ); if (ensemble_config_has_key( ensemble_config , state_kw )) { const char * obs_key = conf_instance_get_name_ref(conf_instance); int size = history_get_last_restart( history ); obs_vector_type * obs_vector = obs_vector_alloc( GEN_OBS , obs_key , ensemble_config_get_node(ensemble_config , state_kw ), size); int obs_restart_nr = __conf_instance_get_restart_nr(conf_instance , obs_key , history , size); const char * index_file = NULL; const char * index_list = NULL; const char * obs_file = NULL; const char * error_covar_file = NULL; if (conf_instance_has_item(conf_instance , "INDEX_FILE")) index_file = conf_instance_get_item_value_ref( conf_instance, "INDEX_FILE" ); if (conf_instance_has_item(conf_instance , "INDEX_LIST")) index_list = conf_instance_get_item_value_ref( conf_instance, "INDEX_LIST" ); if (conf_instance_has_item(conf_instance , "OBS_FILE")) obs_file = conf_instance_get_item_value_ref( conf_instance, "OBS_FILE" ); if (conf_instance_has_item(conf_instance , "ERROR_COVAR")) error_covar_file = conf_instance_get_item_value_ref( conf_instance, "ERROR_COVAR" ); { const enkf_config_node_type * config_node = ensemble_config_get_node( ensemble_config , state_kw); if (enkf_config_node_get_impl_type(config_node) == GEN_DATA) { double scalar_error = -1; double scalar_value = -1; gen_obs_type * gen_obs ; if (conf_instance_has_item(conf_instance , "VALUE")) { scalar_value = conf_instance_get_item_value_double(conf_instance , "VALUE"); scalar_error = conf_instance_get_item_value_double(conf_instance , "ERROR"); } /** The config system has ensured that we have either OBS_FILE or (VALUE and ERROR). */ gen_obs = gen_obs_alloc( enkf_config_node_get_ref( config_node ) , obs_key , obs_file , scalar_value , scalar_error , index_file , index_list , error_covar_file); obs_vector_install_node( obs_vector , obs_restart_nr , gen_obs ); } else { ert_impl_type impl_type = enkf_config_node_get_impl_type(config_node); util_abort("%s: %s has implementation type:\'%s\' - expected:\'%s\'.\n",__func__ , state_kw , enkf_types_get_impl_name(impl_type) , enkf_types_get_impl_name(GEN_DATA)); } } return obs_vector; } else { fprintf(stderr,"** Warning the ensemble key:%s does not exist - observation:%s not added \n", state_kw , obs_key); return NULL; } }
static int __conf_instance_get_restart_nr(const conf_instance_type * conf_instance, const char * obs_key , const history_type * history , int size) { int obs_restart_nr = -1; /* To shut up compiler warning. */ if(conf_instance_has_item(conf_instance, "RESTART")) { obs_restart_nr = conf_instance_get_item_value_int(conf_instance, "RESTART"); if(obs_restart_nr > size) util_abort("%s: Observation %s occurs at restart %i, but history file has only %i restarts.\n", __func__, obs_key, obs_restart_nr, size); } else if(conf_instance_has_item(conf_instance, "DATE")) { time_t obs_date = conf_instance_get_item_value_time_t(conf_instance, "DATE" ); obs_restart_nr = history_get_restart_nr_from_time_t( history , obs_date ); } else if (conf_instance_has_item(conf_instance, "DAYS")) { double days = conf_instance_get_item_value_double(conf_instance, "DAYS"); obs_restart_nr = history_get_restart_nr_from_days( history , days ); } else util_abort("%s: Internal error. Invalid conf_instance?\n", __func__); return obs_restart_nr; }
obs_vector_type * obs_vector_alloc_from_BLOCK_OBSERVATION(const conf_instance_type * conf_instance , const ecl_grid_type * grid , const ecl_sum_type * refcase , const history_type * history, ensemble_config_type * ensemble_config) { if(!conf_instance_is_of_class(conf_instance, "BLOCK_OBSERVATION")) util_abort("%s: internal error. expected \"BLOCK_OBSERVATION\" instance, got \"%s\".\n", __func__, conf_instance_get_class_name_ref(conf_instance) ); block_obs_source_type source_type = SOURCE_SUMMARY; const char * obs_label = conf_instance_get_name_ref(conf_instance); const char * source_string = conf_instance_get_item_value_ref(conf_instance , "SOURCE"); const char * field_name = conf_instance_get_item_value_ref(conf_instance , "FIELD"); const char * sum_kw = NULL; bool OK = true; if (strcmp(source_string , "FIELD") == 0) { source_type = SOURCE_FIELD; if (!ensemble_config_has_key( ensemble_config , field_name)) { OK = false; fprintf(stderr,"** Warning the ensemble key:%s does not exist - observation:%s not added \n", field_name , obs_label); } } else if (strcmp( source_string , "SUMMARY") == 0) { source_type = SOURCE_SUMMARY; sum_kw = __summary_kw( field_name ); } else util_abort("%s: internal error \n",__func__); if (OK) { obs_vector_type * obs_vector = NULL; int size = history_get_last_restart( history ); int obs_restart_nr ; stringlist_type * summary_keys = stringlist_alloc_new(); stringlist_type * obs_pt_keys = conf_instance_alloc_list_of_sub_instances_of_class_by_name(conf_instance, "OBS"); int num_obs_pts = stringlist_get_size(obs_pt_keys); double * obs_value = util_calloc(num_obs_pts , sizeof * obs_value); double * obs_std = util_calloc(num_obs_pts , sizeof * obs_std ); int * obs_i = util_calloc(num_obs_pts , sizeof * obs_i ); int * obs_j = util_calloc(num_obs_pts , sizeof * obs_j ); int * obs_k = util_calloc(num_obs_pts , sizeof * obs_k ); obs_restart_nr = __conf_instance_get_restart_nr(conf_instance , obs_label , history , size); /** Build the observation. */ for(int obs_pt_nr = 0; obs_pt_nr < num_obs_pts; obs_pt_nr++) { const char * obs_key = stringlist_iget(obs_pt_keys, obs_pt_nr); const conf_instance_type * obs_instance = conf_instance_get_sub_instance_ref(conf_instance, obs_key); const char * error_mode = conf_instance_get_item_value_ref(obs_instance, "ERROR_MODE"); double error = conf_instance_get_item_value_double(obs_instance, "ERROR"); double value = conf_instance_get_item_value_double(obs_instance, "VALUE"); double min_error = conf_instance_get_item_value_double(obs_instance, "ERROR_MIN"); if (strcmp( error_mode , "REL") == 0) error *= value; else if (strcmp( error_mode , "RELMIN") == 0) error = util_double_max( error * value , min_error ); obs_value[obs_pt_nr] = value; obs_std [obs_pt_nr] = error; /** The input values i,j,k come from the user, and are offset 1. They are immediately shifted with -1 to become C-based offset zero. */ obs_i[obs_pt_nr] = conf_instance_get_item_value_int( obs_instance, "I") - 1; obs_j[obs_pt_nr] = conf_instance_get_item_value_int( obs_instance, "J") - 1; obs_k[obs_pt_nr] = conf_instance_get_item_value_int( obs_instance, "K") - 1; if (source_type == SOURCE_SUMMARY) { char * summary_key = smspec_alloc_block_ijk_key( SUMMARY_KEY_JOIN_STRING , sum_kw , obs_i[obs_pt_nr] + 1 , obs_j[obs_pt_nr] + 1 , obs_k[obs_pt_nr] + 1 ); stringlist_append_owned_ref( summary_keys , summary_key ); } } if (source_type == SOURCE_FIELD) { const enkf_config_node_type * config_node = ensemble_config_get_node( ensemble_config , field_name); const field_config_type * field_config = enkf_config_node_get_ref( config_node ); block_obs_type * block_obs = block_obs_alloc_complete(obs_label, source_type , NULL , field_config , grid , num_obs_pts, obs_i, obs_j, obs_k, obs_value, obs_std); if (block_obs != NULL) { obs_vector = obs_vector_alloc( BLOCK_OBS , obs_label , ensemble_config_get_node(ensemble_config , field_name), size ); obs_vector_install_node( obs_vector , obs_restart_nr , block_obs); } } else if (source_type == SOURCE_SUMMARY) { OK = true; if (refcase != NULL) { for (int i=0; i < stringlist_get_size( summary_keys ); i++) { const char * sum_key = stringlist_iget( summary_keys , i ); if (!ecl_sum_has_key(refcase , sum_key)) { /* If the */ fprintf(stderr,"** Warning missing summary %s for cell: (%d,%d,%d) in refcase - make sure that \"BPR %d %d %d\" is included in ECLIPSE summary specification \n" , sum_key , obs_i[i]+1 , obs_j[i]+1 , obs_k[i]+1 , obs_i[i]+1 , obs_j[i]+1 , obs_k[i]+1 ); //OK = false; } } } if (OK) { // We can create the container node and add the summary nodes. enkf_config_node_type * container_config = ensemble_config_add_container( ensemble_config , NULL ); for (int i=0; i < stringlist_get_size( summary_keys ); i++) { const char * sum_key = stringlist_iget( summary_keys , i ); enkf_config_node_type * child_node = ensemble_config_add_summary( ensemble_config , sum_key , LOAD_FAIL_WARN ); enkf_config_node_update_container( container_config , child_node ); } { block_obs_type * block_obs = block_obs_alloc_complete(obs_label, source_type , summary_keys , enkf_config_node_get_ref(container_config) , grid , num_obs_pts, obs_i, obs_j, obs_k, obs_value, obs_std); if (block_obs != NULL) { obs_vector = obs_vector_alloc( BLOCK_OBS , obs_label , container_config, size ); obs_vector_install_node( obs_vector , obs_restart_nr , block_obs); } } } } else util_abort("%s: invalid source value \n",__func__); free(obs_value); free(obs_std); free(obs_i); free(obs_j); free(obs_k); stringlist_free(obs_pt_keys); stringlist_free(summary_keys); return obs_vector; } else { fprintf(stderr,"** Warning the ensemble key:%s does not exist - observation:%s not added \n", field_name , obs_label); return NULL; } }
bool obs_vector_load_from_HISTORY_OBSERVATION(obs_vector_type * obs_vector , const conf_instance_type * conf_instance , const history_type * history , ensemble_config_type * ensemble_config, double std_cutoff ) { if(!conf_instance_is_of_class(conf_instance, "HISTORY_OBSERVATION")) util_abort("%s: internal error. expected \"HISTORY_OBSERVATION\" instance, got \"%s\".\n",__func__, conf_instance_get_class_name_ref(conf_instance) ); { bool initOK = false; int size , restart_nr; double_vector_type * value = double_vector_alloc(0,0); double_vector_type * std = double_vector_alloc(0,0); bool_vector_type * valid = bool_vector_alloc(0 , false); /* The auto_corrf parameters can not be "segmentized" */ double auto_corrf_param = -1; const char * auto_corrf_name = NULL; double error = conf_instance_get_item_value_double(conf_instance, "ERROR" ); double error_min = conf_instance_get_item_value_double(conf_instance, "ERROR_MIN" ); const char * error_mode = conf_instance_get_item_value_ref( conf_instance, "ERROR_MODE"); const char * sum_key = conf_instance_get_name_ref( conf_instance ); if(conf_instance_has_item(conf_instance, "AUTO_CORRF")) { auto_corrf_name = conf_instance_get_item_value_ref( conf_instance , "AUTO_CORRF"); auto_corrf_param = conf_instance_get_item_value_double(conf_instance, "AUTO_CORRF_PARAM"); if(conf_instance_has_item(conf_instance, "AUTO_CORRF_PARAM")) auto_corrf_param = conf_instance_get_item_value_double(conf_instance, "AUTO_CORRF_PARAM"); else util_abort("%s: When specifying AUTO_CORRF you must also give a vlaue for AUTO_CORRF_PARAM",__func__); } // Get time series data from history object and allocate size = history_get_last_restart(history); if (history_init_ts( history , sum_key , value , valid )) { // Create the standard deviation vector if(strcmp(error_mode, "ABS") == 0) { for( restart_nr = 0; restart_nr < size; restart_nr++) double_vector_iset( std , restart_nr , error ); } else if(strcmp(error_mode, "REL") == 0) { for( restart_nr = 0; restart_nr < size; restart_nr++) double_vector_iset( std , restart_nr , error * abs( double_vector_iget( value , restart_nr ))); } else if(strcmp(error_mode, "RELMIN") == 0) { for(restart_nr = 0; restart_nr < size; restart_nr++) { double tmp_std = util_double_max( error_min , error * abs( double_vector_iget( value , restart_nr ))); double_vector_iset( std , restart_nr , tmp_std); } } else util_abort("%s: Internal error. Unknown error mode \"%s\"\n", __func__, error_mode); // Handle SEGMENTs which can be used to customize the observation error. */ { stringlist_type * segment_keys = conf_instance_alloc_list_of_sub_instances_of_class_by_name(conf_instance, "SEGMENT"); stringlist_sort( segment_keys , NULL ); int num_segments = stringlist_get_size(segment_keys); for(int segment_nr = 0; segment_nr < num_segments; segment_nr++) { const char * segment_name = stringlist_iget(segment_keys, segment_nr); const conf_instance_type * segment_conf = conf_instance_get_sub_instance_ref(conf_instance, segment_name); int start = conf_instance_get_item_value_int( segment_conf, "START" ); int stop = conf_instance_get_item_value_int( segment_conf, "STOP" ); double error_segment = conf_instance_get_item_value_double(segment_conf, "ERROR" ); double error_min_segment = conf_instance_get_item_value_double(segment_conf, "ERROR_MIN" ); const char * error_mode_segment = conf_instance_get_item_value_ref( segment_conf, "ERROR_MODE"); if(start < 0) { printf("%s: WARNING - Segment out of bounds. Truncating start of segment to 0.\n", __func__); start = 0; } if(stop >= size) { printf("%s: WARNING - Segment out of bounds. Truncating end of segment to %d.\n", __func__, size - 1); stop = size -1; } if(start > stop) { printf("%s: WARNING - Segment start after stop. Truncating end of segment to %d.\n", __func__, start ); stop = start; } // Create the standard deviation vector if(strcmp(error_mode_segment, "ABS") == 0) { for( restart_nr = start; restart_nr <= stop; restart_nr++) double_vector_iset( std , restart_nr , error_segment) ; } else if(strcmp(error_mode_segment, "REL") == 0) { for( restart_nr = start; restart_nr <= stop; restart_nr++) double_vector_iset( std , restart_nr , error_segment * abs(double_vector_iget( value , restart_nr))); } else if(strcmp(error_mode_segment, "RELMIN") == 0) { for(restart_nr = start; restart_nr <= stop ; restart_nr++) { double tmp_std = util_double_max( error_min_segment , error_segment * abs( double_vector_iget( value , restart_nr ))); double_vector_iset( std , restart_nr , tmp_std); } } else util_abort("%s: Internal error. Unknown error mode \"%s\"\n", __func__, error_mode); } stringlist_free(segment_keys); } /* This is where the summary observations are finally added. */ for (restart_nr = 0; restart_nr < size; restart_nr++) { if (bool_vector_safe_iget( valid , restart_nr)) { if (double_vector_iget( std , restart_nr) > std_cutoff) { obs_vector_add_summary_obs( obs_vector , restart_nr , sum_key , sum_key , double_vector_iget( value ,restart_nr) , double_vector_iget( std , restart_nr ) , auto_corrf_name , auto_corrf_param); } else fprintf(stderr,"** Warning: to small observation error in observation %s:%d - ignored. \n", sum_key , restart_nr); } } initOK = true; } double_vector_free(std); double_vector_free(value); bool_vector_free(valid); return initOK; } }