-
Notifications
You must be signed in to change notification settings - Fork 0
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
Deepro dev #1
Deepro dev #1
Conversation
…s to eval_net_motion_corruption.py for 2D motion corruption
…motion_corruption.py
…just be modifying build_recon_val_laoder
…anslational motion corruption
…ngle, translation, nshots, and trajectory as paramters
…ode is untested/undebugged
meddlr/data/build.py
Outdated
angle: float = 0, | ||
translation: float = 0, | ||
nshots: int = 0, | ||
trajectory: str = "blocked", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we want to avoid taking in too many arguments - consider passing in a data_transform
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I pass in just a data_transform as a parameter (for instance like MotionDataTransform), how would I pass in the parameters for angle, translation, nshots, and trajectory into the MotionDataTransform? Thanks, Deepro.
meddlr/data/transforms/2D_motion.py
Outdated
This module is responsible for simulating different motion artifacts. | ||
""" | ||
|
||
def __init__(self, nshots, angle, translate, trajectory, seed=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add type annotations. For example nshots: int
meddlr/data/transforms/2D_motion.py
Outdated
This should be equivalent to ceil(phase_encode_dim / | ||
echo_train_length). | ||
angle : The (min, max) angle for rotation. Values should be in | ||
degrees and should be >=-180, <=180. Use 'None' to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use range notation instead [-180, 180]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this can be None
, make sure it is listed as an optional variable: angle: Optional[Tuple[int, int]]
. Given that it is optional, it should default to None
meddlr/data/transforms/2D_motion.py
Outdated
translate: The fraction of (height, width) to translate. | ||
e.g. 0.1 => 10% of the corresponding dimension. | ||
So (0.1, 0.2) => 10% of height, 20% of width. | ||
Use 'None' to ignore translation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment for angle
meddlr/data/transforms/2D_motion.py
Outdated
This function supports two trajectories: | ||
- 'blocked' : Where each shot corresponds to a consecutive block of | ||
kspace. (e.g. 1 1 2 2 3 3) | ||
- 'interleaved' : Where shots are interleaved (e.g. 1 2 3 1 2 3) | ||
|
||
We assume the phase encode direction is left to right (i.e. along | ||
width dimesion). | ||
|
||
TODO: Add support for sensitivity maps. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these comments don't apply for this function - move them to the class docstring level
meddlr/data/transforms/transform.py
Outdated
add_motion: bool = False, | ||
angle: float = 0, | ||
translation: float = 0, | ||
nshots: int = 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is a default value of 0
ever valid? if not, set it to None
and raise a ValueError if it is not set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ad12 Should this ValueError be raised if a parameter is set to None? Sorry, just trying to better understand. I added an Optional to the angle and translation parameters for the motion corruption function, so the function can handle None parameters for angle and translation right? So, would I still raise that ValueError? Or do I raise it for something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would nshots be checked to see if it was set? And thus would that raise a ValueError? Also, would the type annotation for nshots in this function be just nshots: int? Thanks, Deepro.
@@ -364,3 +365,211 @@ def __call__(self, kspace, maps, target, fname, slice_id, is_fixed, acceleration | |||
target = target.squeeze(0) | |||
|
|||
return masked_kspace, maps, target, mean, std, norm | |||
|
|||
|
|||
class MotionDataTransform: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are only going to use this transform for inference right now - only keep the logic that is relevant when is_test=True
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should something be done to handle for when is_test is False? Or is that not necessary for now? Thanks.
meddlr/data/transforms/transform.py
Outdated
def _call_augmentor( | ||
self, kspace, maps, target, fname, slice_id, is_fixed, acceleration: int = None | ||
): | ||
assert not self._is_test, "Augmentor is not supported with testing yet" | ||
|
||
# Convert everything from numpy arrays to tensors | ||
kspace = cplx.to_tensor(kspace).unsqueeze(0) | ||
maps = cplx.to_tensor(maps).unsqueeze(0) | ||
target_init = cplx.to_tensor(target).unsqueeze(0) | ||
target = ( | ||
torch.complex(target_init, torch.zeros_like(target_init)).unsqueeze(-1) | ||
if not torch.is_complex(target_init) | ||
else target_init | ||
) # handle rss vs. sensitivity-integrated | ||
norm = torch.sqrt(torch.mean(cplx.abs(target) ** 2)) | ||
|
||
seed = sum(tuple(map(ord, fname))) if self._is_test or is_fixed else None # noqa | ||
mask_gen = partial( | ||
self._subsampler.__call__, mode="2D", seed=seed, acceleration=acceleration | ||
) | ||
|
||
out, _, _ = self.augmentor( | ||
kspace, | ||
maps=maps, | ||
target=target, | ||
normalizer=self._normalizer, | ||
mask_gen=mask_gen, | ||
skip_tfm=is_fixed, # Skip augmentations for unsupervised scans. | ||
) | ||
masked_kspace = out["kspace"] | ||
maps = out["maps"] | ||
target = out["target"] | ||
mean = out["mean"] | ||
std = out["std"] | ||
|
||
# Get rid of batch dimension... | ||
masked_kspace = masked_kspace.squeeze(0) | ||
maps = maps.squeeze(0) | ||
target = target.squeeze(0) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dont think you need this function for your transform class
meddlr/data/transforms/transform.py
Outdated
add_motion = self.add_motion and ( | ||
self._is_test or (not is_fixed and self.rng.uniform() < self.p_motion) | ||
) | ||
if add_motion: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
motion simulation should happen before the undersampling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where should the noise simulation go? Before or after the undersampling? Thanks, Deepro.
Also make sure to run the linter and formatter - run |
… for MotionDataTransform to form an instance and pass it through the above stated function.
Wrote eval_net_motion.py (which is a edited copy of eval_net.py) to run inference on test set scans with 2D motion corruption via the methodology outlined in previous Google Colabs. To do this, motion sweep values were removed from eval_net_motion.py and build_recon_val_loader was modified to induce 2D Motion Corruption. This was done by modifying the build_recon_val_loader function in meddlr/data/build.py by adding angle, translation, nshots, and trajectory parameters and by replacing DataTransform with a newly made MotionDataTransform that takes in the angle, translation, nshots, and trajectory values specified in the parameters. MotionDataTransform is written in meddlr/data/transforms/transform.py and copies much of the original DataTransform. This biggest and most important change is the replacement of MotionModel with MotionModel2D, which takes in nshots, angle, translation, and trajectory values specified. MotionModel2D conducts the 2D Motion Corruption and is written in meddlr/data/transforms/2D_motion.py. It copies largely from MotionModel but simulates 2D motion for multi-shot Cartesian MRI instead.
Notes:
This is completely untested and undebugged code.
Please let me know what you think / what I need to fix / what I could improve. In addition, let me know if there are any places that are confusing and that need better commenting, or if there are areas that need better documentation.
Thanks,
Deepro.