def main():

    # Parse command line arguments.
    parser = argparse.ArgumentParser(
        description=
        'This script open an interactive tree view with all settings of a biogeochemical model.'
    )
    parser.add_argument(
        'path',
        help=
        'Path to a YAML file with the model configuration (typically fabm.yaml)',
        nargs='?',
        default='fabm.yaml')
    args = parser.parse_args()

    # Create model object
    model = pyfabm.Model(args.path)

    # Create Qt application object
    app = QtGui.QApplication([' '])

    # Create dialog box with model configuration tree.
    dialog = QtGui.QDialog()
    dialog.setWindowTitle('Configure model')
    layout = QtGui.QHBoxLayout()
    tree = pyfabm.gui_qt.TreeView(model, dialog)
    layout.addWidget(tree)
    dialog.setLayout(layout)
    dialog.show()

    # Show dialog
    ret = app.exec_()
Exemple #2
0
def test_pyfabm(args, testcases):
    build_dir = os.path.join(args.work_root, 'build')
    if not cmake('test_pyfabm',
                 build_dir,
                 os.path.join(fabm_base, 'src/drivers/python'),
                 args.cmake,
                 cmake_arguments=[
                     '-DCMAKE_BUILD_TYPE=debug',
                     '-DPYTHON_EXECUTABLE=%s' % sys.executable
                 ] + args.cmake_arguments):
        return
    sys.path.insert(0, build_dir)
    import pyfabm
    dependency_names = set()
    print('pyfabm loaded from %s (library = %s)' %
          (pyfabm.__file__, pyfabm.dllpath))
    print('Running FABM testcases with pyfabm:')
    for case, path in testcases.items():
        print('  %s... ' % case, end='')
        sys.stdout.flush()
        m = pyfabm.Model(path)
        m.cell_thickness = 1.
        for d in m.dependencies:
            dependency_names.add(d.name)
            d.value = 1.
        m.start()
        m.getRates()
        print('SUCCESS')
    try:
        pyfabm.unload()
    except Exception as e:
        print('Failed to unload pyfabm: %s' % e)
    if args.verbose:
        print('Combined dependency list:\n%s' %
              '\n'.join(sorted(dependency_names)))
Exemple #3
0
def main():
    import argparse

    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        'path',
        help=
        'Path to a YAML file with the model configuration (typically fabm.yaml)',
        nargs='?',
        default='fabm.yaml')
    parser.add_argument(
        '--all',
        '-a',
        action='store_true',
        help='Show diagnostics that are by default excluded from output')
    args = parser.parse_args()

    # Create model object from YAML file.
    model = pyfabm.Model(args.path)

    print('Interior state variables:')
    for variable in model.interior_state_variables:
        print('  %s = %s (%s)' %
              (variable.name, variable.long_name, variable.units))

    print('Surface-attached state variables:')
    for variable in model.surface_state_variables:
        print('  %s = %s (%s)' %
              (variable.name, variable.long_name, variable.units))

    print('Bottom-attached state variables:')
    for variable in model.bottom_state_variables:
        print('  %s = %s (%s)' %
              (variable.name, variable.long_name, variable.units))

    print('Interior diagnostic variables:')
    for variable in model.interior_diagnostic_variables:
        if variable.output or args.all:
            print('  %s = %s (%s)' %
                  (variable.name, variable.long_name, variable.units))

    print('Horizontal diagnostic variables:')
    for variable in model.horizontal_diagnostic_variables:
        if variable.output or args.all:
            print('  %s = %s (%s)' %
                  (variable.name, variable.long_name, variable.units))

    print('Conserved quantities:')
    for variable in model.conserved_quantities:
        print('  %s (%s)' % (variable.name, variable.units))

    print('Dependencies:')
    for variable in model.dependencies:
        print('  %s = %s (%s)' %
              (variable.name, variable.long_name, variable.units))
