def test_setup_iterative_ensemble_smoother(self): config_file = self.createTestPath("local/poly_example/poly.ert") with ErtTestContext("_setup_iterative_ensemble_smoother", config_file) as work_area: ert = work_area.getErt() facade = LibresFacade(ert) args = Namespace( realizations="0-4,7,8", target_case="test_case_%d", num_iterations="10", ) model = model_factory._setup_iterative_ensemble_smoother( ert, args, facade.get_ensemble_size(), facade.get_current_case_name(), ) self.assertTrue(isinstance(model, IteratedEnsembleSmoother)) self.assertEqual(4, len(model._simulation_arguments.keys())) self.assertTrue( "active_realizations" in model._simulation_arguments) self.assertTrue("target_case" in model._simulation_arguments) self.assertTrue("analysis_module" in model._simulation_arguments) self.assertTrue("num_iterations" in model._simulation_arguments) self.assertTrue(facade.get_number_of_iterations() == 10) model.create_context(0)
def test_setup_multiple_data_assimilation(self): config_file = self.createTestPath("local/poly_example/poly.ert") with ErtTestContext("test_single_test_run", config_file) as work_area: ert = work_area.getErt() facade = LibresFacade(ert) args = Namespace( realizations="0-4,7,8", weights="6,4,2", target_case="test_case_%d", start_iteration="0", ) model = model_factory._setup_multiple_data_assimilation( ert, args, facade.get_ensemble_size(), facade.get_current_case_name(), ) self.assertTrue(isinstance(model, MultipleDataAssimilation)) self.assertEqual(5, len(model._simulation_arguments.keys())) self.assertTrue( "active_realizations" in model._simulation_arguments) self.assertTrue("target_case" in model._simulation_arguments) self.assertTrue("analysis_module" in model._simulation_arguments) self.assertTrue("weights" in model._simulation_arguments) self.assertTrue("start_iteration" in model._simulation_arguments) model.create_context(0)
def test_default_target_case_name_format_mode(self): config_file = self.createTestPath("local/poly_example/poly.ert") with ErtTestContext("test_default_target_case_name_format_mode", config_file) as work_area: ert = work_area.getErt() facade = LibresFacade(ert) args = Namespace(target_case=None) res = model_factory._target_case_name( ert, args, facade.get_current_case_name(), format_mode=True) self.assertEqual("default_%d", res)
def test_custom_target_case_name(self): config_file = self.createTestPath("local/poly_example/poly.ert") with ErtTestContext("test_custom_target_case_name", config_file) as work_area: ert = work_area.getErt() facade = LibresFacade(ert) custom_name = "test" args = Namespace(target_case=custom_name) res = model_factory._target_case_name( ert, args, facade.get_current_case_name()) self.assertEqual(custom_name, res)
def __init__(self, facade: LibresFacade): self.facade = facade QWidget.__init__(self) self.setMinimumWidth(500) self.setMinimumHeight(200) self._dynamic = False self.setWindowTitle("Load results manually") self.activateWindow() layout = QFormLayout() current_case = facade.get_current_case_name() run_path_text = QTextEdit() run_path_text.setText(self.readCurrentRunPath()) run_path_text.setDisabled(True) run_path_text.setFixedHeight(80) layout.addRow("Load data from current run path: ", run_path_text) self._case_model = AllCasesModel(self.facade) self._case_combo = QComboBox() self._case_combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self._case_combo.setMinimumContentsLength(20) self._case_combo.setModel(self._case_model) self._case_combo.setCurrentIndex(self._case_model.indexOf(current_case)) layout.addRow("Load into case:", self._case_combo) self._active_realizations_model = ActiveRealizationsModel(self.facade) self._active_realizations_field = StringBox( self._active_realizations_model, "load_results_manually/Realizations" ) self._active_realizations_field.setValidator(RangeStringArgument()) layout.addRow("Realizations to load:", self._active_realizations_field) self._iterations_model = ValueModel(self.iteration_count) self._iterations_field = StringBox( self._iterations_model, "load_results_manually/iterations" ) self._iterations_field.setValidator(IntegerArgument()) layout.addRow("Iteration to load:", self._iterations_field) self.setLayout(layout)
def test_tracking( extra_config, extra_poly_eval, cmd_line_arguments, num_successful, num_iters, progress, assert_present_in_snapshot, tmpdir, source_root, ): experiment_folder = "poly_example" shutil.copytree( os.path.join(source_root, "test-data", "local", f"{experiment_folder}"), os.path.join(str(tmpdir), f"{experiment_folder}"), ) config_lines = [ "INSTALL_JOB poly_eval2 POLY_EVAL\n" "SIMULATION_JOB poly_eval2\n", extra_config, ] with tmpdir.as_cwd(): with open(f"{experiment_folder}/poly.ert", "a") as fh: fh.writelines(config_lines) with fileinput.input(f"{experiment_folder}/poly_eval.py", inplace=True) as fin: for line in fin: if line.strip().startswith("coeffs"): print(extra_poly_eval) print(line, end="") parser = ArgumentParser(prog="test_main") parsed = ert_parser( parser, cmd_line_arguments, ) FeatureToggling.update_from_args(parsed) res_config = ResConfig(parsed.config) os.chdir(res_config.config_path) ert = EnKFMain(res_config, strict=True, verbose=parsed.verbose) facade = LibresFacade(ert) model = create_model( ert, facade.get_ensemble_size(), facade.get_current_case_name(), parsed, ) evaluator_server_config = EvaluatorServerConfig( custom_port_range=range(1024, 65535), custom_host="127.0.0.1" ) thread = threading.Thread( name="ert_cli_simulation_thread", target=model.start_simulations_thread, args=(evaluator_server_config,), ) thread.start() tracker = EvaluatorTracker( model, ee_con_info=evaluator_server_config.get_connection_info(), ) snapshots = {} for event in tracker.track(): if isinstance(event, FullSnapshotEvent): snapshots[event.iteration] = event.snapshot if isinstance(event, SnapshotUpdateEvent): if event.partial_snapshot is not None: snapshots[event.iteration].merge(event.partial_snapshot.data()) if isinstance(event, EndEvent): pass assert tracker._progress() == progress assert len(snapshots) == num_iters for iter_, snapshot in snapshots.items(): successful_reals = list( filter( lambda item: item[1].status == REALIZATION_STATE_FINISHED, snapshot.reals.items(), ) ) assert len(successful_reals) == num_successful for ( iter_expression, snapshot_expression, expected, ) in assert_present_in_snapshot: for i, snapshot in snapshots.items(): if re.match(iter_expression, str(i)): check_expression( snapshot.to_dict(), snapshot_expression, expected, f"Snapshot {i} did not match:\n", ) thread.join() FeatureToggling.reset()
def run_cli(args): res_config = ResConfig(args.config) # Create logger inside function to make sure all handlers have been added to # the root-logger. logger = logging.getLogger(__name__) logger.info( "Logging forward model jobs", extra={ "workflow_jobs": str(res_config.model_config.getForwardModel().joblist()) }, ) os.chdir(res_config.config_path) ert = EnKFMain(res_config, strict=True, verbose=args.verbose) facade = LibresFacade(ert) if args.mode == WORKFLOW_MODE: execute_workflow(ert, args.name) return model = create_model( ert, facade.get_ensemble_size(), facade.get_current_case_name(), args, ) # Test run does not have a current_case if "current_case" in args and args.current_case: facade.select_or_create_new_case(args.current_case) if (args.mode in [ ENSEMBLE_SMOOTHER_MODE, ITERATIVE_ENSEMBLE_SMOOTHER_MODE, ES_MDA_MODE ] and args.target_case == facade.get_current_case_name()): msg = ( "ERROR: Target file system and source file system can not be the same. " "They were both: {}.".format(args.target_case)) raise ErtCliError(msg) evaluator_server_config = EvaluatorServerConfig( custom_port_range=args.port_range) thread = threading.Thread( name="ert_cli_simulation_thread", target=model.start_simulations_thread, args=(evaluator_server_config, ), ) thread.start() tracker = EvaluatorTracker( model, ee_con_info=evaluator_server_config.get_connection_info()) out = open(os.devnull, "w") if args.disable_monitoring else sys.stderr monitor = Monitor(out=out, color_always=args.color_always) try: monitor.monitor(tracker) except (SystemExit, KeyboardInterrupt): print("\nKilling simulations...") tracker.request_termination() if args.disable_monitoring: out.close() thread.join() if model.hasRunFailed(): raise ErtCliError(model.getFailMessage())
def run(self, target_name="analysis_case", prior_name=None, group_by="data_key"): """Perform analysis of parameters change per obs group prior to posterior of ahm""" ert = self.ert() facade = LibresFacade(self.ert()) obs_keys = [ facade.get_observation_key(nr) for nr, _ in enumerate(facade.get_observations()) ] key_map = _group_observations(facade, obs_keys, group_by) prior_name, target_name = check_names( facade.get_current_case_name(), prior_name, target_name, ) # Get the prior scalar parameter distributions prior_data = GenKwCollector.loadAllGenKwData(ert, prior_name) raise_if_empty( dataframes=[ prior_data, MisfitCollector.loadAllMisfitData(ert, prior_name) ], messages=[ "Empty prior ensemble", "Empty parameters set for History Matching", ], ) # create dataframe with observations vectors (1 by 1 obs and also all_obs) combinations = make_obs_groups(key_map) field_parameters = sorted(ert.ensembleConfig().getKeylistFromImplType( ErtImplType.FIELD)) scalar_parameters = sorted(ert.ensembleConfig().getKeylistFromImplType( ErtImplType.GEN_KW)) # identify the set of actual parameters that was updated for now just go # through scalar parameters but in future if easier access to field parameter # updates should also include field parameters dkeysf = get_updated_parameters(prior_data, scalar_parameters) # setup dataframe for calculated data kolmogorov_smirnov_data, active_obs, misfitval = ( pd.DataFrame(sorted(dkeysf), columns=["Parameters"]), pd.DataFrame(), pd.DataFrame(index=["misfit"]), ) # loop over keys and calculate the KS matrix, # conditioning one parameter at the time. field_output = {} for group_name, obs_group in combinations.items(): print("Processing:", group_name) # Use localization to evaluate change of parameters for each observation with tempfile.TemporaryDirectory() as update_log_path: _run_ministep( ert, obs_group, field_parameters + scalar_parameters, prior_name, target_name, update_log_path, ) # Get the active vs total observation info df_update_log = make_update_log_df(update_log_path) # Get the updated scalar parameter distributions self.reporter.publish_csv( group_name, GenKwCollector.loadAllGenKwData(ert, target_name)) active_obs.at["ratio", group_name] = ( str(count_active_observations(df_update_log)) + " active/" + str(len(df_update_log.index))) # Get misfit values misfitval[group_name] = [ calc_observationsgroup_misfit( group_name, df_update_log, MisfitCollector.loadAllMisfitData(ert, prior_name), ) ] # Calculate Ks matrix for scalar parameters kolmogorov_smirnov_data[group_name] = kolmogorov_smirnov_data[ "Parameters"].map( calc_kolmogorov_smirnov( dkeysf, prior_data, GenKwCollector.loadAllGenKwData(ert, target_name), )) field_output[group_name] = _get_field_params( ert, facade.get_ensemble_size(), field_parameters, target_name) kolmogorov_smirnov_data.set_index("Parameters", inplace=True) # Calculate Ks matrix for Fields parameters if field_parameters: # Get grid characteristics to be able to plot field avg maps grid_xyzcenter = load_grid_to_dataframe( ert.eclConfig().get_gridfile()) all_input_prior = _get_field_params(ert, facade.get_ensemble_size(), field_parameters, prior_name) for fieldparam in field_parameters: scaler = StandardScaler() scaler.fit(all_input_prior[fieldparam]) pca = PCA(0.98).fit( pd.DataFrame(scaler.transform( all_input_prior[fieldparam]))) pc_fieldprior_df = pd.DataFrame(data=pca.transform( scaler.transform(all_input_prior[fieldparam]))) all_kolmogorov_smirnov = pd.DataFrame( pc_fieldprior_df.columns.tolist(), columns=["PCFieldParameters"]) # Get the posterior Field parameters map_calc_properties = (grid_xyzcenter[grid_xyzcenter["KZ"] == 1].copy().reset_index()) for group_name in combinations.keys(): map_calc_properties[ "Mean_D_" + group_name] = calc_mean_delta_grid( field_output[group_name][fieldparam], all_input_prior[fieldparam], grid_xyzcenter, ) pc_fieldpost_df = pd.DataFrame(data=pca.transform( scaler.transform(field_output[group_name] [fieldparam]))) all_kolmogorov_smirnov[ group_name] = all_kolmogorov_smirnov[ "PCFieldParameters"].map( calc_kolmogorov_smirnov( pc_fieldpost_df, pc_fieldprior_df, pc_fieldpost_df, )) all_kolmogorov_smirnov.set_index("PCFieldParameters", inplace=True) # add the field max Ks to the scalar Ks matrix kolmogorov_smirnov_data.loc[ "FIELD_" + fieldparam] = all_kolmogorov_smirnov.max() self.reporter.publish_csv("delta_field" + fieldparam, map_calc_properties) # save/export the Ks matrix, active_obs, misfitval and prior data self.reporter.publish_csv("ks", kolmogorov_smirnov_data) self.reporter.publish_csv("active_obs_info", active_obs) self.reporter.publish_csv("misfit_obs_info", misfitval) self.reporter.publish_csv("prior", prior_data)
class SimulationPanel(QWidget): def __init__(self, ert: EnKFMain, notifier: ErtNotifier, config_file: str): self.notifier = notifier QWidget.__init__(self) self.ert = ert self.facade = LibresFacade(ert) self._config_file = config_file self.setObjectName("Simulation_panel") layout = QVBoxLayout() self._simulation_mode_combo = QComboBox() self._simulation_mode_combo.setObjectName("Simulation_mode") addHelpToWidget(self._simulation_mode_combo, "run/simulation_mode") self._simulation_mode_combo.currentIndexChanged.connect( self.toggleSimulationMode) simulation_mode_layout = QHBoxLayout() simulation_mode_layout.addSpacing(10) simulation_mode_layout.addWidget(QLabel("Simulation mode:"), 0, Qt.AlignVCenter) simulation_mode_layout.addWidget(self._simulation_mode_combo, 0, Qt.AlignVCenter) simulation_mode_layout.addSpacing(20) self.run_button = QToolButton() self.run_button.setObjectName("start_simulation") self.run_button.setText("Start simulation") self.run_button.setIcon(resourceIcon("play_circle.svg")) self.run_button.setIconSize(QSize(32, 32)) self.run_button.clicked.connect(self.runSimulation) self.run_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) addHelpToWidget(self.run_button, "run/start_simulation") simulation_mode_layout.addWidget(self.run_button) simulation_mode_layout.addStretch(1) layout.addSpacing(5) layout.addLayout(simulation_mode_layout) layout.addSpacing(10) self._simulation_stack = QStackedWidget() self._simulation_stack.setLineWidth(1) self._simulation_stack.setFrameStyle(QFrame.StyledPanel) layout.addWidget(self._simulation_stack) self._simulation_widgets = OrderedDict() """ :type: OrderedDict[BaseRunModel,SimulationConfigPanel]""" self.addSimulationConfigPanel(SingleTestRunPanel(ert, notifier)) self.addSimulationConfigPanel(EnsembleExperimentPanel(ert, notifier)) if self.facade.have_observations: self.addSimulationConfigPanel(EnsembleSmootherPanel(ert, notifier)) self.addSimulationConfigPanel( MultipleDataAssimilationPanel(self.facade, notifier)) self.addSimulationConfigPanel( IteratedEnsembleSmootherPanel(self.facade, notifier)) self.setLayout(layout) def addSimulationConfigPanel(self, panel): assert isinstance(panel, SimulationConfigPanel) self._simulation_stack.addWidget(panel) simulation_model = panel.getSimulationModel() self._simulation_widgets[simulation_model] = panel self._simulation_mode_combo.addItem(simulation_model.name(), simulation_model) panel.simulationConfigurationChanged.connect( self.validationStatusChanged) def getActions(self): return [] def getCurrentSimulationModel(self): return self._simulation_mode_combo.itemData( self._simulation_mode_combo.currentIndex(), Qt.UserRole) def getSimulationArguments(self): """@rtype: dict[str,object]""" simulation_widget = self._simulation_widgets[ self.getCurrentSimulationModel()] args = simulation_widget.getSimulationArguments() return args def runSimulation(self): case_name = self.facade.get_current_case_name() message = ( f"Are you sure you want to use case '{case_name}' for initialization of " "the initial ensemble when running the simulations?") start_simulations = QMessageBox.question( self, "Start simulations?", message, QMessageBox.Yes | QMessageBox.No) if start_simulations == QMessageBox.Yes: arguments = self.getSimulationArguments() dialog = RunDialog( self._config_file, create_model( self.ert, self.facade.get_ensemble_size(), self.facade.get_current_case_name(), arguments, ), ) dialog.startSimulation() dialog.exec_() self.notifier.emitErtChange( ) # simulations may have added new cases def toggleSimulationMode(self): current_model = self.getCurrentSimulationModel() if current_model is not None: widget = self._simulation_widgets[self.getCurrentSimulationModel()] self._simulation_stack.setCurrentWidget(widget) self.validationStatusChanged() def validationStatusChanged(self): widget = self._simulation_widgets[self.getCurrentSimulationModel()] self.run_button.setEnabled(widget.isConfigurationValid())