csdms

Source code for dakotathon.plugins.hydrotrend

#! /usr/bin/env python
"""Provides a Dakota interface to the HydroTrend model."""

import os
import shutil
import subprocess
import numpy as np
from .base import PluginBase
from dakotathon.utils import get_response_descriptors, write_results, compute_statistic


classname = "HydroTrend"


[docs]def is_installed(): """Check whether HydroTrend is in the execution path.""" try: subprocess.call(["hydrotrend", "--version"]) except OSError: return False else: return True
[docs]class HydroTrend(PluginBase): """Represent a HydroTrend simulation in a Dakota experiment."""
[docs] def __init__( self, input_dir="HYDRO_IN", output_dir="HYDRO_OUTPUT", input_file="HYDRO.IN", input_template="HYDRO.IN.dtmpl", hypsometry_file="HYDRO0.HYPS", output_files=None, output_statistics=None, **kwargs ): """Configure a default HydroTrend simulation. Parameters ---------- input_dir : str, optional HydroTrend input directory (default is 'HYDRO_IN'). output_dir : str, optional HydroTrend output directory (default is 'HYDRO_OUTPUT'). input_file : str, optional HydroTrend input file (default is 'HYDRO.IN'). input_template : str, optional Dakota template formed from HydroTrend input file (default is 'HYDRO.IN.dtmpl'). hypsometry_file : str, optional The hypsometry file for the HydroTrend experiment. output_files : str or list or tuple of str, optional HydroTrend output files to analyze. output_statistics : str or list or tuple of str, optional Statistics to apply to HydroTrend output. **kwargs Optional keyword arguments. Examples -------- Create a HydroTrend instance with: >>> h = HydroTrend() """ PluginBase.__init__(self, **kwargs) self.input_dir = input_dir self.output_dir = output_dir self.input_file = input_file self.input_template = input_template self.hypsometry_file = hypsometry_file self.output_files = output_files self.output_statistics = output_statistics self.output_values = []
[docs] def setup(self, config): """Configure HydroTrend inputs. Sets attributes using information from the run configuration file. The Dakota parsing utility ``dprepro`` reads parameters from Dakota to create a new HydroTrend input file from a template. Parameters ---------- config : dict Stores configuration settings for a Dakota experiment. """ self.setup_files(config) self.setup_directories(config) subprocess.call( ["dprepro", config["parameters_file"], self.input_template, self.input_file] ) shutil.copy(self.input_file, self.input_dir) shutil.copy(self.hypsometry_file, self.input_dir)
[docs] def setup_files(self, config): """Configure HydroTrend input and output files. Parameters ---------- config : dict Configuration settings for a Dakota experiment. """ self.input_template = config["template_file"] self.hypsometry_file, = config["auxiliary_files"] self.output_files = config["response_files"] self.output_statistics = config["response_statistics"]
[docs] def setup_directories(self, config): """Configure HydroTrend input and output directories. Parameters ---------- config : dict Configuration settings for a Dakota experiment. """ # self.input_dir = os.path.join(config['run_directory'], 'HYDRO_IN') # self.output_dir = os.path.join(config['run_directory'], 'HYDRO_OUTPUT') self.input_dir = os.path.join("..", "HYDRO_IN") self.output_dir = os.path.join("..", "HYDRO_OUTPUT") if os.path.exists(self.input_dir) is False: os.mkdir(self.input_dir, 0o755) if os.path.exists(self.output_dir) is False: os.mkdir(self.output_dir, 0o755)
[docs] def call(self): """Invoke HydroTrend through the shell.""" subprocess.call( ["hydrotrend", "--in-dir", self.input_dir, "--out-dir", self.output_dir] )
[docs] def load(self, output_file): """Read a column of data from a HydroTrend output file. Parameters ---------- output_file : str The path to a text HydroTrend output file. Returns ------- array_like A numpy array, or None on an error. """ try: series = np.loadtxt(output_file, skiprows=2) except (IOError, StopIteration): return None else: return series
[docs] def calculate(self): """Calculate Dakota output functions.""" for rfile, rstat in zip(self.output_files, self.output_statistics): shutil.copy(os.path.join(self.output_dir, rfile), os.curdir) series = self.load(rfile) if series is not None: val = compute_statistic(rstat, series) self.output_values.append(val) else: self.output_values.append(float("nan"))
[docs] def write(self, params_file, results_file): """Write the Dakota results file. Parameters ---------- params_file : str A Dakota parameters file. results_file : str A Dakota results file. """ labels = get_response_descriptors(params_file) write_results(results_file, self.output_values, labels)