Exemple #4
0
def main():

    parser = argparse.ArgumentParser(description='This script lists all state variables, diagnostic variables, conserved quantities and environmental dependencies of a biogeochemical model.')
    parser.add_argument('path',help='Path to a YAML file with the model configuration (typically fabm.yaml)',nargs='?',default='fabm.yaml')
    args = parser.parse_args()

    # Create model object from YAML file.
    model = pyfabm.Model(args.path)

    print 'Interior state variables:'
    for variable in model.bulk_state_variables:
       print '  %s = %s (%s)' % (variable.name,variable.long_name,variable.units)

    print 'Surface-attached state variables:'
    for variable in model.surface_state_variables:
       print '  %s = %s (%s)' % (variable.name,variable.long_name,variable.units)

    print 'Bottom-attached state variables:'
    for variable in model.bottom_state_variables:
       print '  %s = %s (%s)' % (variable.name,variable.long_name,variable.units)

    print 'Interior diagnostic variables:'
    for variable in model.bulk_diagnostic_variables:
       print '  %s = %s (%s)' % (variable.name,variable.long_name,variable.units)

    print 'Horizontal diagnostic variables:'
    for variable in model.horizontal_diagnostic_variables:
       print '  %s = %s (%s)' % (variable.name,variable.long_name,variable.units)

    print 'Conserved quantities:'
    for variable in model.conserved_quantities:
       print '  %s (%s)' % (variable.name,variable.units)

    print 'Dependencies:'
    for variable in model.dependencies:
       print '  %s = %s (%s)' % (variable.name,variable.long_name,variable.units)
Exemple #5
0
def main():
    import argparse

    tests = {
        'randomized': testRandomized,
        'extremes_per_variable': testExtremes,
        'extremes_randomized': testRandomizedExtremes,
        'extremes_all': testExtremesRecursive
    }

    parser = argparse.ArgumentParser(
        description=
        'This script verifies that a biogeochemical model returns valid derivatives under a wide variety of inputs (state variables, environmental dependencies). Different tests can be run, using either random values or extremes for inputs, and running randomized or exhaustive tests.'
    )
    parser.add_argument(
        'model_path',
        help=
        'Path to a YAML file with the model configuration (typically fabm.yaml)'
    )
    parser.add_argument(
        'ranges_path',
        help=
        'Path to a YAML file with ranges for all model inputs (state variables, environmental dependencies)'
    )
    parser.add_argument(
        '--test',
        choices=tests.keys(),
        action='append',
        help=
        'Path to a YAML file with ranges for all model inputs (state variables, environmental dependencies)'
    )
    parser.add_argument('--write-ranges',
                        action='store_true',
                        help='Write ranges file with default variable ranges')
    args = parser.parse_args()

    # Create model object from YAML file.
    model = pyfabm.Model(args.model_path)

    if args.write_ranges:
        with open(args.ranges_path, 'w') as f:

            def writeRanges(variables):
                for variable in variables:
                    f.write('%s: [0,%s]\n' %
                            (variable.name, 10 * variable.value))

            writeRanges(model.state_variables)
            writeRanges(model.dependencies)
        print('Default ranges have been written to %s.' % args.ranges_path)
        sys.exit(0)

    with open(args.ranges_path, 'rU') as f:
        ranges = yaml.load(f)
    if not isinstance(ranges, dict):
        print(
            'Range file %s should contain a dictionary mapping each variable to its range (or constant value).'
            % args.ranges_path)
        sys.exit(1)

    vary = []
    found_variables = set()
    testRangePresence(ranges, model.state_variables, vary, found_variables)
    testRangePresence(ranges, model.dependencies, vary, found_variables)

    for variable_name in ranges.keys():
        if variable_name not in found_variables:
            print(
                'WARNING: range specification for unknown variable %s in %s will be ignored.'
                % (variable_name, args.ranges_path))

    if args.test is None:
        check(model)
    else:
        for test in args.test:
            tests[test](model, vary)
    sys.exit(1)

parser = argparse.ArgumentParser(
    description=
    'This script lists all state variables, diagnostic variables, conserved quantities and environmental dependencies of a biogeochemical model.'
)
parser.add_argument(
    'path',
    help=
    'Path to a YAML file with the model configuration (typically fabm.yaml)',
    nargs='?',
    default='fabm.yaml')
args = parser.parse_args()

# Create model object from YAML file.
model = pyfabm.Model(args.path)

print 'Interior state variables:'
for variable in model.bulk_state_variables:
    print '  %s = %s (%s)' % (variable.name, variable.long_name,
                              variable.units)

