vortex-nwp 2.0.0b2__tar.gz → 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/PKG-INFO +3 -2
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/pyproject.toml +1 -1
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/__init__.py +19 -5
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/algo/components.py +6 -6
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/algo/mpitools.py +12 -12
- vortex_nwp-2.1.0/src/vortex/algo/mpitools_templates/__init__.py +1 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/handlers.py +10 -4
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/stores.py +11 -19
- vortex_nwp-2.1.0/src/vortex/data/sync_templates/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/forecasts.py +7 -15
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/ifsroot.py +5 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/monitoring.py +5 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/mpitools.py +12 -2
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/odbtools.py +20 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/oopsroot.py +5 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/actions.py +5 -82
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/grib.py +48 -31
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/net.py +27 -5
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/services.py +2 -2
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/systems.py +25 -14
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/config.py +2 -1
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex_nwp.egg-info/PKG-INFO +3 -2
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex_nwp.egg-info/SOURCES.txt +4 -0
- vortex_nwp-2.1.0/tests/test_smartftget.py +81 -0
- vortex_nwp-2.1.0/tests/test_ssh.py +23 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/LICENSE +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/README.md +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/setup.cfg +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/algo/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/algo/mpitools_templates/envelope_wrapper_default.tpl +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/algo/mpitools_templates/envelope_wrapper_mpiauto.tpl +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/algo/mpitools_templates/wrapstd_wrapper_default.tpl +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/algo/serversynctools.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/config.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/abstractstores.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/containers.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/contents.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/executables.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/flow.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/geometries.ini +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/geometries.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/outflow.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/providers.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/data/resources.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/gloves.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/layout/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/layout/contexts.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/layout/dataflow.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/layout/monitor.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/assim.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/clim.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/coupling.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/eda.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/eps.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/fpserver.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/ifsnaming.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/oopstests.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/request.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/algo/stdpost.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/assim.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/boundaries.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/climfiles.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/configfiles.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/consts.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/ctpini.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/diagnostics.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/eda.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/eps.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/executables.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/fields.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/gridfiles.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/logs.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/modelstates.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/monitoring.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/namelists.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/obs.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/oopsexec.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/providers.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/query.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/stores.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/data/surfex.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/syntax/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/syntax/stdattrs.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/addons.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/agt.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/bdap.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/bdcp.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/bdm.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/bdmp.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/conftools.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/drhook.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/grib.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/gribdiff.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/ifstools.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/igastuff.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/mars.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/odb.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/partitioning.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/tools/satrad.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/async.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/beacon.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/diffpygram.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/ens.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/hooks.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/taskdeco.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/usepygram.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/nwp/util/usetnt.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/proxy.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/sessions.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/syntax/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/syntax/stdattrs.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/syntax/stddeco.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/toolbox.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/addons.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/arm.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/compression.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/date.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/ddhpack.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/delayedactions.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/env.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/folder.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/lfi.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/listings.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/names.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/odb.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/parallelism.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/prestaging.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/rawfiles.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/schedulers.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/storage.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/surfex.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/tools/targets.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/__init__.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/empty.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/helpers.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/introspection.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/iosponge.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/roles.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/storefunctions.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/structs.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex/util/worker.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex_nwp.egg-info/dependency_links.txt +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex_nwp.egg-info/requires.txt +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/src/vortex_nwp.egg-info/top_level.txt +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_algo_server.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_arpifs_listings_integration.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_cfgparser.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_cfgtemplating.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_compression.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_config.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_conftools.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_containers.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_doctests.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_ecmwf_interface.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_env.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_epygram.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_gco.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_ifstools.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_import.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_iosponge.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_job_examples.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_layoutappconf.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_layoutjobs.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_layoutmonitor.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_layoutnodes.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_net_netstat.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_net_ssh.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_partitioning.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_providers.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_sessions_stuff.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_simpleworkflow.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_storage.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_stores.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_syntax.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_targets.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_templates.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_toolsodb.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_uget.py +0 -0
- {vortex_nwp-2.0.0b2 → vortex_nwp-2.1.0}/tests/test_vortexnames.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: vortex-nwp
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: A Python library to write Numerical Weather Prediction pipelines components
|
|
5
5
|
Author-email: The Vortex Team <vortex.support@meteo.fr>
|
|
6
6
|
License: CECILL-C
|
|
@@ -21,6 +21,7 @@ Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
|
21
21
|
Provides-Extra: dev
|
|
22
22
|
Requires-Dist: ruff==0.9.1; extra == "dev"
|
|
23
23
|
Requires-Dist: pytest; extra == "dev"
|
|
24
|
+
Dynamic: license-file
|
|
24
25
|
|
|
25
26
|
## vortex
|
|
26
27
|
|
|
@@ -21,7 +21,18 @@ strongly advised.
|
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
import atexit
|
|
24
|
-
import
|
|
24
|
+
import sys
|
|
25
|
+
import os
|
|
26
|
+
|
|
27
|
+
# importlib.metadata included in stdlib from 3.8 onwards.
|
|
28
|
+
# For older versions, import third-party importlib_metadata
|
|
29
|
+
if sys.version_info < (3, 8):
|
|
30
|
+
import importlib_metadata
|
|
31
|
+
import importlib
|
|
32
|
+
|
|
33
|
+
importlib.metadata = importlib_metadata
|
|
34
|
+
else:
|
|
35
|
+
import importlib.metadata
|
|
25
36
|
|
|
26
37
|
from bronx.fancies import loggers as bloggers
|
|
27
38
|
import bronx.stdtypes.date
|
|
@@ -42,10 +53,10 @@ from .toolbox import algo as task
|
|
|
42
53
|
|
|
43
54
|
from . import nwp as nwp # footprints import
|
|
44
55
|
|
|
45
|
-
__version__ = "2.0
|
|
56
|
+
__version__ = "2.1.0"
|
|
46
57
|
__prompt__ = "Vortex v-" + __version__ + ":"
|
|
47
58
|
|
|
48
|
-
__nextversion__ = "2.
|
|
59
|
+
__nextversion__ = "2.1.1"
|
|
49
60
|
__tocinfoline__ = "VORTEX core package"
|
|
50
61
|
|
|
51
62
|
__all__ = [
|
|
@@ -100,8 +111,11 @@ footprints.setup.callback = vortexfpdefaults
|
|
|
100
111
|
ticket = sessions.get
|
|
101
112
|
sh = sessions.system
|
|
102
113
|
|
|
103
|
-
# If a config file can be found in current dir, load it
|
|
104
|
-
|
|
114
|
+
# If a config file can be found in current dir, load it else load .vortex.d/vortex.toml
|
|
115
|
+
if os.path.isfile("vortex.toml"):
|
|
116
|
+
config.load_config("vortex.toml")
|
|
117
|
+
else:
|
|
118
|
+
config.load_config(os.environ["HOME"] + "/.vortex.d/vortex.toml")
|
|
105
119
|
|
|
106
120
|
# Load some superstars sub-packages
|
|
107
121
|
|
|
@@ -50,7 +50,7 @@ from bronx.syntax.decorators import nicedeco
|
|
|
50
50
|
import footprints
|
|
51
51
|
from taylorism import Boss
|
|
52
52
|
import vortex
|
|
53
|
-
|
|
53
|
+
import vortex.config as config
|
|
54
54
|
from vortex.algo import mpitools
|
|
55
55
|
from vortex.syntax.stdattrs import DelayedEnvValue
|
|
56
56
|
from vortex.tools.parallelism import ParallelResultParser
|
|
@@ -704,15 +704,15 @@ class AlgoComponent(footprints.FootprintBase, metaclass=AlgoComponentMeta):
|
|
|
704
704
|
|
|
705
705
|
def export(self, packenv):
|
|
706
706
|
"""Export environment variables in given pack."""
|
|
707
|
-
for k, v in from_config(section=packenv).items():
|
|
707
|
+
for k, v in config.from_config(section=packenv).items():
|
|
708
708
|
if k not in self.env:
|
|
709
709
|
logger.info("Setting %s env %s = %s", packenv.upper(), k, v)
|
|
710
710
|
self.env[k] = v
|
|
711
711
|
|
|
712
712
|
def prepare(self, rh, opts):
|
|
713
713
|
"""Set some defaults env values."""
|
|
714
|
-
if
|
|
715
|
-
self.export("
|
|
714
|
+
if config.is_defined(section="env"):
|
|
715
|
+
self.export("env")
|
|
716
716
|
|
|
717
717
|
def absexcutable(self, xfile):
|
|
718
718
|
"""Retuns the absolute pathname of the ``xfile`` executable."""
|
|
@@ -1841,7 +1841,7 @@ class Parallel(xExecutableAlgoComponent):
|
|
|
1841
1841
|
def _mpitool_attributes(self, opts):
|
|
1842
1842
|
"""Return the dictionary of attributes needed to create the mpitool object."""
|
|
1843
1843
|
# Read the appropriate configuration in the target file
|
|
1844
|
-
conf_dict = from_config(section="mpitool")
|
|
1844
|
+
conf_dict = config.from_config(section="mpitool")
|
|
1845
1845
|
if self.mpiname:
|
|
1846
1846
|
conf_dict["mpiname"] = self.mpiname
|
|
1847
1847
|
# Make "mpirun" the default mpi command name
|
|
@@ -1850,7 +1850,7 @@ class Parallel(xExecutableAlgoComponent):
|
|
|
1850
1850
|
possible_attrs = functools.reduce(
|
|
1851
1851
|
lambda s, t: s | t,
|
|
1852
1852
|
[
|
|
1853
|
-
set(cls.
|
|
1853
|
+
set(cls.footprint_retrieve().attr.keys())
|
|
1854
1854
|
for cls in footprints.proxy.mpitools
|
|
1855
1855
|
],
|
|
1856
1856
|
)
|
|
@@ -182,8 +182,8 @@ class MpiTool(footprints.FootprintBase):
|
|
|
182
182
|
)
|
|
183
183
|
|
|
184
184
|
_envelope_bit_kind = "basicenvelopebit"
|
|
185
|
-
_envelope_wrapper_tpl = "
|
|
186
|
-
_wrapstd_wrapper_tpl = "
|
|
185
|
+
_envelope_wrapper_tpl = "envelope_wrapper_default.tpl"
|
|
186
|
+
_wrapstd_wrapper_tpl = "wrapstd_wrapper_default.tpl"
|
|
187
187
|
_envelope_wrapper_name = "./global_envelope_wrapper.py"
|
|
188
188
|
_wrapstd_wrapper_name = "./global_wrapstd_wrapper.py"
|
|
189
189
|
_envelope_rank_var = "MPIRANK"
|
|
@@ -700,11 +700,11 @@ class MpiTool(footprints.FootprintBase):
|
|
|
700
700
|
if not self.mpiwrapstd:
|
|
701
701
|
return None
|
|
702
702
|
# Create the launchwrapper
|
|
703
|
-
with importlib.resources.
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
703
|
+
with importlib.resources.path(
|
|
704
|
+
"vortex.algo.mpitools_templates",
|
|
705
|
+
self._wrapstd_wrapper_tpl,
|
|
706
|
+
) as tplpath:
|
|
707
|
+
wtpl = config.load_template(tplpath, encoding="utf-8")
|
|
708
708
|
with open(self._wrapstd_wrapper_name, "w", encoding="utf-8") as fhw:
|
|
709
709
|
fhw.write(
|
|
710
710
|
wtpl.substitute(
|
|
@@ -911,11 +911,11 @@ class MpiTool(footprints.FootprintBase):
|
|
|
911
911
|
"Here are the envelope details:\n%s", "\n".join(binding_str)
|
|
912
912
|
)
|
|
913
913
|
# Create the launchwrapper
|
|
914
|
-
with importlib.resources.
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
914
|
+
with importlib.resources.path(
|
|
915
|
+
"vortex.algo.mpitools_templates",
|
|
916
|
+
self._envelope_wrapper_tpl,
|
|
917
|
+
) as tplpath:
|
|
918
|
+
wtpl = config.load_template(tplpath, encoding="utf-8")
|
|
919
919
|
with open(self._envelope_wrapper_name, "w", encoding="utf-8") as fhw:
|
|
920
920
|
fhw.write(
|
|
921
921
|
wtpl.substitute(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Empty init file
|
|
@@ -5,6 +5,7 @@ the various caches or archives".
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import functools
|
|
8
|
+
import importlib
|
|
8
9
|
import re
|
|
9
10
|
import sys
|
|
10
11
|
|
|
@@ -1116,18 +1117,23 @@ class Handler:
|
|
|
1116
1117
|
self,
|
|
1117
1118
|
pr_getter=None,
|
|
1118
1119
|
tplfile=None,
|
|
1119
|
-
tplskip="@sync-skip.tpl",
|
|
1120
|
-
tplfetch="@sync-fetch.tpl",
|
|
1121
1120
|
py_exec=sys.executable,
|
|
1122
1121
|
py_opts="",
|
|
1123
1122
|
):
|
|
1124
1123
|
"""Build a getter for the expected resource."""
|
|
1125
1124
|
if tplfile is None:
|
|
1126
|
-
tplfile =
|
|
1125
|
+
tplfile = (
|
|
1126
|
+
"sync-" + ("fetch" if self.is_expected() else "skip") + ".tpl"
|
|
1127
|
+
)
|
|
1128
|
+
with importlib.resources.path(
|
|
1129
|
+
"vortex.data.sync_templates",
|
|
1130
|
+
tplfile,
|
|
1131
|
+
) as tplpath:
|
|
1132
|
+
tpl = config.load_template(tplpath)
|
|
1127
1133
|
if pr_getter is None:
|
|
1128
1134
|
pr_getter = self.container.localpath() + ".getpr"
|
|
1129
1135
|
t = self._cur_session
|
|
1130
|
-
|
|
1136
|
+
|
|
1131
1137
|
with open(pr_getter, "w", encoding="utf-8") as fd:
|
|
1132
1138
|
fd.write(
|
|
1133
1139
|
tpl.substitute(
|
|
@@ -527,6 +527,10 @@ class _VortexBaseArchiveStore(ArchiveStore, _VortexStackedStorageMixin):
|
|
|
527
527
|
"""Remap actual remote path to distant store path for intrusive actions."""
|
|
528
528
|
raise NotImplementedError
|
|
529
529
|
|
|
530
|
+
def remap_write(self, remote, options):
|
|
531
|
+
"""Remap actual remote path to distant store path for intrusive actions."""
|
|
532
|
+
raise NotImplementedError
|
|
533
|
+
|
|
530
534
|
def remap_list(self, remote, options):
|
|
531
535
|
"""Reformulates the remote path to compatible vortex namespace."""
|
|
532
536
|
if len(remote["path"].split("/")) >= 4:
|
|
@@ -537,8 +541,6 @@ class _VortexBaseArchiveStore(ArchiveStore, _VortexStackedStorageMixin):
|
|
|
537
541
|
)
|
|
538
542
|
return None
|
|
539
543
|
|
|
540
|
-
remap_write = remap_read
|
|
541
|
-
|
|
542
544
|
@property
|
|
543
545
|
def stacks_autorefill(self):
|
|
544
546
|
"""Where to refill a stack retrieved from the archive."""
|
|
@@ -755,6 +757,8 @@ class VortexStdBaseArchiveStore(_VortexBaseArchiveStore):
|
|
|
755
757
|
raise e
|
|
756
758
|
return remote
|
|
757
759
|
|
|
760
|
+
remap_write = remap_read
|
|
761
|
+
|
|
758
762
|
|
|
759
763
|
class VortexStdStackedArchiveStore(VortexStdBaseArchiveStore):
|
|
760
764
|
"""Archive for casual VORTEX experiments: Support for legacy/Olive XPIDs.
|
|
@@ -1105,16 +1109,10 @@ class VortexCacheStore(_AbstractVortexCacheMultiStore):
|
|
|
1105
1109
|
|
|
1106
1110
|
def alternates_netloc(self):
|
|
1107
1111
|
"""For Non-Op users, Op caches may be accessed in read-only mode."""
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
**netloc_m.groupdict()
|
|
1113
|
-
)
|
|
1114
|
-
s_mt_netloc = "{base:s}.stacked-cache-mt.{country:s}".format(
|
|
1115
|
-
**netloc_m.groupdict()
|
|
1116
|
-
)
|
|
1117
|
-
return [mt_netloc, s_mt_netloc]
|
|
1112
|
+
return [
|
|
1113
|
+
f"{self.netloc.firstname}.cache-mt.fr",
|
|
1114
|
+
f"{self.netloc.firstname}.stacked-cache-mt.fr",
|
|
1115
|
+
]
|
|
1118
1116
|
|
|
1119
1117
|
|
|
1120
1118
|
class VortexVsopCacheStore(_AbstractVortexCacheMultiStore):
|
|
@@ -1219,13 +1217,7 @@ class VortexStackStore(_AbstractVortexStackMultiStore):
|
|
|
1219
1217
|
|
|
1220
1218
|
def alternates_netloc(self):
|
|
1221
1219
|
"""Go through the various stacked stores."""
|
|
1222
|
-
|
|
1223
|
-
r"(?P<base>vortex.*)\.stack\.(?P<country>\w+)", self.netloc
|
|
1224
|
-
)
|
|
1225
|
-
s_mt_netloc = "{base:s}.stacked-cache-mt.{country:s}".format(
|
|
1226
|
-
**netloc_m.groupdict()
|
|
1227
|
-
)
|
|
1228
|
-
return [s_mt_netloc]
|
|
1220
|
+
return [f"{self.netloc.firstname}.stacked-cache-mt.fr"]
|
|
1229
1221
|
|
|
1230
1222
|
|
|
1231
1223
|
class VortexVsopStackStore(_AbstractVortexStackMultiStore):
|
|
File without changes
|
|
@@ -283,21 +283,12 @@ class LAMForecast(Forecast):
|
|
|
283
283
|
values=["lamfc", "lamforecast"],
|
|
284
284
|
remap=dict(lamforecast="lamfc"),
|
|
285
285
|
),
|
|
286
|
-
synctool=dict(
|
|
287
|
-
info="The name of the script called when waiting for coupling files",
|
|
288
|
-
optional=True,
|
|
289
|
-
default="atcp.alad",
|
|
290
|
-
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
291
|
-
),
|
|
292
|
-
synctpl=dict(
|
|
293
|
-
info="The template used to generate the *synctool* script",
|
|
294
|
-
optional=True,
|
|
295
|
-
default="@sync-fetch.tpl",
|
|
296
|
-
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
297
|
-
),
|
|
298
286
|
),
|
|
299
287
|
)
|
|
300
288
|
|
|
289
|
+
synctool = "atcp.alad"
|
|
290
|
+
synctpl = "sync-fetch.tpl"
|
|
291
|
+
|
|
301
292
|
def spawn_command_options(self):
|
|
302
293
|
"""Dictionary provided for command line factory."""
|
|
303
294
|
return dict(
|
|
@@ -341,10 +332,11 @@ class LAMForecast(Forecast):
|
|
|
341
332
|
)
|
|
342
333
|
sh.softlink(thisbound, lbcnc(number=i))
|
|
343
334
|
if self.mksync:
|
|
344
|
-
|
|
345
|
-
|
|
335
|
+
bound.mkgetpr(
|
|
336
|
+
pr_getter=self.synctool + ".{:03d}".format(i),
|
|
337
|
+
)
|
|
346
338
|
if firstsync is None:
|
|
347
|
-
firstsync =
|
|
339
|
+
firstsync = self.synctool + ".{:03d}".format(i)
|
|
348
340
|
|
|
349
341
|
# Set up the first synchronization step
|
|
350
342
|
if firstsync is not None:
|
|
@@ -120,6 +120,11 @@ class IFSParallel(
|
|
|
120
120
|
"""Extend default tag with ``kind`` value."""
|
|
121
121
|
return super().fstag() + "." + self.kind
|
|
122
122
|
|
|
123
|
+
def _mpitool_attributes(self, opts):
|
|
124
|
+
conf_dict = super()._mpitool_attributes(opts)
|
|
125
|
+
conf_dict.update({"mplbased": True})
|
|
126
|
+
return conf_dict
|
|
127
|
+
|
|
123
128
|
def valid_executable(self, rh):
|
|
124
129
|
"""Be sure that the specifed executable is ifsmodel compatible."""
|
|
125
130
|
valid = super().valid_executable(rh)
|
|
@@ -57,6 +57,11 @@ class OdbMonitoring(
|
|
|
57
57
|
)
|
|
58
58
|
)
|
|
59
59
|
|
|
60
|
+
def _mpitool_attributes(self, opts):
|
|
61
|
+
conf_dict = super()._mpitool_attributes(opts)
|
|
62
|
+
conf_dict.update({"mplbased": True})
|
|
63
|
+
return conf_dict
|
|
64
|
+
|
|
60
65
|
def _fix_nam_macro(self, rh, macro, value):
|
|
61
66
|
"""Set a given namelist macro and issue a log message."""
|
|
62
67
|
rh.contents.setmacro(macro, value)
|
|
@@ -64,18 +64,28 @@ class MpiAuto(mpitools.MpiTool):
|
|
|
64
64
|
),
|
|
65
65
|
bindingmethod=dict(
|
|
66
66
|
info="How to bind the MPI processes",
|
|
67
|
-
values=["
|
|
67
|
+
values=["vortex", "arch", "launcherspecific"],
|
|
68
68
|
optional=True,
|
|
69
69
|
doc_visibility=footprints.doc.visibility.ADVANCED,
|
|
70
70
|
doc_zorder=-90,
|
|
71
71
|
),
|
|
72
|
+
mplbased=dict(
|
|
73
|
+
info="Is the executable based on MPL?",
|
|
74
|
+
type=bool,
|
|
75
|
+
optional=True,
|
|
76
|
+
default=False,
|
|
77
|
+
),
|
|
72
78
|
)
|
|
73
79
|
)
|
|
74
80
|
|
|
75
|
-
_envelope_wrapper_tpl = "
|
|
81
|
+
_envelope_wrapper_tpl = "envelope_wrapper_mpiauto.tpl"
|
|
76
82
|
_envelope_rank_var = "MPIAUTORANK"
|
|
77
83
|
_needs_mpilib_specific_mpienv = False
|
|
78
84
|
|
|
85
|
+
def __init__(self, *args, **kwargs):
|
|
86
|
+
super().__init__(*args, **kwargs)
|
|
87
|
+
self.bindingmethod = "arch" if self.mplbased else "vortex"
|
|
88
|
+
|
|
79
89
|
def _reshaped_mpiopts(self):
|
|
80
90
|
"""Raw list of mpi tool command line options."""
|
|
81
91
|
options = super()._reshaped_mpiopts()
|
|
@@ -850,6 +850,11 @@ class OdbAverage(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin):
|
|
|
850
850
|
)
|
|
851
851
|
)
|
|
852
852
|
|
|
853
|
+
def _mpitool_attributes(self, opts):
|
|
854
|
+
conf_dict = super()._mpitool_attributes(opts)
|
|
855
|
+
conf_dict.update({"mplbased": True})
|
|
856
|
+
return conf_dict
|
|
857
|
+
|
|
853
858
|
def prepare(self, rh, opts):
|
|
854
859
|
"""Find any ODB candidate in input files."""
|
|
855
860
|
|
|
@@ -962,6 +967,11 @@ class OdbCompress(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin):
|
|
|
962
967
|
)
|
|
963
968
|
)
|
|
964
969
|
|
|
970
|
+
def _mpitool_attributes(self, opts):
|
|
971
|
+
conf_dict = super()._mpitool_attributes(opts)
|
|
972
|
+
conf_dict.update({"mplbased": True})
|
|
973
|
+
return conf_dict
|
|
974
|
+
|
|
965
975
|
def prepare(self, rh, opts):
|
|
966
976
|
"""Find any ODB candidate in input files and fox ODB env accordingly."""
|
|
967
977
|
|
|
@@ -1027,6 +1037,11 @@ class OdbMatchup(Parallel, odb.OdbComponentDecoMixin, drhook.DrHookDecoMixin):
|
|
|
1027
1037
|
)
|
|
1028
1038
|
)
|
|
1029
1039
|
|
|
1040
|
+
def _mpitool_attributes(self, opts):
|
|
1041
|
+
conf_dict = super()._mpitool_attributes(opts)
|
|
1042
|
+
conf_dict.update({"mplbased": True})
|
|
1043
|
+
return conf_dict
|
|
1044
|
+
|
|
1030
1045
|
def prepare(self, rh, opts):
|
|
1031
1046
|
"""Find ODB candidates in input files."""
|
|
1032
1047
|
|
|
@@ -1116,6 +1131,11 @@ class OdbReshuffle(
|
|
|
1116
1131
|
_OUT_DIRECTORY = "reshuffled"
|
|
1117
1132
|
_BARE_OUT_LAYOUT = "ccma"
|
|
1118
1133
|
|
|
1134
|
+
def _mpitool_attributes(self, opts):
|
|
1135
|
+
conf_dict = super()._mpitool_attributes(opts)
|
|
1136
|
+
conf_dict.update({"mplbased": True})
|
|
1137
|
+
return conf_dict
|
|
1138
|
+
|
|
1119
1139
|
def prepare(self, rh, opts):
|
|
1120
1140
|
"""Find ODB candidates in input files."""
|
|
1121
1141
|
|
|
@@ -619,6 +619,11 @@ class OOPSParallel(
|
|
|
619
619
|
logger.error("The binary < %s > has no cycle attribute", repr(rh))
|
|
620
620
|
return False
|
|
621
621
|
|
|
622
|
+
def _mpitool_attributes(self, opts):
|
|
623
|
+
conf_dict = super()._mpitool_attributes(opts)
|
|
624
|
+
conf_dict.update({"mplbased": True})
|
|
625
|
+
return conf_dict
|
|
626
|
+
|
|
622
627
|
def prepare(self, rh, opts):
|
|
623
628
|
"""Preliminary setups."""
|
|
624
629
|
super().prepare(rh, opts)
|
|
@@ -10,8 +10,6 @@ to be processed: e.g. mail, routing, alarm.
|
|
|
10
10
|
import bronx.stdtypes.catalog
|
|
11
11
|
import footprints
|
|
12
12
|
from bronx.fancies import loggers
|
|
13
|
-
from bronx.fancies.display import dict_as_str
|
|
14
|
-
from vortex import sessions
|
|
15
13
|
|
|
16
14
|
#: Export nothing
|
|
17
15
|
__all__ = []
|
|
@@ -134,105 +132,30 @@ class Action:
|
|
|
134
132
|
class TunableAction(Action):
|
|
135
133
|
"""An Action that may be tuned
|
|
136
134
|
|
|
137
|
-
|
|
138
|
-
- accepts the syntax `ad.action_tune(key=value)` (which has priority)
|
|
135
|
+
accepts the syntax `ad.action_tune(key=value)` (which has priority)
|
|
139
136
|
"""
|
|
140
137
|
|
|
141
138
|
def __init__(self, configuration=None, **kwargs):
|
|
142
139
|
super().__init__(**kwargs)
|
|
143
140
|
self._tuning = dict()
|
|
144
|
-
self._conf_section = configuration
|
|
145
|
-
self._conf_dict = None
|
|
146
|
-
|
|
147
|
-
@property
|
|
148
|
-
def _shtarget(self):
|
|
149
|
-
"""Warning: this may be a `vortex.syntax.stdattrs.DelayedInit` object
|
|
150
|
-
during Vortex initialization and may not have a `sections()` method
|
|
151
|
-
nor a `config` property.
|
|
152
|
-
"""
|
|
153
|
-
return sessions.current().sh.default_target
|
|
154
|
-
|
|
155
|
-
@property
|
|
156
|
-
def _conf_items(self):
|
|
157
|
-
"""Check and return the configuration: a section in the target-xxx.ini file.
|
|
158
|
-
|
|
159
|
-
If the configuration is None, an attempt is made to use the Action's kind.
|
|
160
|
-
Don't use before Vortex initialization is done (see `_shtarget`).
|
|
161
|
-
"""
|
|
162
|
-
if self._conf_dict is None:
|
|
163
|
-
if self._conf_section is None:
|
|
164
|
-
if self.kind in self._shtarget.sections():
|
|
165
|
-
self._conf_section = self.kind
|
|
166
|
-
else:
|
|
167
|
-
if self._conf_section not in self._shtarget.sections():
|
|
168
|
-
raise KeyError(
|
|
169
|
-
'No section "{}" in "{}"'.format(
|
|
170
|
-
self._conf_section, self._shtarget.config.file
|
|
171
|
-
)
|
|
172
|
-
)
|
|
173
|
-
if self._conf_section is None:
|
|
174
|
-
self._conf_dict = dict()
|
|
175
|
-
else:
|
|
176
|
-
self._conf_dict = self._shtarget.items(self._conf_section)
|
|
177
|
-
return self._conf_dict
|
|
178
141
|
|
|
179
142
|
def service_info(self, **kw):
|
|
180
|
-
for k, v in self.
|
|
143
|
+
for k, v in self._tuning.items():
|
|
181
144
|
kw.setdefault(k, v)
|
|
182
145
|
return super().service_info(**kw)
|
|
183
146
|
|
|
184
|
-
def tune(self,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
``section`` is a specific section name, or ``None`` for all.
|
|
188
|
-
"""
|
|
189
|
-
if section is None or section == self._conf_section:
|
|
190
|
-
self._tuning.update(kw)
|
|
191
|
-
|
|
192
|
-
def _get_config_dict(self):
|
|
193
|
-
final_dict = dict()
|
|
194
|
-
final_dict.update(self._conf_items)
|
|
195
|
-
final_dict.update(self._tuning)
|
|
196
|
-
return final_dict
|
|
197
|
-
|
|
198
|
-
def info(self):
|
|
199
|
-
"""Informative string (may serve debugging purposes)."""
|
|
200
|
-
s = super().info() + " - tunable\n"
|
|
201
|
-
mix = dict()
|
|
202
|
-
mix.update(self._conf_items)
|
|
203
|
-
mix.update(self._tuning)
|
|
204
|
-
prt = dict()
|
|
205
|
-
for k, v in mix.items():
|
|
206
|
-
if k in self._tuning:
|
|
207
|
-
prt["++ " + k] = "{} (was: {})".format(
|
|
208
|
-
v,
|
|
209
|
-
str(self._conf_items[k])
|
|
210
|
-
if k in self._conf_items
|
|
211
|
-
else "<not set>",
|
|
212
|
-
)
|
|
213
|
-
else:
|
|
214
|
-
prt[" " + k] = v
|
|
215
|
-
if self._conf_section is not None:
|
|
216
|
-
s += " " * 4 + "configuration: " + self._conf_section + "\n"
|
|
217
|
-
s += dict_as_str(prt, prefix=4)
|
|
218
|
-
return s.strip()
|
|
147
|
+
def tune(self, **kw):
|
|
148
|
+
self._tuning.update(kw)
|
|
219
149
|
|
|
220
150
|
def getx(self, key, *args, **kw):
|
|
221
151
|
"""Shortcut to access the configuration overridden by the tuning."""
|
|
222
152
|
if key in self._tuning:
|
|
223
153
|
return self._tuning[key]
|
|
224
154
|
|
|
225
|
-
if self._conf_section is not None:
|
|
226
|
-
return self._shtarget.getx(
|
|
227
|
-
key=self._conf_section + ":" + key, *args, **kw
|
|
228
|
-
)
|
|
229
|
-
|
|
230
155
|
if "default" in kw:
|
|
231
156
|
return kw["default"]
|
|
232
157
|
|
|
233
|
-
raise KeyError(
|
|
234
|
-
'The "{:s}" entry was not found in any configuration'.format(key)
|
|
235
|
-
)
|
|
158
|
+
raise KeyError('The "{:s}" entry was not found'.format(key))
|
|
236
159
|
|
|
237
160
|
|
|
238
161
|
class SendMail(Action):
|
|
@@ -10,6 +10,7 @@ It also provdes an AlgoComponent's Mixin to properly setup the environment
|
|
|
10
10
|
when using the grib_api or ecCodes libraries.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
+
from pathlib import Path
|
|
13
14
|
from urllib import parse as urlparse
|
|
14
15
|
|
|
15
16
|
import re
|
|
@@ -563,37 +564,41 @@ class EcGribDecoMixin(AlgoComponentDecoMixin):
|
|
|
563
564
|
"After gribapi_setup %s = %s", a_var, self.env.getvar(a_var)
|
|
564
565
|
)
|
|
565
566
|
|
|
566
|
-
def _eccodes_envsetup(
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
567
|
+
def _eccodes_envsetup(
|
|
568
|
+
self,
|
|
569
|
+
eccodes_lib,
|
|
570
|
+
envvar="ECCODES_DEFINITIONS_PATH",
|
|
571
|
+
tgt_path="definitions",
|
|
572
|
+
):
|
|
573
|
+
"""Export envirionment variables required by ECCODES
|
|
574
|
+
|
|
575
|
+
Value is
|
|
576
|
+
|
|
577
|
+
/path/to/eccodes-X.Y.Z/share/eccodes/<target_path>
|
|
578
|
+
|
|
579
|
+
eccodes_lib: Absolute path to the eccodes so file
|
|
580
|
+
envvar: Name of the environment variable to export
|
|
581
|
+
tgt_path: Name of the eccodes install subdirectory to appear
|
|
582
|
+
in the value
|
|
583
|
+
"""
|
|
584
|
+
if envvar in self.env:
|
|
585
|
+
return envvar
|
|
586
|
+
if envvar.replace("ECCODES", "GRIB") in self.env:
|
|
587
|
+
logger.warning(
|
|
588
|
+
(
|
|
589
|
+
"%s is left unconfigured because the old grib_api's"
|
|
590
|
+
"variable is defined. ",
|
|
591
|
+
"Please remove that!",
|
|
592
|
+
),
|
|
593
|
+
envvar,
|
|
594
|
+
)
|
|
595
|
+
return envvar.replace("ECCODES", "GRIB")
|
|
596
|
+
eccodes_root = Path(eccodes_lib).parent.parent
|
|
597
|
+
self.env.setgenericpath(
|
|
598
|
+
envvar,
|
|
599
|
+
str(eccodes_root / "share" / "eccodes" / tgt_path),
|
|
571
600
|
)
|
|
572
|
-
|
|
573
|
-
eccodes_root = self.system.path.split(eccodes_root)[0]
|
|
574
|
-
eccodes_share = self.system.path.join(eccodes_root, "share", "eccodes")
|
|
575
|
-
defvar = "ECCODES_DEFINITION_PATH"
|
|
576
|
-
if defvar not in self.env:
|
|
577
|
-
if "GRIB_DEFINITION_PATH" in self.env:
|
|
578
|
-
logger.warning(dep_warn, defvar)
|
|
579
|
-
defvar = "GRIB_DEFINITION_PATH"
|
|
580
|
-
else:
|
|
581
|
-
self.env.setgenericpath(
|
|
582
|
-
defvar, self.system.path.join(eccodes_share, "definitions")
|
|
583
|
-
)
|
|
584
|
-
samplevar = "ECCODES_SAMPLES_PATH"
|
|
585
|
-
if samplevar not in self.env:
|
|
586
|
-
if "GRIB_SAMPLES_PATH" in self.env:
|
|
587
|
-
logger.warning(dep_warn, samplevar)
|
|
588
|
-
samplevar = "GRIB_SAMPLES_PATH"
|
|
589
|
-
else:
|
|
590
|
-
self.env.setgenericpath(
|
|
591
|
-
samplevar,
|
|
592
|
-
self.system.path.join(
|
|
593
|
-
eccodes_share, "ifs_samples", "grib1"
|
|
594
|
-
),
|
|
595
|
-
)
|
|
596
|
-
return defvar, samplevar
|
|
601
|
+
return envvar
|
|
597
602
|
|
|
598
603
|
def eccodes_setup(self, rh, opts, compat=False, fatal=True):
|
|
599
604
|
"""Setup the grib_api related stuff.
|
|
@@ -605,7 +610,19 @@ class EcGribDecoMixin(AlgoComponentDecoMixin):
|
|
|
605
610
|
# Detect the library's path and setup appropriate variables
|
|
606
611
|
eccodes_lib, gribapi_lib = self._ecgrib_libs_detext(rh)
|
|
607
612
|
if eccodes_lib is not None:
|
|
608
|
-
defvar
|
|
613
|
+
defvar = self._eccodes_envsetup(
|
|
614
|
+
eccodes_lib,
|
|
615
|
+
envvar="ECCODES_DEFINITIONS_PATH",
|
|
616
|
+
tgt_path="definitions",
|
|
617
|
+
)
|
|
618
|
+
subdir = Path("ifs_samples") / (
|
|
619
|
+
"grib1" if rh.resource.cycle < "cy49" else "grib1_mlgrib2"
|
|
620
|
+
)
|
|
621
|
+
samplevar = self._eccodes_envsetup(
|
|
622
|
+
eccodes_lib,
|
|
623
|
+
envvar="ECCODES_SAMPLES_PATH",
|
|
624
|
+
tgt_path=subdir,
|
|
625
|
+
)
|
|
609
626
|
elif compat:
|
|
610
627
|
defvar, samplevar = self._gribapi_envsetup(gribapi_lib)
|
|
611
628
|
else:
|