pypulseq icon indicating copy to clipboard operation
pypulseq copied to clipboard

Fixes timing of write_gre sequence.

Open h3lg3 opened this issue 9 months ago • 3 comments

The GRE sequence https://github.com/imr-framework/pypulseq/blob/0398b12bc1d86c1997ed5ad34242a22cc95003bd/examples/scripts/write_gre.py has a small TE/TR timing error if the rf.ringdown_time gets longer than the gz.fall_time. Taking the max() of both fixes the issue which becomes relevant for longer ringdown times or thick slices.

h3lg3 avatar Feb 28 '25 15:02 h3lg3

Coverage

Coverage Report
FileStmtsMissCoverMissing
/home/runner/.local/lib/python3.12/site-packages/pypulseq
   add_gradients.py1235159%44, 52, 58, 61, 75–86, 92, 120–123, 130–131, 150, 157, 162–241
   add_ramps.py36360%1–89
   align.py35489%41, 45, 69, 73
   calc_duration.py25196%37
   calc_ramp.py2182142%45–353
   calc_rf_bandwidth.py272026%37–59, 63–67
   check_timing.py872769%72, 76, 101, 194, 201, 211–255
   compress_shape.py30197%28
   convert.py40880%42, 48, 66, 72–73, 82, 88–89
   event_lib.py961485%6–9, 48–51, 70–71, 205–210
   make_adc.py921386%63, 72–76, 79, 128, 131, 135, 141, 145, 184, 186, 188, 196
   make_adiabatic_pulse.py1293970%196–200, 217–221, 229–230, 253, 259, 328–347, 451–460, 498–506
   make_arbitrary_grad.py37781%68, 71, 74, 77, 81, 83, 103
   make_arbitrary_rf.py665517%83–160
   make_block_pulse.py46393%112–116, 119
   make_delay.py9189%27
   make_digital_output_pulse.py16288%39, 47
   make_extended_trapezoid.py561279%67, 70, 76, 82, 85, 88, 91, 94, 116, 134, 136, 139
   make_extended_trapezoid_area.py93397%52, 227, 230
   make_gauss_pulse.py692071%127–131, 134–158, 165, 168
   make_label.py19384%36, 41, 43
   make_sigpy_pulse.py1163173%12–13, 112, 115, 119, 154, 157–161, 165, 168–169, 172–173, 188, 195, 200, 212, 215, 240–250, 264, 267, 297–307
   make_sinc_pulse.py681085%94, 100, 127–131, 135, 138–139, 142–143, 165
   make_trapezoid.py111794%177, 190, 196, 214, 232, 237, 255
   make_trigger.py16288%44, 52
   opts.py66986%78, 83, 102, 142, 166–170
   points_to_waveform.py9189%27
   rotate.py691480%15, 55, 66–69, 85–90, 112, 119–120
   scale_grad.py14471%28–30, 33
   sigpy_pulse_opts.py26773%34–41
   split_gradient.py393121%46–103
   split_gradient_at.py702761%63–90, 110, 114, 118–120, 154–156
   traj_to_grad.py13931%26–40
/home/runner/.local/lib/python3.12/site-packages/pypulseq/SAR
   SAR_calc.py1139813%33–40, 55–62, 89–108, 129–132, 168–212, 242–246, 264–306
/home/runner/.local/lib/python3.12/site-packages/pypulseq/Sequence
   block.py3683291%59, 62, 70, 76, 91, 99, 105, 116, 119, 122, 130, 135, 144, 196, 245, 249, 265, 305–308, 337–338, 404, 410, 430, 499, 535, 541, 568, 606, 640
   calc_grad_spectrum.py81766%68–190
   calc_pns.py403122%45–96
   ext_test_report.py1401192%23, 58, 61, 135, 227–233
   install.py754244%31, 52, 69, 71, 112–131, 148, 181–184, 200–212, 254–278
   parula.py4250%19–86
   read_seq.py3126878%42–43, 90, 93, 105, 110, 116, 123, 132, 141, 146, 149, 157–159, 192, 197, 205–254, 284–287, 302–303, 332–349, 412, 415, 450, 458, 532, 574–578
   sequence.py72321770%11–14, 101–111, 132–145, 183, 248–251, 292, 319, 336, 384, 412, 439–444, 481, 497, 588, 610, 651–654, 708, 740, 751–752, 758, 769, 775, 777, 785, 818–826, 847–869, 912, 914, 917, 943–944, 947–950, 986–996, 1034–1035, 1071–1072, 1098, 1104, 1107, 1144, 1265–1278, 1301, 1329, 1351–1353, 1374, 1405, 1416–1429, 1441–1452, 1498–1499, 1508–1526, 1550, 1580–1588, 1620–1730, 1759, 1773–1783, 1795
   write_seq.py172895%41, 65, 68–75
/home/runner/.local/lib/python3.12/site-packages/pypulseq/utils
   cumsum.py14193%17
   safe_pns_prediction.py12611310%50–87, 102–189, 197–214, 222, 244–250, 279–286, 310–336, 344–383, 396–411, 415
   tracing.py16662%33–34, 42, 54–55, 75
/home/runner/.local/lib/python3.12/site-packages/pypulseq/utils/siemens
   asc_to_hw.py58539%21–28, 48–106
   readasc.py48456%25–100
TOTAL4358148966% 

Tests Skipped Failures Errors Time
1285 18 :zzz: 0 :x: 0 :fire: 2m 51s :stopwatch:

github-actions[bot] avatar Feb 28 '25 15:02 github-actions[bot]

Going from the GRE sequence I wrote for https://github.com/pulseq/MR-Physics-with-Pulseq/, the correct delay calculation should be:

delay_TE = (
    math.ceil(
        (
            TE
            - (pp.calc_duration(gz, rf) - pp.calc_rf_center(rf)[0] - rf.delay)
            - pp.calc_duration(gx_pre)
            - pp.calc_duration(gx) / 2
            - pp.eps
        )
        / seq.grad_raster_time
    )
    * seq.grad_raster_time
)

This should fix your issue, and it does not assume that the center of the RF pulse is in the center of the waveform. seq.test_report() is accurate in reporting TE, so any errors with the nominal TE should show up there.

I had meant to update the example sequences based on the "clean" ones we developed for that course, but I never got around to it. This issue almost certainly exists in other examples.

FrankZijlstra avatar Apr 11 '25 20:04 FrankZijlstra

I adopted your proposed change. It seems that previously a rounding issue led to a delay_TE of 82 ms. Now it is 81 ms. Therefore the reference seq file for testing in '\tests\expected_output' needs to be updated.

h3lg3 avatar Apr 14 '25 12:04 h3lg3