Skip to content
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

Testing is good #19

Merged
merged 13 commits into from
Oct 4, 2023
Merged

Testing is good #19

merged 13 commits into from
Oct 4, 2023

Conversation

bendhouseart
Copy link
Collaborator

Adding testing for eventual CI and in an effort to support:

  1. Inherited anatomical files
  2. Single anatomical files within a session folder in a multi-session study
  3. Multiple anatomical files within each session folder for multi-session study

@bendhouseart bendhouseart marked this pull request as draft September 20, 2023 20:45
@bendhouseart bendhouseart self-assigned this Sep 21, 2023
@bendhouseart
Copy link
Collaborator Author

@bilgelm tagging you on this as I'm adding a bunch of stuff to the Makefile to make black etc easier to apply locally

@bendhouseart
Copy link
Collaborator Author

bendhouseart commented Sep 21, 2023

Additionally, it looks like we're going to be able to use the deface mask to check whether or not the output has been defaced or not, see https://bids-specification.readthedocs.io/en/stable/glossary.html#defacemask-suffixes

The next concrete steps are going to be to add checks for those defaced masks post pipeline, from there we can formally begin validating the pipeline outputs for various layouts (inherited, anat in first session folder, ...) with make testall.

We are a bit limited at the moment by the size of Freesurfer (~18GB) wrt to running automated tests here on gh actions, hence another motivation for making the Makefile. I'm hopeful that we'll be able to upgrade our GH account/actions runner to a larger instance in the future and automate testing, building the docker image, etc etc. But, in the meantime we'll just be doing everything locally with make.

I'm envisioning a large enough gh actions runner that is able to execute the following:

- name: set up 3rd party dependencies
   run: |
     make installfreesurfer
     make installbidsvalidator
     make installdocker
- name: run tests
   run: make tests

etc etc

@bendhouseart
Copy link
Collaborator Author

Part of testing is going to require conversion of the defacemask into .nii from .mgz as well as writing out the filename in terms of a bids compliant set of entities with the suffix _defacemask.

This is going to a hard requirement for testing going forward, however, it all appears to be bids valid, see the following example (ignore the datalad stuff):

sub-PS50
├── ses-baseline
│   ├── anat
│   │   ├── sub-PS50_ses-baseline_T1w.json -> ../../../.git/annex/objects/p8/xM/MD5E-s1321--4c2c1a45095196ebc00f34118bb99167.json/MD5E-s1321--4c2c1a45095196ebc00f34118bb99167.json
│   │   ├── sub-PS50_ses-baseline_T1w.nii.gz -> ../../../.git/annex/objects/x3/QK/MD5E-s15632037--1a3307921378137adb2fbf2827fab266.nii.gz/MD5E-s15632037--1a3307921378137adb2fbf2827fab266.nii.gz
│   │   └── sub-PS50_ses-baseline_mod-T1w_defacemask.nii.gz
│   └── pet
│       ├── sub-PS50_ses-baseline_pet.json -> ../../../.git/annex/objects/KQ/x8/MD5E-s3359--7237477e4d2802851eb4eb11c05e7ddd.json/MD5E-s3359--7237477e4d2802851eb4eb11c05e7ddd.json
│       ├── sub-PS50_ses-baseline_pet.nii.gz -> ../../../.git/annex/objects/61/9Q/MD5E-s145802787--af6e71a315e35dd1525c9abda5611280.nii.gz/MD5E-s145802787--af6e71a315e35dd1525c9abda5611280.nii.gz
│       ├── sub-PS50_ses-baseline_recording-manual_blood.json -> ../../../.git/annex/objects/Qk/G1/MD5E-s702--d8b2947c6ecc12911297da3b1b843514.json/MD5E-s702--d8b2947c6ecc12911297da3b1b843514.json
│       └── sub-PS50_ses-baseline_recording-manual_blood.tsv -> ../../../.git/annex/objects/j1/2g/MD5E-s1268--58e9845e8c151c1197dfb0237c697b99.tsv/MD5E-s1268--58e9845e8c151c1197dfb0237c697b99.tsv
└── ses-blocked
    └── pet
        ├── sub-PS50_ses-blocked_pet.json -> ../../../.git/annex/objects/mx/j3/MD5E-s3324--25ecdc9902770d79e592651cd7a9ab5b.json/MD5E-s3324--25ecdc9902770d79e592651cd7a9ab5b.json
        ├── sub-PS50_ses-blocked_pet.nii.gz -> ../../../.git/annex/objects/4W/JX/MD5E-s142495013--0c27a85eb5fcfef6c2e6883e64b7d61d.nii.gz/MD5E-s142495013--0c27a85eb5fcfef6c2e6883e64b7d61d.nii.gz
        ├── sub-PS50_ses-blocked_recording-manual_blood.json -> ../../../.git/annex/objects/Qk/G1/MD5E-s702--d8b2947c6ecc12911297da3b1b843514.json/MD5E-s702--d8b2947c6ecc12911297da3b1b843514.json
        └── sub-PS50_ses-blocked_recording-manual_blood.tsv -> ../../../.git/annex/objects/ww/ZK/MD5E-s1295--ca58145d917c4f2aeda5e3c89fa804d4.tsv/MD5E-s1295--ca58145d917c4f2aeda5e3c89fa804d4.tsv

5 directories, 11 files

@bendhouseart
Copy link
Collaborator Author

@bilgelm @mnoergaard I think the latest comment above is a good way to proceed with testing and refactoring. Could you take a look and comment whether you agree or disagree?

Copy link
Contributor

@bilgelm bilgelm left a comment

Choose a reason for hiding this comment

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

Testing is good indeed! Thanks Anthony for implementing these. I was able to run the tests successfully.

from os import cpu_count
from bids.layout import BIDSLayout

import tempfile
Copy link
Contributor

Choose a reason for hiding this comment

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

pytest has temp dir fixtures (https://docs.pytest.org/en/6.2.x/tmpdir.html); not sure if that would be more advantageous to use than the tempfile based implementation

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, pytest has everything, but despite my owning a book on it I'm not wholly familiar. I think we could move to using exclusively pytest, but for the moment it works and I'm able to easily inspect the temp dir if something fails.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Okay, this is getting out of hand. I've gone ahead and created a petutils library that includes the sort of directory tree's we're intent on testing on. It has it's own fixtures that use pytest's tmpdir. Going to just merge this and switch over directory creation to the fixtures contained in in openneuropet/petutils for further development.

n_procs=nthreads,
)
petdeface.run()

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to check if the defaced PET file(s) is/are created.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

See my comment about the mask files, we're going to need to slightly modify the pipeline to output nifti masks instead of mgz, but that's irrelevant for the purposes of this branch/PR. I'd like to add all the tests even if it means everything is failing.

import tempfile

# collect test bids dataset from data directory
data_dir = Path(__file__).parent.parent / "data"
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we consider downsampling the test data to speed up the tests?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

From my understanding it's a registration issue with the current test data, either way I think we should optimize later and push through with it now.

.gitignore Outdated Show resolved Hide resolved
import pytest
from pathlib import Path
import shutil
import bids
Copy link
Contributor

Choose a reason for hiding this comment

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

L1 and L4 can be deleted as these imports are not being used

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think pytest might be as I use a fixture from it, and bids will be used to validate that the outputs look correct.

@bendhouseart bendhouseart marked this pull request as ready for review October 4, 2023 22:11
petdeface/petdeface.py Outdated Show resolved Hide resolved
@bendhouseart bendhouseart merged commit 931f08a into main Oct 4, 2023
@bendhouseart bendhouseart deleted the testing-is-good branch October 4, 2023 22:23
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.

2 participants