phonon-charge-pdf 2.0.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.
Files changed (83) hide show
  1. phonon_charge_pdf-2.0.0/.gitattributes +14 -0
  2. phonon_charge_pdf-2.0.0/.github/workflows/LICENSE.txt +77 -0
  3. phonon_charge_pdf-2.0.0/.github/workflows/build.yml +317 -0
  4. phonon_charge_pdf-2.0.0/.github/workflows/publish.yml +62 -0
  5. phonon_charge_pdf-2.0.0/.gitignore +49 -0
  6. phonon_charge_pdf-2.0.0/CITATION.cff +42 -0
  7. phonon_charge_pdf-2.0.0/Dockerfile_gfortran +92 -0
  8. phonon_charge_pdf-2.0.0/Dockerfile_intel +129 -0
  9. phonon_charge_pdf-2.0.0/Dockerfile_jupyter +140 -0
  10. phonon_charge_pdf-2.0.0/Dockerfile_llvm +113 -0
  11. phonon_charge_pdf-2.0.0/Dockerfile_tau_intel +144 -0
  12. phonon_charge_pdf-2.0.0/LICENSE +28 -0
  13. phonon_charge_pdf-2.0.0/PKG-INFO +431 -0
  14. phonon_charge_pdf-2.0.0/README.md +414 -0
  15. phonon_charge_pdf-2.0.0/app/profile_driver.f90 +59 -0
  16. phonon_charge_pdf-2.0.0/app/profile_region.f90 +54 -0
  17. phonon_charge_pdf-2.0.0/docs/PROFILING.md +100 -0
  18. phonon_charge_pdf-2.0.0/environment.yaml +38 -0
  19. phonon_charge_pdf-2.0.0/figures/chisquare_er_simulator.png +0 -0
  20. phonon_charge_pdf-2.0.0/figures/chisquare_nr_simulator.png +0 -0
  21. phonon_charge_pdf-2.0.0/figures/chisquare_ppqn.png +0 -0
  22. phonon_charge_pdf-2.0.0/ford.md +30 -0
  23. phonon_charge_pdf-2.0.0/fpm.toml +11 -0
  24. phonon_charge_pdf-2.0.0/osg/normgrid.sub +33 -0
  25. phonon_charge_pdf-2.0.0/osg/normgrid_job.sh +16 -0
  26. phonon_charge_pdf-2.0.0/phonon_charge_pdf.egg-info/PKG-INFO +431 -0
  27. phonon_charge_pdf-2.0.0/phonon_charge_pdf.egg-info/SOURCES.txt +81 -0
  28. phonon_charge_pdf-2.0.0/phonon_charge_pdf.egg-info/dependency_links.txt +1 -0
  29. phonon_charge_pdf-2.0.0/phonon_charge_pdf.egg-info/requires.txt +7 -0
  30. phonon_charge_pdf-2.0.0/phonon_charge_pdf.egg-info/scm_file_list.json +78 -0
  31. phonon_charge_pdf-2.0.0/phonon_charge_pdf.egg-info/scm_version.json +8 -0
  32. phonon_charge_pdf-2.0.0/phonon_charge_pdf.egg-info/top_level.txt +1 -0
  33. phonon_charge_pdf-2.0.0/pyproject.toml +32 -0
  34. phonon_charge_pdf-2.0.0/python/__init__.py +28 -0
  35. phonon_charge_pdf-2.0.0/python/cli/__init__.py +5 -0
  36. phonon_charge_pdf-2.0.0/python/cli/normgrid.py +821 -0
  37. phonon_charge_pdf-2.0.0/python/cli/normplan.py +190 -0
  38. phonon_charge_pdf-2.0.0/python/cli/normtables.py +135 -0
  39. phonon_charge_pdf-2.0.0/python/cli/table_registry.json +15 -0
  40. phonon_charge_pdf-2.0.0/python/event_generator.py +355 -0
  41. phonon_charge_pdf-2.0.0/python/internal/__init__.py +4 -0
  42. phonon_charge_pdf-2.0.0/python/internal/_ppqfort_bindings.py +260 -0
  43. phonon_charge_pdf-2.0.0/python/internal/ppq_dist.py +533 -0
  44. phonon_charge_pdf-2.0.0/python/ppq_pdf.py +229 -0
  45. phonon_charge_pdf-2.0.0/scripts/generate_version_include.py +59 -0
  46. phonon_charge_pdf-2.0.0/setup.cfg +4 -0
  47. phonon_charge_pdf-2.0.0/slurm/build_table.job +34 -0
  48. phonon_charge_pdf-2.0.0/slurm/build_table.sh +145 -0
  49. phonon_charge_pdf-2.0.0/slurm/normgrid.sbatch +132 -0
  50. phonon_charge_pdf-2.0.0/slurm/pull_container.job +112 -0
  51. phonon_charge_pdf-2.0.0/slurm/submit_alderaan.sh +68 -0
  52. phonon_charge_pdf-2.0.0/specs/held_ER.json +51 -0
  53. phonon_charge_pdf-2.0.0/specs/held_NR.json +56 -0
  54. phonon_charge_pdf-2.0.0/specs/spec_ER.json +49 -0
  55. phonon_charge_pdf-2.0.0/specs/spec_NR.json +55 -0
  56. phonon_charge_pdf-2.0.0/src/PpqFort_m.f90 +130 -0
  57. phonon_charge_pdf-2.0.0/src/PpqFort_s.f90 +1177 -0
  58. phonon_charge_pdf-2.0.0/src/gl_tables.f90.inc +378 -0
  59. phonon_charge_pdf-2.0.0/test/PpqFort_test_m.f90 +68 -0
  60. phonon_charge_pdf-2.0.0/test/driver.f90 +14 -0
  61. phonon_charge_pdf-2.0.0/test/python/README.md +100 -0
  62. phonon_charge_pdf-2.0.0/test/python/band_breakpoints.py +139 -0
  63. phonon_charge_pdf-2.0.0/test/python/chisquare_harness.py +332 -0
  64. phonon_charge_pdf-2.0.0/test/python/debug_bin_example.py +54 -0
  65. phonon_charge_pdf-2.0.0/test/python/quad_breakpoints_demo.py +136 -0
  66. phonon_charge_pdf-2.0.0/test/python/sample_from_pdf.py +282 -0
  67. phonon_charge_pdf-2.0.0/test/python/test_PpqFort.py +239 -0
  68. phonon_charge_pdf-2.0.0/test/python/test_PpqFort_vectorFuncs.py +126 -0
  69. phonon_charge_pdf-2.0.0/test/python/test_chisquare_er_simulator.py +207 -0
  70. phonon_charge_pdf-2.0.0/test/python/test_chisquare_nr_simulator.py +208 -0
  71. phonon_charge_pdf-2.0.0/test/python/test_chisquare_ppqn.py +221 -0
  72. phonon_charge_pdf-2.0.0/test/python/test_normgrid.py +251 -0
  73. phonon_charge_pdf-2.0.0/test/python/test_normplan.py +120 -0
  74. phonon_charge_pdf-2.0.0/test/python/test_normtables.py +109 -0
  75. phonon_charge_pdf-2.0.0/test/python/test_pip_packaging.py +63 -0
  76. phonon_charge_pdf-2.0.0/test/python/test_ppq_pdf_tables.py +105 -0
  77. phonon_charge_pdf-2.0.0/test/python/test_region_integral.py +188 -0
  78. phonon_charge_pdf-2.0.0/test/python/test_safe_integrator_multimodal.py +72 -0
  79. phonon_charge_pdf-2.0.0/test/python/test_version.py +46 -0
  80. phonon_charge_pdf-2.0.0/test/python/verify_sample_from_pdf.py +69 -0
  81. phonon_charge_pdf-2.0.0/test/slurm/sacct +8 -0
  82. phonon_charge_pdf-2.0.0/test/slurm/sbatch +29 -0
  83. phonon_charge_pdf-2.0.0/test/slurm/test_build_table.sh +69 -0