print 'Surface-attached state variables:'
for variable in model.surface_state_variables:
    print '  %s = %s (%s)' % (variable.name, variable.long_name,
                              variable.units)

print 'Bottom-attached state variables:'
for variable in model.bottom_state_variables:
    print '  %s = %s (%s)' % (variable.name, variable.long_name,
                              variable.units)
    print 'Unable to load pyfabm. Please build and install FABM with FABM_HOST=python.'
    sys.exit(1)
import pyfabm.gui_qt

from PySide import QtCore,QtGui

# Parse command line arguments.
parser = optparse.OptionParser()
options, args = parser.parse_args()
if len(sys.argv)!=2:
   print 'This script takes one argument: the path to a YAML file with FABM settings (typically fabm.yaml).'
   sys.exit(2)
yamlfile = sys.argv[1]

# Create model object
model = pyfabm.Model(yamlfile)

# Create Qt application object
app = QtGui.QApplication([' '])

# Create dialog box with model configuration tree.
dialog = QtGui.QDialog()
dialog.setWindowTitle('Configure model')
layout = QtGui.QHBoxLayout()
tree = pyfabm.gui_qt.TreeView(model,dialog)
layout.addWidget(tree)
dialog.setLayout(layout)
dialog.show()

# Show dialog
ret = app.exec_()
def evaluate(yaml_path, sources=(), location={}, assignments={}, verbose=True, ignore_missing=False, surface=True, bottom=True):
    # Create model object from YAML file.
    model = pyfabm.Model(yaml_path)

    allvariables = list(model.state_variables) + list(model.dependencies)
    name2variable = {}
    for variable in allvariables:
        name2variable[variable.name] = variable
        if hasattr(variable, 'output_name'):
            name2variable[variable.output_name] = variable
    lcname2variable = dict([(name.lower(), variable) for (name, variable) in name2variable.items()])

    def set_state(**dim2index):
        missing = set(allvariables)
        variable2source = {}

        def set_variable(variable, value, source):
            missing.discard(variable)
            if variable in variable2source:
                print 'WARNING: %s = %s set by %s is overwritten with %s set by %s' % (variable.name, variable.value, variable2source[variable], value, source)
            variable2source[variable] = source
            variable.value = value

        for path in sources:
            if path.endswith('yaml'):
                with open(path) as f:
                    data = yaml.load(f)
                for name, value in data.items():
                    variable = name2variable.get(name)
                    if variable is None:
                        variable = lcname2variable.get(name.lower())
                    if variable is None:
                        print 'ERROR: variable "%s" specified in %s not found in model' % (name, path)
                        sys.exit(1)
                    set_variable(variable, float(value), path)
            else:
                with netCDF4.Dataset(path) as nc:
                    for variable in allvariables:
                        if variable.output_name not in nc.variables:
                            continue
                        ncvar = nc.variables[variable.output_name]
                        indices = []
                        for dim, length in zip(ncvar.dimensions, ncvar.shape):
                            index = 0
                            if length > 1:
                                if dim not in dim2index:
                                    print 'ERROR: Dimension %s of %s has length > 1; an index must be specified with %s=INDEX' % (dim, variable.output_name, dim)
                                    sys.exit(1)
                                index = dim2index[dim]
                            indices.append(index)
                        set_variable(variable, float(ncvar[tuple(indices)]), path)

        for name, value in assignments.items():
            if name not in name2variable:
                print 'Explicitly specified variable "%s" not found in model.' % name
                sys.exit(2)
            variable = name2variable[name]
            missing.discard(variable)
            variable2source[variable] = 'command line'
            variable.value = float(value)

        if verbose:
            print
            print 'State:'
            for variable in sorted(model.state_variables, cmp=lambda x, y: cmp(x.name.lower(), y.name.lower())):
                print '  %s: %s [%s]' % (variable.name, variable.value, variable2source.get(variable))
            print 'Environment:'
            for variable in sorted(model.dependencies, cmp=lambda x, y: cmp(x.name.lower(), y.name.lower())):
                print '  %s: %s [%s]' % (variable.name, variable.value, variable2source.get(variable))

        if missing:
            print 'The following variables are still missing:'
            for variable in sorted(missing, cmp=lambda x, y: cmp(x.name.lower(), y.name.lower())):
                print '- %s' % variable.name,
                if variable.name != variable.output_name:
                    print '(NetCDF: %s)' % variable.output_name,
                print

        return missing

    missing = set_state(**location)
    if missing and not ignore_missing:
        sys.exit(1)

    print 'State variables with largest value:'
    for variable in sorted(model.state_variables, cmp=lambda x, y: cmp(abs(y.value), abs(x.value)))[:3]:
        print '  %s: %s %s' % (variable.name, variable.value, variable.units)

    # Get model rates
    rates = model.getRates(surface=surface, bottom=bottom)
    assert len(rates) == len(model.state_variables), 'Length of array with rates does not match number of state variables'

    if verbose:
        print 'Diagnostics:'
        for variable in sorted(model.diagnostic_variables, cmp=lambda x, y: cmp(x.name.lower(), y.name.lower())):
            if variable.output:
                print '  %s: %s %s' % (variable.name, variable.value, variable.units)

    # Check whether rates of change are valid numbers
    valids = numpy.isfinite(rates)
    if not valids.all():
        print 'The following state variables have an invalid rate of change:'
        for variable, rate, valid in zip(model.state_variables, rates, valids):
            if not valid:
                print '  %s: %s' % (variable.name, rate)

    eps = 1e-30
    relative_rates = numpy.array([rate/(variable.value+eps) for variable, rate in zip(model.state_variables, rates)])

    if verbose:
        # Show all rates of change, odered by their value relative to the state variable's value.
        print 'Relative rates of change (low to high):'
        for variable, rate, relative_rate in sorted(zip(model.state_variables, rates, relative_rates), cmp=lambda x, y: cmp(x[2], y[2])):
            print '  %s: %s d-1' % (variable.name, 86400*relative_rate)

    print 'Largest relative rates of change:'
    for variable, rate, relative_rate in sorted(zip(model.state_variables, rates, relative_rates), cmp=lambda x, y: cmp(abs(y[2]), abs(x[2])))[:3]:
        print '  %s: %s d-1' % (variable.name, 86400*relative_rate)

    i = relative_rates.argmin()
    print 'Minimum time step = %.3f s due to decrease in %s' % (-1./relative_rates[i], model.state_variables[i].name)
