ucgmsim-workflow 2026.9.1__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.
Files changed (66) hide show
  1. ucgmsim_workflow-2026.9.1/.github/workflows/ci.yml +12 -0
  2. ucgmsim_workflow-2026.9.1/.github/workflows/claude-review.yml +11 -0
  3. ucgmsim_workflow-2026.9.1/.github/workflows/container.yml +79 -0
  4. ucgmsim_workflow-2026.9.1/.github/workflows/publish-PyPI.yml +91 -0
  5. ucgmsim_workflow-2026.9.1/.gitignore +191 -0
  6. ucgmsim_workflow-2026.9.1/.isort.cfg +2 -0
  7. ucgmsim_workflow-2026.9.1/PKG-INFO +43 -0
  8. ucgmsim_workflow-2026.9.1/container/Dockerfile +84 -0
  9. ucgmsim_workflow-2026.9.1/container/runner.def +23 -0
  10. ucgmsim_workflow-2026.9.1/cylc/flow.cylc +69 -0
  11. ucgmsim_workflow-2026.9.1/cylc/workflow-setup +75 -0
  12. ucgmsim_workflow-2026.9.1/pyproject.toml +170 -0
  13. ucgmsim_workflow-2026.9.1/setup.cfg +4 -0
  14. ucgmsim_workflow-2026.9.1/tests/test_cli.py +60 -0
  15. ucgmsim_workflow-2026.9.1/tests/test_generate_domain.py +112 -0
  16. ucgmsim_workflow-2026.9.1/tests/test_hf.py +172 -0
  17. ucgmsim_workflow-2026.9.1/tests/test_log_utils.py +199 -0
  18. ucgmsim_workflow-2026.9.1/tests/test_realisation.py +956 -0
  19. ucgmsim_workflow-2026.9.1/tests/test_realisation_to_srf.py +265 -0
  20. ucgmsim_workflow-2026.9.1/tests/test_utils.py +184 -0
  21. ucgmsim_workflow-2026.9.1/ucgmsim_workflow.egg-info/PKG-INFO +43 -0
  22. ucgmsim_workflow-2026.9.1/ucgmsim_workflow.egg-info/SOURCES.txt +64 -0
  23. ucgmsim_workflow-2026.9.1/ucgmsim_workflow.egg-info/dependency_links.txt +1 -0
  24. ucgmsim_workflow-2026.9.1/ucgmsim_workflow.egg-info/entry_points.txt +23 -0
  25. ucgmsim_workflow-2026.9.1/ucgmsim_workflow.egg-info/requires.txt +39 -0
  26. ucgmsim_workflow-2026.9.1/ucgmsim_workflow.egg-info/scm_file_list.json +60 -0
  27. ucgmsim_workflow-2026.9.1/ucgmsim_workflow.egg-info/scm_version.json +8 -0
  28. ucgmsim_workflow-2026.9.1/ucgmsim_workflow.egg-info/top_level.txt +1 -0
  29. ucgmsim_workflow-2026.9.1/uv.lock +3595 -0
  30. ucgmsim_workflow-2026.9.1/workflow/__init__.py +103 -0
  31. ucgmsim_workflow-2026.9.1/workflow/default_parameters/__init__.py +0 -0
  32. ucgmsim_workflow-2026.9.1/workflow/default_parameters/root/__init__.py +0 -0
  33. ucgmsim_workflow-2026.9.1/workflow/default_parameters/root/defaults.yaml +1226 -0
  34. ucgmsim_workflow-2026.9.1/workflow/default_parameters/v24_2_2_1/__init__.py +0 -0
  35. ucgmsim_workflow-2026.9.1/workflow/default_parameters/v24_2_2_1/defaults.yaml +8 -0
  36. ucgmsim_workflow-2026.9.1/workflow/default_parameters/v24_2_2_2/__init__.py +0 -0
  37. ucgmsim_workflow-2026.9.1/workflow/default_parameters/v24_2_2_2/defaults.yaml +8 -0
  38. ucgmsim_workflow-2026.9.1/workflow/default_parameters/v24_2_2_4/__init__.py +0 -0
  39. ucgmsim_workflow-2026.9.1/workflow/default_parameters/v24_2_2_4/defaults.yaml +8 -0
  40. ucgmsim_workflow-2026.9.1/workflow/defaults.py +46 -0
  41. ucgmsim_workflow-2026.9.1/workflow/log_utils.py +170 -0
  42. ucgmsim_workflow-2026.9.1/workflow/realisations.py +1337 -0
  43. ucgmsim_workflow-2026.9.1/workflow/schemas.py +1208 -0
  44. ucgmsim_workflow-2026.9.1/workflow/scripts/__init__.py +7 -0
  45. ucgmsim_workflow-2026.9.1/workflow/scripts/bb_sim.py +233 -0
  46. ucgmsim_workflow-2026.9.1/workflow/scripts/check_domain.py +106 -0
  47. ucgmsim_workflow-2026.9.1/workflow/scripts/check_srf.py +153 -0
  48. ucgmsim_workflow-2026.9.1/workflow/scripts/convert_vm_hdf5_to_emod3d.py +74 -0
  49. ucgmsim_workflow-2026.9.1/workflow/scripts/copy_velocity_model_parameters.py +67 -0
  50. ucgmsim_workflow-2026.9.1/workflow/scripts/create_e3d_par.py +294 -0
  51. ucgmsim_workflow-2026.9.1/workflow/scripts/gcmt_auto_simulate.py +124 -0
  52. ucgmsim_workflow-2026.9.1/workflow/scripts/gcmt_to_realisation.py +299 -0
  53. ucgmsim_workflow-2026.9.1/workflow/scripts/generate_domain.py +609 -0
  54. ucgmsim_workflow-2026.9.1/workflow/scripts/generate_rupture_propagation.py +129 -0
  55. ucgmsim_workflow-2026.9.1/workflow/scripts/generate_station_coordinates.py +139 -0
  56. ucgmsim_workflow-2026.9.1/workflow/scripts/generate_stoch.py +102 -0
  57. ucgmsim_workflow-2026.9.1/workflow/scripts/generate_velocity_model.py +254 -0
  58. ucgmsim_workflow-2026.9.1/workflow/scripts/hf_sim.py +483 -0
  59. ucgmsim_workflow-2026.9.1/workflow/scripts/im_calc.py +330 -0
  60. ucgmsim_workflow-2026.9.1/workflow/scripts/import_realisation.py +90 -0
  61. ucgmsim_workflow-2026.9.1/workflow/scripts/lf_to_xarray.py +55 -0
  62. ucgmsim_workflow-2026.9.1/workflow/scripts/merge_ts.py +433 -0
  63. ucgmsim_workflow-2026.9.1/workflow/scripts/migrate.py +589 -0
  64. ucgmsim_workflow-2026.9.1/workflow/scripts/nshm2022_to_realisation.py +401 -0
  65. ucgmsim_workflow-2026.9.1/workflow/scripts/realisation_to_srf.py +900 -0
  66. ucgmsim_workflow-2026.9.1/workflow/utils.py +218 -0
