Skip to content

Revision of the System Settings Usage#160

Open
schote wants to merge 9 commits intomainfrom
sequence-io
Open

Revision of the System Settings Usage#160
schote wants to merge 9 commits intomainfrom
sequence-io

Conversation

@schote
Copy link
Owner

@schote schote commented Feb 23, 2026

Before calculating a sequence, it must be loaded to the sequence interpreter. This can be achieved either by using the from_pypulseq method or the read method of the interpreter, which is inherited from the pypulseq Sequence.
When using from_pypulseq, so far the system limits were checked and compared to the system specified in the device configuration, before all the attributes of Sequence were overwritten in SequenceProvider. Thereby also the sequence system was overwritten.

With this PR the system defined in the device configuration is considered to be fixed. A sequence, no matter if it is loaded from file or from an existing pypulseq Sequence should not touch the system configuration.

@github-actions
Copy link

github-actions bot commented Feb 23, 2026

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/console
   __init__.py10190%11
src/console/interfaces
   acquisition_data.py1232580%96–99, 110–111, 129–130, 145–148, 158–159, 188–189, 193–199, 215–216, 227, 231, 249
   acquisition_parameter.py107496%126, 163, 178, 213
   device_configuration.py53296%60, 66
   dimensions.py962277%45–46, 67–68, 71, 79, 89, 95, 101, 107, 113–115, 125–127, 137–139, 149–151
   rx_data.py861879%77–81, 89, 101, 105, 107, 122, 130–135, 143, 151, 154, 157
src/console/pulseq_interpreter
   sequence_provider.py2301394%257–258, 351–352, 463, 513–514, 583, 609–610, 626, 635, 639
src/console/spcm_control
   abstract_device.py79790%2–149
   acquisition_control.py1531530%3–360
   rx_device.py2092090%2–493
   tx_device.py1751750%2–465
src/console/spcm_control/spcm
   pyspcm.py1611610%3–295
   tools.py54540%3–128
src/console/utilities
   json_encoder.py8362%22–24
   load_configuration.py20670%18–20, 28–30
   plot.py531670%31–32, 80–98
src/console/utilities/data
   mrd_helper.py43881%37, 43, 49, 52, 60, 63, 68, 71
   write_acquisition_to_mrd.py49590%43–44, 68, 86, 91
src/console/utilities/sequences/calibration
   fid_tx_adjust.py22195%66
   se_tx_adjust.py29293%62–64
src/console/utilities/sequences/spectrometry
   fid.py15150%2–75
   se_spectrum.py25292%51, 85
src/console/utilities/sequences/tse
   tse_3d.py2427569%110–111, 113–114, 116–117, 124–125, 127–129, 131–134, 145–148, 153–156, 163–174, 191, 213–220, 226, 257, 320–337, 344–345, 412, 415–427, 535–546
TOTAL5298104980% 

Tests Skipped Failures Errors Time
192 0 💤 0 ❌ 0 🔥 29.294s ⏱️

@schote schote linked an issue Feb 23, 2026 that may be closed by this pull request
@schote schote requested review from Toreil and h3lg3 February 23, 2026 14:35
@schote schote linked an issue Feb 23, 2026 that may be closed by this pull request
@h3lg3
Copy link
Collaborator

h3lg3 commented Feb 24, 2026

Testing the branch results in

  File "C:\Users\hhert\Git-projects\nexus-console\src\console\pulseq_interpreter\sequence_provider.py", line 534, in _calculate_gradient
    self.system.gamma * 1e-3 * self.gpa_gain[output_channel] * self.grad_eff[output_channel]
  File "C:\Users\hhert\miniconda3\envs\console-env\lib\site-packages\pydantic\main.py", line 1026, in __getattr__
    raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
AttributeError: 'SystemLimits' object has no attribute 'gamma'

I guess the system.gamma is missing.

system = Opts(
    gamma=42.576e6,
)

@schote schote marked this pull request as ready for review February 25, 2026 11:45
@schote
Copy link
Owner Author

schote commented Feb 25, 2026

Testing the branch results in

  File "C:\Users\hhert\Git-projects\nexus-console\src\console\pulseq_interpreter\sequence_provider.py", line 534, in _calculate_gradient
    self.system.gamma * 1e-3 * self.gpa_gain[output_channel] * self.grad_eff[output_channel]
  File "C:\Users\hhert\miniconda3\envs\console-env\lib\site-packages\pydantic\main.py", line 1026, in __getattr__
    raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
AttributeError: 'SystemLimits' object has no attribute 'gamma'

I guess the system.gamma is missing.

system = Opts(
    gamma=42.576e6,
)

I just tested the branch on the system and was not able to reproduce this issue. Which version of pypulseq have you installed?

@h3lg3
Copy link
Collaborator

h3lg3 commented Feb 25, 2026

Could you try

# seq.system.gamma exists
print(seq.system.gamma)

seq_provider.from_pypulseq(seq)
# seq_provider.system.gamma does not exist
print(seq_provider.system.gamma)

# unroll_sequence throws error
unrolled_sequence = seq_provider.unroll_sequence(acquisition_parameter)

@schote
Copy link
Owner Author

schote commented Feb 25, 2026

Could you try

# seq.system.gamma exists
print(seq.system.gamma)

seq_provider.from_pypulseq(seq)
# seq_provider.system.gamma does not exist
print(seq_provider.system.gamma)

# unroll_sequence throws error
unrolled_sequence = seq_provider.unroll_sequence(acquisition_parameter)
image

Works with pypulseq 1.5.0 and 1.4.2

@h3lg3
Copy link
Collaborator

h3lg3 commented Mar 4, 2026

I figured out the problem here. If you initialize the seq_provider with the system_limits from system_limits: SystemLimits = load_system_limits("example_device_config.yaml") like below, then gamma is missing in seq_provider but is present in seq (seq_provider.from_pypulseq(seq)) because system_limits is missing gamma. Thats when the error is provoked.


seq = pp.Sequence(system)


seq_provider = SequenceProvider(
        gradient_efficiency=config.tx.gradient_efficiency,
        gpa_gain=config.tx.gpa_gain,
        gradient_output_limits=config.tx.channel_max_amplitude[1:],
        gradients_50ohms = config.tx.gradients_terminated_50ohm,
        rf_output_limit = config.tx.channel_max_amplitude[0],
        rf_50ohms = config.tx.rf_terminated_50ohm,
        spcm_dwell_time=1/(config.tx.sampling_rate * 1e6),
        rf_to_mvolt=config.tx.rf_to_mvolt,
        system=system_limits,
    )

seq_provider.from_pypulseq(seq)`

However, if you use system_limits.get_opts(), the PyPulseq default B0 = 1.5 is added. Is that the desired behavior? Maybe the system_limits can be extended to contain all Opts parameters?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Issue with check of system limits Explore support for Pulseq 1.5.x

2 participants