Exemple #9
0
def processFile(infile,outfile,subtract_background=False,add_missing=False):
   # Create model object from YAML file.
   model = pyfabm.Model(infile)

   # Load the old configuration
   with open(infile,'rU') as f:
      config = yaml.load(f)

   def findMaximumDepth(d):
      n = 0
      for key,value in d.items():
         if isinstance(value,dict):
            l = 2+findMaximumDepth(value)
         else:
            l = len(key)+2+len(str(value)) # key, followed by ": ", followed by value
         n = max(n,l)
      return n

   def reorderParameters(modelname,parameters):
      """This reorders the parameters and adjusts the letter case of parameter names so that both match their declaration in the code."""
      newparameters = collections.OrderedDict()
      parameters_lower = dict([(key.lower(),value) for key,value in parameters.items()])
      modelname = modelname.lower()
      for parameter in model.parameters:
         if parameter.name.lower().startswith(modelname+'/'):
            name = parameter.name[len(modelname)+1:]
            name_lc = name.lower()
            if name_lc in parameters_lower: newparameters[name] = parameters_lower[name_lc]
      assert len(newparameters)==len(parameters)
      return newparameters

   def addMissingParameters(modelname,parameters):
      """This adds all parameters that have a default specified in the code but are missing from the yaml file."""
      parameters_lower = frozenset([key.lower() for key in parameters.keys()])
      modelname = modelname.lower()
      for parameter in model.parameters:
         if parameter.name.lower().startswith(modelname+'/'):
            name = parameter.name[len(modelname)+1:]
            if name.lower() not in parameters_lower and '/' not in name and parameter.default is not None: parameters[name] = parameter.default

   def reorderCouplings(modelname,variables):
      newvariables = collections.OrderedDict()
      modelname = modelname.lower()

      # First insert all couplings we do not understand (e.g., to whole models)
      couplings_lower = set([coupling.name.lower() for coupling in model.couplings])
      for name in variables.keys():
         if modelname+'/'+name.lower() not in couplings_lower:
            newvariables[name] = variables[name]

      variables_lower = dict([(key.lower(),value) for key,value in variables.items()])
      for coupling in model.couplings:
         if coupling.name.lower().startswith(modelname+'/'):
            name = coupling.name[len(modelname)+1:]
            name_lower = name.lower()
            if name_lower in variables_lower:
               newvariables[name] = variables_lower[name_lower]
      return newvariables

   def python2yaml(value):
      if value is None: return ''
      if isinstance(value,bool):
         return 'true' if value else 'false'
      return str(value)

   def processDict(f,d,path=[]):
      # If processing parameter list, reorder according to their registration by the model.
      if len(path)==3:
         if path[-1]=='parameters':
            d = reorderParameters(path[1],d)
            if len(d)==0: return
         elif path[-1]=='coupling':
            d = reorderCouplings(path[1],d)

      # If processing model instances list, first wield out models with use=False
      if len(path)==1 and path[0]=='instances':
         for key in d.keys():
            instance = d[key]
            if isinstance(instance,dict) and not instance.get('use',True): del d[key]

      # If processing a model dictionary, reorder according to prescribed order.
      if len(path)==2 and path[0]=='instances':
         d.pop('use',None)
         if add_missing: addMissingParameters(path[1],d.setdefault('parameters',collections.OrderedDict()))
         if not d.get('parameters',{}): d.pop('parameters',None)
         newd = collections.OrderedDict()
         order = ('long_name','model','parameters','initialization','coupling')
         for key in order:
            if key in d: newd[key] = d.pop(key)
         assert not d,'Model "%s" contains unknown keys %s' % (path[1],', '.join(d.keys()))
         d = newd

      nspace = len(path)*2
      for key, value in d.items():
         f.write(' '*nspace)
         if isinstance(value,dict):
            f.write('%s:\n' % key)
            processDict(f,value,path=path+[key])
         else:
            metadata = None
            if len(path)==3:
               if path[-1]=='parameters':
                  metadata = model.findParameter(path[1]+'/'+key)
                  value = metadata.value
               elif path[-1]=='initialization':
                  metadata = model.findStateVariable(path[1]+'/'+key)
                  value = metadata.value
                  if subtract_background: value -= metadata.background_value
               elif path[-1]=='coupling':
                  try:
                     metadata = model.findCoupling(path[1]+'/'+key)
                  except KeyError:
                     # If YAML coupling was not found, it typically is a coupling to a model rather than to a variable. Ignore this.
                     pass
            value = python2yaml(value)
            if metadata is not None:
               f.write('%s: %s' % (metadata.name[len(path[1])+1:],value))
               l = nspace+len(key)+2+len(str(value))
               f.write('%s# %s' % (' '*(icommentstart-l),metadata.long_name,))
               if metadata.units: f.write(' (%s)' % (metadata.units,))
               if getattr(metadata,'default',None) is not None: f.write(', default = %s' % (python2yaml(metadata.default),))
            else:
               f.write('%s: %s' % (key,value))
            f.write('\n')

   icommentstart = findMaximumDepth(config)+3
   with open(outfile,'w') as f:   
      processDict(f,config)
