-
Notifications
You must be signed in to change notification settings - Fork 5
ENH: Validate PET data objects' attributes at instantiation #336
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?
Conversation
|
Depends on PR #335. |
e094509 to
a548cbc
Compare
a548cbc to
96e916b
Compare
|
@mnoergaard While working on this I've realized that as things stand now on
I think that answer will allow me to refactor this properly and avoid inconsistencies. Thanks. |
@jhlegarreta - that is correct! Thanks. |
745e408 to
bc7617e
Compare
|
@mnoergaard Please, see if the refactoring for the PET data class instantiation and |
803b020 to
1eae4b2
Compare
|
Pending to do an additional refactoring (in a separate commit) to stick to the convention adopted for dMRI data to split the |
ffe563c to
37ed54c
Compare
|
Re #336 (comment) as of commit 37ed54c and the
Also, it should be possible to host and read midframe and total duration data from a JSON file (or any other file), much like it is done with the frame duration data, falling back to the default way of computing them if not present. Refactoring things this way (i.e. allowing to provide all attributes to the WDTY @mnoergaard? Sorry for so many questions. Hopefully we will converge and the implementation across the multiple ways to read/write data will be consistent and robust after this. |
6751a06 to
bbe0ca0
Compare
|
Comments:
So, we need to discuss:
We probably want to override the base class |
1353c92 to
e7a03a1
Compare
Validate PET data objects' attributes at instantiation: ensures that the attributes are present and match the expected dimensionalities. **PET class attributes** Refactor the PET attributes so that the required (`frame_time` and `uptake`) and optional (`frame_duration`, `midframe`, `total_duration`) parameters are accepted by the constructor. Although the optional parameters can be computed from the required parameters, excluding them from the `__init__` (using the `init=False` `attrs` option) would make such that when dumping a PET instance to an HDF5, further processing would be required to exclude those elements to allow reading the file, and they would need to be computed at every instantiation. Also, they may take user-provided values, so it is necessary for the constructor to allow them. Although `uptake` can also be computed from the PET frame data, the rationale behind requiring it is similar to the one for the DWI class `bzero`: users will be able to compute the `uptake` using their preferred strategy and provide it to the constructor. For the `from_nii` function, if a callable is provided, it will be used to compute the value; otherwise a default strategy is used to compute it. Validate and format attributes so that the computation of the relevant temporal and uptake attributes is done at a single place, i.e. when instantiating the `PET` object. Avoids potential inconsistencies. Time-origin shift the `frame_time` values when formatting them. Make the `_compute_uptake_statistic` public so that users can call it. **`from_nii`** function: Refactor the `from_nii` function to accept filenames instead of a mix of filenames (e.g. the PET image sequence and brainmask) and temporal and uptake attribute arrays. Honors the name of the function, increases consistency with the dMRI counterpart and allows to offer a uniform API. This allows to read the required and optional parameters from the provided files so that they are present when instantiating the PET object. Use the `get_data` utils function in `from_nii` to handle automatically the data type when loading the PET data. **`PET.load`** class method: Remove the `PET.load` class method and rely on the `data.__init__.load` function: - If an HDF5 filename is provided, it is assumed that it hosts all necessary information, and the data module `load` function should take of loading all data. - If the provided arguments are NIfTI files plus other data files, the function will call the `pet.PET.from_nii` function. Change the `kwargs` arguments to be able to identify the relevant keyword arguments that are now present in the `from_nii` function. Change accordingly the `PET.load(pet_file, json_file)` call in the PET notebook and the `test_pet_load` test function. **Tests**: Refactor the PET data creation fixture in `conftest.py` to accept the required/optional arguments and to return the necessary data. Refactor the tests accordingly and increase consistency with the `dmri` data module testing helper functions. Reduces cognitive load and maintenance burden. Add additional object instantiation equality checks: check that objects intantiated through reading NIfTI files equal objects instantiated directly. Check the PET dataset attributes systematically in round trip tests by collecting all named attributes that need to be tested. Modify accordingly the PET model and integration tests. Modify test parameterization values to values that make sense (i.e. are consistent with the way they are computed from the `frame_time` attribute). Take advantage of the patch set to make other opinionated choices: - Prefer using the global `setup_random_pet_data` fixture over the local `random_dataset` fixture: it allows to control the parameters of the generated data and increases consistency with the practice adopted across the dMRI dataset tests. Remove the `random_dataset` fixture. - Prefer using `assert np.allclose` over `np.testing.assert_array_equal` for the sake of consistency **Dependencies** Require `attrs>24.1.0` so that `attrs.Converter` can be used. Documentation: https://www.attrs.org/en/25.4.0/api.html#converters
e7a03a1 to
747b002
Compare
Validate PET data objects' attributes at instantiation: ensures that the attributes are present and match the expected dimensionalities.
PET class attributes
Refactor the PET attributes so that the required (
frame_timeanduptake) and optional (frame_duration,midframe,total_duration) parameters are accepted by the constructor. Although the optional parameters can be computed from the required parameters, excluding them from the__init__(using theinit=Falseattrsoption) would make such that when dumping a PET instance to an HDF5, further processing would be required to exclude those elements to allow reading the file, and they would need to be computed at every instantiation. Also, they may take user-provided values, so it is necessary for the constructor to allow them.Although
uptakecan also be computed from the PET frame data, the rationale behind requiring it is similar to the one for the DWI classbzero: users will be able to compute theuptakeusing their preferred strategy and provide it to the constructor. For thefrom_niifunction, if a callable is provided, it will be used to compute the value; otherwise a default strategy is used to compute it.Validate and format attributes so that the computation of the relevant temporal and uptake attributes is done at a single place, i.e. when instantiating the
PETobject. Avoids potential inconsistencies.Time-origin shift the
frame_timevalues when formatting them.Make the
_compute_uptake_statisticpublic so that users can call it.from_niifunction:Refactor the
from_niifunction to accept filenames instead of a mix of filenames (e.g. the PET image sequence and brainmask) and temporal and uptake attribute arrays. Honors the name of the function, increases consistency with the dMRI counterpart and allows to offer a uniform API. This allows to read the required and optional parameters from the provided files so that they are present when instantiating the PET object.Use the
get_datautils function infrom_niito handle automatically the data type when loading the PET data.PET.loadclass method:Remove the
PET.loadclass method and rely on thedata.__init__.loadfunction:loadfunction should take of loading all data.pet.PET.from_niifunction.Change the
kwargsarguments to be able to identify the relevant keyword arguments that are now present in thefrom_niifunction.Change accordingly the
PET.load(pet_file, json_file)call in the PET notebook and thetest_pet_loadtest function.Tests:
Refactor the PET data creation fixture in
conftest.pyto accept the required/optional arguments and to return the necessary data.Refactor the tests accordingly and increase consistency with the
dmridata module testing helper functions. Reduces cognitive load and maintenance burden.Add additional object instantiation equality checks: check that objects intantiated through reading NIfTI files equal objects instantiated directly.
Check the PET dataset attributes systematically in round trip tests by collecting all named attributes that need to be tested.
Modify accordingly the PET model and integration tests.
Modify test parameterization values to values that make sense (i.e. are consistent with the way they are computed from the
frame_timeattribute).Take advantage of the patch set to make other opinionated choices:
setup_random_pet_datafixture over the localrandom_datasetfixture: it allows to control the parameters of the generated data and increases consistency with the practice adopted across the dMRI dataset tests. Remove therandom_datasetfixture.assert np.allcloseovernp.testing.assert_array_equalfor the sake of consistency