pulserver 0.4.1__tar.gz → 0.4.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.4.1 → pulserver-0.4.2}/CMakeLists.txt +1 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/PKG-INFO +4 -5
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/design.md +7 -8
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/ir.md +3 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/internals/index.md +1 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/internals/ir-cache.md +63 -24
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/internals/protocol-wire.md +14 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/internals/reconstruction-proxy.md +11 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/internals/virtual-scanner.md +5 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/terminology.md +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/architecture.md +2 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/reconstruction-session.md +12 -7
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/safety-checks.md +3 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/scanner-representation.md +1 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/user-guide/reconstruction-client.md +17 -8
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/user-guide/reconstruction-plugins.md +6 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/user-guide/running.md +30 -17
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/user-guide/scanner-sequences.md +81 -32
- {pulserver-0.4.1 → pulserver-0.4.2}/pyproject.toml +3 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/cache/pulseg_cache.c +63 -12
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/core/pulseg_core.c +125 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/core/pulseg_error.c +6 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg_collection.h +77 -43
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg_errors.h +1 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg_playout.h +69 -5
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg_types.h +78 -40
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseq/pulseq_types.h +8 -3
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/playout/pulseg_playout.c +278 -3
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/pulseg_internal.h +36 -14
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/structure/pulseg_descriptor.c +48 -18
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/structure/pulseg_getters.c +282 -172
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/structure/pulseg_repetition.c +11 -9
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/collection.cpp +12 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/dedup.cpp +1 -0
- pulserver-0.4.2/src/cpp/ir/gradient_stretch.cpp +332 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/pulseg_convert.h +5 -5
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/structure.cpp +101 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/module.cpp +106 -36
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/playout.cpp +2 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_plugins.py +0 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/_user.py +36 -3
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/bssfp2d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/fse3d.py +14 -5
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre3d.py +3 -3
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre_multiecho2d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre_multiecho3d.py +4 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre_spiral2d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre_stack_of_spirals3d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/mprage3d.py +11 -5
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/mprage_stack_of_spirals3d.py +9 -3
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/mprage_stack_of_stars3d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se3d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se_spiral2d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se_stack_of_spirals3d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/zte3d.py +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/design/__init__.py +3 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/design/_entries.py +95 -13
- pulserver-0.4.2/src/pulserver/design/_options.py +160 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/design/_plugin.py +155 -61
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/_command.py +9 -18
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/_limits.py +25 -15
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/_server.py +7 -9
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/_service.py +46 -60
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/_store.py +8 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/ir/__init__.py +4 -3
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/ir/_convert.py +6 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/ir/_playout.py +47 -8
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/ir/_source.py +54 -7
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/ir/_waves.py +35 -16
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/protocol/_wire.py +17 -8
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_designs.py +1 -24
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_enrich.py +14 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_motion.py +67 -7
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_proxy.py +130 -38
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_seqdesc.py +10 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_correct.py +38 -13
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/mrd2dicom.py +7 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/offline.py +13 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_console.py +1 -1
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_fourier.py +3 -3
- pulserver-0.4.2/tests/_host.py +138 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/sequences/epi_2d_main.seq +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/sequences/mprage_stack_of_spirals_3d.seq +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/sequences/zte_3d.seq +2 -2
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/native/read_cache_summary.c +37 -18
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_correct.py +34 -20
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_mrd2dicom.py +26 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_console_sequences.py +1 -36
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_design_service.py +43 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir.py +17 -12
- pulserver-0.4.2/tests/test_ir_gradient_stretch.py +292 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_grouping.py +4 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_playout.py +29 -0
- pulserver-0.4.2/tests/test_ir_prescan.py +96 -0
- pulserver-0.4.2/tests/test_ir_prescan_tour.py +125 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_rf.py +90 -0
- pulserver-0.4.2/tests/test_ir_rf_freq.py +103 -0
- pulserver-0.4.2/tests/test_ir_timing.py +139 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_limits.py +46 -6
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_motion.py +57 -6
- pulserver-0.4.2/tests/test_plugin_options.py +279 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_proxy.py +120 -4
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_virtual_fourier.py +46 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_wire.py +5 -0
- pulserver-0.4.2/tests/test_zoo_defaults.py +116 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_zoo_evaluation.py +6 -2
- pulserver-0.4.2/tests/test_zoo_fov_offset.py +205 -0
- pulserver-0.4.2/tests/test_zoo_mrd_labels.py +138 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_zoo_wave.py +3 -5
- pulserver-0.4.1/src/cpp/ir/repetition.cpp +0 -216
- pulserver-0.4.1/src/pulserver/_zoo/parameters/bssfp2d/retrospective.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/fse3d/dual_region.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/fse3d/navigator.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/fse3d/optimized.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/fse3d/shuffling.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/fse3d/wave.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/gre3d/full_plane.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/gre3d/wave.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/gre_multiecho2d/bipolar.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/gre_multiecho3d/bipolar.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/gre_multiecho3d/full_plane.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/gre_multiecho3d/wave.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/gre_spiral2d/variable_density.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/gre_stack_of_spirals3d/variable_density.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/mprage3d/navigator.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/mprage3d/shuffling.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/mprage3d/wave.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/mprage_stack_of_spirals3d/variable_density.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/se3d/full_plane.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/se_spiral2d/variable_density.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/se_stack_of_spirals3d/variable_density.toml +0 -2
- pulserver-0.4.1/src/pulserver/_zoo/parameters/zte3d/meridian.toml +0 -2
- pulserver-0.4.1/src/pulserver/design/_options.py +0 -133
- pulserver-0.4.1/tests/_host.py +0 -72
- pulserver-0.4.1/tests/test_ir_groups.py +0 -85
- pulserver-0.4.1/tests/test_ir_repetition_gradients.py +0 -150
- pulserver-0.4.1/tests/test_plugin_options.py +0 -240
- {pulserver-0.4.1 → pulserver-0.4.2}/.claude/skills/build-and-test/SKILL.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.claude/skills/write-documentation/SKILL.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.dockerignore +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.gitattributes +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/DISCUSSION_TEMPLATE/q-a.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/ISSUE_TEMPLATE/documentation.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/dependabot.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/codeql.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/console.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/docs.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/fields.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/image.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/koma.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/style.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/tags-release.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/test-ci.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.github/workflows/wheels.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.gitignore +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/.pre-commit-config.yaml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/AGENTS.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/CODE_OF_CONDUCT.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/CONTRIBUTING.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/LICENSE +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/LICENSES/gadgetron-python-MIT.txt +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/LICENSES/python-ismrmrd-server-MIT.txt +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/NEXT.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/README.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/SECURITY.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/SKILLS.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/codecov.yml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docker/Dockerfile +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docker/compose.yaml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docker/entrypoint.sh +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docker/limits/limits.txt +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docker/smoke.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/architecture-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/architecture.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/capabilities.js +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/context-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/context.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/pulseg-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/pulseg.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/pulserver-logo-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/pulserver-logo.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/pulserver-mark-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/pulserver-mark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/pulserver.css +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/repetition-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/repetition.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/safety-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/safety.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/session-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/session.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/virtual-dark.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_static/virtual.svg +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_templates/autosummary/base.rst +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_templates/autosummary/class.rst +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_templates/autosummary/enum.rst +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/_templates/autosummary/function.rst +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/host.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/index.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/mrd.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/protocol.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/proxy.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/recon.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/validate.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api/virtual.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/api_objects.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/colab.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/conf.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/documentation.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/index.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/installation.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/internals/calibration.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/internals/sar-ratios.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/releases.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/style.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/developer-guide/workflow.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/examples/course.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/examples/index.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/examples/tours.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/index.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/protocol.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/raw-data.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/reconstruction.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/explanations/virtual-scanner.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/figure_style.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/index.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/misc/contributors.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/misc/index.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/misc/license.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/misc/related.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/user-guide/index.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/docs/user-guide/virtual-scanner.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/01-course/01_protocol_to_image.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/01-course/02_sequence_plugin.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/01-course/03_scanner_representation.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/01-course/04_reconstruction_plugin.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/01-course/05_recon_plugin.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/01-course/06_testing_on_the_virtual_scanner.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/01-course/README.rst +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/01-course/_gallery_header.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/02-tours/01_protocol_resolution.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/02-tours/02_segmentation.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/02-tours/03_fov_offset_enrichment.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/02-tours/README.rst +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/02-tours/_gallery_header.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/README.rst +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/gallery/_gallery_header.md +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/scripts/build_docs.sh +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/scripts/check_throughput.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/scripts/format_and_lint.sh +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/scripts/make_artwork.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/scripts/publish_docs.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/setup.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/CMakeLists.txt +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/core/pulseg_math.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg_cache.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg_config.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg_io.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseg/pulseg_protocol.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseq/pulseq.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/include/pulseq/pulseq_config.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/io/pulseg_opts.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/io/pulseg_protocol.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/pulseq/pulseq_internal.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/pulseq/pulseq_shape.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/c/structure/pulseg_waves.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/fourier/bindings.cpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/fourier/bindings.hpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/fourier/parallel.hpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/fourier/timeline.cpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/fourier/timeline.hpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/from_libraries.cpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/from_libraries.hpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/pulseq_file.cpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/pulseq_file.h +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/wave_plan.cpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/ir/waves.cpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/native.hpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/cpp/playout.hpp +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_accelerators.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_cli.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_labels.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_logs.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_memory.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/_evaluation.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/_inversion.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/_pmc.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/_saturation.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/_slab.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/recon/epi.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/recon/nufft.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/recon/nufft_train.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/recon/pics.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/recon/pics_train.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/recon/pmc.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/bssfp3d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/epi2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/epi3d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre_propeller2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre_radial2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre_stack_of_blades3d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/gre_stack_of_stars3d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se_epi_propeller2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se_propeller2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se_radial2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se_stack_of_blades3d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/_zoo/sequences/se_stack_of_stars3d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/design/_rf.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/__main__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/_blocks.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/host/_push.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/ir/_checks.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/ir/_vendor.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/mrd/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/mrd/_acquisitions.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/mrd/_header.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/mrd/_images.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/mrd/_metadata.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/mrd/_sequence.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/protocol/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/protocol/_keys.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/protocol/_prescription.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/protocol/_schema.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/__main__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_held.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_intake.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_local.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_queue.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/proxy/_workers.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/__main__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_buffers.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_calibration.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_exam_image.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_figure.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_loader.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_replay.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/application.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/concurrency.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/connection.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/constants.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/exam.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/readers.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_runtime/writers.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/_units.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/gadgets.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/handlers/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/handlers/epi.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/handlers/nufft.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/handlers/nufft_train.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/handlers/pics.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/handlers/pics_train.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/handlers/pmc.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/recon/plugin.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/validate/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/validate/_command.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/validate/_compare.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/validate/_validate.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/validate/_xml.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/__init__.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_brainweb.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_client.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_coils.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_command.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_export.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_girf.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_localizer.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_motion.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_phantom.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_stream.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_timeline.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/src/pulserver/virtual/_tissue.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/_analytic.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/_seqtext.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/_synthetic.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/_virtual.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/_zoo.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/conftest.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/bssfp.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/epi_2d_main.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/gre_2d_3sl.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/steady_dess_hard_0hz.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/steady_dess_hard_30hz.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/steady_echo_hard_0hz.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/steady_echo_hard_30hz.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/steady_echo_selective_0hz.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/bloch/steady_fid_hard_0hz.npy +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/sequences/dedup_gre_pair.seq +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/sequences/dedup_gre_pair_b.seq +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/fixtures/sequences/gre_2d_3sl.seq +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/koma/Project.toml +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/koma/simulate.jl +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/native/check_initializers.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/native/print_wave_samples.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/native/read_rf_definitions.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/native/read_rf_timing.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/native/replay_an_instance.c +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/plugins/crash.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/plugins/gre2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/plugins/gre2d_raw.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/plugins/rf_train.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/plugins/stall.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/plugins/strong.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/plugins/tiny.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/plugins/typed.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_app.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_buffers.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_calibration.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_coil_compression.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_connection.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_epi.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_exam_image.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_flags.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_gadgets.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_handlers.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_images.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_loader.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_nufft.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_pics.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_pmc.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_prewhiten.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_readers_writers.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_slots.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon/test_units.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon_plugins/children.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon_plugins/crash.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon_plugins/device.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon_plugins/exam.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon_plugins/gre2d.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/recon_plugins/pose.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_console.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_design_push.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_design_server.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_docs.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_docstring_defaults.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_docstrings.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_enrich.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_exam_artifacts.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_exam_calibration.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_exam_sharing.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_host_slots.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_image.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_checks.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_designed.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_extensions.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_labels.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_profile.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_repetition.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_segments.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_source.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_steady_excitation.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_vendor.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_ir_waves.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_keys.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_koma.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_logs.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_memory.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_mrd_images.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_mrd_sequence.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_plugins.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_protocol.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_publish_docs.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_resolution.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_rf_layout.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_scan_command.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_seqdesc.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_sequence_plugin.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_smoke.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_validate.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_virtual.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_virtual_brainweb.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_virtual_clock.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_virtual_coils.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_virtual_export.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_virtual_localizer.py +0 -0
- {pulserver-0.4.1 → pulserver-0.4.2}/tests/test_virtual_sequences.py +0 -0
|
@@ -28,7 +28,7 @@ pybind11_add_module(_ext
|
|
|
28
28
|
${CMAKE_SOURCE_DIR}/src/cpp/ir/collection.cpp
|
|
29
29
|
${CMAKE_SOURCE_DIR}/src/cpp/ir/waves.cpp
|
|
30
30
|
${CMAKE_SOURCE_DIR}/src/cpp/ir/wave_plan.cpp
|
|
31
|
-
${CMAKE_SOURCE_DIR}/src/cpp/ir/
|
|
31
|
+
${CMAKE_SOURCE_DIR}/src/cpp/ir/gradient_stretch.cpp
|
|
32
32
|
${CMAKE_SOURCE_DIR}/src/cpp/fourier/bindings.cpp
|
|
33
33
|
${CMAKE_SOURCE_DIR}/src/cpp/fourier/timeline.cpp
|
|
34
34
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pulserver
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Orchestrator for MR acquisitions: sequence design, scanner preparation and reconstruction.
|
|
5
5
|
Keywords: mri,pulseq,mrd,ismrmrd,reconstruction,scanner
|
|
6
6
|
Author-Email: Matteo Cencini <matteo.cencini@gmail.com>
|
|
@@ -21,22 +21,21 @@ Project-URL: Documentation, https://pulserver.github.io/pulserver/
|
|
|
21
21
|
Project-URL: Issues, https://github.com/pulserver/pulserver/issues
|
|
22
22
|
Project-URL: Source, https://github.com/pulserver/pulserver
|
|
23
23
|
Requires-Python: >=3.10
|
|
24
|
-
Requires-Dist: pypulseqpp>=0.0.
|
|
24
|
+
Requires-Dist: pypulseqpp>=0.0.46
|
|
25
25
|
Requires-Dist: numpy>=2.2.6
|
|
26
26
|
Requires-Dist: ismrmrd>=1.15.0
|
|
27
27
|
Requires-Dist: pydicom>=3.0.2
|
|
28
28
|
Requires-Dist: torch>=2.4
|
|
29
29
|
Requires-Dist: blochsim>=0.0.12
|
|
30
|
-
Requires-Dist: bartorch>=0.0.
|
|
30
|
+
Requires-Dist: bartorch>=0.0.17
|
|
31
31
|
Requires-Dist: brainweb-dl>=0.4.6
|
|
32
32
|
Requires-Dist: websockets>=16.1.1
|
|
33
|
-
Requires-Dist: tomli>=2.0.1; python_version < "3.11"
|
|
34
33
|
Provides-Extra: dev
|
|
35
34
|
Requires-Dist: pytest>=9.1.1; extra == "dev"
|
|
36
35
|
Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
|
|
37
36
|
Requires-Dist: pytest-xdist>=3; extra == "dev"
|
|
38
37
|
Requires-Dist: coverage>=7.16.2; extra == "dev"
|
|
39
|
-
Requires-Dist: ruff==0.17.
|
|
38
|
+
Requires-Dist: ruff==0.17.1; extra == "dev"
|
|
40
39
|
Requires-Dist: pre-commit>=4.6.2; extra == "dev"
|
|
41
40
|
Requires-Dist: build; extra == "dev"
|
|
42
41
|
Provides-Extra: doc
|
|
@@ -28,17 +28,16 @@ control variable, are described in {doc}`../explanations/protocol`.
|
|
|
28
28
|
|
|
29
29
|
## Options
|
|
30
30
|
|
|
31
|
-
A plugin's options are module constants
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
plugin with its defaults.
|
|
31
|
+
A plugin's options are module constants that shape its sequence function and
|
|
32
|
+
the protocol it declares. Each is a user entry holding the index of its value
|
|
33
|
+
among its choices, and a design call loads the plugin at the options its
|
|
34
|
+
request states ({ref}`plugin-options`).
|
|
36
35
|
|
|
37
36
|
| Object | Description |
|
|
38
37
|
| --- | --- |
|
|
39
|
-
| {obj}`~pulserver.design.option` |
|
|
40
|
-
| {obj}`~pulserver.design.
|
|
41
|
-
| {obj}`~pulserver.design.OptionError` | An option a
|
|
38
|
+
| {obj}`~pulserver.design.option` | Declare an option at a user entry; the value the plugin is loaded with. |
|
|
39
|
+
| {obj}`~pulserver.design.OptionParam` | The entry an option is listed as: the index of its value among its choices. |
|
|
40
|
+
| {obj}`~pulserver.design.OptionError` | An option a plugin is loaded with that it does not declare or take, or a declaration the console cannot list. |
|
|
42
41
|
|
|
43
42
|
## RF layout
|
|
44
43
|
|
|
@@ -40,7 +40,8 @@ the cache layout in {doc}`../developer-guide/internals/ir-cache`.
|
|
|
40
40
|
| {obj}`~pulserver.ir.Format` | Whether a quantity is stored as a float in its SI unit or as an integer. |
|
|
41
41
|
| {obj}`~pulserver.ir.sample_wave` | A cache's wave on a playout's gradient raster, as loaded into a region of its waveform memory. |
|
|
42
42
|
| {obj}`~pulserver.ir.playout` | Both stages of a segmented playout of a cache, the scan or its receive-gain prescan, recorded: what each position prepares, the registers of each block, what each wave reads from waveform memory and, on request, the waveforms each block plays. |
|
|
43
|
-
| {obj}`~pulserver.ir.Prescan` | The receive-gain calibration a playout plays instead of the scan: one subsequence, to the instance completing its readouts. |
|
|
44
|
-
| {obj}`~pulserver.ir.
|
|
43
|
+
| {obj}`~pulserver.ir.Prescan` | The receive-gain calibration a playout plays instead of the scan: one subsequence, to the instance completing its readouts, opened by the pTx tour on request. |
|
|
44
|
+
| {obj}`~pulserver.ir.prescan_tour` | The pTx prescan tour of a cache: the segment instance holding each channel's largest drive of every parallel-transmit RF definition. |
|
|
45
|
+
| {obj}`~pulserver.ir.gradient_stretch` | The gradients of a subsequence's hyper-repetition-long stretch of most gradient energy, or of the one from its heaviest repetition, as corner points and on a raster: what a scanner's heating model is evaluated on. |
|
|
45
46
|
| {obj}`~pulserver.ir.chain` | Files of the `NextSequence` chain starting at a sequence file, in play order. |
|
|
46
47
|
| {obj}`~pulserver.ir.cache_path` | Cache file of a sequence file. |
|
|
@@ -7,7 +7,7 @@ authors.
|
|
|
7
7
|
| Page | Contents |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| {doc}`calibration` | Prewhitening, coil compression, sensitivity maps and the reuse of stored maps |
|
|
10
|
-
| {doc}`ir-cache` | Conversion passes, waves, playout stages, the
|
|
10
|
+
| {doc}`ir-cache` | Conversion passes, waves, playout stages, the gradient stretches, the cache file and the C89 library |
|
|
11
11
|
| {doc}`protocol-wire` | RF layout, protocol keys and values, and the protocol text blocks |
|
|
12
12
|
| {doc}`reconstruction-proxy` | Reconstruction units, image headers, enrichment and trajectory rules, readout placement and workers |
|
|
13
13
|
| {doc}`sar-ratios` | pTx SAR ratios from VOPs against a reference pulse |
|
|
@@ -95,8 +95,8 @@ the chain is read. RF and ADC frequency and phase offsets are stored absolute:
|
|
|
95
95
|
the ppm offsets are resolved on the host, at the gamma and B0 of the call's
|
|
96
96
|
limits, by pypulseqpp's `SequenceLibraries.absolute_offsets`. The labels
|
|
97
97
|
and flags in force at each block, with `PMC` in force from the first, are
|
|
98
|
-
pypulseqpp's `Sequence.evaluate_labels`, and
|
|
99
|
-
`Sequence.label_blocks` lists
|
|
98
|
+
pypulseqpp's `Sequence.evaluate_labels`, and the blocks that set `TRID` are
|
|
99
|
+
those `Sequence.label_blocks` lists; the rotation and RF shim a block
|
|
100
100
|
plays are `Sequence.block_rotations` and `Sequence.block_shims`. A segment
|
|
101
101
|
position records whether the scanner may move its excitation at run time by a
|
|
102
102
|
carrier offset alone: every instance plays its RF pulse under one gradient,
|
|
@@ -200,10 +200,35 @@ instance.
|
|
|
200
200
|
|
|
201
201
|
The receive-gain calibration prescan plays one subsequence from its start to
|
|
202
202
|
the segment instance that completes the readouts its sequence declares
|
|
203
|
-
(`NumGainCalibrationReadouts
|
|
203
|
+
(`NumGainCalibrationReadouts`). A readout whose block carries the `NOPRESCAN`
|
|
204
|
+
label plays without being acquired and is not counted, so a multi-echo
|
|
205
|
+
sequence calibrates on its first echo. The count ends with a repetition, so the gain
|
|
206
|
+
is set on whole repetitions of the scan; the conversion refuses one that ends
|
|
207
|
+
inside a repetition, and takes the readouts through the first repetition that
|
|
208
|
+
acquires when the sequence declares none. It waits for no trigger and
|
|
204
209
|
drives no digital output, and every gradient whose amplitude varies across
|
|
205
210
|
repetitions, a phase encoding for instance, plays at zero, as does a wave any
|
|
206
|
-
of whose logical axes varies.
|
|
211
|
+
of whose logical axes varies. An RF pulse whose frequency offset varies across
|
|
212
|
+
repetitions, the slices of a stack, plays at the mean offset over them, as a
|
|
213
|
+
scanner calibrates on one slice. Both are kept per position within the
|
|
214
|
+
repetition, as the gradient flags are, and reported on the block instance
|
|
215
|
+
(`rf_freq_variable` and `rf_freq_mean_hz`). The offsets are those of the
|
|
216
|
+
cache, the field-of-view offset included, so the mean is the centre of the
|
|
217
|
+
positioned stack.
|
|
218
|
+
|
|
219
|
+
A parallel-transmit sequence can open its prescan with the pTx tour
|
|
220
|
+
(`pulseg_get_prescan_tour`): for every channel of every parallel-transmit RF
|
|
221
|
+
definition of every subsequence, the segment instance holding the largest
|
|
222
|
+
drive that channel receives, the RF amplitude times the channel's shim
|
|
223
|
+
magnitude, or the amplitude alone for a pulse with a waveform per channel.
|
|
224
|
+
Each instance is visited once, under the prescan's rules, whether or not it
|
|
225
|
+
reads out; the tour either acquires its readouts, counted on top of the
|
|
226
|
+
calibration's, or plays them unacquired. A playout reaches each visit by
|
|
227
|
+
seeking the cursor to its first block (`pulseg_cursor_seek`). A visit plays
|
|
228
|
+
part of one occurrence of its subsequence's repetition, each pulse at its
|
|
229
|
+
largest, so resting after it until it has lasted the time per occurrence the
|
|
230
|
+
scan's RF is costed at keeps its average power within the scan's; the rest is
|
|
231
|
+
the interpreter's, from the visit's duration.
|
|
207
232
|
|
|
208
233
|
Waveform memory holds samples of the type and scale a scanner build defines
|
|
209
234
|
before it includes the library: `PULSEG_WAVE_SAMPLE`, the type;
|
|
@@ -229,29 +254,43 @@ to that type.
|
|
|
229
254
|
|
|
230
255
|
## Heaviest repetition
|
|
231
256
|
|
|
232
|
-
A scanner evaluates its gradient-heating model on the gradients of
|
|
233
|
-
|
|
234
|
-
(
|
|
235
|
-
|
|
236
|
-
|
|
257
|
+
A scanner evaluates its gradient-heating model on the gradients of two
|
|
258
|
+
stretches of each subsequence, each as if played without end against its own
|
|
259
|
+
duration ({func}`~pulserver.ir.gradient_stretch`,
|
|
260
|
+
`pulseg_get_gradient_stretch`). A stretch is the run of whole segment instances
|
|
261
|
+
from one instance's start until they last the subsequence's hyper-repetition,
|
|
262
|
+
or `PULSEG_STRETCH_US`, 10 s, where that is shorter, or to the subsequence's end
|
|
263
|
+
where it comes first, each block at its played duration, a pure delay at its
|
|
264
|
+
instance's. The hyper-repetition is the shortest run of repetitions whose
|
|
265
|
+
durations repeat over the whole subsequence, a last run cut short allowed
|
|
266
|
+
(`hyper_copies` and `hyper_us` of `pulseg_get_tr_timing`, from the prefix
|
|
267
|
+
function of the repetitions' durations in us): one repetition where all last
|
|
268
|
+
the same, five for a five-slice packet whose last slice carries the pad, all of
|
|
269
|
+
them where they do not repeat. Where it is one repetition, the second stretch
|
|
270
|
+
is the heaviest repetition itself.
|
|
271
|
+
|
|
272
|
+
| Stretch | Start |
|
|
273
|
+
|---|---|
|
|
274
|
+
| `PULSEG_STRETCH_HEAVIEST` | Of the instance starts whose stretch lasts that long, the one of largest $E$, the earliest on a tie; the subsequence's start where none does |
|
|
275
|
+
| `PULSEG_STRETCH_HEAVIEST_REPETITION` | The instance holding the start of the repetition of largest $E$, of those the execution stream holds from its first block, the earliest on a tie |
|
|
237
276
|
|
|
238
277
|
$$
|
|
239
278
|
E = \int \lVert \mathbf{g}(t) \rVert^2 \, dt
|
|
240
279
|
$$
|
|
241
280
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
raster samples them at the
|
|
254
|
-
(`pulseg_sample_corner_points`).
|
|
281
|
+
sums, over the blocks and their gradient events, the square of each event's
|
|
282
|
+
amplitude times the integral of its normalised waveform's square, which a
|
|
283
|
+
rotation leaves unchanged, so neither choice depends on the blocks' rotations.
|
|
284
|
+
The first stretch is found by sliding its end ahead of its start over the
|
|
285
|
+
instances, each walk passing over the stream once. The second holds a short
|
|
286
|
+
burst the first averages out; the host's sound pressure check
|
|
287
|
+
(`pypulseqpp.safety.check_spl`) chooses the same repetition. Each block plays
|
|
288
|
+
at its own amplitudes and with its own shapes and rotation, or through its
|
|
289
|
+
wave: a waveform that plays, not an envelope of several. The gradients are
|
|
290
|
+
joined over the blocks as corner points on one timeline, along the logical
|
|
291
|
+
axes and linear in between; the prescription's rotation takes them to the
|
|
292
|
+
physical axes, and a model that needs them on a raster samples them at the
|
|
293
|
+
centres of its intervals (`pulseg_sample_corner_points`).
|
|
255
294
|
|
|
256
295
|
## Cache file
|
|
257
296
|
|
|
@@ -259,7 +298,7 @@ The cache has the name of the first sequence file with its extension replaced,
|
|
|
259
298
|
`.pseg` by default. It is divided into sections that a consumer loads
|
|
260
299
|
independently. The pulse-generation stage of a playout reads the
|
|
261
300
|
definitions, their waveforms, the waves and their layout, and the gradients of
|
|
262
|
-
each subsequence's
|
|
301
|
+
each subsequence's stretches; the scan loop also reads
|
|
263
302
|
the per-block instances, the rotations and the execution stream, whose size
|
|
264
303
|
scales with the scan length. Integer and float fields are 4 bytes. The byte
|
|
265
304
|
order is recorded in the file, and a reader on a machine of the other byte order swaps on load. A
|
|
@@ -289,7 +328,7 @@ playout to the cursor's, bit for bit.
|
|
|
289
328
|
|
|
290
329
|
The IR is built by C++ passes in `src/cpp/ir/`, which run only on the host:
|
|
291
330
|
the segmentation, the waves, their layout in a playout's waveform memory and
|
|
292
|
-
each subsequence's
|
|
331
|
+
each subsequence's stretches. The cache reader and writer, the
|
|
293
332
|
accessors a playout uses to walk the loaded collection, and the two stages of a
|
|
294
333
|
playout are compiled into the interpreter, whose vendor toolchains accept ANSI
|
|
295
334
|
C. They are therefore C89, in `src/c/`, and call nothing in `src/cpp/`. The
|
|
@@ -96,6 +96,20 @@ imaging_mode: stringlist|1|2d|3d
|
|
|
96
96
|
A value block carries `name: value` lines only, a string list as the index of
|
|
97
97
|
its chosen option.
|
|
98
98
|
|
|
99
|
+
An option ({ref}`plugin-options`) is an integer user entry, the index of its
|
|
100
|
+
choice. Its mode, `dropdown` with the indices as options (`0|1` for a flag),
|
|
101
|
+
marks it as an option; an interpreter shows it as a number, like any user entry:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
user36_value: int|dropdown|0|0|1|1||0|1
|
|
105
|
+
user36_name: description|Navigator: 0 off, 1 on
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
A `list` call reads only the option entries of the value block it is given, and
|
|
109
|
+
lists the plugin at those options; `validate` and `generate` load the plugin at
|
|
110
|
+
the options of their request before reading the rest of it against that
|
|
111
|
+
listing. An interpreter lists the plugin again when an option entry changes.
|
|
112
|
+
|
|
99
113
|
The RF blocks follow a reply when the call asks for them, and no block follows
|
|
100
114
|
where the evaluation is invalid or states no layout. They are lists of numbers:
|
|
101
115
|
each number is ASCII decimal with nine significant digits, the numbers of a list
|
|
@@ -188,10 +188,17 @@ arrives, and replayed to a worker once a slot is released. The client remains
|
|
|
188
188
|
connected meanwhile, and the images are returned through its connection.
|
|
189
189
|
|
|
190
190
|
Images, DICOM datasets and text produced by the worker are relayed to the
|
|
191
|
-
client as they are produced
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
191
|
+
client as they are produced once the client's stream has ended whole, with its
|
|
192
|
+
`CLOSE` or a last acquisition flagged `LAST_IN_MEASUREMENT`; what the worker
|
|
193
|
+
produces before, such as a unit that closes on the last readout, is held until
|
|
194
|
+
then. A stream that ends otherwise is refused and the held output dropped, so a
|
|
195
|
+
scan the scanner stopped after its last readout returns nothing. A worker that
|
|
196
|
+
stops reading, as one whose plugin failed, has the rest of the stream read and
|
|
197
|
+
dropped, so what it said reaches the client of a whole stream. Closing either
|
|
198
|
+
connection closes the other. Once the client's stream ends, the proxy waits for
|
|
199
|
+
the worker to close however long the reconstruction takes, unless it was
|
|
200
|
+
started with a reconstruction timeout, past which the worker is terminated and
|
|
201
|
+
the client told so.
|
|
195
202
|
|
|
196
203
|
## Enrichment
|
|
197
204
|
|
|
@@ -90,9 +90,9 @@ $$
|
|
|
90
90
|
\alpha_j = \alpha\,|b^+(\mathbf{r}_j)|\,P(\mathbf{g}\cdot\mathbf{r}_j + f_j - f_\mathrm{rf}),
|
|
91
91
|
$$
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
along one direction $\hat{\mathbf{n}}$, as a spectral-spatial pulse's
|
|
93
|
+
with $b^+$ relative to the pulse's nominal amplitude, about its axis turned as
|
|
94
|
+
a pulse phase of $-\arg b^+$ turns it ({ref}`transmit-phase-convention`). A
|
|
95
|
+
pulse played under a gradient that changes along one direction $\hat{\mathbf{n}}$, as a spectral-spatial pulse's
|
|
96
96
|
alternating lobes do, has a profile in both the field and the position along
|
|
97
97
|
it, $P(f_j - f_\mathrm{rf}, \hat{\mathbf{n}}\cdot\mathbf{r}_j)$, simulated
|
|
98
98
|
from its samples under that gradient; a pulse played under no gradient, or
|
|
@@ -230,7 +230,8 @@ A pulse plays on every transmit channel, weighted by the coil's default shim,
|
|
|
230
230
|
the weights of magnitude $1/\sqrt{N}$ for $N$ channels that bring the channels
|
|
231
231
|
into phase at the isocentre, where the pulse then has its nominal amplitude:
|
|
232
232
|
each cube sees the transmit field
|
|
233
|
-
$b^+(\mathbf{r}) = \sum_c w_c\,s^+_c(\mathbf{r})$, for the weights
|
|
233
|
+
$b^+(\mathbf{r}) = \sum_c \overline{w_c}\,s^+_c(\mathbf{r})$, for the weights
|
|
234
|
+
$w_c$, which drive the channels. The
|
|
234
235
|
squares of the weights sum to 1, so the channels together carry the power of
|
|
235
236
|
one channel at the pulse's amplitude, and an RF shim is written in the same
|
|
236
237
|
normalisation: a circularly polarised shim of $N$ channels has weights of
|
|
@@ -91,8 +91,8 @@ every block. The *repetition* of a subsequence is the period
|
|
|
91
91
|
`pypulseqpp.Sequence.repetition()` reports, the whole subsequence where it
|
|
92
92
|
does not repeat; the conversion finds virtual segments within it. Do not write
|
|
93
93
|
"repeating unit", which implies that every sequence is periodic, nor "segment
|
|
94
|
-
definition" for a virtual segment. A `TRID` label
|
|
95
|
-
|
|
94
|
+
definition" for a virtual segment. A `TRID` label is carried with each block
|
|
95
|
+
and places no segment boundary. The *IR cache* is the file; the *collection* is what a
|
|
96
96
|
reader loads from it.
|
|
97
97
|
|
|
98
98
|
**Virtual scanner.** The stand-ins for the scanner in tests: the *virtual
|
|
@@ -99,7 +99,8 @@ designs/
|
|
|
99
99
|
manifest.json identity and identifier, limits, package versions,
|
|
100
100
|
creation time, plugin and source, scan time,
|
|
101
101
|
field-of-view offset, SHA-256 of every file
|
|
102
|
-
motion.buf the poses of a scan corrected for motion
|
|
102
|
+
motion.buf the poses of a scan corrected for motion, created
|
|
103
|
+
empty with its design
|
|
103
104
|
```
|
|
104
105
|
|
|
105
106
|
A design is reused while its scan holds it; a design call that resolves to
|
|
@@ -29,10 +29,13 @@ on the other end refuses a series it cannot serve, enriches it from its design
|
|
|
29
29
|
Code: {class}`~pulserver.proxy.DesignCache`, {class}`~pulserver.proxy.DesignIntake`. Tests: *a design pushed to the intake is reconstructed from its store*; *a series naming no stored design is refused* (`test_proxy.py`).
|
|
30
30
|
- **Refuses a malformed stream with a text the console shows.**
|
|
31
31
|
|
|
32
|
-
Code: {class}`~pulserver.proxy.ReconProxy`. Tests: *a series carrying no header or two is refused*; *a series that ends before its last readout is refused*; *a message the proxy cannot read ends the output with its type* (`test_proxy.py`).
|
|
33
|
-
- **
|
|
32
|
+
Code: {class}`~pulserver.proxy.ReconProxy`. Tests: *a series carrying no header or two is refused*; *a series that ends before its last readout is refused*; *a message the proxy cannot read ends the output with its type*; *a series carrying a message the proxy cannot read is refused* (`test_proxy.py`).
|
|
33
|
+
- **Returns nothing of a scan whose client ends the stream without a `CLOSE`, though its images were already made.**
|
|
34
34
|
|
|
35
|
-
Code: {class}`~pulserver.proxy.ReconProxy`. Tests: *
|
|
35
|
+
Code: {class}`~pulserver.proxy.ReconProxy`. Tests: *a scan stopped after its last readout exports nothing* (`test_proxy.py`).
|
|
36
|
+
- **Reconstructs each series in a fresh worker process, with spares that have already imported the engine, and returns why one failed.**
|
|
37
|
+
|
|
38
|
+
Code: {class}`~pulserver.proxy.ReconProxy`. Tests: *the spare worker is replaced after each series*; *the proxy process does not import the reconstruction engine*; *a crashing plugin closes its series and frees the slot*; *a plugin crashing while its series still arrives reports why* (`test_proxy.py`).
|
|
36
39
|
- **Bounds concurrent series by slots, one per GPU by default, and holds the rest on disk.**
|
|
37
40
|
|
|
38
41
|
Code: `--slots`, `--gpu-slots`, `--queue`. Tests: *a second series waits for a slot and still returns images*; *a series with every slot busy is held on disk until one frees*; *a series reads the gpu its slot holds* (`test_proxy.py`).
|
|
@@ -51,9 +54,9 @@ on the other end refuses a series it cannot serve, enriches it from its design
|
|
|
51
54
|
- **Publishes the poses of a motion-corrected series to the running scan.**
|
|
52
55
|
|
|
53
56
|
Code: `pulserver.proxy._motion`. Tests: *a motion corrected series publishes its poses to the scan*; *a series not corrected for motion writes no pose file* (`test_proxy.py`).
|
|
54
|
-
- **Keeps each series
|
|
57
|
+
- **Keeps each series enriched, for an offline rerun that gives the same image.**
|
|
55
58
|
|
|
56
|
-
Code: `--save-data`. Tests: *a kept series runs offline and gives the image the proxy returned*; *what a proxy keeps is the
|
|
59
|
+
Code: `--save-data`. Tests: *a kept series runs offline and gives the image the proxy returned*; *what a proxy keeps is the series it reconstructed, enriched*; *a kept series given its design is not enriched twice* (`test_proxy.py`).
|
|
57
60
|
- **Holds images for a client that dropped, and closes on its own when idle.**
|
|
58
61
|
|
|
59
62
|
Code: `--idle-timeout`. Tests: *images whose client has gone reach it when it returns*; *the idle timeout counts from the last client leaving* (`test_proxy.py`).
|
|
@@ -85,8 +88,10 @@ A series is `CONFIG`, `HEADER`, the `ACQUISITION`s and optional `WAVEFORM`s,
|
|
|
85
88
|
then `CLOSE`; what returns is `IMAGE`, `DICOM_WITHNAME` and `TEXT` messages,
|
|
86
89
|
then `CLOSE`. These are the identifiers of Gadgetron's MRD streaming protocol.
|
|
87
90
|
A refused series receives one `TEXT` beginning `pulserver:` and a `CLOSE` at
|
|
88
|
-
once.
|
|
89
|
-
|
|
91
|
+
once. A stream that ends without its `CLOSE` is a scan that did not finish: it
|
|
92
|
+
is refused, and what its reconstruction produced is not returned. An MRD
|
|
93
|
+
message carries no length, so a message type the proxy cannot read ends the
|
|
94
|
+
series.
|
|
90
95
|
|
|
91
96
|
### Workers and slots
|
|
92
97
|
|
|
@@ -91,8 +91,9 @@ converted into the IR cache with its sound pressure levels and SAR ratios.
|
|
|
91
91
|
|
|
92
92
|
Two logical axes at 0.8 of the amplitude limit put $0.8\sqrt{2}$ of it on one
|
|
93
93
|
physical axis at 45°. So the sequence is designed under `design_max_grad` and
|
|
94
|
-
`design_max_slew`, which the scanner derates for the prescription,
|
|
95
|
-
|
|
94
|
+
`design_max_slew`, which the scanner derates for the prescription, less the
|
|
95
|
+
design margin of `pypulseqpp.apply_system_derates`, and checked on the physical
|
|
96
|
+
axes against `max_grad` and `max_slew` as sent. The rotation arrives
|
|
96
97
|
in the protocol's `fov_rotation_ij` entries; your sequence function never sees
|
|
97
98
|
it.
|
|
98
99
|
|
|
@@ -177,7 +177,7 @@ Two offsets give two caches, and two designs.
|
|
|
177
177
|
| Aspect | PulSeg 2.1-alpha | pulserver |
|
|
178
178
|
| --- | --- | --- |
|
|
179
179
|
| Segment-instance boundaries | Marked by the sequence designer with `TRID` labels (§4.2) | Found within the repetition under the {class}`~pulserver.ir.Grouping` |
|
|
180
|
-
| `TRID` | Identifies the virtual segment an instance plays |
|
|
180
|
+
| `TRID` | Identifies the virtual segment an instance plays | Carried with each block; it places no segment boundary |
|
|
181
181
|
| Periodicity | Not part of the model | Taken from pypulseqpp when present, and used to encode the stream |
|
|
182
182
|
| Multishot gradient variants | One base block with shot variants, chosen per instance by the optional `gradient_shot_index` | No shot index: a gradient that differs between instances is played as a wave from waveform memory, or the run is a variant of its virtual segment |
|
|
183
183
|
|
|
@@ -31,12 +31,19 @@ names none, or that sends no config, unless it forwards with a
|
|
|
31
31
|
the proxy searches its own `--plugins` directories for that name, whatever the
|
|
32
32
|
path's directory.
|
|
33
33
|
|
|
34
|
-
The client then reads until the proxy's `CLOSE`: images (`IMAGE`, 1022),
|
|
35
|
-
|
|
36
|
-
reconstruction produces them.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
The client then reads until the proxy's `CLOSE`: images (`IMAGE`, 1022), DICOM
|
|
35
|
+
datasets (`DICOM_WITHNAME`, 1018) and texts (`TEXT`, 5), in the order the
|
|
36
|
+
reconstruction produces them. Nothing is returned before the series has ended
|
|
37
|
+
whole, with the client's `CLOSE` or a last acquisition flagged
|
|
38
|
+
`LAST_IN_MEASUREMENT`: a reconstruction may finish on the last readout, and
|
|
39
|
+
what it produces then is held until that end. A text beginning `pulserver:`
|
|
40
|
+
reports a series that failed. A refused series receives that text and a `CLOSE`
|
|
41
|
+
at once; the proxy then discards what the client still sends until it closes
|
|
42
|
+
the connection, so the client can finish sending and read the reason.
|
|
43
|
+
|
|
44
|
+
A client ends a scan the scanner stopped by shutting its side of the connection
|
|
45
|
+
for writing without a `CLOSE`, then reading the reply as usual. The series is
|
|
46
|
+
refused and nothing it produced is returned, even when every readout arrived.
|
|
40
47
|
|
|
41
48
|
## Header
|
|
42
49
|
|
|
@@ -107,8 +114,10 @@ noise scans and navigators included, and no other.
|
|
|
107
114
|
|
|
108
115
|
A series is refused, and its reconstruction stopped, when an acquisition has a
|
|
109
116
|
sample count other than its readout's, when the scan counters skip or repeat
|
|
110
|
-
one, when an acquisition before the last is flagged `LAST_IN_MEASUREMENT`,
|
|
111
|
-
when the stream carries more or fewer acquisitions than the chain plays
|
|
117
|
+
one, when an acquisition before the last is flagged `LAST_IN_MEASUREMENT`,
|
|
118
|
+
when the stream carries more or fewer acquisitions than the chain plays, or
|
|
119
|
+
when it ends without a `CLOSE` or a last acquisition flagged
|
|
120
|
+
`LAST_IN_MEASUREMENT`.
|
|
112
121
|
|
|
113
122
|
## See also
|
|
114
123
|
|
|
@@ -399,10 +399,12 @@ process ID, level and logger name.
|
|
|
399
399
|
## Offline reconstruction
|
|
400
400
|
|
|
401
401
|
{meth}`~pulserver.recon.ReconPlugin.run` reconstructs an ISMRMRD HDF5 file in
|
|
402
|
-
the calling process, through the same hooks. A file
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
402
|
+
the calling process, through the same hooks. A file the proxy's `--save-data`
|
|
403
|
+
keeps is enriched already and plays as it stands. A file recorded as the
|
|
404
|
+
scanner sends it, such as `pulserver scan --mrd raw.h5` writes, is enriched
|
|
405
|
+
first from the design it was played from, found in a design store or given as
|
|
406
|
+
its sequence file, with its manifest beside it; given a design, an enriched
|
|
407
|
+
file is still played as it stands, never enriched twice:
|
|
406
408
|
|
|
407
409
|
```python
|
|
408
410
|
images = PLUGIN.run("raw.h5", store="designs")
|
|
@@ -17,7 +17,7 @@ store are described in {doc}`../explanations/architecture`.
|
|
|
17
17
|
## Design calls
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
pulserver design list --plugins DIR --plugin NAME [--limits FILE --rf-definitions] [--socket PATH]
|
|
20
|
+
pulserver design list --plugins DIR --plugin NAME [--values FILE] [--limits FILE --rf-definitions] [--socket PATH]
|
|
21
21
|
pulserver design validate --plugins DIR --plugin NAME --limits FILE [--rf-layout] [--exam DIR] [--socket PATH] < VALUES
|
|
22
22
|
pulserver design generate --plugins DIR --plugin NAME --limits FILE --store DIR --scan NAME [--exam DIR] [--push URL] [--socket PATH] < VALUES
|
|
23
23
|
pulserver design import --limits FILE --store DIR --scan NAME [--push URL] [--socket PATH] < IMPORT
|
|
@@ -36,7 +36,7 @@ directory name, not starting with `.`.
|
|
|
36
36
|
|
|
37
37
|
| Call | Reply |
|
|
38
38
|
| --- | --- |
|
|
39
|
-
| `list` | `PROTOCOL` and the plugin's listing block; with `--rf-definitions`, the `[RfDefinitions]` block |
|
|
39
|
+
| `list` | `PROTOCOL` and the plugin's listing block at the options of the value block in `--values` ({ref}`plugin-options`); with `--rf-definitions`, the `[RfDefinitions]` block |
|
|
40
40
|
| `validate` | `VALID <seconds>` or `INVALID`, an `INFO` line and the value block of the resolved protocol; with `--rf-layout`, a valid reply ends with the `[RfLayout]` block |
|
|
41
41
|
| `generate` | `GENERATED <id>`, the identifier of the design in the scan's directory |
|
|
42
42
|
| `import` | `IMPORTED <id>` |
|
|
@@ -53,9 +53,9 @@ evaluation states an RF layout ({ref}`stating-the-rf-layout`).
|
|
|
53
53
|
`--rf-definitions` evaluates the plugin at its default protocol under
|
|
54
54
|
`--limits`, which it then requires. `--rf-layout` follows a valid reply with the
|
|
55
55
|
RF layout of the evaluated request, its amplitudes relative to the peaks the
|
|
56
|
-
listing states. Without `--rf-definitions`, `list` depends on the plugin file
|
|
57
|
-
and the installed packages only, so its reply can be written once
|
|
58
|
-
installation and read without a call.
|
|
56
|
+
listing states. Without `--rf-definitions`, `list` depends on the plugin file,
|
|
57
|
+
its options and the installed packages only, so its reply can be written once
|
|
58
|
+
at installation and read without a call.
|
|
59
59
|
|
|
60
60
|
`--exam` names the directory of the current exam's cache, which is passed to
|
|
61
61
|
the plugin hooks that take `exam` ({ref}`exam-cache`); for such a plugin the
|
|
@@ -107,12 +107,21 @@ design_max_slew: 86.603
|
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
The lines without a prefix are keyword arguments of `pypulseqpp.Opts`, of which
|
|
110
|
-
`B0`, the field in T, is required: ppm offsets are resolved at it. The limits
|
|
111
|
-
are the `system` the plugin designs under and the checks
|
|
112
|
-
include the scanner's RF and ADC dead times, RF ringdown time and ADC sample
|
|
110
|
+
`B0`, the field in T, is required: ppm offsets are resolved at it. The limits,
|
|
111
|
+
less a design margin, are the `system` the plugin designs under, and the checks
|
|
112
|
+
hold the design to them as sent, so include the scanner's RF and ADC dead times, RF ringdown time and ADC sample
|
|
113
113
|
divisor; `pypulseqpp.Opts` sets the dead times to zero and the divisor to four
|
|
114
114
|
when they are left out.
|
|
115
115
|
|
|
116
|
+
`max_b1` is the peak B1 the transmit chain allows, in µT, or in the `b1_unit`
|
|
117
|
+
given beside it, as the scanner states it; left out, the pulses are not
|
|
118
|
+
limited. The selective and non-selective excitation and refocusing modules of
|
|
119
|
+
pypulseqpp keep their own duration while the pulse peaks within
|
|
120
|
+
`pypulseqpp.MAX_B1_DERATE` of it, and are otherwise lengthened, flip
|
|
121
|
+
angle and time-bandwidth product held, until it does; the shortest TE and TR a
|
|
122
|
+
plugin reports follow. Spectral, adiabatic, two-dimensional and multiband
|
|
123
|
+
pulses are designed as given.
|
|
124
|
+
|
|
116
125
|
`max_grad` and `max_slew` are the limits of the gradient coils, to which the
|
|
117
126
|
checks hold every physical axis. Logical axes played together add on one
|
|
118
127
|
physical axis, so under an oblique prescription a design held to `max_grad` and
|
|
@@ -126,7 +135,11 @@ scanner for the prescription's rotation:
|
|
|
126
135
|
| `design_max_slew` | Slew rate each logical axis is designed under, in the `slew_unit` of `max_slew` |
|
|
127
136
|
|
|
128
137
|
A design limit above the scanner's leaves the scanner's, and one left out is the
|
|
129
|
-
scanner's.
|
|
138
|
+
scanner's. The plugin designs under these limits derated once by
|
|
139
|
+
`pypulseqpp.apply_system_derates`: the gradient amplitude, slew rate and peak
|
|
140
|
+
B1 scaled by `pypulseqpp.MAX_GRAD_DERATE`, `MAX_SLEW_DERATE` and
|
|
141
|
+
`MAX_B1_DERATE`. The checks, the design's identity and its manifest keep the
|
|
142
|
+
limits as the scanner sent them. `validate` resolves a request under the same limits as `generate`.
|
|
130
143
|
An imported chain is not designed, and is checked against `max_grad` and
|
|
131
144
|
`max_slew` alone.
|
|
132
145
|
|
|
@@ -277,7 +290,7 @@ pulserver proxy --store DIR --port N --forward HOST:PORT [--forward-config NAME]
|
|
|
277
290
|
| `--forward` | `HOST:PORT` of the MRD server that reconstructs every series, instead of local workers |
|
|
278
291
|
| `--forward-config` | Config name sent to the `--forward` server; the series' reconstruction plugin when unset |
|
|
279
292
|
| `--dicom` | Convert each image to DICOM before it is relayed, whatever reconstructed it; for a client that reads DICOM only |
|
|
280
|
-
| `--save-data` | Directory each series is kept in
|
|
293
|
+
| `--save-data` | Directory each series is kept in, enriched; kept nowhere when unset |
|
|
281
294
|
| `--idle-timeout` | Seconds without a client after which the proxy closes, never while a series is reconstructed. Unlimited when unset |
|
|
282
295
|
| `--logfile` | File the log is appended to, together with the standard output and error of the proxy and its workers, so whatever a reconstruction plugin logs, prints or warns lands there too; standard error when unset |
|
|
283
296
|
| `--log-level` | `DEBUG`, `INFO`, `WARNING` or `ERROR`; `INFO` when unset |
|
|
@@ -304,10 +317,10 @@ place of a new reconstruction.
|
|
|
304
317
|
### Saved series
|
|
305
318
|
|
|
306
319
|
With `--save-data`, each series is also written to
|
|
307
|
-
`<save-data>/mrd_<timestamp>.h5` as the
|
|
308
|
-
|
|
309
|
-
plugin on that file
|
|
310
|
-
({ref}`series-replay`). The queue directory holds a series only until it is
|
|
320
|
+
`<save-data>/mrd_<timestamp>.h5` as the proxy reconstructs it: header and
|
|
321
|
+
acquisitions enriched, the header marked `pulserver_enriched`, each acquisition
|
|
322
|
+
as it arrives. `pulserver replay` runs a plugin on that file as it stands and
|
|
323
|
+
gives the image the proxy did ({ref}`series-replay`). The queue directory holds a series only until it is
|
|
311
324
|
reconstructed.
|
|
312
325
|
|
|
313
326
|
### Proxy lifetime
|
|
@@ -337,9 +350,9 @@ determine when it is reconstructed. The server receives a config file message
|
|
|
337
350
|
naming the series' reconstruction plugin, which a reconstruction server runs,
|
|
338
351
|
or the `--forward-config` name, such as the configuration by which a Gadgetron
|
|
339
352
|
or FIRE server selects its pipeline. The client's config text is not
|
|
340
|
-
forwarded. What the server returns is relayed to the client
|
|
341
|
-
|
|
342
|
-
naming the type.
|
|
353
|
+
forwarded. What the server returns is relayed to the client once the client's
|
|
354
|
+
stream has ended whole, as from a worker; a message type the proxy cannot read
|
|
355
|
+
ends the relay, and the client receives a `pulserver:` text naming the type.
|
|
343
356
|
|
|
344
357
|
### Sequence description
|
|
345
358
|
|