Exemple #10
0
    def __init__(self,
                 parameters={},
                 prey=(),
                 temperature=None,
                 recruitment_from_prey=0,
                 fabm_yaml_path=None,
                 depth=None,
                 initial_density=1.,
                 verbose=True):
        self.parameters = dict(parameters)
        self.initial_density = initial_density

        self.temperature_provider = None
        if temperature is not None:
            self.temperature_provider = datasources.asValueProvider(
                temperature)
        self.depth_provider = None
        if depth is not None:
            self.depth_provider = datasources.asValueProvider(depth)

        assert not pyfabm.hasError(
        ), 'pyfabm library has crashed previously (stop has been called).'
        #fabm_yaml_path = 'fabm.yaml'
        if fabm_yaml_path is None:
            fabm_yaml_fd, fabm_yaml_path = tempfile.mkstemp()
            fabm_yaml_file = os.fdopen(fabm_yaml_fd, 'w')
        else:
            fabm_yaml_file = open(fabm_yaml_path, 'w')
        mizer_params = dict(parameters)
        if depth is not None:
            mizer_params['biomass_has_prey_unit'] = False
        mizer_coupling = {'waste': 'zero_hz'}
        mizer_initialization = {}
        for iclass in range(mizer_params['nclass']):
            mizer_initialization[
                'Nw%i' %
                (iclass + 1, )] = initial_density / mizer_params['nclass']
        mizer_yaml = {
            'model': 'mizer/size_structured_population',
            'parameters': mizer_params,
            'coupling': mizer_coupling,
            'initialization': mizer_initialization
        }
        fabm_yaml = {'instances': {'fish': mizer_yaml}}

        if not isinstance(prey, BasePreyCollection):
            prey = PreyCollection(*prey)
        self.prey = prey

        iprey = 0
        for name, mass in zip(self.prey.names, self.prey.masses):
            iprey += 1
            fabm_yaml['instances'][name] = {
                'model': 'mizer/prey',
                'parameters': {
                    'w': float(mass)
                }
            }
            mizer_coupling['Nw_prey%i' % iprey] = '%s/Nw' % name
        mizer_params['nprey'] = iprey
        with fabm_yaml_file:
            yaml.dump(fabm_yaml, fabm_yaml_file, default_flow_style=False)

        self.fabm_model = pyfabm.Model(fabm_yaml_path)
        assert not pyfabm.hasError(
        ), 'pyfabm library failed during initialization'

        self.prey_indices = numpy.empty((iprey, ), dtype=int)
        for iprey, name in enumerate(self.prey.names):
            for self.prey_indices[iprey], variable in enumerate(
                    self.fabm_model.state_variables):
                if variable.path == '%s/Nw' % name:
                    break
            else:
                assert False, 'Prey %s/Nw not found in model.' % name

        self.bin_indices = []
        self.bin_masses = []
        while 1:
            for i, variable in enumerate(self.fabm_model.state_variables):
                if variable.path == 'fish/Nw%i' % (len(self.bin_indices) +
                                                   1, ):
                    self.bin_masses.append(
                        variable.getRealProperty('particle_mass'))
                    break
            else:
                break
            self.bin_indices.append(i)
        self.bin_masses = numpy.array(self.bin_masses)
        log10masses = numpy.log10(self.bin_masses)
        self.log10bin_width = log10masses[1] - log10masses[
            0]  # assume equal log10 spacing between mizer size classes
        self.bin_widths = 10.**(log10masses + self.log10bin_width / 2) - 10.**(
            log10masses - self.log10bin_width / 2)

        # Used to convert between depth-integrated fluxes and depth-explicit fluxes (not used if prey is prescribed)
        self.fabm_model.cell_thickness = 1.
        try:
            self.fabm_model.findDependency('bottom_depth').value = 1.
        except KeyError:
            pass

        if temperature is not None:
            self.temperature = self.fabm_model.findDependency('temperature')
            self.temperature.value = self.temperature_provider.mean()
            assert self.temperature.value > -10. and self.temperature.value < 40., 'Invalid temperature mean (%s)' % self.temperature.value
        if depth is not None:
            self.interaction_depth = self.fabm_model.findDependency(
                'fish/interaction_depth')
            self.interaction_depth.value = self.depth_provider.mean()
            if verbose:
                print('Mean depth: %.1f m' % (self.interaction_depth.value, ))

        # Verify the model is ready to be used
        assert self.fabm_model.checkReady(
        ), 'One or more model dependencies have not been fulfilled.'

        if verbose:
            for parameter in self.fabm_model.parameters:
                if parameter.path.startswith('fish/'):
                    print('%s: %s %s' % (parameter.long_name, parameter.value,
                                         parameter.units))

        self.initial_state = numpy.copy(self.fabm_model.state)
        self.recruitment_from_prey = recruitment_from_prey
