unifhy-org / unifhy

A Unified Framework for Hydrology
https://unifhy-org.github.io/unifhy
BSD 3-Clause "New" or "Revised" License
11 stars 5 forks source link

Support scalar and array for component parameters #21

Closed ThibHlln closed 3 years ago

ThibHlln commented 3 years ago

At the moment a Component expects its parameters to be scalar values, i.e. they are the same everywhere in the SpaceDomain (and also constant over time).

Since there is no type checking on the parameters, only their availability, an array can be provided for the parameters. However, this is problematic in several ways:

So there needs to be a way to deal with these two problems.

For the first one, if the parameter is given as an array, a NC file could be written (if parameter value does not come from one already), and the yaml file should point to this file. The scalar case should probably still be supported in the way it is at the moment, as writing a NC file for one scalar is probably not optimal.

For the second one, not sure how to deal with it yet. Converting scalars to arrays could be a solution, so that a component would also get arrays.

ThibHlln commented 3 years ago

In terms of the API, I think we should support cf.Data and cf.Field as parameter values. This would allow us to add checks on the parameter units.

If parameters are scalars, it is more straightforward to create a Data object than a Field:

parameters = {
    'paramater_a': cf.Data(10, 'm2'),
    'parameter_b': cf.Data(120, 's')
}

If parameters are arrays, they need to be provided metadata (at least for spatial context), so a Data object would not be enough, and a Field would be required - it will most likely be stored in a file (if not, the framework would store it in a file in config_directory):

parameters = {
    'paramater_a': cf.read('my_file.nc').select_field('long_name=parameter_a'),
    'parameter_b': cf.read('my_file.nc').select_field('long_name=parameter_b'),
}

In terms of the YAML configuration file, the former could be stored as follows:

parameters:
  parameter_a: [10, m2]
  parameter_b: [120, s]

While the latter could be stored as follows:

parameters:
  parameter_a:
    files: [my_file.nc]
    select: paramater_a
  parameter_b:
    files: [my_file.nc]
    select: paramater_b