OpenDrift / opendrift

Open source framework for ocean trajectory modelling
https://opendrift.github.io
GNU General Public License v2.0
231 stars 113 forks source link

Question on setting run config using a dictionary #1283

Open simonweppe opened 2 months ago

simonweppe commented 2 months ago

Hi there @knutfrode ,

I have a question about the best way to set a full model configuration using a dictionary (to automate some of our runs). In some ways related to release [v1111].(https://github.com/OpenDrift/opendrift/blob/1eadfa728debc49d11bffa3a70769ddb5d5e6aab/history.rst#2024-01-25--release-v1111)

From what I understand, one can now set several config at the same time for a given "category" (e.g. 'seed', 'general' etc..), as follow:

    o.set_config('seed',{'seafloor':True})
    o.set_config('general',{'time_step_minutes':120,
                            'coastline_action':'stranding'})

Ideally I'd like to do it in one go for the entire config (rather than category by category). Is there something place already ? This could be an option below, with a new function set_configspec() ? Keen to hear your feedback on this..happy to do a PR if it makes sense.

configspec_obj = o.get_configspec() # returns a dictionnary with all config
# change the config
configspec_obj['general:time_step_minutes']['value'] = 120
o.set_configspec(configspec_obj)

where

    def set_configspec(self, configspec):
        '''
        Sets the entire config using the config object <configspec> returned 
        by configspec = o.get_configspec()

        Example usage :

        config_obj = o.get_configspec()
        config['general:time_step_minutes']['value'] = 120
        o.set_configspec() 

        '''
        for key,sub_dict in configspec.items() :
            # here is key is expected to be 'general:seafloor_action'
            value =  sub_dict['value']
            self.set_config(key,value) 
            logger.info(f'set_config(\'{key}\', {value})')
        return configspec  
knutfrode commented 2 months ago

Hi Simon,

Yes I agree this makes very much sense. I will come back to this next week, but my first thoughts:

It would be good to have a quick round of discussion and thinking around this, to make a good mechanism to support many (future) needs in one go, and not having to modify it soon (and breaking backwards compatibility).

Thus in the meantime @gauteh or @vegardb could have some opinions or suggestions here.

simonweppe commented 2 months ago

Yes this is what we are aiming for, single command to run a simulation from a json file. Happy to contribute/collaborate on this.

knutfrode commented 2 months ago

Hi, I now realized/recalled that the set_config/get_config methods are simply operating on a plain dictionary self._config, after performing some checks (I had forgot, as earlier a 3rd party package was used for the config). https://github.com/OpenDrift/opendrift/blob/master/opendrift/config.py However, this means that it is presently possible to copy the config from one simulation object to another as simple as: o2._config = o1._config (which can still be followed by subsequent calls of o2.set_config(key, value))

One could update get_config to simply return _config dictionary if called without any parameters/keys, and likewise set_configto accept the above to be achieved with a more conistentent API: o2.set_config(o1.get_config()) However, I am not sure if this is necessary or actually better than simply copying the dictionary as above?

If you think that either of these ways would solve the config need, we are then left with the second task of creating a (generic) way of running a simulation from commandline and possibly config file with: opendrift_run -f conf.json or more explicitly opendrift_run -c <key1>:<value1> -c <key2>:<value2> -seed lon,lat,z,time,number,radius,<properties> -r <reader1> -r <reader2> ...... This can be done in several different ways, so would need a little more thinking before put into action. E.g. one would like to allow different methods of seeding such as point, cone, time series, polygon, shapefile etc

simonweppe commented 2 months ago

Thanks @knutfrode - yes that o1._config is pretty handy to get a full config of an object, then edit items as needed.

Indeed lots of different ways to do the wrapping for the reader loading and allow use of other methods etc...we'll start and share as we go, happy to join a chat if that becomes a priority for you at some point.