Exemple #11
0
parser = argparse.ArgumentParser(description='This script verifies that a biogeochemical model returns valid derivatives under a wide variety of inputs (state variables, environmental dependencies). Different tests can be run, using either random values or extremes for inputs, and running randomized or exhaustive tests.')
parser.add_argument('model_path',help='Path to a YAML file with the model configuration (typically fabm.yaml)')
parser.add_argument('ranges_path',help='Path to a YAML file with ranges for all model inputs (state variables, environmental dependencies)')
parser.add_argument('--test',type=str,choices=('randomized','extremes_per_variable','extremes_randomized','extremes_all'),action='append',help='Path to a YAML file with ranges for all model inputs (state variables, environmental dependencies)')
parser.add_argument('--write-ranges',action='store_true',help='Write ranges file with default variable ranges',default=False)
args = parser.parse_args()

try:
   import pyfabm
except ImportError:
   print 'Unable to load pyfabm. See https://github.com/fabm-model/code/wiki/python.'
   sys.exit(1)

# Create model object from YAML file.
model = pyfabm.Model(args.model_path)

if args.write_ranges:
    with open(args.ranges_path,'w') as f:
        def writeRanges(variables):
            for variable in variables:
                f.write('%s: [0,%s]\n' % (variable.name,10*variable.value))
        writeRanges(model.state_variables)
        writeRanges(model.dependencies)
    print 'Default ranges have been written to %s.' % args.ranges_path
    sys.exit(0)

