Proof-of-concept for total TRX integration - #3281
mattcieslak wants to merge 9 commits into
Conversation
d5fc100 to
bbe79ef
Compare
|
Similarly to #3265, closing in favour of #3415. While this PR does take a step in the right direction from #3265 in so far as promoting TRX to have software-package-wide compatibility, there are multiple attributes of the proposed changeset that motivated re-attempting implementation from scratch.
While it won't be supported in this form, this is nevertheless useful content, over and above motivating me to make my own attempt in #3415. Any features that went into the requirements document for this generative exercise that have been overlooked in #3415 can be added; either as comments there, or perhaps better as a standalone Issue listing desired additional features so that implementation can be planned accordingly. I'm slowly building up some project-level agent configuration that will eventually be added to the repository. I'm hoping that articulating some of the design philosophies will help mitigate models going down an implementation route that maintainers won't like. Any inputs in this regard from your experience could be useful. Cheers |
I tried adding TRX support in #3265 and realized that there are a lot of TRX-related functions that should probably be reusable outside of tckconvert.cpp. So I tried out adding TRX support across all of mrtrix and was able to get it working and passing old and new tests. In this PR, every command that accepted TCK now accepts TRX, with (mostly) no new required CLI options. Many commands gain the ability to embed computed sidecar data (weights, per-vertex scalars, atlas labels) directly into the TRX file rather than scattering it across separate
.txt/.tsf/.csvfiles.I did some benchmarking of TRX-backed vs classic MRtrix3 workflows here.
Big picture
A single TRX file accumulates all the data classically split across multiple sidecar files:
The strategy I took is that a sidecar output argument (weights path, TSF path, scalar dump path) doubles as a TRX field name when given without a file extension. For example:
All existing behavior is preserved when an extension is present or the input is TCK.
Specifics
All of the trx-specific handling is implemented in
trx_utils.h, not in command code. Commands do not containif (is_trx_input)branches. Three helper functions do almost all the integration logic:open_tractogram(path, properties)to open TCK or TRX transparently, returningunique_ptr<ReaderInterface<float>>, populatingproperties["count"].resolve_dps_weights(path, field_name_or_path)— returns per-streamline weights from an embedded dps field or external text file.resolve_dpv_scalars(path, field_name_or_path)— same for per-vertex scalars.Most CLI programs only need two line substitutions:
This only works because I changed
TrackLoader's constructor to acceptReaderInterface<float>&instead ofReader<float>&. Not sure if this is cool.Gotchas
VOXEL_TO_RASMMin the trx header is informational only. It's really only useful to convert to trk, which I hope goes away someday. I kind of want to not even print it intckinfobecause it's never applied during reading or writing.tckedit,tcksift) usetrx::TrxFile::subset_streamlines()to remap all dps/dpv/groups to surviving streamlines automatically.tcktransformTRX→TRX path): modify positions in-place on the loadedTrxFile; all metadata is preserved with no extra infrastructure.tckresample), dps and groups are copied to the new file. dpv is discarded with a warning (vertex-count change invalidates per-vertex data). If users want to get dpv back they could reruntckmapwith the resampled trx.Critical Note
I want to be clear this is just a proof of concept showing what TRX integration could look like, not a proposal to merge exactly this code. I'm pretty satisfied with the MRtrix3-TRX workflow in this PR but obviously am a newbie to MRtrix3 development and c++, and want to be a good citizen. I'm happy to implement any suggestions here or in separate PRs!
Also, it's worth mentioning that it will be extremely nice to be able to mix and match software tools. We will soon be able to
antsApplyTransformsToTRX, read/write streamlines with DSI Studio and are already able to use trx throughout trekker, ITK and in Python/DIPY.