-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Various bug fixes, features, and cleanups #159
Conversation
- Also fixes a few functions that could modify the `system` object
…er Siemens scanners)
… of assuming a linear ordering.
- Removed unused imports from `sequence.py` - Updated type signature of `Sequence.adc_times` - Fixed bug in `Sequence.adc_times` that would give an error if no ADC events are in the sequence - `Sequence.read` now clears the block cache
…get_gradients` - Added `time_range` option to `get_gradients` - Added `time_range` option to `calculate_pns`
- Removed `keys` field from `event_lib` (always ended up as a keys[k] = k mapping) - Ignored `old_data` in `event_lib.update` (`old_data` can just be looked up in the `data` field)
- Moved `block_cache` resets so it always remains valid - Added `block_cache` reset for `rf_library` updates. - Fixed small issue where `grad.last` would not be restored correctly - Updated `grad_library.update_data` call because `old_data` is no longer needed
@FrankZijlstra I have some questions:
|
The check is only there to calculate
The problem is that the calculation can depend on the previous block, and it needs the gradients definitions and waveforms, which aren't necessarily loaded once you get to the [BLOCKS] section. I think the alternative is to look only for arbitrary waveforms/extended trapezoids in the gradients after everything is read, then look up which blocks they're used in, then do the first/last calculations. But it's not a major issue, the current implementation just makes reading a bit slower. The bigger issue I found is that setting first/last during reading is not always consistent with creating a sequence. For example, The first/last values of these gradients are only relevant for functions like
You might be right on this one, I hadn't realized the cached blocks could be edited in-place (should check that this is not happening anywhere else in the codebase). I'll go over it another time to see if this change was necessary.
I think you're referring to this?
The reason this is necessary is because |
Thanks for the detailed explanations! There is a conflict due to me merging your previous PR, so we need to solve that, too. I also checked the |
…cation of the cache to set first/last values
… to match behaviour of `set_block`
I updated the block cache code, now it avoids the new Added a few more small things:
|
@FrankZijlstra GitHub says there are still conflicts, so I could not merge. |
That's weird, for me it says "This branch has no conflicts with the base branch". |
Bug fixes:
Sequence.adc_times
gave an error when no ADC events are in the sequence.Sequence.read
now clears the block cache (e.g. if there already was a sequence loaded,read
overwrites it, and should clear the block cache), and makes sure the block cache remains valid while filling ingrad.first
andgrad.last
.Sequence.read
wheregrad.last
would not be filled in correctly (a larger issue with restoring these values remains, added a TODO note).split_gradient
, which didn't work before.block_events
, which fixes Interpretation of block ID and block order pulseq/pulseq#40. One small issue remains inset_block
, where finding the previous block would be expensive, given how often this function is called...Features:
asc_to_hw
(only available for newer scanners)time_range
parameters forcalculate_pns
andget_gradients
Opts
(usingopts.set_as_default
), similar to pulseq/pulseq@6138cc0. This saves having to pass a system object if it is always the same (see example below).Cleanups:
sequence.py
Sequence.adc_times
calculate_pns
now uses piecewise-polynomial gradients fromget_gradients
set_block
because it always passed (first and last amplitudes are always 0)keys
field fromevent_lib
because it was alwayskeys[k] = k
, and updated all references to this field to usedata
ordata.keys()
instead.event_lib.update
now ignores theold_data
argument because it was not needed in the first place (old data was just used to update thekeymap
field and can just be looked up indata
)Notes:
Opts
is as we would want it to be:Gives the same result as:
Compared to the implementation in Matlab:
update_data
inread
: Any modification of any event library needs to clear the cache for all blocks that use the changed event. I think that users should not access and change these libraries themselves, or it should be documented that the block cache needs to be cleared when doing so (and using functions that iterate over all blocks afterwards, e.g.calculate_kspace
). For event libraries to do this any time an update happens (insert
can in theory also overwrite data), it would need to access theSequence
object and it might incur a performance hit.read
accesses all blocks usingget_block
, just to update the first/last values of arbitrary gradients.