Skip to content

ENH: Add nib-roi command to crop (maybe flip) axes #947

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

Merged
merged 7 commits into from
Oct 16, 2020

Conversation

effigies
Copy link
Member

@effigies effigies commented Aug 20, 2020

Quick command to easily crop images using slice notation. Inspired by fslroi.

Features:

  1. Python slicing syntax.
  2. Scale factors and original values preserved exactly.
  3. Flips on spatial axes are permitted with a -1 step (but downsampling with other steps is not...)

Safety checks that are not there:

  1. Zero-length slices are not checked for, e.g. -i 1:1 or -j 5:6:-1.
  2. Using the same input and output file on an uncompressed image will cause a BusError as the image being read will be truncated. will avoid mmaping and is tested for.

With a basic usable tool, I'm not inclined to push further today, so I figured I'd give people a chance to comment.

@pep8speaks
Copy link

pep8speaks commented Aug 20, 2020

Hello @effigies, Thank you for updating!

Cheers! There are no style issues detected in this Pull Request. 🍻 To test for issues locally, pip install flake8 and then run flake8 nibabel.

Comment last updated at 2020-10-09 12:41:12 UTC

@codecov
Copy link

codecov bot commented Aug 20, 2020

Codecov Report

Merging #947 into master will increase coverage by 0.04%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #947      +/-   ##
==========================================
+ Coverage   91.87%   91.91%   +0.04%     
==========================================
  Files          98       99       +1     
  Lines       12451    12514      +63     
  Branches     2193     2204      +11     
==========================================
+ Hits        11439    11502      +63     
  Misses        678      678              
  Partials      334      334              
Impacted Files Coverage Δ
nibabel/cmdline/roi.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2f918b1...4623e12. Read the comment docs.

@effigies effigies added this to the 3.2.0 milestone Sep 15, 2020
@effigies
Copy link
Member Author

This could use a review. @chrispycheng any interest?

@chrispycheng
Copy link
Contributor

@effigies Sure, let me get back to you! Plate's a bit stacked ATM

@effigies
Copy link
Member Author

No worries.

Copy link
Contributor

@chrispycheng chrispycheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran the function and looks awesome! Skimmed the code and raised just one point of concern for your review. Also, figured I wouldn't rehash codecov, esp. since areas lacking coverage seem pretty insignificant.

@effigies
Copy link
Member Author

Thanks for the review. I went ahead and added tests that should cover the remaining lines.

@effigies
Copy link
Member Author

effigies commented Oct 9, 2020

The quest for coverage ended up finding an edge case. Full coverage and tests passing.

@chrispycheng Do you have time for a final review?

@chrispycheng
Copy link
Contributor

chrispycheng commented Oct 15, 2020 via email

@effigies
Copy link
Member Author

No worries. Thanks for the heads up.

Copy link
Member

@mgxd mgxd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good - few comments

print("Could not slice image. Full traceback follows.")
raise
nb.save(sliced_img, opts.out_file)
return 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed?

Suggested change
return 0

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, makes the output of calling main() identical to the exit code, though. If I change this, I think I'll need to update a test, but I can.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nbd 🤷‍♂️

parser.add_argument("-t", metavar="T1:T2", help="Start/stop along fourth axis (0-indexed)")
parser.add_argument("in_file", help="Image file to crop")
parser.add_argument("out_file", help="Output file name")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this show the help if no arguments are provided?

Suggested change
if not args:
parser.print_help()
sys.exit(1)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do at least get usage:

$ nib-roi
usage: nib-roi [-h] [--version] [-i I1:I2[:-1]] [-j J1:J2[:-1]]
               [-k K1:K2[:-1]] [-t T1:T2]
               in_file out_file
nib-roi: error: the following arguments are required: in_file, out_file
$ nib-roi --help
usage: nib-roi [-h] [--version] [-i I1:I2[:-1]] [-j J1:J2[:-1]]
               [-k K1:K2[:-1]] [-t T1:T2]
               in_file out_file

Crop images to a region of interest

positional arguments:
  in_file        Image file to crop
  out_file       Output file name

optional arguments:
  -h, --help     show this help message and exit
  --version      show program's version number and exit
  -i I1:I2[:-1]  Start/stop [flip] along first axis (0-indexed)
  -j J1:J2[:-1]  Start/stop [flip] along second axis (0-indexed)
  -k K1:K2[:-1]  Start/stop [flip] along third axis (0-indexed)
  -t T1:T2       Start/stop along fourth axis (0-indexed)

If a start or stop value is omitted, the start or end of the axis is assumed.

We don't have a terribly consistent style, to go by:

$ nib-ls; echo $?

0
$ nib-conform; echo $?
usage: nib-conform [-h] [--out-shape OUT_SHAPE OUT_SHAPE OUT_SHAPE]
                   [--voxel-size VOXEL_SIZE VOXEL_SIZE VOXEL_SIZE]
                   [--orientation ORIENTATION] [-f] [-V]
                   infile outfile
nib-conform: error: the following arguments are required: infile, outfile
2
$ nib-diff; echo $?
Traceback (most recent call last):
  File "/home/cjmarkie/anaconda3/envs/nibabel_dev/bin/nib-diff", line 11, in <module>
    load_entry_point('nibabel', 'console_scripts', 'nib-diff')()
  File "/home/cjmarkie/Projects/nipy/nibabel/nibabel/cmdline/diff.py", line 362, in main
    dtype=opts.dtype
  File "/home/cjmarkie/Projects/nipy/nibabel/nibabel/cmdline/diff.py", line 315, in diff
    assert len(files) >= 2, "Please enter at least two files"
AssertionError: Please enter at least two files
1
$ nib-tck2trk; echo $?
usage: nib-tck2trk [-h] [-f] anatomy tractogram [tractogram ...]
nib-tck2trk: error: the following arguments are required: anatomy, tractogram
2

But on the whole I think I'm okay with argparse defaults.

@effigies
Copy link
Member Author

Since none of the comments seemed blocking, I'm going to go ahead and merge. Thanks for the reviews, @chrispycheng, @mgxd!

@effigies effigies merged commit 917afab into nipy:master Oct 16, 2020
@effigies effigies deleted the enh/nib-roi branch October 16, 2020 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants