pulserver 0.0.2__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.
- pulserver-0.0.2/.claude/skills/build-and-test/SKILL.md +44 -0
- pulserver-0.0.2/.claude/skills/write-documentation/SKILL.md +91 -0
- pulserver-0.0.2/.dockerignore +11 -0
- pulserver-0.0.2/.gitattributes +16 -0
- pulserver-0.0.2/.github/ISSUE_TEMPLATE/bug_report.yml +43 -0
- pulserver-0.0.2/.github/ISSUE_TEMPLATE/config.yml +8 -0
- pulserver-0.0.2/.github/ISSUE_TEMPLATE/feature_request.yml +36 -0
- pulserver-0.0.2/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- pulserver-0.0.2/.github/dependabot.yml +40 -0
- pulserver-0.0.2/.github/workflows/codeql.yml +36 -0
- pulserver-0.0.2/.github/workflows/console.yml +39 -0
- pulserver-0.0.2/.github/workflows/docs.yml +133 -0
- pulserver-0.0.2/.github/workflows/fields.yml +72 -0
- pulserver-0.0.2/.github/workflows/image.yml +57 -0
- pulserver-0.0.2/.github/workflows/koma.yml +65 -0
- pulserver-0.0.2/.github/workflows/style.yml +42 -0
- pulserver-0.0.2/.github/workflows/tags-release.yml +59 -0
- pulserver-0.0.2/.github/workflows/test-ci.yml +107 -0
- pulserver-0.0.2/.github/workflows/wheels.yml +64 -0
- pulserver-0.0.2/.gitignore +38 -0
- pulserver-0.0.2/.pre-commit-config.yaml +31 -0
- pulserver-0.0.2/AGENTS.md +343 -0
- pulserver-0.0.2/CLAUDE.md +1 -0
- pulserver-0.0.2/CMakeLists.txt +62 -0
- pulserver-0.0.2/CODE_OF_CONDUCT.md +42 -0
- pulserver-0.0.2/CONTRIBUTING.md +26 -0
- pulserver-0.0.2/GEMINI.md +1 -0
- pulserver-0.0.2/LICENSE +21 -0
- pulserver-0.0.2/LICENSES/gadgetron-python-MIT.txt +21 -0
- pulserver-0.0.2/LICENSES/python-ismrmrd-server-MIT.txt +21 -0
- pulserver-0.0.2/NEXT.md +100 -0
- pulserver-0.0.2/PKG-INFO +245 -0
- pulserver-0.0.2/README.md +194 -0
- pulserver-0.0.2/SECURITY.md +36 -0
- pulserver-0.0.2/SKILLS.md +17 -0
- pulserver-0.0.2/codecov.yml +22 -0
- pulserver-0.0.2/docker/Dockerfile +59 -0
- pulserver-0.0.2/docker/compose.yaml +51 -0
- pulserver-0.0.2/docker/entrypoint.sh +20 -0
- pulserver-0.0.2/docker/limits/limits.txt +9 -0
- pulserver-0.0.2/docker/smoke.py +98 -0
- pulserver-0.0.2/docs/_static/architecture-dark.svg +46 -0
- pulserver-0.0.2/docs/_static/architecture.svg +46 -0
- pulserver-0.0.2/docs/_static/capabilities.js +15 -0
- pulserver-0.0.2/docs/_static/context-dark.svg +39 -0
- pulserver-0.0.2/docs/_static/context.svg +39 -0
- pulserver-0.0.2/docs/_static/pulseg-dark.svg +46 -0
- pulserver-0.0.2/docs/_static/pulseg.svg +46 -0
- pulserver-0.0.2/docs/_static/pulserver-logo-dark.svg +39 -0
- pulserver-0.0.2/docs/_static/pulserver-logo.svg +39 -0
- pulserver-0.0.2/docs/_static/pulserver-mark-dark.svg +38 -0
- pulserver-0.0.2/docs/_static/pulserver-mark.svg +38 -0
- pulserver-0.0.2/docs/_static/pulserver.css +86 -0
- pulserver-0.0.2/docs/_static/repetition-dark.svg +47 -0
- pulserver-0.0.2/docs/_static/repetition.svg +47 -0
- pulserver-0.0.2/docs/_static/safety-dark.svg +42 -0
- pulserver-0.0.2/docs/_static/safety.svg +42 -0
- pulserver-0.0.2/docs/_static/session-dark.svg +40 -0
- pulserver-0.0.2/docs/_static/session.svg +40 -0
- pulserver-0.0.2/docs/_static/virtual-dark.svg +40 -0
- pulserver-0.0.2/docs/_static/virtual.svg +40 -0
- pulserver-0.0.2/docs/_templates/autosummary/base.rst +5 -0
- pulserver-0.0.2/docs/_templates/autosummary/class.rst +29 -0
- pulserver-0.0.2/docs/_templates/autosummary/enum.rst +8 -0
- pulserver-0.0.2/docs/_templates/autosummary/function.rst +5 -0
- pulserver-0.0.2/docs/api/design.md +67 -0
- pulserver-0.0.2/docs/api/host.md +28 -0
- pulserver-0.0.2/docs/api/index.md +34 -0
- pulserver-0.0.2/docs/api/ir.md +46 -0
- pulserver-0.0.2/docs/api/mrd.md +53 -0
- pulserver-0.0.2/docs/api/protocol.md +100 -0
- pulserver-0.0.2/docs/api/proxy.md +56 -0
- pulserver-0.0.2/docs/api/recon.md +72 -0
- pulserver-0.0.2/docs/api/validate.md +32 -0
- pulserver-0.0.2/docs/api/virtual.md +70 -0
- pulserver-0.0.2/docs/api_objects.py +91 -0
- pulserver-0.0.2/docs/colab.py +129 -0
- pulserver-0.0.2/docs/conf.py +367 -0
- pulserver-0.0.2/docs/developer-guide/documentation.md +832 -0
- pulserver-0.0.2/docs/developer-guide/index.md +26 -0
- pulserver-0.0.2/docs/developer-guide/installation.md +52 -0
- pulserver-0.0.2/docs/developer-guide/internals/calibration.md +176 -0
- pulserver-0.0.2/docs/developer-guide/internals/index.md +25 -0
- pulserver-0.0.2/docs/developer-guide/internals/ir-cache.md +298 -0
- pulserver-0.0.2/docs/developer-guide/internals/protocol-wire.md +150 -0
- pulserver-0.0.2/docs/developer-guide/internals/reconstruction-proxy.md +289 -0
- pulserver-0.0.2/docs/developer-guide/internals/sar-ratios.md +57 -0
- pulserver-0.0.2/docs/developer-guide/internals/virtual-scanner.md +565 -0
- pulserver-0.0.2/docs/developer-guide/releases.md +14 -0
- pulserver-0.0.2/docs/developer-guide/style.md +43 -0
- pulserver-0.0.2/docs/developer-guide/terminology.md +265 -0
- pulserver-0.0.2/docs/developer-guide/workflow.md +39 -0
- pulserver-0.0.2/docs/examples/course.md +35 -0
- pulserver-0.0.2/docs/examples/index.md +37 -0
- pulserver-0.0.2/docs/examples/tours.md +18 -0
- pulserver-0.0.2/docs/explanations/architecture.md +124 -0
- pulserver-0.0.2/docs/explanations/index.md +34 -0
- pulserver-0.0.2/docs/explanations/protocol.md +99 -0
- pulserver-0.0.2/docs/explanations/raw-data.md +97 -0
- pulserver-0.0.2/docs/explanations/reconstruction-session.md +113 -0
- pulserver-0.0.2/docs/explanations/reconstruction.md +114 -0
- pulserver-0.0.2/docs/explanations/safety-checks.md +122 -0
- pulserver-0.0.2/docs/explanations/scanner-representation.md +192 -0
- pulserver-0.0.2/docs/explanations/virtual-scanner.md +110 -0
- pulserver-0.0.2/docs/figure_style.py +79 -0
- pulserver-0.0.2/docs/index.md +16 -0
- pulserver-0.0.2/docs/misc/contributors.md +7 -0
- pulserver-0.0.2/docs/misc/index.md +15 -0
- pulserver-0.0.2/docs/misc/license.md +25 -0
- pulserver-0.0.2/docs/misc/related.md +12 -0
- pulserver-0.0.2/docs/user-guide/index.md +97 -0
- pulserver-0.0.2/docs/user-guide/reconstruction-client.md +87 -0
- pulserver-0.0.2/docs/user-guide/reconstruction-plugins.md +422 -0
- pulserver-0.0.2/docs/user-guide/running.md +438 -0
- pulserver-0.0.2/docs/user-guide/scanner-sequences.md +540 -0
- pulserver-0.0.2/docs/user-guide/virtual-scanner.md +383 -0
- pulserver-0.0.2/gallery/01-course/01_protocol_to_image.py +242 -0
- pulserver-0.0.2/gallery/01-course/02_sequence_plugin.py +447 -0
- pulserver-0.0.2/gallery/01-course/03_scanner_representation.py +285 -0
- pulserver-0.0.2/gallery/01-course/04_reconstruction_plugin.py +304 -0
- pulserver-0.0.2/gallery/01-course/05_recon_plugin.py +249 -0
- pulserver-0.0.2/gallery/01-course/06_testing_on_the_virtual_scanner.py +340 -0
- pulserver-0.0.2/gallery/01-course/README.rst +6 -0
- pulserver-0.0.2/gallery/01-course/_gallery_header.md +1 -0
- pulserver-0.0.2/gallery/02-tours/01_protocol_resolution.py +216 -0
- pulserver-0.0.2/gallery/02-tours/02_segmentation.py +166 -0
- pulserver-0.0.2/gallery/02-tours/03_fov_offset_enrichment.py +209 -0
- pulserver-0.0.2/gallery/02-tours/README.rst +6 -0
- pulserver-0.0.2/gallery/02-tours/_gallery_header.md +1 -0
- pulserver-0.0.2/gallery/README.rst +6 -0
- pulserver-0.0.2/gallery/_gallery_header.md +2 -0
- pulserver-0.0.2/pyproject.toml +156 -0
- pulserver-0.0.2/scripts/build_docs.sh +22 -0
- pulserver-0.0.2/scripts/check_throughput.py +100 -0
- pulserver-0.0.2/scripts/format_and_lint.sh +19 -0
- pulserver-0.0.2/scripts/make_artwork.py +586 -0
- pulserver-0.0.2/scripts/publish_docs.py +150 -0
- pulserver-0.0.2/setup.py +5 -0
- pulserver-0.0.2/src/c/CMakeLists.txt +43 -0
- pulserver-0.0.2/src/c/cache/pulseg_cache.c +2992 -0
- pulserver-0.0.2/src/c/core/pulseg_core.c +1136 -0
- pulserver-0.0.2/src/c/core/pulseg_error.c +227 -0
- pulserver-0.0.2/src/c/core/pulseg_math.c +259 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg.h +34 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg_cache.h +161 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg_collection.h +887 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg_config.h +122 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg_errors.h +82 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg_io.h +66 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg_playout.h +241 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg_protocol.h +467 -0
- pulserver-0.0.2/src/c/include/pulseg/pulseg_types.h +1066 -0
- pulserver-0.0.2/src/c/include/pulseq/pulseq.h +45 -0
- pulserver-0.0.2/src/c/include/pulseq/pulseq_config.h +109 -0
- pulserver-0.0.2/src/c/include/pulseq/pulseq_types.h +449 -0
- pulserver-0.0.2/src/c/io/pulseg_opts.c +63 -0
- pulserver-0.0.2/src/c/io/pulseg_protocol.c +907 -0
- pulserver-0.0.2/src/c/playout/pulseg_playout.c +558 -0
- pulserver-0.0.2/src/c/pulseg_internal.h +1049 -0
- pulserver-0.0.2/src/c/pulseq/pulseq_internal.h +36 -0
- pulserver-0.0.2/src/c/pulseq/pulseq_shape.c +86 -0
- pulserver-0.0.2/src/c/structure/pulseg_descriptor.c +239 -0
- pulserver-0.0.2/src/c/structure/pulseg_getters.c +3522 -0
- pulserver-0.0.2/src/c/structure/pulseg_repetition.c +102 -0
- pulserver-0.0.2/src/c/structure/pulseg_waves.c +1015 -0
- pulserver-0.0.2/src/cpp/fourier/bindings.cpp +370 -0
- pulserver-0.0.2/src/cpp/fourier/bindings.hpp +13 -0
- pulserver-0.0.2/src/cpp/fourier/parallel.hpp +256 -0
- pulserver-0.0.2/src/cpp/fourier/timeline.cpp +473 -0
- pulserver-0.0.2/src/cpp/fourier/timeline.hpp +182 -0
- pulserver-0.0.2/src/cpp/ir/collection.cpp +254 -0
- pulserver-0.0.2/src/cpp/ir/dedup.cpp +1851 -0
- pulserver-0.0.2/src/cpp/ir/from_libraries.cpp +551 -0
- pulserver-0.0.2/src/cpp/ir/from_libraries.hpp +32 -0
- pulserver-0.0.2/src/cpp/ir/pulseg_convert.h +103 -0
- pulserver-0.0.2/src/cpp/ir/pulseq_file.cpp +329 -0
- pulserver-0.0.2/src/cpp/ir/pulseq_file.h +53 -0
- pulserver-0.0.2/src/cpp/ir/repetition.cpp +216 -0
- pulserver-0.0.2/src/cpp/ir/structure.cpp +3606 -0
- pulserver-0.0.2/src/cpp/ir/wave_plan.cpp +376 -0
- pulserver-0.0.2/src/cpp/ir/waves.cpp +474 -0
- pulserver-0.0.2/src/cpp/module.cpp +994 -0
- pulserver-0.0.2/src/cpp/native.hpp +269 -0
- pulserver-0.0.2/src/cpp/playout.cpp +684 -0
- pulserver-0.0.2/src/cpp/playout.hpp +26 -0
- pulserver-0.0.2/src/pulserver/__init__.py +13 -0
- pulserver-0.0.2/src/pulserver/_accelerators.py +68 -0
- pulserver-0.0.2/src/pulserver/_cli.py +54 -0
- pulserver-0.0.2/src/pulserver/_labels.py +184 -0
- pulserver-0.0.2/src/pulserver/_logs.py +44 -0
- pulserver-0.0.2/src/pulserver/_memory.py +21 -0
- pulserver-0.0.2/src/pulserver/_plugins.py +83 -0
- pulserver-0.0.2/src/pulserver/_zoo/__init__.py +35 -0
- pulserver-0.0.2/src/pulserver/_zoo/_evaluation.py +325 -0
- pulserver-0.0.2/src/pulserver/_zoo/_inversion.py +110 -0
- pulserver-0.0.2/src/pulserver/_zoo/_pmc.py +26 -0
- pulserver-0.0.2/src/pulserver/_zoo/_saturation.py +118 -0
- pulserver-0.0.2/src/pulserver/_zoo/_slab.py +37 -0
- pulserver-0.0.2/src/pulserver/_zoo/_user.py +160 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/bssfp2d/retrospective.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/fse3d/dual_region.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/fse3d/navigator.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/fse3d/optimized.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/fse3d/shuffling.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/fse3d/wave.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/gre3d/full_plane.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/gre3d/wave.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/gre_multiecho2d/bipolar.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/gre_multiecho3d/bipolar.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/gre_multiecho3d/full_plane.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/gre_multiecho3d/wave.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/gre_spiral2d/variable_density.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/gre_stack_of_spirals3d/variable_density.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/mprage3d/navigator.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/mprage3d/shuffling.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/mprage3d/wave.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/mprage_stack_of_spirals3d/variable_density.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/se3d/full_plane.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/se_spiral2d/variable_density.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/se_stack_of_spirals3d/variable_density.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/parameters/zte3d/meridian.toml +2 -0
- pulserver-0.0.2/src/pulserver/_zoo/recon/epi.py +3 -0
- pulserver-0.0.2/src/pulserver/_zoo/recon/nufft.py +3 -0
- pulserver-0.0.2/src/pulserver/_zoo/recon/nufft_train.py +3 -0
- pulserver-0.0.2/src/pulserver/_zoo/recon/pics.py +3 -0
- pulserver-0.0.2/src/pulserver/_zoo/recon/pics_train.py +3 -0
- pulserver-0.0.2/src/pulserver/_zoo/recon/pmc.py +3 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/bssfp2d.py +180 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/bssfp3d.py +93 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/epi2d.py +163 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/epi3d.py +206 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/fse3d.py +206 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre2d.py +75 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre3d.py +77 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre_multiecho2d.py +69 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre_multiecho3d.py +82 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre_propeller2d.py +56 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre_radial2d.py +55 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre_spiral2d.py +73 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre_stack_of_blades3d.py +61 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre_stack_of_spirals3d.py +81 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/gre_stack_of_stars3d.py +60 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/mprage3d.py +133 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/mprage_stack_of_spirals3d.py +91 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/mprage_stack_of_stars3d.py +71 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se2d.py +71 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se3d.py +72 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se_epi_propeller2d.py +121 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se_propeller2d.py +60 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se_radial2d.py +59 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se_spiral2d.py +77 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se_stack_of_blades3d.py +65 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se_stack_of_spirals3d.py +85 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/se_stack_of_stars3d.py +64 -0
- pulserver-0.0.2/src/pulserver/_zoo/sequences/zte3d.py +90 -0
- pulserver-0.0.2/src/pulserver/design/__init__.py +51 -0
- pulserver-0.0.2/src/pulserver/design/_entries.py +561 -0
- pulserver-0.0.2/src/pulserver/design/_options.py +133 -0
- pulserver-0.0.2/src/pulserver/design/_plugin.py +617 -0
- pulserver-0.0.2/src/pulserver/design/_rf.py +111 -0
- pulserver-0.0.2/src/pulserver/host/__init__.py +14 -0
- pulserver-0.0.2/src/pulserver/host/__main__.py +8 -0
- pulserver-0.0.2/src/pulserver/host/_blocks.py +116 -0
- pulserver-0.0.2/src/pulserver/host/_command.py +281 -0
- pulserver-0.0.2/src/pulserver/host/_limits.py +318 -0
- pulserver-0.0.2/src/pulserver/host/_push.py +65 -0
- pulserver-0.0.2/src/pulserver/host/_server.py +263 -0
- pulserver-0.0.2/src/pulserver/host/_service.py +637 -0
- pulserver-0.0.2/src/pulserver/host/_store.py +317 -0
- pulserver-0.0.2/src/pulserver/ir/__init__.py +47 -0
- pulserver-0.0.2/src/pulserver/ir/_checks.py +495 -0
- pulserver-0.0.2/src/pulserver/ir/_convert.py +649 -0
- pulserver-0.0.2/src/pulserver/ir/_playout.py +135 -0
- pulserver-0.0.2/src/pulserver/ir/_source.py +800 -0
- pulserver-0.0.2/src/pulserver/ir/_vendor.py +113 -0
- pulserver-0.0.2/src/pulserver/ir/_waves.py +191 -0
- pulserver-0.0.2/src/pulserver/mrd/__init__.py +38 -0
- pulserver-0.0.2/src/pulserver/mrd/_acquisitions.py +380 -0
- pulserver-0.0.2/src/pulserver/mrd/_header.py +269 -0
- pulserver-0.0.2/src/pulserver/mrd/_images.py +113 -0
- pulserver-0.0.2/src/pulserver/mrd/_metadata.py +229 -0
- pulserver-0.0.2/src/pulserver/mrd/_sequence.py +480 -0
- pulserver-0.0.2/src/pulserver/protocol/__init__.py +89 -0
- pulserver-0.0.2/src/pulserver/protocol/_keys.py +485 -0
- pulserver-0.0.2/src/pulserver/protocol/_prescription.py +67 -0
- pulserver-0.0.2/src/pulserver/protocol/_schema.py +141 -0
- pulserver-0.0.2/src/pulserver/protocol/_wire.py +584 -0
- pulserver-0.0.2/src/pulserver/proxy/__init__.py +26 -0
- pulserver-0.0.2/src/pulserver/proxy/__main__.py +170 -0
- pulserver-0.0.2/src/pulserver/proxy/_designs.py +171 -0
- pulserver-0.0.2/src/pulserver/proxy/_enrich.py +785 -0
- pulserver-0.0.2/src/pulserver/proxy/_held.py +154 -0
- pulserver-0.0.2/src/pulserver/proxy/_intake.py +159 -0
- pulserver-0.0.2/src/pulserver/proxy/_local.py +103 -0
- pulserver-0.0.2/src/pulserver/proxy/_motion.py +232 -0
- pulserver-0.0.2/src/pulserver/proxy/_proxy.py +1142 -0
- pulserver-0.0.2/src/pulserver/proxy/_queue.py +71 -0
- pulserver-0.0.2/src/pulserver/proxy/_seqdesc.py +343 -0
- pulserver-0.0.2/src/pulserver/proxy/_workers.py +206 -0
- pulserver-0.0.2/src/pulserver/recon/__init__.py +51 -0
- pulserver-0.0.2/src/pulserver/recon/__main__.py +106 -0
- pulserver-0.0.2/src/pulserver/recon/_buffers.py +765 -0
- pulserver-0.0.2/src/pulserver/recon/_calibration.py +481 -0
- pulserver-0.0.2/src/pulserver/recon/_correct.py +98 -0
- pulserver-0.0.2/src/pulserver/recon/_exam_image.py +107 -0
- pulserver-0.0.2/src/pulserver/recon/_loader.py +35 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/__init__.py +1 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/application.py +314 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/concurrency.py +252 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/connection.py +574 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/constants.py +63 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/exam.py +292 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/mrd2dicom.py +789 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/offline.py +91 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/readers.py +261 -0
- pulserver-0.0.2/src/pulserver/recon/_runtime/writers.py +213 -0
- pulserver-0.0.2/src/pulserver/recon/_units.py +115 -0
- pulserver-0.0.2/src/pulserver/recon/gadgets.py +270 -0
- pulserver-0.0.2/src/pulserver/recon/handlers/__init__.py +1 -0
- pulserver-0.0.2/src/pulserver/recon/handlers/epi.py +211 -0
- pulserver-0.0.2/src/pulserver/recon/handlers/nufft.py +293 -0
- pulserver-0.0.2/src/pulserver/recon/handlers/nufft_train.py +34 -0
- pulserver-0.0.2/src/pulserver/recon/handlers/pics.py +258 -0
- pulserver-0.0.2/src/pulserver/recon/handlers/pics_train.py +37 -0
- pulserver-0.0.2/src/pulserver/recon/handlers/pmc.py +128 -0
- pulserver-0.0.2/src/pulserver/recon/plugin.py +1095 -0
- pulserver-0.0.2/src/pulserver/validate/__init__.py +15 -0
- pulserver-0.0.2/src/pulserver/validate/_command.py +105 -0
- pulserver-0.0.2/src/pulserver/validate/_compare.py +274 -0
- pulserver-0.0.2/src/pulserver/validate/_validate.py +270 -0
- pulserver-0.0.2/src/pulserver/validate/_xml.py +162 -0
- pulserver-0.0.2/src/pulserver/virtual/__init__.py +50 -0
- pulserver-0.0.2/src/pulserver/virtual/_brainweb.py +381 -0
- pulserver-0.0.2/src/pulserver/virtual/_client.py +171 -0
- pulserver-0.0.2/src/pulserver/virtual/_coils.py +334 -0
- pulserver-0.0.2/src/pulserver/virtual/_command.py +433 -0
- pulserver-0.0.2/src/pulserver/virtual/_console.py +761 -0
- pulserver-0.0.2/src/pulserver/virtual/_export.py +212 -0
- pulserver-0.0.2/src/pulserver/virtual/_fourier.py +1978 -0
- pulserver-0.0.2/src/pulserver/virtual/_girf.py +85 -0
- pulserver-0.0.2/src/pulserver/virtual/_localizer.py +100 -0
- pulserver-0.0.2/src/pulserver/virtual/_motion.py +191 -0
- pulserver-0.0.2/src/pulserver/virtual/_phantom.py +293 -0
- pulserver-0.0.2/src/pulserver/virtual/_stream.py +514 -0
- pulserver-0.0.2/src/pulserver/virtual/_timeline.py +899 -0
- pulserver-0.0.2/src/pulserver/virtual/_tissue.py +72 -0
- pulserver-0.0.2/tests/_analytic.py +259 -0
- pulserver-0.0.2/tests/_host.py +72 -0
- pulserver-0.0.2/tests/_seqtext.py +103 -0
- pulserver-0.0.2/tests/_synthetic.py +25 -0
- pulserver-0.0.2/tests/_virtual.py +139 -0
- pulserver-0.0.2/tests/_zoo.py +97 -0
- pulserver-0.0.2/tests/conftest.py +319 -0
- pulserver-0.0.2/tests/fixtures/bloch/bssfp.npy +0 -0
- pulserver-0.0.2/tests/fixtures/bloch/epi_2d_main.npy +0 -0
- pulserver-0.0.2/tests/fixtures/bloch/gre_2d_3sl.npy +0 -0
- pulserver-0.0.2/tests/fixtures/bloch/steady_dess_hard_0hz.npy +0 -0
- pulserver-0.0.2/tests/fixtures/bloch/steady_dess_hard_30hz.npy +0 -0
- pulserver-0.0.2/tests/fixtures/bloch/steady_echo_hard_0hz.npy +0 -0
- pulserver-0.0.2/tests/fixtures/bloch/steady_echo_hard_30hz.npy +0 -0
- pulserver-0.0.2/tests/fixtures/bloch/steady_echo_selective_0hz.npy +0 -0
- pulserver-0.0.2/tests/fixtures/bloch/steady_fid_hard_0hz.npy +0 -0
- pulserver-0.0.2/tests/fixtures/sequences/dedup_gre_pair.seq +1742 -0
- pulserver-0.0.2/tests/fixtures/sequences/dedup_gre_pair_b.seq +1741 -0
- pulserver-0.0.2/tests/fixtures/sequences/epi_2d_main.seq +5834 -0
- pulserver-0.0.2/tests/fixtures/sequences/gre_2d_3sl.seq +1974 -0
- pulserver-0.0.2/tests/fixtures/sequences/mprage_stack_of_spirals_3d.seq +14929 -0
- pulserver-0.0.2/tests/fixtures/sequences/zte_3d.seq +2161 -0
- pulserver-0.0.2/tests/koma/Project.toml +8 -0
- pulserver-0.0.2/tests/koma/simulate.jl +89 -0
- pulserver-0.0.2/tests/native/check_initializers.c +55 -0
- pulserver-0.0.2/tests/native/print_wave_samples.c +113 -0
- pulserver-0.0.2/tests/native/read_cache_summary.c +220 -0
- pulserver-0.0.2/tests/native/read_rf_definitions.c +57 -0
- pulserver-0.0.2/tests/native/replay_an_instance.c +113 -0
- pulserver-0.0.2/tests/plugins/crash.py +18 -0
- pulserver-0.0.2/tests/plugins/gre2d.py +53 -0
- pulserver-0.0.2/tests/plugins/gre2d_raw.py +15 -0
- pulserver-0.0.2/tests/plugins/rf_train.py +43 -0
- pulserver-0.0.2/tests/plugins/stall.py +21 -0
- pulserver-0.0.2/tests/plugins/strong.py +30 -0
- pulserver-0.0.2/tests/plugins/tiny.py +44 -0
- pulserver-0.0.2/tests/plugins/typed.py +80 -0
- pulserver-0.0.2/tests/recon/test_app.py +194 -0
- pulserver-0.0.2/tests/recon/test_buffers.py +1017 -0
- pulserver-0.0.2/tests/recon/test_calibration.py +515 -0
- pulserver-0.0.2/tests/recon/test_coil_compression.py +279 -0
- pulserver-0.0.2/tests/recon/test_connection.py +401 -0
- pulserver-0.0.2/tests/recon/test_correct.py +165 -0
- pulserver-0.0.2/tests/recon/test_epi.py +201 -0
- pulserver-0.0.2/tests/recon/test_exam_image.py +73 -0
- pulserver-0.0.2/tests/recon/test_flags.py +59 -0
- pulserver-0.0.2/tests/recon/test_gadgets.py +377 -0
- pulserver-0.0.2/tests/recon/test_handlers.py +178 -0
- pulserver-0.0.2/tests/recon/test_images.py +436 -0
- pulserver-0.0.2/tests/recon/test_loader.py +32 -0
- pulserver-0.0.2/tests/recon/test_mrd2dicom.py +907 -0
- pulserver-0.0.2/tests/recon/test_nufft.py +496 -0
- pulserver-0.0.2/tests/recon/test_pics.py +296 -0
- pulserver-0.0.2/tests/recon/test_pmc.py +91 -0
- pulserver-0.0.2/tests/recon/test_prewhiten.py +292 -0
- pulserver-0.0.2/tests/recon/test_readers_writers.py +182 -0
- pulserver-0.0.2/tests/recon/test_slots.py +52 -0
- pulserver-0.0.2/tests/recon/test_units.py +770 -0
- pulserver-0.0.2/tests/recon_plugins/children.py +22 -0
- pulserver-0.0.2/tests/recon_plugins/crash.py +19 -0
- pulserver-0.0.2/tests/recon_plugins/device.py +18 -0
- pulserver-0.0.2/tests/recon_plugins/exam.py +19 -0
- pulserver-0.0.2/tests/recon_plugins/gre2d.py +87 -0
- pulserver-0.0.2/tests/recon_plugins/pose.py +24 -0
- pulserver-0.0.2/tests/test_console.py +863 -0
- pulserver-0.0.2/tests/test_console_sequences.py +237 -0
- pulserver-0.0.2/tests/test_design_push.py +370 -0
- pulserver-0.0.2/tests/test_design_server.py +371 -0
- pulserver-0.0.2/tests/test_design_service.py +991 -0
- pulserver-0.0.2/tests/test_docs.py +124 -0
- pulserver-0.0.2/tests/test_docstring_defaults.py +166 -0
- pulserver-0.0.2/tests/test_docstrings.py +28 -0
- pulserver-0.0.2/tests/test_enrich.py +642 -0
- pulserver-0.0.2/tests/test_exam_artifacts.py +97 -0
- pulserver-0.0.2/tests/test_exam_calibration.py +86 -0
- pulserver-0.0.2/tests/test_exam_sharing.py +169 -0
- pulserver-0.0.2/tests/test_host_slots.py +117 -0
- pulserver-0.0.2/tests/test_image.py +70 -0
- pulserver-0.0.2/tests/test_ir.py +973 -0
- pulserver-0.0.2/tests/test_ir_checks.py +357 -0
- pulserver-0.0.2/tests/test_ir_designed.py +81 -0
- pulserver-0.0.2/tests/test_ir_extensions.py +137 -0
- pulserver-0.0.2/tests/test_ir_grouping.py +97 -0
- pulserver-0.0.2/tests/test_ir_groups.py +85 -0
- pulserver-0.0.2/tests/test_ir_labels.py +56 -0
- pulserver-0.0.2/tests/test_ir_playout.py +385 -0
- pulserver-0.0.2/tests/test_ir_profile.py +77 -0
- pulserver-0.0.2/tests/test_ir_repetition.py +188 -0
- pulserver-0.0.2/tests/test_ir_repetition_gradients.py +150 -0
- pulserver-0.0.2/tests/test_ir_rf.py +242 -0
- pulserver-0.0.2/tests/test_ir_segments.py +212 -0
- pulserver-0.0.2/tests/test_ir_source.py +233 -0
- pulserver-0.0.2/tests/test_ir_steady_excitation.py +153 -0
- pulserver-0.0.2/tests/test_ir_vendor.py +108 -0
- pulserver-0.0.2/tests/test_ir_waves.py +291 -0
- pulserver-0.0.2/tests/test_keys.py +177 -0
- pulserver-0.0.2/tests/test_koma.py +163 -0
- pulserver-0.0.2/tests/test_limits.py +419 -0
- pulserver-0.0.2/tests/test_logs.py +46 -0
- pulserver-0.0.2/tests/test_memory.py +27 -0
- pulserver-0.0.2/tests/test_motion.py +246 -0
- pulserver-0.0.2/tests/test_mrd_images.py +16 -0
- pulserver-0.0.2/tests/test_mrd_sequence.py +311 -0
- pulserver-0.0.2/tests/test_plugin_options.py +240 -0
- pulserver-0.0.2/tests/test_plugins.py +90 -0
- pulserver-0.0.2/tests/test_protocol.py +506 -0
- pulserver-0.0.2/tests/test_proxy.py +1319 -0
- pulserver-0.0.2/tests/test_publish_docs.py +114 -0
- pulserver-0.0.2/tests/test_resolution.py +245 -0
- pulserver-0.0.2/tests/test_rf_layout.py +771 -0
- pulserver-0.0.2/tests/test_scan_command.py +294 -0
- pulserver-0.0.2/tests/test_seqdesc.py +231 -0
- pulserver-0.0.2/tests/test_sequence_plugin.py +459 -0
- pulserver-0.0.2/tests/test_smoke.py +14 -0
- pulserver-0.0.2/tests/test_validate.py +314 -0
- pulserver-0.0.2/tests/test_virtual.py +653 -0
- pulserver-0.0.2/tests/test_virtual_brainweb.py +224 -0
- pulserver-0.0.2/tests/test_virtual_clock.py +205 -0
- pulserver-0.0.2/tests/test_virtual_coils.py +275 -0
- pulserver-0.0.2/tests/test_virtual_export.py +239 -0
- pulserver-0.0.2/tests/test_virtual_fourier.py +721 -0
- pulserver-0.0.2/tests/test_virtual_localizer.py +143 -0
- pulserver-0.0.2/tests/test_virtual_sequences.py +84 -0
- pulserver-0.0.2/tests/test_wire.py +111 -0
- pulserver-0.0.2/tests/test_zoo_evaluation.py +1245 -0
- pulserver-0.0.2/tests/test_zoo_wave.py +101 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build-and-test
|
|
3
|
+
description: Build pulserver from this checkout and run its formatter, linter, test suite and documentation build. Use before reporting any change complete, and whenever a test result or a skip has to be quoted rather than assumed.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Build and test
|
|
7
|
+
|
|
8
|
+
The extension `pulserver._ext` is compiled from `src/cpp/` and `src/c/`, so a
|
|
9
|
+
checkout has to be installed before anything imports `pulserver`. Run the whole
|
|
10
|
+
sequence and report the results it actually produced.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install -e '.[dev,doc]'
|
|
14
|
+
bash scripts/format_and_lint.sh --check
|
|
15
|
+
pytest -q -ra
|
|
16
|
+
bash scripts/build_docs.sh
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`scripts/format_and_lint.sh` runs `ruff format` and `ruff check`; without
|
|
20
|
+
`--check` it rewrites the files instead of reporting them. It is the entry point
|
|
21
|
+
pre-commit and CI use, so a style failure in CI is reproducible here.
|
|
22
|
+
|
|
23
|
+
## Interpreting the run
|
|
24
|
+
|
|
25
|
+
- The install needs a C compiler, a C++17 compiler and CMake. `src/c/` is
|
|
26
|
+
compiled with `-std=c90 -pedantic-errors`: a C99 construct is a build error,
|
|
27
|
+
not a warning to silence.
|
|
28
|
+
- `tests/test_ir.py` compiles `src/c/` as a 32-bit scanner build and skips
|
|
29
|
+
without a 32-bit toolchain (`gcc-multilib`). Report that skip; it is not a
|
|
30
|
+
pass.
|
|
31
|
+
- The CUDA leg of the `device` fixture skips without a device.
|
|
32
|
+
- The scanner-sequence plugins under `tests/plugins/` bind arguments of the
|
|
33
|
+
installed pypulseqpp's sequence functions. A failure naming an argument the
|
|
34
|
+
function does not take means the plugin and the installed pypulseqpp
|
|
35
|
+
disagree; check `pip show pypulseqpp` against the floor in `pyproject.toml`
|
|
36
|
+
before changing either.
|
|
37
|
+
- `tests/test_docs.py` runs the user-guide doctests and holds every public name
|
|
38
|
+
to its API page; a new public name needs a row there.
|
|
39
|
+
|
|
40
|
+
## Documentation
|
|
41
|
+
|
|
42
|
+
Documentation changes are validated by the documentation build and
|
|
43
|
+
`tests/test_docs.py`, not by reading the source. See the `write-documentation`
|
|
44
|
+
skill.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: write-documentation
|
|
3
|
+
description: Write, move or audit pulserver documentation — docstrings, user-guide, explanation, API and developer-guide pages, and the README. Use before creating or substantially modifying any documentation, and when deciding which documentation type a piece of material belongs to.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Write documentation
|
|
7
|
+
|
|
8
|
+
Two documents govern documentation and both are binding. Read them before
|
|
9
|
+
writing:
|
|
10
|
+
|
|
11
|
+
- `docs/developer-guide/documentation.md` — what belongs in each form of
|
|
12
|
+
documentation and how each is written.
|
|
13
|
+
- `docs/developer-guide/terminology.md` — terminology, register, units,
|
|
14
|
+
frames, safety language and source-of-truth rules.
|
|
15
|
+
|
|
16
|
+
The `Docstrings` and `Comments` sections of `AGENTS.md` govern docstrings and
|
|
17
|
+
comments.
|
|
18
|
+
|
|
19
|
+
## Choose the type first
|
|
20
|
+
|
|
21
|
+
| Location | Type | Answers |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `docs/user-guide/` | How-to | How do I install, run and extend pulserver? |
|
|
24
|
+
| `docs/explanations/` | Conceptual explanation, one flat list in data-flow order | Why does it work this way? |
|
|
25
|
+
| `gallery/01-course/` | Course lessons, read in order | What does a new user need to work independently? |
|
|
26
|
+
| `gallery/02-tours/` | Tours: applications, advanced branches, specialised workflows | What does a representative workflow look like? |
|
|
27
|
+
| `docs/api/` | Reference, from the docstrings | What exactly does this object do? |
|
|
28
|
+
| `docs/developer-guide/` | Contributor procedure | How is this repository developed? |
|
|
29
|
+
| `docs/developer-guide/internals/` | Implementation design | How is it built, and what does a playout rely on? |
|
|
30
|
+
| `README.md` | Project summary and documentation landing page | What is this, and where is the rest? |
|
|
31
|
+
|
|
32
|
+
Material in the wrong type is moved, not deleted. Implementation design found
|
|
33
|
+
on an explanation page — file layouts, memory budgets, tolerances, test
|
|
34
|
+
inventories — moves to `docs/developer-guide/internals/`, and the explanation
|
|
35
|
+
links to it.
|
|
36
|
+
|
|
37
|
+
A lesson belongs in the course only if it is on the shortest coherent path
|
|
38
|
+
that gives a new user the framework's core mental model and enough practical
|
|
39
|
+
competence to work independently; anything else is a Tour. A lesson has an
|
|
40
|
+
introduction, a *Learning objectives* list and previous/next lines; a Tour
|
|
41
|
+
opens with its objective and a prerequisites line and has neither.
|
|
42
|
+
|
|
43
|
+
The IR is written in PulSeg's terms — base block, virtual segment, segment
|
|
44
|
+
instance, execution stream — and *repetition* is the period
|
|
45
|
+
`pypulseqpp.Sequence.repetition()` reports. Never "repeating unit", never
|
|
46
|
+
"app" for a sequence function (`terminology.md`).
|
|
47
|
+
|
|
48
|
+
## Verify before writing
|
|
49
|
+
|
|
50
|
+
State nothing the code does not do. Read the implementation, its callers and
|
|
51
|
+
its tests, and the C or C++ behind it when there is any. For the file formats
|
|
52
|
+
and wire protocols, the authorities are the code in `src/pulserver/protocol/`,
|
|
53
|
+
`src/c/include/pulseg/` and `src/pulserver/recon/_runtime/`. Flag a discrepancy
|
|
54
|
+
you cannot resolve rather than guessing.
|
|
55
|
+
|
|
56
|
+
## Mechanics
|
|
57
|
+
|
|
58
|
+
- A runnable example on a user-guide page is a `pycon` block with `>>>`
|
|
59
|
+
prompts, ending with a blank line before the closing fence; it is executed
|
|
60
|
+
by `tests/test_docs.py`. An example that needs a running service or a data
|
|
61
|
+
file is a plain `python` block.
|
|
62
|
+
- An API page lists its subpackage's public names in `| Object | Description |`
|
|
63
|
+
tables of `{obj}` links under a `currentmodule` directive.
|
|
64
|
+
`docs/api_objects.py` writes the per-object stubs from those tables into
|
|
65
|
+
`docs/generated/`, which is not tracked.
|
|
66
|
+
- An explanation page ends with a `## See also` list linking the how-to and
|
|
67
|
+
the API pages it relates to. One with more than one `##` section opens with
|
|
68
|
+
a TL;DR admonition, ```` ```{admonition} TL;DR ```` and `:class: tldr`,
|
|
69
|
+
directly under its title; no landing, API or example page has one.
|
|
70
|
+
- A figure takes its style from `docs/figure_style.py`; a script sets no font
|
|
71
|
+
size, DPI or colour literal and imports the colours it needs. A static
|
|
72
|
+
figure is a light/dark SVG pair written by `scripts/make_artwork.py` and
|
|
73
|
+
shown with `only-light` and `only-dark`.
|
|
74
|
+
- A new page is added to the table and the hidden toctree of its section's
|
|
75
|
+
`index.md`.
|
|
76
|
+
- A new gallery script goes into its section's directory under `gallery/`,
|
|
77
|
+
named with a numeric prefix, and gets a row and a toctree entry on the
|
|
78
|
+
section's landing page under `docs/examples/` (`course.md` or `tours.md`). A new section is a directory
|
|
79
|
+
with `README.rst` and `_gallery_header.md`, an entry in `GALLERY_SECTIONS`,
|
|
80
|
+
and a landing page listed in `docs/examples/index.md`.
|
|
81
|
+
|
|
82
|
+
## Validate
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pytest -q tests/test_docs.py tests/test_docstrings.py tests/test_docstring_defaults.py
|
|
86
|
+
bash scripts/build_docs.sh
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Open `docs/build/html/index.html` and check the rendered pages in the light
|
|
90
|
+
and the dark theme, and the sidebar: User guide, Developer guide, Explanations,
|
|
91
|
+
Examples (Course, then Tours), API, Misc.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
* text=auto eol=lf
|
|
2
|
+
|
|
3
|
+
*.png binary
|
|
4
|
+
*.jpg binary
|
|
5
|
+
*.svg text
|
|
6
|
+
*.npy binary
|
|
7
|
+
*.npz binary
|
|
8
|
+
*.mat binary
|
|
9
|
+
*.h5 binary
|
|
10
|
+
*.dcm binary
|
|
11
|
+
# The IR cache a sequence is converted to.
|
|
12
|
+
*.pseg binary
|
|
13
|
+
|
|
14
|
+
# Sequence files written by pypulseqpp for the tests: collapsed in diffs and
|
|
15
|
+
# left out of the language statistics.
|
|
16
|
+
tests/fixtures/** linguist-generated=true
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report reproducible incorrect behaviour or a documentation defect.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: dropdown
|
|
6
|
+
id: subsystem
|
|
7
|
+
attributes:
|
|
8
|
+
label: Affected area
|
|
9
|
+
options:
|
|
10
|
+
- "Scanner sequences (pulserver.design, pulserver.protocol)"
|
|
11
|
+
- "Design calls and the design store (pulserver.host)"
|
|
12
|
+
- "IR conversion or the C cache library (pulserver.ir, src/c)"
|
|
13
|
+
- "Reconstruction proxy and enrichment (pulserver.proxy)"
|
|
14
|
+
- "Reconstruction plugins and MRD data (pulserver.recon, pulserver.mrd)"
|
|
15
|
+
- "Documentation"
|
|
16
|
+
- "Other"
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: observed
|
|
21
|
+
attributes:
|
|
22
|
+
label: Observed and expected behaviour
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: reproduce
|
|
27
|
+
attributes:
|
|
28
|
+
label: Smallest reproducer
|
|
29
|
+
description: >
|
|
30
|
+
Self-contained Python code, a plugin file, a minimal `.seq` file, or the
|
|
31
|
+
design call and its reply. Prefer synthetic data to a scanner
|
|
32
|
+
acquisition.
|
|
33
|
+
render: python
|
|
34
|
+
validations:
|
|
35
|
+
required: true
|
|
36
|
+
- type: textarea
|
|
37
|
+
id: environment
|
|
38
|
+
attributes:
|
|
39
|
+
label: Environment
|
|
40
|
+
description: pulserver, pypulseqpp and Python versions, plus OS and architecture.
|
|
41
|
+
placeholder: "pulserver 0.x; pypulseqpp 0.x; Python 3.12; Ubuntu 24.04 x86-64"
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Question or idea
|
|
4
|
+
url: https://github.com/pulserver/pulserver/discussions
|
|
5
|
+
about: Ask about usage, or propose something before it is a bug report.
|
|
6
|
+
- name: Security vulnerability
|
|
7
|
+
url: https://github.com/pulserver/pulserver/security/advisories/new
|
|
8
|
+
about: Report privately. Please do not open a public issue.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a narrowly scoped addition to pulserver.
|
|
3
|
+
labels: ["enhancement"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: use-case
|
|
7
|
+
attributes:
|
|
8
|
+
label: Scientific or technical use case
|
|
9
|
+
description: State the missing capability and the acquisition or reconstruction workflow it serves.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: proposal
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed interface or behaviour
|
|
16
|
+
description: Include primary literature, a vendor or MRD convention, or an existing implementation where relevant.
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: dropdown
|
|
20
|
+
id: layer
|
|
21
|
+
attributes:
|
|
22
|
+
label: Where it belongs
|
|
23
|
+
description: >
|
|
24
|
+
Sequence design belongs to pypulseqpp and reconstruction algorithms to
|
|
25
|
+
bartorch; pulserver holds the orchestration between them and the scanner.
|
|
26
|
+
options:
|
|
27
|
+
- "pulserver"
|
|
28
|
+
- "pypulseqpp (sequence design)"
|
|
29
|
+
- "bartorch (reconstruction)"
|
|
30
|
+
- "Not sure"
|
|
31
|
+
validations:
|
|
32
|
+
required: true
|
|
33
|
+
- type: textarea
|
|
34
|
+
id: alternatives
|
|
35
|
+
attributes:
|
|
36
|
+
label: Alternatives considered
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## What changed
|
|
2
|
+
|
|
3
|
+
<!-- Concise implementation summary. -->
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
<!-- Problem and relevant issue or discussion. -->
|
|
8
|
+
|
|
9
|
+
## Validation
|
|
10
|
+
|
|
11
|
+
<!-- Exact commands and results. Include tests added for new behaviour. -->
|
|
12
|
+
|
|
13
|
+
## Documentation impact
|
|
14
|
+
|
|
15
|
+
<!-- User-facing changes, or "None" with a reason. -->
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# The Actions in .github/workflows pin third-party code that runs with
|
|
4
|
+
# repository credentials, so these are the updates worth having weekly.
|
|
5
|
+
- package-ecosystem: github-actions
|
|
6
|
+
directory: "/"
|
|
7
|
+
target-branch: main
|
|
8
|
+
schedule:
|
|
9
|
+
interval: weekly
|
|
10
|
+
day: monday
|
|
11
|
+
labels: ["dependencies", "ci"]
|
|
12
|
+
commit-message:
|
|
13
|
+
prefix: "ci"
|
|
14
|
+
groups:
|
|
15
|
+
actions:
|
|
16
|
+
patterns: ["*"]
|
|
17
|
+
|
|
18
|
+
- package-ecosystem: pip
|
|
19
|
+
directory: "/"
|
|
20
|
+
target-branch: main
|
|
21
|
+
schedule:
|
|
22
|
+
interval: weekly
|
|
23
|
+
day: monday
|
|
24
|
+
open-pull-requests-limit: 5
|
|
25
|
+
labels: ["dependencies", "python"]
|
|
26
|
+
commit-message:
|
|
27
|
+
prefix: "deps"
|
|
28
|
+
groups:
|
|
29
|
+
# The sequence engine's signatures are what the scanner plugins bind to,
|
|
30
|
+
# so its bumps arrive alone and get a full run of their own.
|
|
31
|
+
engine:
|
|
32
|
+
patterns: ["pypulseqpp"]
|
|
33
|
+
mr-data:
|
|
34
|
+
patterns: ["numpy", "ismrmrd", "pydicom"]
|
|
35
|
+
build:
|
|
36
|
+
patterns: ["scikit-build-core", "pybind11", "setuptools_scm"]
|
|
37
|
+
dev-tooling:
|
|
38
|
+
patterns: ["pytest*", "coverage", "ruff", "pre-commit", "build"]
|
|
39
|
+
docs:
|
|
40
|
+
patterns: ["sphinx*", "myst-parser", "linkify-it-py", "matplotlib"]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
analyze:
|
|
11
|
+
name: Analyze ${{ matrix.language }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
# Code scanning on a private repository needs GitHub Advanced Security,
|
|
14
|
+
# and uploading results without it is a hard error rather than a warning.
|
|
15
|
+
# The job stands down while the repository is private and starts working
|
|
16
|
+
# on its own once it is made public.
|
|
17
|
+
if: github.event.repository.visibility == 'public'
|
|
18
|
+
permissions:
|
|
19
|
+
security-events: write
|
|
20
|
+
packages: read
|
|
21
|
+
actions: read
|
|
22
|
+
contents: read
|
|
23
|
+
strategy:
|
|
24
|
+
fail-fast: false
|
|
25
|
+
matrix:
|
|
26
|
+
# c-cpp covers src/c, the library a scanner links, and src/cpp.
|
|
27
|
+
language: [python, c-cpp]
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v7
|
|
30
|
+
- uses: github/codeql-action/init@v4
|
|
31
|
+
with:
|
|
32
|
+
languages: ${{ matrix.language }}
|
|
33
|
+
build-mode: none
|
|
34
|
+
- uses: github/codeql-action/analyze@v4
|
|
35
|
+
with:
|
|
36
|
+
category: "/language:${{ matrix.language }}"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# The console of the virtual scanner with Gadgetron behind pulserver's proxy,
|
|
2
|
+
# composed from docker/ and driven through one exam and one scan.
|
|
3
|
+
name: Console
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
pull_request:
|
|
8
|
+
paths:
|
|
9
|
+
- docker/**
|
|
10
|
+
- src/pulserver/virtual/_console.py
|
|
11
|
+
- src/pulserver/proxy/**
|
|
12
|
+
- .github/workflows/console.yml
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
compose:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 60
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v7
|
|
23
|
+
with:
|
|
24
|
+
fetch-depth: 0
|
|
25
|
+
- uses: actions/setup-python@v7
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
- name: Start the console, the proxy and Gadgetron
|
|
29
|
+
run: docker compose -f docker/compose.yaml up -d --build
|
|
30
|
+
- name: Scan through the console
|
|
31
|
+
run: |
|
|
32
|
+
pip install websockets pydicom numpy
|
|
33
|
+
python docker/smoke.py ws://127.0.0.1:8765
|
|
34
|
+
- name: Logs
|
|
35
|
+
if: always()
|
|
36
|
+
run: docker compose -f docker/compose.yaml logs --no-color
|
|
37
|
+
- name: Stop
|
|
38
|
+
if: always()
|
|
39
|
+
run: docker compose -f docker/compose.yaml down -v
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
# Builds the documentation and publishes it to GitHub Pages, which serves the
|
|
4
|
+
# gh-pages branch. The site holds one directory per version: main publishes
|
|
5
|
+
# `latest`, a release tag publishes `vX.Y.Z` and copies it to `stable`, and the
|
|
6
|
+
# root redirects to whichever of the two a reader should see.
|
|
7
|
+
#
|
|
8
|
+
# A pull request builds only when a maintainer comments `/build-docs` on it,
|
|
9
|
+
# and the build answers on the pull request with its result. That build
|
|
10
|
+
# publishes nothing; main publishes after the merge.
|
|
11
|
+
#
|
|
12
|
+
# The branch is the site's archive. GitHub Pages can be deployed from an
|
|
13
|
+
# artifact instead, but a deployment replaces the whole site, so publishing one
|
|
14
|
+
# version would drop the others.
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
push:
|
|
18
|
+
branches: [main]
|
|
19
|
+
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
|
|
20
|
+
issue_comment:
|
|
21
|
+
types: [created]
|
|
22
|
+
workflow_dispatch:
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
|
|
27
|
+
# Every publish commits to the same branch, so main, the tags and a manual run
|
|
28
|
+
# share one group and wait for each other rather than racing to push. A pull
|
|
29
|
+
# request publishes nothing and gets a group of its own.
|
|
30
|
+
concurrency:
|
|
31
|
+
group: docs-${{ github.event.issue.number || 'publish' }}
|
|
32
|
+
cancel-in-progress: ${{ github.event_name == 'issue_comment' }}
|
|
33
|
+
|
|
34
|
+
jobs:
|
|
35
|
+
docs:
|
|
36
|
+
if: >-
|
|
37
|
+
github.event_name != 'issue_comment' ||
|
|
38
|
+
(github.event.issue.pull_request &&
|
|
39
|
+
startsWith(github.event.comment.body, '/build-docs') &&
|
|
40
|
+
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association))
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
permissions:
|
|
43
|
+
contents: write # the publish step pushes the built site to gh-pages
|
|
44
|
+
pull-requests: write # a requested build answers on its pull request
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v7
|
|
47
|
+
with:
|
|
48
|
+
# A comment runs on the default branch; the build is of the pull
|
|
49
|
+
# request's head.
|
|
50
|
+
ref: ${{ github.event_name == 'issue_comment' && format('refs/pull/{0}/head', github.event.issue.number) || '' }}
|
|
51
|
+
fetch-depth: 0 # setuptools_scm reads the tags
|
|
52
|
+
|
|
53
|
+
- uses: actions/setup-python@v7
|
|
54
|
+
with:
|
|
55
|
+
python-version: "3.12"
|
|
56
|
+
cache: pip
|
|
57
|
+
|
|
58
|
+
- name: Name this version
|
|
59
|
+
id: version
|
|
60
|
+
# A release is built as `stable`, the URL a reader should land on, and
|
|
61
|
+
# archived under its tag as well; the canonical link in both copies
|
|
62
|
+
# points at `stable`.
|
|
63
|
+
run: |
|
|
64
|
+
if [ "$GITHUB_REF_TYPE" = tag ]; then
|
|
65
|
+
echo "dir=$GITHUB_REF_NAME" >> "$GITHUB_OUTPUT"
|
|
66
|
+
echo "canonical=stable" >> "$GITHUB_OUTPUT"
|
|
67
|
+
else
|
|
68
|
+
echo "dir=latest" >> "$GITHUB_OUTPUT"
|
|
69
|
+
echo "canonical=latest" >> "$GITHUB_OUTPUT"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# autodoc imports the package, so the compiled extension is built too.
|
|
73
|
+
# The gallery reconstructs with the shipped pics plugin, on bartorch
|
|
74
|
+
# over torch's CPU build.
|
|
75
|
+
- name: Install
|
|
76
|
+
run: |
|
|
77
|
+
python -m pip install --upgrade pip
|
|
78
|
+
python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
|
|
79
|
+
python -m pip install '.[doc]'
|
|
80
|
+
|
|
81
|
+
- name: Build
|
|
82
|
+
env:
|
|
83
|
+
PULSERVER_DOCS_VERSION: ${{ steps.version.outputs.canonical }}
|
|
84
|
+
PULSERVER_DOCS_RELEASE: ${{ steps.version.outputs.dir }}
|
|
85
|
+
run: bash scripts/build_docs.sh
|
|
86
|
+
|
|
87
|
+
- name: Check that the site is only the site
|
|
88
|
+
# Sphinx caches parsed documents in the output directory unless given
|
|
89
|
+
# `-d`, and the cache is far larger than the pages. Publishing commits
|
|
90
|
+
# whatever is there to a branch that is never pruned.
|
|
91
|
+
run: |
|
|
92
|
+
if [ -e docs/build/html/.doctrees ]; then
|
|
93
|
+
echo "::error::The doctree cache is inside the built site and would be published." >&2
|
|
94
|
+
exit 1
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
- name: Publish
|
|
98
|
+
if: >-
|
|
99
|
+
github.event_name != 'issue_comment' &&
|
|
100
|
+
(github.ref == 'refs/heads/main' || github.ref_type == 'tag')
|
|
101
|
+
env:
|
|
102
|
+
DIR: ${{ steps.version.outputs.dir }}
|
|
103
|
+
GH_TOKEN: ${{ github.token }}
|
|
104
|
+
run: |
|
|
105
|
+
site="$RUNNER_TEMP/pages"
|
|
106
|
+
remote="https://x-access-token:$GH_TOKEN@github.com/$GITHUB_REPOSITORY"
|
|
107
|
+
# The branch does not exist before the first publish.
|
|
108
|
+
if ! git clone --depth 1 --branch gh-pages "$remote" "$site"; then
|
|
109
|
+
git init -b gh-pages "$site"
|
|
110
|
+
git -C "$site" remote add origin "$remote"
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# Only this version's directory is replaced; a release refreshes
|
|
114
|
+
# stable only when it is the newest, and the root and the switcher's
|
|
115
|
+
# list are rewritten from what the site then holds.
|
|
116
|
+
python scripts/publish_docs.py docs/build/html "$DIR" "$site"
|
|
117
|
+
|
|
118
|
+
git -C "$site" add -A
|
|
119
|
+
git -C "$site" -c user.name='github-actions[bot]' \
|
|
120
|
+
-c user.email='41898282+github-actions[bot]@users.noreply.github.com' \
|
|
121
|
+
commit -m "Documentation for $DIR from $GITHUB_SHA" \
|
|
122
|
+
|| { echo "No documentation change to publish."; exit 0; }
|
|
123
|
+
git -C "$site" push origin gh-pages
|
|
124
|
+
|
|
125
|
+
- name: Answer on the pull request
|
|
126
|
+
if: always() && github.event_name == 'issue_comment'
|
|
127
|
+
env:
|
|
128
|
+
GH_TOKEN: ${{ github.token }}
|
|
129
|
+
RESULT: ${{ job.status }}
|
|
130
|
+
RUN: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
131
|
+
run: |
|
|
132
|
+
gh pr comment ${{ github.event.issue.number }} --repo "$GITHUB_REPOSITORY" \
|
|
133
|
+
--body "Documentation build: $RESULT ($RUN)"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# BrainWeb's head in the virtual scanner's coils: each coil's transmit and
|
|
2
|
+
# receive maps and the transmit coils' VOPs, solved by mariepy's
|
|
3
|
+
# examples/brainweb.py and published as an image that holds only those files,
|
|
4
|
+
# which docker/Dockerfile copies in by digest. mariepy runs here as a program;
|
|
5
|
+
# none of its code enters pulserver or its image.
|
|
6
|
+
name: Fields
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
inputs:
|
|
11
|
+
mariepy:
|
|
12
|
+
description: mariepy commit the fields are solved with
|
|
13
|
+
required: true
|
|
14
|
+
resolution:
|
|
15
|
+
description: Voxel pitch of the head, in mm
|
|
16
|
+
required: false
|
|
17
|
+
default: "5"
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
packages: write
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
solve:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 360
|
|
27
|
+
env:
|
|
28
|
+
RESOLUTION: ${{ inputs.resolution }}
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v7
|
|
31
|
+
with:
|
|
32
|
+
repository: pulserver/mariepy
|
|
33
|
+
ref: ${{ inputs.mariepy }}
|
|
34
|
+
fetch-depth: 0 # setuptools_scm reads the version from the history
|
|
35
|
+
|
|
36
|
+
- uses: actions/setup-python@v7
|
|
37
|
+
with:
|
|
38
|
+
python-version: "3.12"
|
|
39
|
+
|
|
40
|
+
- name: Install mariepy
|
|
41
|
+
run: |
|
|
42
|
+
python -m pip install --upgrade pip
|
|
43
|
+
python -m pip install torch --index-url https://download.pytorch.org/whl/cpu
|
|
44
|
+
python -m pip install . brainweb-dl scipy
|
|
45
|
+
|
|
46
|
+
- name: Solve
|
|
47
|
+
run: python examples/brainweb.py --out fields --resolution "$RESOLUTION"
|
|
48
|
+
|
|
49
|
+
- name: Record what solved them
|
|
50
|
+
env:
|
|
51
|
+
RUN: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
52
|
+
run: >-
|
|
53
|
+
printf '{"mariepy": "%s", "resolution_mm": %d, "run": "%s"}\n'
|
|
54
|
+
"$(git rev-parse HEAD)" "$RESOLUTION" "$RUN" > fields/provenance.json
|
|
55
|
+
|
|
56
|
+
- uses: actions/upload-artifact@v7
|
|
57
|
+
with:
|
|
58
|
+
name: brainweb-fields
|
|
59
|
+
path: fields
|
|
60
|
+
|
|
61
|
+
- name: Publish
|
|
62
|
+
env:
|
|
63
|
+
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
64
|
+
ACTOR: ${{ github.actor }}
|
|
65
|
+
run: |
|
|
66
|
+
image="ghcr.io/pulserver/brainweb-fields:$(git rev-parse --short HEAD)-${RESOLUTION}mm"
|
|
67
|
+
echo "$TOKEN" | docker login ghcr.io -u "$ACTOR" --password-stdin
|
|
68
|
+
printf '%s\n' 'FROM scratch' \
|
|
69
|
+
'LABEL org.opencontainers.image.source=https://github.com/pulserver/pulserver' \
|
|
70
|
+
'COPY . /' | docker build -t "$image" -f - fields
|
|
71
|
+
docker push "$image"
|
|
72
|
+
echo "Published $(docker inspect --format '{{index .RepoDigests 0}}' "$image")" >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# pulserver's image, whose default command is the console of the virtual
|
|
2
|
+
# scanner reconstructing in its own process: built with the coils' field maps,
|
|
3
|
+
# scanned through on the BrainWeb brain it carries, which loads without a
|
|
4
|
+
# network, in the head coils' maps, and published from main.
|
|
5
|
+
name: Image
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
pull_request:
|
|
11
|
+
paths:
|
|
12
|
+
- docker/**
|
|
13
|
+
- src/**
|
|
14
|
+
- tests/plugins/gre2d.py
|
|
15
|
+
- pyproject.toml
|
|
16
|
+
- CMakeLists.txt
|
|
17
|
+
- .dockerignore
|
|
18
|
+
- .github/workflows/image.yml
|
|
19
|
+
workflow_dispatch:
|
|
20
|
+
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
packages: write
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
image:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
timeout-minutes: 60
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v7
|
|
31
|
+
- uses: actions/setup-python@v7
|
|
32
|
+
with:
|
|
33
|
+
python-version: "3.12"
|
|
34
|
+
- name: Build
|
|
35
|
+
run: docker build -f docker/Dockerfile -t pulserver .
|
|
36
|
+
- name: Scan through its console
|
|
37
|
+
run: |
|
|
38
|
+
docker run -d --name console -p 127.0.0.1:8765:8765 pulserver
|
|
39
|
+
pip install websockets pydicom numpy
|
|
40
|
+
python docker/smoke.py ws://127.0.0.1:8765 head8/head32
|
|
41
|
+
- name: Load BrainWeb without a network
|
|
42
|
+
run: >-
|
|
43
|
+
docker run --rm --network none --entrypoint python pulserver -c
|
|
44
|
+
"from pulserver.virtual import BrainWeb; print(BrainWeb().fractions.shape)"
|
|
45
|
+
- name: Give its console options after the image's name
|
|
46
|
+
run: docker run --rm pulserver --help | grep -e --spacing
|
|
47
|
+
- name: Publish
|
|
48
|
+
if: github.event_name == 'push'
|
|
49
|
+
run: |
|
|
50
|
+
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
|
|
51
|
+
for tag in latest "${{ github.sha }}"; do
|
|
52
|
+
docker tag pulserver "ghcr.io/pulserver/pulserver:$tag"
|
|
53
|
+
docker push "ghcr.io/pulserver/pulserver:$tag"
|
|
54
|
+
done
|
|
55
|
+
- name: Logs
|
|
56
|
+
if: always()
|
|
57
|
+
run: docker logs console
|