Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
paquiteau committed Feb 3, 2025
2 parents 3b71a97 + b0fa0e7 commit bf18a00
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/cli-conf/scenario2-2d.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defaults:
- handlers:
- activation-block
- sampler:
- stack-of-spiral
- rotated-stack-of-spiral
- reconstructors:
- adjoint
#- sequential
Expand Down Expand Up @@ -35,6 +35,7 @@ handlers:
block_on: 20 # seconds
block_off: 20 #seconds
duration: 360 # seconds
delta_r2s: 1000 # millisecond^-1

sampler:
stack-of-spiral:
Expand All @@ -43,6 +44,13 @@ sampler:
nb_revolutions: 10
constant: true
spiral_name: "galilean"
rotated-stack-of-spiral:
acsz: 1
accelz: 1
nb_revolutions: 10
constant: false
spiral_name: "galilean"
rotate_frame_angle: 0

engine:
n_jobs: 1
Expand Down
2 changes: 2 additions & 0 deletions src/snake/core/sampling/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .samplers import (
EPI3dAcquisitionSampler,
StackOfSpiralSampler,
RotatedStackOfSpiralSampler,
NonCartesianAcquisitionSampler,
EVI3dAcquisitionSampler,
LoadTrajectorySampler,
Expand All @@ -15,5 +16,6 @@
"EPI3dAcquisitionSampler",
"EVI3dAcquisitionSampler",
"StackOfSpiralSampler",
"RotatedStackOfSpiralSampler",
"NonCartesianAcquisitionSampler",
]
44 changes: 44 additions & 0 deletions src/snake/core/sampling/samplers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
stack_spiral_factory,
stacked_epi_factory,
evi_factory,
rotate_trajectory,
)
from snake.mrd_utils.utils import ACQ
from snake._meta import batched, EnvConfig
from mrinufft.io import read_trajectory
from collections.abc import Generator


class NonCartesianAcquisitionSampler(BaseSampler):
Expand Down Expand Up @@ -276,6 +278,48 @@ def _single_frame(self, sim_conf: SimConfig) -> NDArray:
)


class RotatedStackOfSpiralSampler(StackOfSpiralSampler):
"""
Spiral 2D Acquisition Handler to generate k-space data.
Parameters
----------
rotate_frame_angle: AngleRotation | int
Angle of rotation of the frame.
frame_index: int
Index of the frame.
**kwargs:
Extra arguments (smaps, n_jobs, backend etc...)
"""

__sampler_name__ = "rotated-stack-of-spiral"
rotate_frame_angle: AngleRotation | int = 0
frame_index: int = 0

def fix_angle_rotation(
self, frame: Generator[np.ndarray, None, None], angle: AngleRotation | float = 0
) -> Generator[np.ndarray, None, None]:
"""Rotate the trajectory by a given angle."""
for traj in frame:
yield from rotate_trajectory((x for x in [traj]), angle)

def get_next_frame(self, sim_conf: SimConfig) -> NDArray:
"""Generate the next rotated frame."""
base_frame = self._single_frame(sim_conf)
if self.constant or self.rotate_frame_angle == 0:
return base_frame
else:
self.frame_index += 1
rotate_frame_angle = np.pi * (self.rotate_frame_angle / 180)
base_frame_gen = (traj[None, ...] for traj in base_frame)
rotated_frame = self.fix_angle_rotation(
base_frame_gen, float(rotate_frame_angle * self.frame_index)
)
return np.concatenate(
[traj.astype(np.float32) for traj in rotated_frame], axis=0
)


class EPI3dAcquisitionSampler(BaseSampler):
"""Sampling pattern for EPI-3D."""

Expand Down

0 comments on commit bf18a00

Please sign in to comment.