Skip to content

Conversation

@Stockless
Copy link
Collaborator

This PR addresses issue #555 by adding support for reading Pulseq files in version 1.5.0.

@Stockless Stockless self-assigned this Sep 17, 2025
@Stockless Stockless marked this pull request as draft September 17, 2025 15:40
Copy link
Member

@cncastillo cncastillo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use three correct logic so pulseq 1.4 still works. No need to pass the version into the get_X functions, you can just check the input length of the library.

@codecov
Copy link

codecov bot commented Sep 23, 2025

Codecov Report

❌ Patch coverage is 86.32075% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.01%. Comparing base (b5c63a9) to head (f9636ae).

Files with missing lines Patch % Lines
KomaMRIFiles/src/Sequence/Pulseq.jl 90.27% 18 Missing ⚠️
KomaMRIBase/src/datatypes/sequence/RF.jl 46.66% 8 Missing ⚠️
KomaMRIBase/src/datatypes/Sequence.jl 57.14% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #614      +/-   ##
==========================================
- Coverage   90.14%   90.01%   -0.14%     
==========================================
  Files          57       57              
  Lines        3228     3366     +138     
==========================================
+ Hits         2910     3030     +120     
- Misses        318      336      +18     
Flag Coverage Δ
base 88.85% <59.25%> (-0.24%) ⬇️
core 89.73% <ø> (ø)
files 93.00% <90.27%> (-1.05%) ⬇️
komamri 88.21% <ø> (ø)
plots 90.90% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
KomaMRIBase/src/KomaMRIBase.jl 100.00% <ø> (ø)
KomaMRIBase/src/datatypes/sequence/Grad.jl 94.54% <100.00%> (+5.15%) ⬆️
KomaMRIFiles/src/KomaMRIFiles.jl 100.00% <ø> (ø)
KomaMRIBase/src/datatypes/Sequence.jl 92.15% <57.14%> (-0.04%) ⬇️
KomaMRIBase/src/datatypes/sequence/RF.jl 73.58% <46.66%> (-10.09%) ⬇️
KomaMRIFiles/src/Sequence/Pulseq.jl 92.53% <90.27%> (-1.31%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cncastillo
Copy link
Member

cncastillo commented Oct 6, 2025

(1) Update get_events to add compat_helper copy: https://github.com/pulseq/pulseq/blob/master/matlab/%2Bmr/%40Sequence/read.m#L520. get_events cannot be hardcoded for the RF case

(2) Test with reader with (take inspiration from https://juliahealth.org/KomaMRI.jl/dev/explanation/5-seq-events/):

  • arbitrary gradients
  • time shaped gradients
  • trapezoidal gradients
  • arbitrary rfs
  • time shaped rfs
  • block rfs

@Stockless can you give use the MATLAB files you were using for the tests?

(3) Modify to consider new RF uses, to calculate k-space correctly (not guess RF use by > 90.0):

  • get_RF_types() → 1st
  • get_RF_center() → 2nd
  • get_Mk() → 3rd

If use is Undefined(), keep using the current method; otherwise, use the provided value.

If center is not defined (i.e., == 0.0), keep the current method; otherwise, use the provided value.

@gsahonero
Copy link
Member

@pvillacorta , @cncastillo mentioned you are interested in working this PR out. I want to get it done too. Let's meet to sort out the efforts?

@pvillacorta
Copy link
Collaborator

@pvillacorta , @cncastillo mentioned you are interested in working this PR out. I want to get it done too. Let's meet to sort out the efforts?

Yes! Let's join forces :)

@cncastillo
Copy link
Member

@pvillacorta @gsahonero do you guys want to plan a meeting to push this?

@pvillacorta
Copy link
Collaborator

@gsahonero and I are meeting this thursday at 4pm (spanish time). I hope we can plan how to finish this PR and the one for writing Pulseq.

@pvillacorta pvillacorta changed the title Read pulseq 1.5.0 Read/Write Pulseq 1.5.0 Nov 13, 2025
@pvillacorta pvillacorta changed the title Read/Write Pulseq 1.5.0 ReadPulseq 1.5.0 Nov 13, 2025
@pvillacorta pvillacorta changed the title ReadPulseq 1.5.0 Read Pulseq 1.5.0 Nov 13, 2025
- Improve Grad and RF constructors for improved readability and error handling.
- Fix documentation typo about `A` and `T` vectors
- Add SHA and MD5 packages for hash generation/verification
- Improve signature generation/verification
- Add missing signature-related functions
- Simplify `read_RF` and `read_ADC` in the same way as `read_Grad`
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KomaMRI Benchmarks

Benchmark suite Current: f9636ae Previous: b5c63a9 Ratio
MRI Lab/Bloch/CPU/2 thread(s) 336553685 ns 340960290 ns 0.99
MRI Lab/Bloch/CPU/4 thread(s) 278804437 ns 272489189 ns 1.02
MRI Lab/Bloch/CPU/8 thread(s) 195474224 ns 212102146.5 ns 0.92
MRI Lab/Bloch/CPU/1 thread(s) 551618997 ns 553123722 ns 1.00
MRI Lab/Bloch/GPU/CUDA 21397402 ns 21705981 ns 0.99
MRI Lab/Bloch/GPU/oneAPI 79630717 ns 79470326.5 ns 1.00
MRI Lab/Bloch/GPU/Metal 93588667 ns 95738917 ns 0.98
MRI Lab/Bloch/GPU/AMDGPU 26134234 ns 26055313 ns 1.00
Slice Selection 3D/Bloch/CPU/2 thread(s) 1587014667 ns 1588926486.5 ns 1.00
Slice Selection 3D/Bloch/CPU/4 thread(s) 888311171.5 ns 886294756.5 ns 1.00
Slice Selection 3D/Bloch/CPU/8 thread(s) 550997453 ns 561392306 ns 0.98
Slice Selection 3D/Bloch/CPU/1 thread(s) 3034738658 ns 3027587378 ns 1.00
Slice Selection 3D/Bloch/GPU/CUDA 33029749.5 ns 32637155 ns 1.01
Slice Selection 3D/Bloch/GPU/oneAPI 125225827 ns 124598595.5 ns 1.01
Slice Selection 3D/Bloch/GPU/Metal 110781917 ns 112846167 ns 0.98
Slice Selection 3D/Bloch/GPU/AMDGPU 34025625.5 ns 34082841 ns 1.00

This comment was automatically generated by workflow using github-action-benchmark.

- Fix contructors, auxiliary functions and tests
- Restore previous `read_Grads`, `read_RF`, and `read_ADC` implementations
- Improve signature handling
@pvillacorta
Copy link
Collaborator

Pulseq files from KomaMRIFiles/test/test_files/pulseq_read_comparison must ve reviewed, since I have not been able to retrieve their signature. For the moment, I have just added a warning when the retrieved signature and the expected one do not coincide (obviously, the ideal case would be to throw an error, but tests would not pass for pulseq_read_comparison).

- Do not use recursive constructors
- Come back to `get_RF_use_from_char(::Val{Char})`
- Remove `get_RF_use_from_char`from RF constructor
- Export RFUses
@pvillacorta
Copy link
Collaborator

I will start with tests tomorrow, with this in mind:

(2) Test with reader with (take inspiration from https://juliahealth.org/KomaMRI.jl/dev/explanation/5-seq-events/):
- arbitrary gradients
- time shaped gradients
- trapezoidal gradients
- arbitrary rfs
- time shaped rfs
- block rfs

I will also try to test the reader with .seq files made with write_seq (see this branch, which is sync with this PR and for the moment is in my Koma fork). Once this PR is merged, I will create a new one with the write functions.

@pvillacorta
Copy link
Collaborator

pvillacorta commented Nov 21, 2025

For tests, I think we need three complementary testing strategies, and all of them are important for proper validation:

1. Round-trip test inside KomaMRI (for both read_seq and write_pulseq)

  • Take a Koma Sequence (call it s1), run write_seq to produce a .seq file, then load it back with read_seq to get s2, and finally check that s1 == s2.
    This verifies internal consistency between writing and reading.
    However, it might not catch certain compatibility issues with other Pulseq interpreters: errors in write_seq could be “undone” by read_seq, so a strict s1 == s2 check doesn’t necessarily guarantee that the generated .seq file fully conforms to the Pulseq 1.5 standard.

2. Cross-checking against sequences generated by MATLAB Pulseq and PyPulseq

  • For write_seq: Generate equivalent sequences using the MATLAB and Python implementations of Pulseq, then compare them with the ones generated by KomaMRI.
  • For read_seq:

3.Ensuring MATLAB and PyPulseq can read KomaMRI-generated sequences (write_seq tests)

  • Another angle is to test interoperability: generate sequences with KomaMRI, load them in MATLAB Pulseq and PyPulseq, and compare their internal representations or waveform plots.
    If both interpreters can parse and reproduce the expected plots, it’s a strong indication that the KomaMRI writer produces fully standard-compliant .seq files.

Together, these three kinds of tests give good coverage:
(1) internal correctness, (2) external consistency with other implementations, and (3) practical interoperability with the broader Pulseq ecosystem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants