-
Notifications
You must be signed in to change notification settings - Fork 4
TST: Add back CLI main entry point testing #106
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
base: main
Are you sure you want to change the base?
TST: Add back CLI main entry point testing #106
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #106 +/- ##
==========================================
+ Coverage 71.35% 74.15% +2.80%
==========================================
Files 23 23
Lines 1138 1153 +15
Branches 139 140 +1
==========================================
+ Hits 812 855 +43
+ Misses 283 249 -34
- Partials 43 49 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
9365f22
to
55fd2cd
Compare
@oesteban Not sure whether you want to add more testing to this now or whether that can be left for future work. |
I moved that test to the parser (it felt more appropriate): Lines 103 to 127 in e488df2
Rather than testing the CLI, what's missing is separating the parsing from the "main" function. That way, we will be able to offer that is usable to other libraries, as opposed to the current implementation that includes the parsing in the begining of the function. |
I see. My bad. And we do not want to keep the following?
So you mean changing nifreeze/src/nifreeze/cli/run.py Lines 32 to 42 in e488df2
to?
I guess we also want to test running the CLI with actual data. |
Pinging @oesteban re #106 (comment). |
b052875
to
9def891
Compare
dataset.to_filename(output_path) | ||
output_h5_filename = Path(Path(args.input_file).name).stem + ".h5" | ||
output_h5_path: Path = Path(args.output_dir) / output_h5_filename | ||
dataset.to_filename(output_h5_path) |
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.
Although having an HDF5 file as input seems the best way for testing,
nifreeze/src/nifreeze/cli/parser.py
Line 68 in 94f6d27
help="Path to the HDF5 file containing the original 4D data.", |
In the mid-term we will want to accept NIfTI files. So the above will need to change. This will need to be added to testing. The above is especially apparent in
https://github.com/nipreps/nifreeze/pull/106/files#diff-240d2e4cff5653f9b0b21aaf6d06a74165c1b72f21c0717735d5c26b41bd52c6R178
where the test loads an HDF5 file that has already gradient information, but the test reads the same/other gradient data files for the sake of testing.
To be addressed in a separate PR.
# Define smoke run method | ||
def smoke_estimator_run(self, dataset, **kwargs): | ||
called["dataset"] = dataset | ||
called["kwargs"] = kwargs |
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 do not know if a better/more pythonic way of monkeypatching can be proposed. I'd be glad to have some suggestions.
3826b90
to
ff2635d
Compare
estimator: Estimator = Estimator( | ||
_model.lower().replace("single", ""), | ||
_model, | ||
prev=prev_model, | ||
single_fit=single_fit, | ||
model_kwargs=model_kwargs, |
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.
The estimator accepts other keyword arguments:
nifreeze/src/nifreeze/estimator.py
Line 84 in 94f6d27
**kwargs, |
To be fixed in a separate PR.
The above comments (except for the monkeypatching question) are left for the records and for separate/future PRs. Would be grateful if this could be reviewed and potentially merged soon unless I got it wrong. |
ff2635d
to
50a02ac
Compare
"models", | ||
[ | ||
"dti", | ||
"dki", |
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.
Did not include averagedwi
:
nifreeze/src/nifreeze/model/base.py
Line 61 in 7cfc148
if model.lower() in ("avg", "average", "mean"): |
because I am testing here the
_model_class
property:https://github.com/nipreps/nifreeze/pull/106/files#diff-240d2e4cff5653f9b0b21aaf6d06a74165c1b72f21c0717735d5c26b41bd52c6R251
which AverageDWIModel
does not have.
The TrivialModel
and ExpectationModel
(to be done in a separate function) were not added due to the same reason.
Maybe some other property could be tested and this function be refactored. To be done in a separate PR.
Slightly related, even if an S0
model is mentioned in
nifreeze/src/nifreeze/model/base.py
Line 47 in 7cfc148
Options: ``"DTI"``, ``"DKI"``, ``"S0"``, ``"AverageDWI"`` |
We'll need to add PET
as well eventually. This list should be defined at a single place, IMO.
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.
A few nit picks
Fix output file in `NiFreeze` entry point function: the input file is expected to be an HDF5 currently, but the serialization of the output is done through the `to_nifti` method, which serializes to `NIfTI` format. Since the extension of the input file is not changed, the method fails to serialized the output data. Fixes: ``` E nibabel.filename_parser.TypesFilenamesError: File extension ".h5" was not in expected list: ['.nii'] ``` raised while adding CLI main entry point testing. Add CLI main entry point testing: the original contents were transferred to `test_parser.py` across commits 0aaacda, b52f052 and f9bbcc6 as they belonged to the `parser` module. The CLI main entry point has been lacking proper testing since the origin. This patch set: - Reintroduces the `test_main.py` test file to test the CLI main entry point exclusively, leaving testing the parser to `test_parser.py`. - Moves the `test_help` function to `test_main.py` as it strictly tests the main call, not the parser logic. - Adds a smoke test to check that the main function is called and output files are written as evidence that the body of the function is executed correctly without actually running the estimation process (it is monkey patched in the test). - Fixes the aforementioned bug.
Make the generated random brain mask be of boolean type. Convert it to unsigned integer type for practical purposes, as `nibabel` does not support boolean types when serializing data. Fixes: ``` self._S0 = np.full( self._data_mask.sum(), > np.round(np.percentile(dataset.dataobj[self._data_mask, ...], 98)), ) E IndexError: arrays used as indices must be of integer (or boolean) type src/nifreeze/model/dmri.py:94: IndexError ``` raised for example in: https://github.com/nipreps/nifreeze/actions/runs/15654840868/job/44104507991?pr=106#step:11:712 Inadvertently introduced in commit 63e6f37.
cdd6374
to
e828e3f
Compare
Refactor the parser module: - Refactor the parsing logic from the CLI main entry point to a new `parse_args` function. In doing so, `build_parser` becomes a function that is intended to stay private in the `parser` module and the only function that is called from `main` is `parse_args`. This allows to confine the complexity of the parsing logic in the `parser` module, and makes the main function more lightweight, and less susceptible to changes derived from code refactoring. - Return an extra keyword argument parameter in `parse_args` in anticipation of forwarding them to the estimator. - Rename the `test_parser` function to `test_parser_extended`, parameterize it, and check that all input arguments are correctly processed to the destination names. - Add the necessary tests to check the parser module. Most notably, add tests to ensure that single fit models are proccessed correctly, that DWI data files are processed correctly, and that DWI models and the estimator can be instantiated correctly with the information provided by the parser (as an evidence that they can be instantiated in the main function following that rationale). Add the `hcph_multishell.txt` gradient file to the testing data suite so that it can be used to test the use of gradient data formatted in such way. The file was created reading the existing `hcph_multishell.bval` and `hcph_multishell.bvec` files as text files and simply stacking them vertically, with a maximum of 6 decimal places.
Prefer `argv` over `args` as the name of the arguments of the parser, and use `args` to name the values returned by the parser. Increases consistency with what the naming used by the argument parsing function and the rest of the test functions.
e828e3f
to
258764c
Compare
Ready to be merged. Improvements can come in separate PRs. |
NiFreeze
entry point functionargv
as the name of the arguments of the parserFixes #101.