[ENH] Refactor dm_xnat_extract + allow nii folders to be replace with sym links to bids folders#334
Conversation
- Added a blacklist check before matching dm names to bids names because apparently blacklisted items are also removed from the bids folders. - Fixed references to cfg, glob function, and ident method
TODO: - Remove the need for use_bids in BidsOptions class - Finish testing edge cases - Add unit tests
nii links werent regenerating when one was missing, unless at least one exporter that needed raw data was found. This has been fixed.
- NiiExporter was failing if run twice, this is fixed. - DBExporter was outputting an error message when json side cars werent found, even if the entire series only existed on xnat
If outputs existed and another exporter that didnt need raw data needed to run, BidsExporter would mistakenly try to run again and report an error due to an empty temp dir (no input data).
| f"Reason - {type(exc).__name__} {exc} ") | ||
|
|
||
|
|
||
| class NrrdExporter(SeriesExporter): |
There was a problem hiding this comment.
I think we can get rid of the nrrd and mnc exporters. We're no longer using CIVET, which requires the mnc files. And our tractography pipelines have a nifti to nrrd converter built in.
There was a problem hiding this comment.
Fair enough! I was just trying not to drop functionality but I can purge those classes :)
|
Is it alright for me to merge this? |
|
@DESm1th sorry this dropped off my radar! I'll review the last bits today after our meet! |
| bids_niftis.append(os.path.join(path, basename)) | ||
| return bids_niftis | ||
|
|
||
| def match_dm_to_bids(self, dm_names, bids_names): |
There was a problem hiding this comment.
Is this ever meant to be called outside the object? Would dm_names and bids_names ever be provided outside of using self?
There was a problem hiding this comment.
Likely not, but I think I left it unprotected since I ended up calling it a lot while testing that the matching worked as expected. I can change this
There was a problem hiding this comment.
I'll leave that up to you! My preference would be to remove the extra arguments for clarity 🙈
| return False | ||
|
|
||
| def export(self, *args, **kwargs): | ||
| # Re run this before exporting, in case new BIDS files exist. |
There was a problem hiding this comment.
A little bit confused about why this needs to be re-initialized. Is it expected that the state of the BIDS directory may change between initializing this class and calling its export function? Doesn't it kind of make the state variables of the class useless/misleading?
There was a problem hiding this comment.
This was the result of an edge case when the data is exported for the very first time. The class would be initialized, the names would be mapped to an empty bids folder (so no nii files) and then when the exporters actually ran, on the first run through no links would be produced.
You're right that it might make more sense to remove the state variables for this reason, but I think there was a good reason why I didnt at the time. I'll have to look at it more closely again when I fix the issues you pointed out to try to remember why I kept them
There was a problem hiding this comment.
Oh ok i took a second look at dm_xnat_extract and understand what you mean here now re: the edge case. I think you end up using the initialized state to check if the outputs exist right? It looks like you might still need it in that case!
Ok this is a really big one (sorry guys), but most of it is just reshuffled code. The really important bits are the contents of
datman/exporters.pywhich contains a set of classes to export to different formats. All the oldexport_x_commandfunctions from xnat_extract are now classes in that file, as is the contents of the xnat_to_bids function, and I've pulled all the database updating code (which was spread through xnat_extract) into its own exporter. I've added a NiiLinkExporter here that takes a subject's bids folder and makes datman-style links for it in the nii folder.Within xnat_extract itself the most important bit is the
export_scansfunction which does the work of creating the exporters, downloading any raw data needed to run them, and then running them.The changes in
datman/xnatis code I've moved from dm_xnat_extract, and the changes elsewhere were small fixes for bugs I encountered while refactoring.