@@ -0,0 +1,12 @@
1
+ name: CI
2
+ on: [pull_request]
3
+
4
+ jobs:
5
+ ci:
6
+ uses: ucgmsim/meta-ci-action/.github/workflows/ci.yml@v1
7
+ with:
8
+ package-dir: workflow
9
+ system-packages: "gmt libgmt-dev ghostscript"
10
+ enable-coverage: true
11
+ cov-package: workflow
12
+ cov-fail-under: 95
@@ -0,0 +1,11 @@
1
+ name: Claude PR Review
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created]
6
+
7
+ jobs:
8
+ review:
9
+ uses: ucgmsim/meta-ci-action/.github/workflows/claude-review.yml@v1
10
+ secrets:
11
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
@@ -0,0 +1,79 @@
1
+ name: Build, Test in Container, and Upload
2
+
3
+ # Runs after a release is published to PyPI (called from publish-PyPI.yml),
4
+ # or manually to rebuild the image for an existing PyPI release.
5
+ on:
6
+ workflow_call:
7
+ inputs:
8
+ version:
9
+ description: 'ucgmsim-workflow version on PyPI to install'
10
+ required: true
11
+ type: string
12
+ ref:
13
+ description: 'Git ref to take the tests from (defaults to the triggering ref)'
14
+ required: false
15
+ type: string
16
+ workflow_dispatch:
17
+ inputs:
18
+ version:
19
+ description: 'ucgmsim-workflow version on PyPI to install'
20
+ required: true
21
+ type: string
22
+
23
+ env:
24
+ REGISTRY: docker.io
25
+ IMAGE_NAME: earthquakesuc/workflow-bootstrap
26
+
27
+ jobs:
28
+ build-test-upload:
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - name: Checkout repository
32
+ uses: actions/checkout@v4
33
+ with:
34
+ ref: ${{ inputs.ref || github.ref }}
35
+
36
+ # PyPI can take a little while to serve a freshly uploaded release.
37
+ - name: Wait for the release to appear on PyPI
38
+ run: |
39
+ for _ in $(seq 30); do
40
+ if curl -sf "https://pypi.org/pypi/ucgmsim-workflow/${{ inputs.version }}/json" > /dev/null; then
41
+ exit 0
42
+ fi
43
+ sleep 10
44
+ done
45
+ echo "ucgmsim-workflow ${{ inputs.version }} not found on PyPI" >&2
46
+ exit 1
47
+
48
+ - name: Log in to Docker Hub
49
+ uses: docker/login-action@v3
50
+ with:
51
+ username: earthquakesuc
52
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
53
+
54
+ - name: Extract metadata
55
+ id: meta
56
+ uses: docker/metadata-action@v5
57
+ with:
58
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
59
+ tags: |
60
+ type=raw,value=${{ inputs.version }}
61
+ type=raw,value=latest
62
+
63
+ - name: Build and push
64
+ uses: docker/build-push-action@v5
65
+ with:
66
+ context: .
67
+ file: ./container/Dockerfile
68
+ build-args: |
69
+ WORKFLOW_VERSION=${{ inputs.version }}
70
+ push: true
71
+ tags: ${{ steps.meta.outputs.tags }}
72
+ labels: ${{ steps.meta.outputs.labels }}
73
+
74
+ - name: Run pytest
75
+ run: |
76
+ docker run --rm \
77
+ -v ${{ github.workspace }}:/mnt \
78
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ inputs.version }} \
79
+ bash -c "pytest /mnt/tests"
@@ -0,0 +1,91 @@
1
+ name: Publish to PyPI
2
+ run-name: Publish Python Package to PyPI for release ${{ github.event.release.tag_name || inputs.tag_name || github.ref_name }}
3
+
4
+ on:
5
+ release:
6
+ types: [published]
7
+ workflow_dispatch:
8
+ inputs:
9
+ tag_name:
10
+ description: 'Git tag to checkout and publish'
11
+ required: false
12
+ type: string
13
+
14
+ jobs:
15
+ build:
16
+ name: Build distribution 📦
17
+ # Pure Python, so one py3-none-any wheel serves every interpreter and
18
+ # platform: no build matrix and no cibuildwheel.
19
+ runs-on: ubuntu-latest
20
+ outputs:
21
+ version: ${{ steps.version.outputs.version }}
22
+
23
+ steps:
24
+ - name: Checkout code
25
+ uses: actions/checkout@v4.1.0
26
+ with:
27
+ ref: ${{ inputs.tag_name || github.ref }}
28
+ # setuptools-scm derives the version from the tag, so it needs the full
29
+ # history rather than a shallow clone.
30
+ fetch-depth: 0
31
+
32
+ - name: Set up Python
33
+ uses: actions/setup-python@v5
34
+ with:
35
+ python-version: "3.13"
36
+
37
+ - name: Build wheel and source distribution
38
+ run: |
39
+ python3 -m pip install build
40
+ python3 -m build
41
+
42
+ - name: Get the package version
43
+ id: version
44
+ # The wheel filename carries the normalised version setuptools-scm
45
+ # derived from the tag, which is what the container installs.
46
+ run: |
47
+ wheel=$(basename dist/*.whl)
48
+ echo "version=$(echo "$wheel" | cut -d- -f2)" >> "$GITHUB_OUTPUT"
49
+
50
+ - name: Store the distribution packages
51
+ uses: actions/upload-artifact@v4
52
+ with:
53
+ name: python-package-distributions
54
+ path: dist/
55
+ if-no-files-found: error
56
+
57
+ publish-to-pypi:
58
+ name: Publish to PyPI
59
+ needs:
60
+ - build
61
+ runs-on: ubuntu-latest
62
+
63
+ environment:
64
+ name: pypi
65
+ url: https://pypi.org/p/ucgmsim-workflow
66
+
67
+ permissions:
68
+ id-token: write
69
+
70
+ steps:
71
+ - name: Download the dists
72
+ uses: actions/download-artifact@v4
73
+ with:
74
+ name: python-package-distributions
75
+ path: dist/
76
+
77
+ - name: Publish distribution to PyPI
78
+ uses: pypa/gh-action-pypi-publish@release/v1
79
+ with:
80
+ packages-dir: dist
81
+
82
+ build-container:
83
+ name: Build and push the container
84
+ needs:
85
+ - build
86
+ - publish-to-pypi
87
+ uses: ./.github/workflows/container.yml
88
+ with:
89
+ version: ${{ needs.build.outputs.version }}
90
+ ref: ${{ inputs.tag_name || github.ref }}
91
+ secrets: inherit
@@ -0,0 +1,191 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/python
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python
3
+
4
+
5
+ docker/runner/EMOD3D/
6
+ docker/runner/nshmdb.db
7
+ docker/runner/genslip_velocity_model.vmod
8
+
9
+ ### Python ###
10
+ # Byte-compiled / optimized / DLL files
11
+ __pycache__/
12
+ *.py[cod]
13
+ *$py.class
14
+
15
+ # C extensions
16
+ *.so
17
+
18
+ # Distribution / packaging
19
+ .Python
20
+ build/
21
+ develop-eggs/
22
+ dist/
23
+ downloads/
24
+ eggs/
25
+ .eggs/
26
+ lib/
27
+ lib64/
28
+ parts/
29
+ sdist/
30
+ var/
31
+ wheels/
32
+ share/python-wheels/
33
+ *.egg-info/
34
+ .installed.cfg
35
+ *.egg
36
+ MANIFEST
37
+
38
+ # PyInstaller
39
+ # Usually these files are written by a python script from a template
40
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
41
+ *.manifest
42
+ *.spec
43
+
44
+ # Installer logs
45
+ pip-log.txt
46
+ pip-delete-this-directory.txt
47
+
48
+ # Unit test / coverage reports
49
+ htmlcov/
50
+ .tox/
51
+ .nox/
52
+ .coverage
53
+ .coverage.*
54
+ .cache
55
+ nosetests.xml
56
+ coverage.xml
57
+ *.cover
58
+ *.py,cover
59
+ .hypothesis/
60
+ .pytest_cache/
61
+ cover/
62
+
63
+ # Translations
64
+ *.mo
65
+ *.pot
66
+
67
+ # Django stuff:
68
+ *.log
69
+ local_settings.py
70
+ db.sqlite3
71
+ db.sqlite3-journal
72
+
73
+ # Flask stuff:
74
+ instance/
75
+ .webassets-cache
76
+
77
+ # Scrapy stuff:
78
+ .scrapy
79
+
80
+ # Sphinx documentation
81
+ docs/_build/
82
+
83
+ # PyBuilder
84
+ .pybuilder/
85
+ target/
86
+
87
+ # Jupyter Notebook
88
+ .ipynb_checkpoints
89
+
90
+ # IPython
91
+ profile_default/
92
+ ipython_config.py
93
+
94
+ # pyenv
95
+ # For a library or package, you might want to ignore these files since the code is
96
+ # intended to run in multiple environments; otherwise, check them in:
97
+ # .python-version
98
+
99
+ # pipenv
100
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
101
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
102
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
103
+ # install all needed dependencies.
104
+ #Pipfile.lock
105
+
106
+ # poetry
107
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
108
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
109
+ # commonly ignored for libraries.
110
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
111
+ #poetry.lock
112
+
113
+ # pdm
114
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
115
+ #pdm.lock
116
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
117
+ # in version control.
118
+ # https://pdm.fming.dev/#use-with-ide
119
+ .pdm.toml
120
+
121
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
122
+ __pypackages__/
123
+
124
+ # Celery stuff
125
+ celerybeat-schedule
126
+ celerybeat.pid
127
+
128
+ # SageMath parsed files
129
+ *.sage.py
130
+
131
+ # Environments
132
+ .env
133
+ .venv
134
+ env/
135
+ venv/
136
+ ENV/
137
+ env.bak/
138
+ venv.bak/
139
+
140
+ # Spyder project settings
141
+ .spyderproject
142
+ .spyproject
143
+
144
+ # Rope project settings
145
+ .ropeproject
146
+
147
+ # mkdocs documentation
148
+ /site
149
+
150
+ # mypy
151
+ .mypy_cache/
152
+ .dmypy.json
153
+ dmypy.json
154
+
155
+ # Pyre type checker
156
+ .pyre/
157
+
158
+ # pytype static type analyzer
159
+ .pytype/
160
+
161
+ # Cython debug symbols
162
+ cython_debug/
163
+
164
+ # PyCharm
165
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
166
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
167
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
168
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
169
+ #.idea/
170
+
171
+ ### Python Patch ###
172
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
173
+ poetry.toml
174
+
175
+ # ruff
176
+ .ruff_cache/
177
+
178
+ # LSP config files
179
+ pyrightconfig.json
180
+
181
+ # End of https://www.toptal.com/developers/gitignore/api/python
182
+
183
+ # Devenv
184
+ .devenv*
185
+ devenv.local.nix
186
+
187
+ # direnv
188
+ .direnv
189
+
190
+ # pre-commit
191
+ .pre-commit-config.yaml
@@ -0,0 +1,2 @@
1
+ [settings]
2
+ known_first_party=qcore,empirical,nshmdb,IM_calculation,mera,source_modelling
@@ -0,0 +1,43 @@
1
+ Metadata-Version: 2.4
2
+ Name: ucgmsim-workflow
3
+ Version: 2026.9.1
4
+ Summary: Next generation workflow powered by cylc.
5
+ Author: QuakeCoRE
6
+ Requires-Python: >=3.12
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: im-calculation<2026.09.01,>=2025.12.5
9
+ Requires-Dist: velocity-modelling>=2026.2.1
10
+ Requires-Dist: nshmdb>=2026.09.1
11
+ Requires-Dist: oq_wrapper>=2025.12.3
12
+ Requires-Dist: qcore-utils>=2025.12.2
13
+ Requires-Dist: source_modelling>=2026.08.1
14
+ Requires-Dist: geopandas
15
+ Requires-Dist: pandas[hdf5,parquet]
16
+ Requires-Dist: pyyaml
17
+ Requires-Dist: xarray[io]
18
+ Requires-Dist: numpy
19
+ Requires-Dist: scipy
20
+ Requires-Dist: shapely
21
+ Requires-Dist: tqdm
22
+ Requires-Dist: typer
23
+ Requires-Dist: requests
24
+ Requires-Dist: schema
25
+ Requires-Dist: structlog
26
+ Requires-Dist: psutil
27
+ Requires-Dist: parse>=1.21.0
28
+ Requires-Dist: rich>=14.3.2
29
+ Provides-Extra: test
30
+ Requires-Dist: pytest>=6.0.0; extra == "test"
31
+ Requires-Dist: hypothesis[numpy]>=6.0.0; extra == "test"
32
+ Requires-Dist: pytest-cov; extra == "test"
33
+ Requires-Dist: coverage[toml]; extra == "test"
34
+ Provides-Extra: types
35
+ Requires-Dist: pandas-stubs; extra == "types"
36
+ Requires-Dist: types-geopandas; extra == "types"
37
+ Requires-Dist: types-requests; extra == "types"
38
+ Requires-Dist: scipy-stubs; extra == "types"
39
+ Provides-Extra: dev
40
+ Requires-Dist: ruff>=0.16.5; extra == "dev"
41
+ Requires-Dist: deptry; extra == "dev"
42
+ Requires-Dist: ty>=0.0.75; extra == "dev"
43
+ Requires-Dist: numpydoc; extra == "dev"
@@ -0,0 +1,84 @@
1
+ # Bootstrap Dockerfile
2
+ FROM ubuntu:latest
3
+
4
+ # Set noninteractive mode for apt
5
+ ENV DEBIAN_FRONTEND=noninteractive
6
+
7
+ # Update package lists and install build dependencies
8
+ RUN apt-get update && apt-get install -y \
9
+ build-essential \
10
+ cmake \
11
+ curl \
12
+ gfortran \
13
+ git \
14
+ pkg-config \
15
+ libfftw3-dev \
16
+ libpapi-dev \
17
+ libopenmpi-dev \
18
+ openmpi-bin \
19
+ openmpi-common \
20
+ libopenblas-openmp-dev \
21
+ libhdf5-dev \
22
+ libssl-dev \
23
+ zlib1g-dev \
24
+ libbz2-dev \
25
+ libreadline-dev \
26
+ libsqlite3-dev \
27
+ libffi-dev \
28
+ liblzma-dev \
29
+ libexpat1-dev \
30
+ libpq-dev \
31
+ gdal-bin \
32
+ libgdal-dev \
33
+ libgdbm-dev \
34
+ libgdbm-compat-dev \
35
+ libncurses5-dev \
36
+ libncursesw5-dev \
37
+ uuid-dev \
38
+ libnss3-dev \
39
+ libedit-dev \
40
+ libuuid1 \
41
+ libdb5.3-dev \
42
+ lzma \
43
+ tcl-dev \
44
+ gdb \
45
+ lcov \
46
+ ca-certificates \
47
+ && rm -rf /var/lib/apt/lists/*
48
+
49
+ # Create software directories (removed uv directory)
50
+ RUN mkdir -p /sw/cargo /sw/rust /sw/python /sw/venv
51
+
52
+ # Python installation
53
+ ARG PYTHON_VERSION=3.13.12
54
+ RUN curl -o /tmp/Python-${PYTHON_VERSION}.tar.xz \
55
+ https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz && \
56
+ cd /tmp && \
57
+ tar xf Python-${PYTHON_VERSION}.tar.xz && \
58
+ cd Python-${PYTHON_VERSION} && \
59
+ ./configure --prefix=/sw/python --enable-optimizations && \
60
+ make -j$(nproc) && \
61
+ make install && \
62
+ cd /tmp && \
63
+ rm -rf Python-${PYTHON_VERSION}*
64
+
65
+ # Set Environment Paths
66
+ ENV RUSTUP_HOME=/sw/rust
67
+ ENV CARGO_HOME=/sw/cargo
68
+ ENV VIRTUAL_ENV="/sw/venv"
69
+ # Added /sw/python/bin to path early to ensure we use the compiled python
70
+ ENV PATH="$VIRTUAL_ENV/bin:/sw/python/bin:/sw/cargo/bin:$PATH"
71
+ ENV LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
72
+
73
+ # Install Rust
74
+ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
75
+
76
+ # Setup Virtual Environment and Install via pip
77
+ # openquake.engine 3.26+ requires gdal~=3.13.1, which is sdist-only and refuses to
78
+ # build against the libgdal 3.12.2 that Ubuntu ships. Cap it until libgdal catches up.
79
+ ARG WORKFLOW_VERSION
80
+ RUN test -n "${WORKFLOW_VERSION}" || { echo "WORKFLOW_VERSION build arg is required" >&2; exit 1; } && \
81
+ python3 -m venv $VIRTUAL_ENV && \
82
+ pip install --no-cache-dir --upgrade pip setuptools wheel && \
83
+ pip install --no-cache-dir "ucgmsim-workflow==${WORKFLOW_VERSION}" "openquake.engine<3.26" --no-binary=h5py && \
84
+ chmod -R a+rX /sw
@@ -0,0 +1,23 @@
1
+ Bootstrap: docker
2
+ From: earthquakesuc/workflow-bootstrap:latest
3
+
4
+ %files
5
+ EMOD3D /EMOD3D
6
+
7
+ %post
8
+ cd /EMOD3D && \
9
+ mkdir build && cd build && \
10
+ cmake -DHF_TIME_WINDOW=off -DUSE_FFTW=on -DCMAKE_C_FLAGS="-march=x86-64 -mtune=generic -std=gnu89" .. && \
11
+ make -j $(nproc) genslip_v5.6.2 srf2stoch generic_slip2srf \
12
+ hb_high_binmod_v6.0.3
13
+
14
+ cd /
15
+ # Keep only the EMOD3D tools folder and compiled binaries
16
+ find /EMOD3D -mindepth 1 -maxdepth 1 ! -name "tools" -exec rm -rf {} \;
17
+
18
+ %environment
19
+ export RUSTUP_HOME=/sw/rust
20
+ export CARGO_HOME=/sw/cargo
21
+ export PATH="/sw/venv/bin:/EMOD3D/tools:/sw/cargo/bin:/sw/python/bin:$PATH"
22
+ export VIRTUAL_ENV="/sw/venv"
23
+ export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
@@ -0,0 +1,69 @@
1
+ [scheduler]
2
+ allow implicit tasks = True
3
+ [scheduling]
4
+ [[graph]]
5
+ R1 = """
6
+ """
7
+ [runtime]
8
+ [[root]]
9
+ platform = mahuika-slurm
10
+ pre-script = """
11
+ module load Apptainer
12
+ """
13
+ [[[directives]]]
14
+ --account = nesi00213
15
+ [[nshm_to_realisation]]
16
+ platform = localhost
17
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif nshm2022-to-realisation /nshmdb.db 0 /share/realisation.json develop
18
+ [[realisation_to_srf]]
19
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif realisation-to-srf /share/realisation.json /share/realisation.srf
20
+ [[generate_stoch]]
21
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif generate-stoch /share/realisation.srf /share/realisation.stoch
22
+ [[generate_velocity_model_parameters]]
23
+ platform = localhost
24
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif generate-velocity-model-parameters /share/realisation.json
25
+ [[generate_velocity_model]]
26
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif sh -c "generate-velocity-model /share/realisation.json --use-nzcvm --num-threads ${SLURM_CPUS_PER_TASK:-32} --work-directory /share"
27
+ [[[directives]]]
28
+ --cpus-per-task = 32
29
+ --time = 01:00:00
30
+ [[convert_vm_hdf5_to_emod3d]]
31
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif convert-vm-hdf5-to-emod3d /share/velocity_model.h5 /share/Velocity_Model
32
+ [[[directives]]]
33
+ --cpus-per-task = 4 # While we only use 4 threads, consider increasing this to allocate more memory per task, as the conversion can be memory intensive. For MN5, setting this 112 will give entire 256GB of the node to the task.
34
+ --time = 02:00:00
35
+ [[generate_station_coordinates]]
36
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif generate-station-coordinates /share/realisation.json /share/stations
37
+ [[generate_model_coordinates]]
38
+ platform = localhost
39
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif generate-model-coordinates /share/realisation.json /share/model
40
+ [[create_e3d_par]]
41
+ platform = localhost
42
+ script = apptainer exec /nesi/nobackup/nesi00213/containers/runner_latest.sif create-e3d-par $CYLC_WORKFLOW_SHARE_DIR/realisation.json $CYLC_WORKFLOW_SHARE_DIR/realisation.srf $CYLC_WORKFLOW_SHARE_DIR/Velocity_Model $CYLC_WORKFLOW_SHARE_DIR/stations $CYLC_WORKFLOW_SHARE_DIR/model $CYLC_WORKFLOW_SHARE_DIR/LF --emod3d-path /nesi/project/nesi00213/opt/maui/hybrid_sim_tools/emod3d-mpi_v3.0.8 --scratch-ffp $CYLC_WORKFLOW_SHARE_DIR/LF
43
+ [[run_emod3d]]
44
+ platform = maui-xc-slurm
45
+ pre-script = ""
46
+ script = srun /nesi/project/nesi00213/opt/maui/hybrid_sim_tools/emod3d-mpi_v3.0.8 -args "par=$CYLC_WORKFLOW_SHARE_DIR/LF/e3d.par"
47
+ [[[directives]]]
48
+ --ntasks = 80
49
+ --hint = nomultithread
50
+ --time = 00:30:00
51
+ [[run_hf]]
52
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif run-hf /share/realisation.json /share/realisation.stoch /share/stations/stations.ll /share/realisation.hf
53
+ [[directives]]
54
+ --cpus-per-task = 128
55
+ --time = 01:00:00
56
+ [[plot_ts]]
57
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif plot-ts /share/LF/OutBin /share/simulation.m4v
58
+
59
+ [[run_bb]]
60
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif bb-sim /share/realisation.json /share/stations/stations.ll /stations.vs30 /share/LF/OutBin /share/realisation.hf /share/Velocity_Model /share/realisation.bb /out
61
+ [[directives]]
62
+ --cpus-per-task = 128
63
+ --time = 01:00:00
64
+
65
+ [[im_calc]]
66
+ script = apptainer exec -c --bind "$PWD:/out,$CYLC_WORKFLOW_SHARE_DIR:/share" /nesi/nobackup/nesi00213/containers/runner_latest.sif im-calc /share/realisation.json /share/realisation.bb /share/im_calc.csv
67
+ [[directives]]
68
+ --cpus-per-task = 128
69
+ --time = 01:00:00
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env bash
2
+
3
+ CYLC_LATEST_VERSION=$(cylc list-versions | grep "^[0-9]" | sort -r | head -n 1)
4
+
5
+ # export the correct environment variables to the users bashrc file
6
+ grep -q 'export PROJECT=nesi00213' ~/.bashrc || echo 'export PROJECT=nesi00213' >>~/.bashrc
7
+ grep -q "export CYLC_VERSION=$CYLC_LATEST_VERSION" ~/.bashrc || echo "export CYLC_VERSION=$CYLC_LATEST_VERSION" >>~/.bashrc
8
+ test -d ~/cylc-src -a -d ~/cylc-run || mkdir ~/cylc-src ~/cylc-run
9
+
10
+ # If the user does not already have an ssh key generated on NeSI login
11
+ # nodes, then we must do so.
12
+ if ! compgen -G "$HOME/.ssh/id_*.pub" >/dev/null; then
13
+ echo "You are about to be prompted for an ssh key password."
14
+ echo "You must hit enter (twice) to ensure the key does not have one."
15
+ sleep 1
16
+ ssh-keygen
17
+ fi
18
+
19
+ # In order for cylc to manage jobs via SSH it needs password-less
20
+ # login via SSH, we do that by authorizing the local SSH keys to
21
+ # login.
22
+
23
+ cat ~/.ssh/id_*.pub >>~/.ssh/authorized_keys
24
+
25
+ # These permissions must be set for the ssh keys to work.
26
+ chmod 700 ~/.ssh
27
+ chmod 600 ~/.ssh/id_*
28
+ chmod 644 ~/.ssh/id_*.pub
29
+ chmod 750 ~
30
+
31
+ # Jupyter Notebook Setup
32
+ mkdir -p ~/.cylc/uiserver
33
+ # Beginning with port=21300, so we don't try to give a user a
34
+ # privileged port, find a port that is unique among nesi00213 project
35
+ # members. Configure cylc to host the gui on that port. The port needs
36
+ # to be unique because users will port-forward this port when they
37
+ # connect to the jupyter lab notebook upon executing cylc gui.
38
+ if ! grep -q "$USER=" /nesi/nobackup/nesi00213/cylc_port_maps; then
39
+ NEXT_WORKFLOW_PORT=$(awk -F= 'BEGIN{port=21299} { if ($2>port) port=$2 fi } END {print port + 1}' /nesi/nobackup/nesi00213/cylc_port_maps)
40
+
41
+ cat <<EOF >~/.cylc/uiserver/jupyter_config.py
42
+ c.ServerApp.open_browser=False
43
+ c.ServerApp.port=$NEXT_WORKFLOW_PORT
44
+ EOF
45
+ # Record the cylc port map so that the next user can find a unique
46
+ # port for themselves.
47
+ echo "$USER=$NEXT_WORKFLOW_PORT" >>/nesi/nobackup/nesi00213/cylc_port_maps
48
+ else
49
+ NEXT_WORKFLOW_PORT=$(grep "$USER=" /nesi/nobackup/nesi00213/cylc_port_maps | cut -d= -f2)
50
+ fi
51
+
52
+ cat <<EOF
53
+ You are correctly setup for Cylc $CYLC_LATEST_VERSION.
54
+ Check that your ssh configuration is working correctly by executing on mahuika:
55
+
56
+ ssh mahuika02 echo Hello from Mahuika02
57
+
58
+ If this command does not prompt for a password, you are good to go.
59
+
60
+ To connect to cylc gui run:
61
+
62
+ On mahuika:
63
+ cylc gui
64
+
65
+ Take note of the url cylc asks you to copy and paste, the one with "127.0.0.1" in the output. It will look something like:
66
+
67
+ http://127.0.0.1:$NEXT_WORKFLOW_PORT/cylc?token=99122750aca901546a5d10ffc2d65b27
68
+
69
+ but your token will vary.
70
+
71
+ On your machine:
72
+ ssh -N -L $NEXT_WORKFLOW_PORT:localhost:$NEXT_WORKFLOW_PORT mahuika
73
+
74
+ Then open the url cylc asked you to copy and paste earlier.
75
+ EOF