@@ -0,0 +1,14 @@
1
+ # Set the default behavior, in case people don't have core.autocrlf set.
2
+ * text=auto
3
+
4
+ # Explicitly declare text files you want to always be normalized and converted
5
+ # to native line endings on checkout.
6
+ *.f90 text
7
+ *.py text
8
+ *.md text
9
+ *.toml text
10
+ *.yaml text
11
+ Dockerfile* text
12
+
13
+ # Denote all files that are truly binary and should not be modified.
14
+ *.sif binary
@@ -0,0 +1,77 @@
1
+ ***********************************
2
+ *** Formal Terms and Conditions ***
3
+ ***********************************
4
+
5
+ All files in this directory and all sub-directories (except where otherwise
6
+ noted) are subject to the following copyright and licensing terms:
7
+
8
+
9
+ ****************************
10
+
11
+ *** Copyright Notice ***
12
+
13
+ Fortran mimetic abstraction language (Formal) Copyright (c) 2026,
14
+ The Regents of the University of California, through Lawrence Berkeley
15
+ National Laboratory (subject to receipt of any required approvals from the
16
+ U.S. Dept. of Energy). All rights reserved.
17
+
18
+ If you have questions about your rights to use or distribute this software,
19
+ please contact Berkeley Lab's Intellectual Property Office at
20
+ IPO@lbl.gov.
21
+
22
+ NOTICE. This Software was developed under funding from the U.S. Department
23
+ of Energy and the U.S. Government consequently retains certain rights. As
24
+ such, the U.S. Government has been granted for itself and others acting on
25
+ its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
26
+ Software to reproduce, distribute copies to the public, prepare derivative
27
+ works, and perform publicly and display publicly, and to permit others to
28
+ do so.
29
+
30
+
31
+ ****************************
32
+
33
+ *** License Agreement ***
34
+
35
+ Fortran mimetic abstraction language (Formal) Copyright (c) 2026,
36
+ The Regents of the University of California, through Lawrence Berkeley
37
+ National Laboratory (subject to receipt of any required approvals from the
38
+ U.S. Dept. of Energy). All rights reserved.
39
+
40
+ Redistribution and use in source and binary forms, with or without
41
+ modification, are permitted provided that the following conditions are met:
42
+
43
+ (1) Redistributions of source code must retain the above copyright notice,
44
+ this list of conditions and the following disclaimer.
45
+
46
+ (2) Redistributions in binary form must reproduce the above copyright
47
+ notice, this list of conditions and the following disclaimer in the
48
+ documentation and/or other materials provided with the distribution.
49
+
50
+ (3) Neither the name of the University of California, Lawrence Berkeley
51
+ National Laboratory, U.S. Dept. of Energy nor the names of its contributors
52
+ may be used to endorse or promote products derived from this software
53
+ without specific prior written permission.
54
+
55
+
56
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
57
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
60
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
61
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
62
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
63
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
64
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
65
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
66
+ POSSIBILITY OF SUCH DAMAGE.
67
+
68
+ You are under no obligation whatsoever to provide any bug fixes, patches,
69
+ or upgrades to the features, functionality or performance of the source
70
+ code ("Enhancements") to anyone; however, if you choose to make your
71
+ Enhancements available either publicly, or directly to Lawrence Berkeley
72
+ National Laboratory, without imposing a separate written license agreement
73
+ for such Enhancements, then you hereby grant the following license: a
74
+ non-exclusive, royalty-free perpetual license to install, use, modify,
75
+ prepare derivative works, incorporate into other computer software,
76
+ distribute, and sublicense such enhancements or derivative works thereof,
77
+ in binary and source code form.
@@ -0,0 +1,317 @@
1
+ # Copyright (c) 2026, The Regents of the University of California
2
+ # Terms of use are as specified in LICENSE.txt
3
+
4
+ name: Build
5
+
6
+ on: [push, pull_request]
7
+
8
+ defaults:
9
+ run:
10
+ shell: bash
11
+
12
+ jobs:
13
+ build:
14
+ name: ${{ matrix.compiler }}-${{ matrix.version }} (${{ matrix.os }})
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ os: [macos-26, macos-15, macos-15-intel, ubuntu-24.04]
20
+ compiler: [ gfortran ]
21
+ version: [ 15 ]
22
+ extra_flags: [ -g -O3 ]
23
+
24
+ exclude:
25
+ - os: ubuntu-24.04
26
+ version: 15 # no package available
27
+
28
+ include:
29
+ # --- LLVM flang coverage ---
30
+
31
+ # macos-15-intel is deliberately NOT covered here: flang is a Tier 3
32
+ # Homebrew formula there and Intel bottles for it are unreliable, so
33
+ # `brew install flang` compiles LLVM + flang from source, ~4 hours,
34
+ # every run -- not a flake, reproduced and timed via the GitHub API.
35
+ # gfortran still covers it above (it has a stable bottle everywhere).
36
+ # macos-26 (Apple Silicon) isn't covered here either, pending
37
+ # confirmation Homebrew has a flang bottle for it yet -- it only
38
+ # replaced the deprecated macos-14 runner in the gfortran-only list
39
+ # above, same reasoning as macos-14 before it. The macos-15 (Apple
40
+ # Silicon) entry below already gives real flang-on-macOS signal,
41
+ # with a working bottle, in a couple of minutes.
42
+ - os: macos-15
43
+ compiler: flang
44
+ version: 21
45
+
46
+ # https://hub.docker.com/r/snowstep/llvm/tags
47
+ - os: ubuntu-24.04
48
+ compiler: flang
49
+ version: latest
50
+ container: snowstep/llvm:noble
51
+ - os: ubuntu-22.04
52
+ compiler: flang
53
+ version: latest
54
+ container: snowstep/llvm:jammy
55
+
56
+ # https://hub.docker.com/r/phhargrove/llvm-flang/tags
57
+ - os: ubuntu-24.04
58
+ compiler: flang
59
+ version: 22
60
+ container: phhargrove/llvm-flang:22.1.3-latest
61
+ - os: ubuntu-24.04
62
+ compiler: flang
63
+ version: 21
64
+ container: phhargrove/llvm-flang:21.1.0-latest
65
+ - os: ubuntu-24.04
66
+ compiler: flang
67
+ version: 20
68
+ container: phhargrove/llvm-flang:20.1.0-latest
69
+ - os: ubuntu-24.04
70
+ compiler: flang
71
+ version: 19
72
+ extra_flags: -g -mmlir -allow-assumed-rank -O3
73
+ container: phhargrove/llvm-flang:19.1.1-latest
74
+
75
+ # --- Intel coverage ---
76
+
77
+ # https://hub.docker.com/r/intel/fortran-essentials/tags
78
+ - os: ubuntu-24.04
79
+ compiler: ifx
80
+ version: 2025.2.0
81
+ error_stop_code: 128
82
+ container: intel/fortran-essentials:2025.2.0-0-devel-ubuntu24.04
83
+
84
+ - os: ubuntu-24.04
85
+ compiler: ifx
86
+ version: 2025.2.2
87
+ error_stop_code: 128
88
+ container: intel/fortran-essentials:2025.2.2-0-devel-ubuntu24.04
89
+
90
+ - os: ubuntu-24.04
91
+ compiler: ifx
92
+ version: latest
93
+ error_stop_code: 128
94
+ container: intel/fortran-essentials:latest
95
+
96
+ container:
97
+ image: ${{ matrix.container }}
98
+
99
+ env:
100
+ COMPILER_VERSION: ${{ matrix.version }}
101
+ FC: ${{ matrix.compiler }}
102
+ FFLAGS: ${{ matrix.extra_flags }}
103
+ FPM_FLAGS: --profile release --verbose
104
+
105
+ steps:
106
+ - name: Install Dependencies Ubuntu
107
+ if: ${{ contains(matrix.os, 'ubuntu') && matrix.compiler == 'gfortran' && matrix.version == '15' }}
108
+ run: |
109
+ sudo apt-get update
110
+ sudo apt list -a 'gfortran-*'
111
+ sudo apt install -y gfortran-${COMPILER_VERSION} build-essential
112
+ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${COMPILER_VERSION} 100 \
113
+ --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${COMPILER_VERSION}
114
+
115
+
116
+ - name: Install Ubuntu Container Dependencies
117
+ if: ${{ contains(matrix.os, 'ubuntu') && matrix.container != '' && !contains(matrix.container, 'phhargrove') }}
118
+ run: |
119
+ set -x
120
+ apt update
121
+ apt install -y build-essential pkg-config make git curl
122
+
123
+ - name: Install macOS Dependencies
124
+ if: contains(matrix.os, 'macos')
125
+ run: |
126
+ set -x
127
+ brew update
128
+ # fpm binary distribution for macOS requires gfortran shared libraries from gcc@12
129
+ brew install gcc@12
130
+
131
+ - name: Install LLVM flang on macOS
132
+ if: contains(matrix.os, 'macos') && matrix.compiler == 'flang'
133
+ run: |
134
+ set -x
135
+ brew install llvm@${COMPILER_VERSION} flang
136
+ # workaround issue #228: clang cannot find homebrew flang's C header
137
+ for p in /opt/homebrew /usr/local $(brew --prefix) ; do find $p/Cellar/flang -name ISO_Fortran_binding.h 2>/dev/null || true ; done
138
+ echo "CFLAGS=-I$(dirname $(find $(brew --prefix)/Cellar/flang -name ISO_Fortran_binding.h | head -1)) ${CFLAGS}" >> "$GITHUB_ENV"
139
+ # Prepend homebrew clang to PATH:
140
+ echo "PATH=$(brew --prefix)/opt/llvm/bin:${PATH}" >> "$GITHUB_ENV"
141
+
142
+ - name: Checkout code
143
+ uses: actions/checkout@v4
144
+ with:
145
+ # setuptools-scm (pyproject.toml) derives the package version from
146
+ # the nearest git tag. This step runs after the dependency-install
147
+ # steps above, not first: on the apt-based containers, git isn't
148
+ # installed yet at the very start of the job, and actions/checkout
149
+ # silently falls back to a tarball download via the GitHub REST
150
+ # API with no .git directory at all when it can't find git on
151
+ # PATH -- no history, no tags, regardless of fetch-depth/
152
+ # fetch-tags below. None of the steps above need the checkout.
153
+ fetch-depth: 0
154
+ fetch-tags: true
155
+
156
+ - name: Setup Compilers
157
+ run: |
158
+ set -x
159
+ if test "$FC" = "flang" ; then \
160
+ echo "FPM_FC=flang-new" >> "$GITHUB_ENV" ; \
161
+ elif test "$FC" = "ifx" ; then \
162
+ echo "FPM_FC=ifx" >> "$GITHUB_ENV" ; \
163
+ echo "FFLAGS=-fpp $FFLAGS" >> "$GITHUB_ENV" ; \
164
+ echo "FFLAGS=-coarray $FFLAGS" >> "$GITHUB_ENV" ; \
165
+ elif test "$FC" = "lfortran" ; then \
166
+ echo "FPM_FC=lfortran" >> "$GITHUB_ENV" ; \
167
+ echo "FFLAGS=--cpp $FFLAGS" >> "$GITHUB_ENV" ; \
168
+ else \
169
+ echo "FPM_FC=gfortran-${COMPILER_VERSION}" >> "$GITHUB_ENV" ; \
170
+ echo "FFLAGS=-ffree-line-length-0 $FFLAGS" >> "$GITHUB_ENV" ; \
171
+ fi
172
+ if test -n "${{ matrix.error_stop_code }}" ; then \
173
+ echo "ERROR_STOP_CODE=${{ matrix.error_stop_code }}" >> "$GITHUB_ENV" ; \
174
+ else \
175
+ echo "ERROR_STOP_CODE=1" >> "$GITHUB_ENV" ; \
176
+ fi
177
+
178
+ - name: Setup FPM
179
+ uses: fortran-lang/setup-fpm@main
180
+ with:
181
+ github-token: ${{ secrets.GITHUB_TOKEN }}
182
+ fpm-version: latest
183
+
184
+ - name: Build FPM
185
+ if: false
186
+ run: |
187
+ set -x
188
+ export FPM_VERSION=0.12.0
189
+ curl --retry 5 -LOsS https://github.com/fortran-lang/fpm/releases/download/v$FPM_VERSION/fpm-$FPM_VERSION.F90
190
+ mkdir fpm-temp
191
+ gfortran-14 -o fpm-temp/fpm fpm-$FPM_VERSION.F90
192
+ echo "PATH=`pwd`/fpm-temp:${PATH}" >> "$GITHUB_ENV"
193
+
194
+ - name: Version info
195
+ run: |
196
+ echo == TOOL VERSIONS ==
197
+ echo Platform version info:
198
+ uname -a
199
+ if test -r /etc/os-release ; then grep -e NAME -e VERSION /etc/os-release ; fi
200
+ if test -x /usr/bin/sw_vers ; then /usr/bin/sw_vers ; fi
201
+ echo
202
+ echo PATH="$PATH"
203
+ for tool in ${FPM_FC} fpm ; do
204
+ ( echo ; set -x ; w=$(which $tool) ; ls -al $w ; ls -alhL $w ; $tool --version )
205
+ done
206
+
207
+ - name: Generate version include
208
+ # src/PpqFort_m.f90 `include`s src/version.f90.inc (not committed --
209
+ # see scripts/generate_version_include.py), generated here from
210
+ # fpm.toml's version field directly in POSIX sh/sed rather than by
211
+ # calling that script, since several matrix jobs run in minimal
212
+ # third-party compiler containers with no guarantee python3 is on
213
+ # PATH. Both read the same fpm.toml line, so there is nothing to
214
+ # keep in sync between them -- only the (stable, one-line) parsing
215
+ # logic is duplicated, not a value that changes every release.
216
+ run: |
217
+ set -x
218
+ V=$(grep '^version' fpm.toml | head -1 | sed -E 's/version[[:space:]]*=[[:space:]]*"([0-9]+)\.([0-9]+)\.([0-9]+)".*/\1 \2 \3/')
219
+ set -- $V
220
+ printf '%s\n' \
221
+ '! Generated by .github/workflows/build.yml from fpm.toml'"'"'s version field.' \
222
+ " integer(c_int), parameter :: version_major = $1" \
223
+ " integer(c_int), parameter :: version_minor = $2" \
224
+ " integer(c_int), parameter :: version_patch = $3" \
225
+ > src/version.f90.inc
226
+ cat src/version.f90.inc
227
+
228
+ - name: Build and Test (Assertions OFF)
229
+ run: |
230
+ set -x
231
+ echo "FPM_FLAGS=${FPM_FLAGS}"
232
+ echo "FFLAGS=$FFLAGS"
233
+ fpm test ${FPM_FLAGS} --flag "$FFLAGS"
234
+
235
+ # Python validation of python/ppq_dist.py and python/event_generator.py
236
+ # against the compiled Fortran library. Skipped for:
237
+ # - the phhargrove/llvm-flang containers, which are minimal
238
+ # (non-apt-based) images that can't reliably get a Python + pip
239
+ # toolchain installed.
240
+ # - ifx: libband_distribution.so (via its -coarray dependency on
241
+ # libjulienne.so) needs an Intel coarray-runtime symbol
242
+ # (for_rtl_ICAF_NUM_IMAGES_TEAM) that's apparently only resolved when
243
+ # linked into a full ifx-built executable (as fpm test's own driver
244
+ # is) -- loading the shared library standalone via ctypes.CDLL hits
245
+ # `OSError: undefined symbol`. Getting ctypes to load an
246
+ # Intel-coarray-enabled .so outside Intel's own build/launch machinery
247
+ # is a separate problem from wiring Python into CI; left for later.
248
+ - name: Install Python
249
+ if: ${{ !contains(matrix.container, 'phhargrove') && matrix.compiler != 'ifx' }}
250
+ uses: actions/setup-python@v5
251
+ with:
252
+ python-version: '3.12'
253
+
254
+ - name: Install band_distribution (pip, editable)
255
+ if: ${{ !contains(matrix.container, 'phhargrove') && matrix.compiler != 'ifx' }}
256
+ run: |
257
+ set -x
258
+ # Invoke the interpreter setup-python just installed by its own
259
+ # absolute path ($pythonLocation), not a bare `python`/`pip`: inside
260
+ # a job container, PATH updates from setup-python's $GITHUB_PATH
261
+ # don't reliably take effect by the next step's `docker exec`, so a
262
+ # bare `python` can silently resolve to the container's own
263
+ # system interpreter instead (no numpy installed there). Using
264
+ # -m pip also sidesteps the installed `pip` wrapper script, whose
265
+ # shebang carries the *host* runner's tool-cache path -- one more
266
+ # path that doesn't resolve inside the container.
267
+ #
268
+ # An editable install of the whole package (pyproject.toml's [test]
269
+ # extra covers everything below, not a bare numpy/scipy/... list)
270
+ # so CI also validates that `pip install` itself works, not just
271
+ # the modules it happens to install.
272
+ "$pythonLocation/bin/python" -m pip install -e ".[test]"
273
+
274
+ - name: Validate pip packaging (graceful degradation without Fortran)
275
+ if: ${{ !contains(matrix.container, 'phhargrove') && matrix.compiler != 'ifx' }}
276
+ run: |
277
+ set -x
278
+ # Deliberately before "Install compiled library to lib/": the
279
+ # point is to prove the package imports and its pure-Python half
280
+ # (event_generator.py) works with no Fortran library anywhere on
281
+ # the system, while PpqPDF fails clearly at construction instead
282
+ # of silently succeeding.
283
+ "$pythonLocation/bin/python" test/python/test_pip_packaging.py
284
+
285
+ - name: Install compiled library to lib/
286
+ if: ${{ !contains(matrix.container, 'phhargrove') && matrix.compiler != 'ifx' }}
287
+ run: |
288
+ set -x
289
+ fpm install --prefix=. ${FPM_FLAGS} --flag "$FFLAGS"
290
+
291
+ - name: Validate ppq_dist.py against the compiled library
292
+ if: ${{ !contains(matrix.container, 'phhargrove') && matrix.compiler != 'ifx' }}
293
+ run: |
294
+ set -x
295
+ # Prepend a relative `lib`, don't replace LD_LIBRARY_PATH/
296
+ # DYLD_LIBRARY_PATH outright: setup-python's portable Python build
297
+ # needs its own entry already in there (to find libpython itself)
298
+ # on the container jobs. And it must be relative, not
299
+ # ${{ github.workspace }}: that context expression is always the
300
+ # host runner's path, even inside a job container where the
301
+ # checkout is bind-mounted at a different path -- a relative path
302
+ # resolves against the shell's cwd, which is the checkout root
303
+ # either way.
304
+ export LD_LIBRARY_PATH="lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
305
+ export DYLD_LIBRARY_PATH="lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}"
306
+ "$pythonLocation/bin/python" test/python/test_PpqFort.py
307
+ "$pythonLocation/bin/python" test/python/test_PpqFort_vectorFuncs.py
308
+ "$pythonLocation/bin/python" test/python/test_safe_integrator_multimodal.py
309
+
310
+ - name: Validate the event generator against the compiled PDFs (smoke test)
311
+ if: ${{ !contains(matrix.container, 'phhargrove') && matrix.compiler != 'ifx' }}
312
+ run: |
313
+ set -x
314
+ export LD_LIBRARY_PATH="lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
315
+ export DYLD_LIBRARY_PATH="lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}"
316
+ "$pythonLocation/bin/python" test/python/test_chisquare_nr_simulator.py 100 64
317
+ "$pythonLocation/bin/python" test/python/test_chisquare_er_simulator.py 100 64
@@ -0,0 +1,62 @@
1
+ # Copyright (c) 2026, The Regents of the University of California
2
+ # Terms of use are as specified in LICENSE.txt
3
+
4
+ name: Publish to PyPI
5
+
6
+ on:
7
+ push:
8
+ tags:
9
+ - 'v*.*.*'
10
+ workflow_dispatch: {}
11
+
12
+ jobs:
13
+ build:
14
+ name: Build sdist and wheel
15
+ runs-on: ubuntu-24.04
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+ with:
20
+ # setuptools-scm derives the version from the nearest git tag --
21
+ # see the matching comment in build.yml.
22
+ fetch-depth: 0
23
+ fetch-tags: true
24
+
25
+ - name: Install Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: '3.12'
29
+
30
+ - name: Build sdist and wheel
31
+ run: |
32
+ set -x
33
+ python -m pip install build
34
+ python -m build
35
+
36
+ - name: Upload build artifacts
37
+ uses: actions/upload-artifact@v4
38
+ with:
39
+ name: dist
40
+ path: dist/
41
+
42
+ publish:
43
+ name: Publish to PyPI
44
+ needs: build
45
+ runs-on: ubuntu-24.04
46
+ # Only an actual version tag publishes; workflow_dispatch is for a dry
47
+ # -run build (the job above) without pushing anything to PyPI.
48
+ if: startsWith(github.ref, 'refs/tags/v')
49
+ environment: pypi
50
+ permissions:
51
+ # Required for PyPI Trusted Publishing (OIDC) -- no API token stored
52
+ # as a secret. See https://docs.pypi.org/trusted-publishers/.
53
+ id-token: write
54
+ steps:
55
+ - name: Download build artifacts
56
+ uses: actions/download-artifact@v4
57
+ with:
58
+ name: dist
59
+ path: dist/
60
+
61
+ - name: Publish to PyPI
62
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,49 @@
1
+ # ignore image files
2
+ *.sif
3
+
4
+ # ignore object and shared object files
5
+ *.so
6
+ *.o
7
+
8
+ # ignore operating system files and temp files
9
+ .DS_Store
10
+ ~*
11
+ *.swp
12
+
13
+ # Compiler-generated files
14
+ a.out
15
+ *.exe
16
+ *.mod
17
+ *.smod
18
+ *.sub
19
+ *.a
20
+ *.so
21
+ *.o
22
+ *.dylib
23
+ *.dll
24
+
25
+ # Ford-generated documentation folder
26
+ doc/html
27
+
28
+ # Python bytecode caches
29
+ __pycache__/
30
+
31
+ # pip/setuptools build artifacts (pip install -e ., python -m build)
32
+ *.egg-info/
33
+ build/
34
+ dist/
35
+
36
+ # Regenerable PDF grid caches (keyed to the .so hash; rebuild on demand)
37
+ *.npz
38
+
39
+ # fpm install output
40
+ bin/
41
+
42
+ # Slurm output and normgrid run artifacts (slurm/normgrid.sbatch writes these)
43
+ logs/
44
+ results/
45
+
46
+ # Generated from fpm.toml's version field by scripts/generate_version_include.py;
47
+ # run that script before building (every Dockerfile does) -- never commit the
48
+ # output, or it can silently go stale when fpm.toml's version is bumped.
49
+ src/version.f90.inc
@@ -0,0 +1,42 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use this software, please cite it using the metadata below."
3
+ title: band_distribution
4
+ type: software
5
+ abstract: >-
6
+ Probability densities of (Ep, Eq) -- total phonon and total charge energy -- for
7
+ electron recoils (PpqG) and nuclear recoils (PpqN) in cryogenic germanium dark matter
8
+ detectors, given a set of detector parameters. A Fortran library parallelized with
9
+ do concurrent, with Python bindings, region-normalization integrals, and precomputed
10
+ normalization tables for MCMC.
11
+ authors:
12
+ - family-names: Roberts
13
+ given-names: Amy
14
+ affiliation: University of Colorado Denver
15
+ orcid: "https://orcid.org/0000-0001-8538-9155"
16
+ - family-names: Rouson
17
+ given-names: Damian
18
+ affiliation: Lawrence Berkeley National Laboratory
19
+ orcid: "https://orcid.org/0000-0002-2344-868X"
20
+ repository-code: "https://github.com/det-lab/band_distribution"
21
+ license: BSD-3-Clause
22
+ keywords:
23
+ - dark matter
24
+ - germanium detectors
25
+ - Fano factor
26
+ - nuclear recoil
27
+ - electron recoil
28
+ - Fortran
29
+ references:
30
+ - type: data
31
+ title: band_distribution normalization tables
32
+ doi: 10.5281/zenodo.23048215 # concept DOI: all versions (new windows are added as versions)
33
+ authors:
34
+ - family-names: Roberts
35
+ given-names: Amy
36
+ orcid: "https://orcid.org/0000-0001-8538-9155"
37
+ - family-names: Rouson
38
+ given-names: Damian
39
+ orcid: "https://orcid.org/0000-0002-2344-868X"
40
+ notes: >-
41
+ Precomputed region-normalization tables used by python/ppq_pdf.py and fetched by
42
+ python/cli/normtables.py (python/cli/table_registry.json).
@@ -0,0 +1,92 @@
1
+ # Ubuntu 26.04 LTS ships gfortran 15.2 as the default gfortran package,
2
+ # which supports the do concurrent locality specifiers (including the
3
+ # Fortran 2023 reduce clause) this project requires.
4
+ FROM ubuntu:26.04
5
+
6
+ ENV DEBIAN_FRONTEND=noninteractive
7
+
8
+ # Version of the repository to build: leave unset (default) to build from
9
+ # this local checkout, including any uncommitted changes; set to a tag or
10
+ # commit hash (--build-arg GIT_REF=v0.9.0) to instead clone and check out
11
+ # that exact revision from GitHub, ignoring the local checkout.
12
+ ARG GIT_REF=""
13
+
14
+ # python3-numpy/python3-scipy provide the packages needed by the python
15
+ # test scripts; python-is-python3 lets them be invoked as `python`
16
+ RUN apt-get update && apt-get install -y \
17
+ git \
18
+ curl \
19
+ ca-certificates \
20
+ vim \
21
+ gfortran \
22
+ python3 \
23
+ python-is-python3 \
24
+ python3-numpy \
25
+ python3-scipy \
26
+ python3-pip \
27
+ && apt-get clean \
28
+ && rm -rf /var/lib/apt/lists/*
29
+
30
+ # matplotlib/equibin/lintsampler are needed by the chi-square validation
31
+ # scripts under test/python/ (test_chisquare_*.py, chisquare_harness.py,
32
+ # sample_from_pdf.py); not available via apt, unlike numpy/scipy above.
33
+ # Matches the same three packages environment.yaml installs for the
34
+ # ifx/flang containers. h5py is for the precomputed normalization
35
+ # tables (python/cli/normgrid.py), pooch for fetching the published ones
36
+ # (python/cli/normtables.py).
37
+ RUN pip install --break-system-packages --no-cache-dir \
38
+ matplotlib equibin lintsampler h5py pooch
39
+
40
+ # Set up working directory
41
+ WORKDIR /app
42
+
43
+ # Install fpm from source (bootstraps itself with gfortran)
44
+ # There is an fpm package on conda but building from source gives a
45
+ # newer version
46
+ RUN git clone https://github.com/fortran-lang/fpm \
47
+ && cd fpm \
48
+ && ./install.sh
49
+
50
+ ENV PATH="/root/.local/bin:${PATH}"
51
+
52
+ # Stage the source: defaults to this local checkout; if GIT_REF is set,
53
+ # the RUN step below discards this and clones that revision instead.
54
+ COPY src /tmp/band_src/src/
55
+ COPY test /tmp/band_src/test
56
+ COPY fpm.toml /tmp/band_src/
57
+ COPY python /tmp/band_src/python/
58
+ COPY scripts /tmp/band_src/scripts/
59
+
60
+ RUN if [ -n "$GIT_REF" ]; then \
61
+ echo "Building band_distribution @ $GIT_REF (overriding local checkout)" && \
62
+ rm -rf /tmp/band_src && \
63
+ git clone https://github.com/det-lab/band_distribution.git /tmp/band_src && \
64
+ cd /tmp/band_src && git checkout "$GIT_REF"; \
65
+ else \
66
+ echo "Building band_distribution from the local checkout"; \
67
+ fi
68
+
69
+ RUN mkdir -p /app/src /app/test /app/python /app/scripts \
70
+ && cp -r /tmp/band_src/src/. /app/src/ \
71
+ && cp -r /tmp/band_src/test/. /app/test/ \
72
+ && cp -r /tmp/band_src/python/. /app/python/ \
73
+ && cp -r /tmp/band_src/scripts/. /app/scripts/ \
74
+ && cp /tmp/band_src/fpm.toml /app/ \
75
+ && rm -rf /tmp/band_src
76
+
77
+ # version.f90.inc (PpqFort_version(); not committed, see the script) must
78
+ # exist before fpm build/test -- it is a plain `include` in src/PpqFort_m.f90
79
+ RUN python scripts/generate_version_include.py
80
+
81
+ # Now compile the fortran code
82
+ RUN fpm test --compiler gfortran --profile release --flag "-march=native -fopenmp -ftree-parallelize-loops=4 -fcoarray=single -fPIC"
83
+ RUN fpm install --prefix=. --flag "-march=native -fopenmp -ftree-parallelize-loops=4 -fcoarray=single -fPIC"
84
+
85
+ # Needed to find the appropriate .so files from within python
86
+ ENV LD_LIBRARY_PATH=/app/lib
87
+
88
+ # Published normalization tables (python/cli/table_registry.json), fetched and
89
+ # hash-checked at build time -- HPC compute nodes often have no internet.
90
+ # python/cli/normtables.py (and so PpqPDF(ppqn_table=NAME)) finds them here.
91
+ ENV BAND_TABLES_DIR=/app/tables
92
+ RUN mkdir -p /app/tables && python /app/python/cli/normtables.py fetch --all