with open(args.ranges_path,'rU') as f:
    ranges = yaml.load(f)
if not isinstance(ranges,dict):
    print 'Range file %s should contain a dicionary mapping each variable to its range (or constant value).' % args.ranges_path
Exemple #12
0
def main():
    """
    Run pyfabm-ERSEM tutorial

    :param model_path: Full path to netCDF model output
    :type model_path: str

    :return: list of oxygen saturation concentrations
    :rtype: list
    """
    dir_path = os.path.dirname(os.path.realpath(__file__))
    ersem_dir = os.path.dirname(os.path.dirname(dir_path))

    # Path to ERSEM yaml file
    ersem_yaml_file = os.path.join(
        ersem_dir, 'testcases', 'fabm-ersem-15.06-L4-noben-docdyn-iop.yaml')

    if not os.path.isfile(ersem_yaml_file):
        raise RuntimeError("Could not find Ersem yaml file with the "
                           "{}".format(ersem_yaml_file))

    # Create model
    model = pyfabm.Model(ersem_yaml_file)

    # Configure the environment
    model.findDependency('longitude').value = -4.15
    model.findDependency('latitude').value = 50.25
    model.findDependency('number_of_days_since_start_of_the_year').value = 0.
    model.findDependency('temperature').value = 10.
    model.findDependency('wind_speed').value = 1.
    model.findDependency('surface_downwelling_shortwave_flux').value = 50.
    model.findDependency('practical_salinity').value = 35.
    model.findDependency('pressure').value = 10.
    model.findDependency('density').value = 1035.
    model.findDependency('mole_fraction_of_carbon_dioxide_in_air').value = 280.
    model.findDependency('absorption_of_silt').value = 0.07
    model.findDependency('bottom_stress').value = 0.
    model.findDependency('cell_thickness').value = 1.
    model.setCellThickness(1)

    # Verify the model is ready to be used
    assert model.checkReady(
    ), 'One or more model dependencies have not been fulfilled.'

    # Define ranges over which temperature and salinity will be varied
    n_points = 50
    temperature_array = np.linspace(5, 35, n_points)
    salinity_array = np.linspace(25, 45, n_points)

    # Create an array in which to store oxygen_saturation_concentrations
    oxygen_saturation_concentration = np.empty((n_points, n_points),
                                               dtype=float)

    # Calculate oxygen saturation concentrations using ERSEM
    for t_idx, t in enumerate(temperature_array):
        model.findDependency('temperature').value = t
        for s_idx, s in enumerate(salinity_array):
            model.findDependency('practical_salinity').value = s
            _ = model.getRates()
            oxygen_saturation_concentration[t_idx, s_idx] = \
                    model.findDiagnosticVariable('O2/osat').value

    # Create the figure
    figure = plt.figure()
    axes = plt.gca()

    # Set color map
    cmap = cm.get_cmap('YlOrRd')

    # Plot
    plot = axes.pcolormesh(temperature_array,
                           salinity_array,
                           oxygen_saturation_concentration,
                           shading='auto',
                           cmap=cmap)

    axes.set_xlabel('Temperature (deg. C)')
    axes.set_ylabel('Salinity (psu)')

    # Add colour bar
    cbar = figure.colorbar(plot)
    cbar.set_label('O$_{2}$ (mmol m$^{-3}$)')

    plt.show()

    return oxygen_saturation_concentration