bone-mechanoregulation 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bone_mechanoregulation-0.1.0/PKG-INFO +271 -0
- bone_mechanoregulation-0.1.0/README.md +244 -0
- bone_mechanoregulation-0.1.0/bone_mechanoregulation.egg-info/PKG-INFO +271 -0
- bone_mechanoregulation-0.1.0/bone_mechanoregulation.egg-info/SOURCES.txt +23 -0
- bone_mechanoregulation-0.1.0/bone_mechanoregulation.egg-info/dependency_links.txt +1 -0
- bone_mechanoregulation-0.1.0/bone_mechanoregulation.egg-info/entry_points.txt +2 -0
- bone_mechanoregulation-0.1.0/bone_mechanoregulation.egg-info/requires.txt +14 -0
- bone_mechanoregulation-0.1.0/bone_mechanoregulation.egg-info/top_level.txt +1 -0
- bone_mechanoregulation-0.1.0/bonemechreg/__init__.py +16 -0
- bone_mechanoregulation-0.1.0/bonemechreg/cli.py +56 -0
- bone_mechanoregulation-0.1.0/bonemechreg/mechreg.py +1281 -0
- bone_mechanoregulation-0.1.0/bonemechreg/parosol.py +88 -0
- bone_mechanoregulation-0.1.0/bonemechreg/post_timelapse.py +192 -0
- bone_mechanoregulation-0.1.0/bonemechreg/results.py +217 -0
- bone_mechanoregulation-0.1.0/bonemechreg/standalone.py +493 -0
- bone_mechanoregulation-0.1.0/bonemechreg/timelapse.py +149 -0
- bone_mechanoregulation-0.1.0/pyproject.toml +49 -0
- bone_mechanoregulation-0.1.0/setup.cfg +4 -0
- bone_mechanoregulation-0.1.0/tests/test_cli_run.py +55 -0
- bone_mechanoregulation-0.1.0/tests/test_mechreg_module.py +551 -0
- bone_mechanoregulation-0.1.0/tests/test_package_surface.py +17 -0
- bone_mechanoregulation-0.1.0/tests/test_parosol_solver.py +80 -0
- bone_mechanoregulation-0.1.0/tests/test_post_timelapse_workflow.py +227 -0
- bone_mechanoregulation-0.1.0/tests/test_standalone.py +151 -0
- bone_mechanoregulation-0.1.0/tests/test_timelapse_dataset.py +97 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bone-mechanoregulation
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Post-timelapse mechanoregulation addon for HR-pQCT datasets
|
|
5
|
+
Author: Matthias Walle
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/wallematthias/BoneMechanoregulation
|
|
8
|
+
Project-URL: Issues, https://github.com/wallematthias/BoneMechanoregulation/issues
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
16
|
+
Requires-Python: <3.14,>=3.11
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: numpy<2.0,>=1.26; python_version < "3.13"
|
|
19
|
+
Requires-Dist: numpy<3.0,>=2.1; python_version >= "3.13"
|
|
20
|
+
Requires-Dist: matplotlib>=3.7
|
|
21
|
+
Requires-Dist: parosol-py>=0.1.13
|
|
22
|
+
Requires-Dist: scipy>=1.10
|
|
23
|
+
Requires-Dist: SimpleITK>=2.2
|
|
24
|
+
Provides-Extra: test
|
|
25
|
+
Requires-Dist: pytest; extra == "test"
|
|
26
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
27
|
+
|
|
28
|
+
# BoneMechanoregulation
|
|
29
|
+
|
|
30
|
+
Post-timelapse mechanoregulation analysis for HR-pQCT datasets.
|
|
31
|
+
|
|
32
|
+
This package is a downstream addon. Run `TimelapsedHRpQCT` first, then run
|
|
33
|
+
BoneMechanoregulation on the Timelapsed output dataset root. The addon reuses
|
|
34
|
+
the Timelapsed pairwise remodelling label images, solves baseline SED from the
|
|
35
|
+
native baseline segmentation, and writes mechanoregulation summaries next to
|
|
36
|
+
each pairwise case.
|
|
37
|
+
|
|
38
|
+
## Prerequisite
|
|
39
|
+
|
|
40
|
+
First create TimelapsedHRpQCT remodelling outputs.
|
|
41
|
+
|
|
42
|
+
With the core TimelapsedHRpQCT CLI, the pipeline convention is:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
timelapsedhrpqct run /path/to/raw_aim_input --output-root /path/to/TimelapsedHRpQCT
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
In the 3D Slicer toolbox, use the `Timelapsed HR-pQCT` module:
|
|
49
|
+
|
|
50
|
+
1. select the AIM dataset root;
|
|
51
|
+
2. choose a results folder, defaulting to `<dataset_root>/TimelapsedHRpQCT`;
|
|
52
|
+
3. click `Run pipeline`;
|
|
53
|
+
4. inspect the generated remodelling images.
|
|
54
|
+
|
|
55
|
+
The Slicer wrapper is the recommended route for interactive preparation, mask
|
|
56
|
+
review, and visual QA before running this mechanoregulation addon.
|
|
57
|
+
|
|
58
|
+
## Install
|
|
59
|
+
|
|
60
|
+
From PyPI:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install bone-mechanoregulation
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For local development:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install -e .
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`parosol-py>=0.1.13` must be available in the same Python environment. The
|
|
73
|
+
mechanoregulation workflow writes a standard ParOSol material-label input from
|
|
74
|
+
the native baseline segmentation, then calls the native `parosol-py`
|
|
75
|
+
XtremeCTI/XtremeCTII profile for the finite-element solve.
|
|
76
|
+
|
|
77
|
+
## Install In 3D Slicer
|
|
78
|
+
|
|
79
|
+
BoneMechanoregulation can also be installed into Slicer's Python environment so
|
|
80
|
+
the same command-line analysis is available from Slicer-side workflows or
|
|
81
|
+
scripted modules.
|
|
82
|
+
|
|
83
|
+
From Slicer's Python interactor or a Slicer Python shell:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import sys
|
|
87
|
+
import subprocess
|
|
88
|
+
|
|
89
|
+
subprocess.check_call([
|
|
90
|
+
sys.executable,
|
|
91
|
+
"-m",
|
|
92
|
+
"pip",
|
|
93
|
+
"install",
|
|
94
|
+
"bone-mechanoregulation",
|
|
95
|
+
])
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
For local development from a checkout:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import sys
|
|
102
|
+
import subprocess
|
|
103
|
+
|
|
104
|
+
subprocess.check_call([
|
|
105
|
+
sys.executable,
|
|
106
|
+
"-m",
|
|
107
|
+
"pip",
|
|
108
|
+
"install",
|
|
109
|
+
"-e",
|
|
110
|
+
"/path/to/BoneMechanoregulation",
|
|
111
|
+
])
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The package supports the same Python version range used by the current
|
|
115
|
+
TimelapsedHRpQCT packaging matrix: Python 3.11, 3.12, and 3.13. If a Slicer
|
|
116
|
+
release ships an older Python, use an external Python environment for the batch
|
|
117
|
+
analysis or install through the matching Slicer toolbox once it provides a
|
|
118
|
+
compatible runtime.
|
|
119
|
+
|
|
120
|
+
## Batch Usage
|
|
121
|
+
|
|
122
|
+
Run this after TimelapsedHRpQCT has produced its derivative tree:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
mechanoregulation run \
|
|
126
|
+
/path/to/TimelapsedHRpQCT \
|
|
127
|
+
--profile XtremeCTII
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The positional `dataset_root` follows the TimelapsedHRpQCT core CLI convention:
|
|
131
|
+
the root path is the main command argument. Here it is the TimelapsedHRpQCT
|
|
132
|
+
output root, not the raw AIM input folder. The addon expects to find pairwise
|
|
133
|
+
remodelling cases under:
|
|
134
|
+
|
|
135
|
+
```text
|
|
136
|
+
<dataset-root>/derivatives/TimelapsedHRpQCT/sub-*/analysis/pairwise_t0/*/
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Current TimelapsedHRpQCT outputs under
|
|
140
|
+
`sub-*/site-*/analysis/visualize/*remodelling.nii.gz` are also supported. For
|
|
141
|
+
these outputs, the mechanics solve uses the native stack-level baseline
|
|
142
|
+
segmentation and compartment masks under `sub-*/site-*/ses-*/stacks/`.
|
|
143
|
+
|
|
144
|
+
Useful flags:
|
|
145
|
+
|
|
146
|
+
- `--profile XtremeCTI` or `--profile XtremeCTII`: native `parosol-py` scanner
|
|
147
|
+
profile. The generated material image uses the standard profile labels:
|
|
148
|
+
`100` for trabecular baseline bone, `127` for cortical baseline bone, and
|
|
149
|
+
all other labels as non-bone.
|
|
150
|
+
- `--dry-run`: count discoverable cases without writing files.
|
|
151
|
+
- `--overwrite`: recompute outputs even if they already exist.
|
|
152
|
+
- `--verbose`: re-raise case errors instead of counting failed cases.
|
|
153
|
+
|
|
154
|
+
## Outputs
|
|
155
|
+
|
|
156
|
+
For current TimelapsedHRpQCT outputs, results are written into a site-level
|
|
157
|
+
`mechanoregulation` folder beside `analysis`, `ses-*`, and
|
|
158
|
+
`transformed_images`:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
sub-<id>/site-<site>/
|
|
162
|
+
analysis/
|
|
163
|
+
visualize/
|
|
164
|
+
*_remodelling.nii.gz
|
|
165
|
+
mechanoregulation/
|
|
166
|
+
<case>_sed.nii.gz
|
|
167
|
+
<case>_baseline_material_labels.nii.gz
|
|
168
|
+
<case>_conditional_curves.png
|
|
169
|
+
<case>_mechanoregulation_summary.csv
|
|
170
|
+
<case>_mechanoregulation_summary.json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Older Timelapsed layouts that already store each pairwise case in its own
|
|
174
|
+
folder keep writing a `mechanoregulation` subfolder beside that pairwise case.
|
|
175
|
+
|
|
176
|
+
Output files:
|
|
177
|
+
|
|
178
|
+
- `<case>_baseline_material_labels.nii.gz`: ParOSol input image built from the
|
|
179
|
+
native baseline segmentation. Label `100` is trabecular baseline bone, label
|
|
180
|
+
`127` is cortical baseline bone, and background plus future formation sites
|
|
181
|
+
are `0`.
|
|
182
|
+
- `<case>_sed.nii.gz`: baseline SED solved with `parosol-py` and aligned to the
|
|
183
|
+
Timelapsed remodelling image grid. If this file already exists, it is reused unless
|
|
184
|
+
`--overwrite` is set.
|
|
185
|
+
- `<case>_conditional_curves.png`: two-panel summary figure. The left panel
|
|
186
|
+
shows Schulte-style binned conditional probability curves for resorption,
|
|
187
|
+
quiescence, and formation. The right panel shows bootstrap logistic
|
|
188
|
+
probability curves.
|
|
189
|
+
- `<case>_mechanoregulation_summary.csv`: one-row table for downstream
|
|
190
|
+
statistics.
|
|
191
|
+
- `<case>_mechanoregulation_summary.json`: full reproducibility payload,
|
|
192
|
+
including curves, settings, sample counts, and confidence intervals.
|
|
193
|
+
|
|
194
|
+
The CSV is intentionally flat and stable. A TimelapsedHRpQCT or Slicer export
|
|
195
|
+
button can merge it into cohort-level exports by scanning each pairwise case's
|
|
196
|
+
`mechanoregulation/*.csv` file and joining by subject/site/session-pair stem.
|
|
197
|
+
That export integration is separate from this package; this package writes the
|
|
198
|
+
per-case CSV files that such an exporter can pick up.
|
|
199
|
+
|
|
200
|
+
## Output Measures
|
|
201
|
+
|
|
202
|
+
The analysis samples baseline SED on the quiescent baseline surface. Formation
|
|
203
|
+
and resorption events are projected symmetrically onto neighbouring baseline
|
|
204
|
+
surface voxels. If projected formation and resorption overlap on the same
|
|
205
|
+
surface voxel, that voxel is counted as quiescent/ambiguous.
|
|
206
|
+
|
|
207
|
+
CSV columns:
|
|
208
|
+
|
|
209
|
+
- `CCR`: maximum correct classification rate from Schulte-style conditional
|
|
210
|
+
probability curves. It summarizes how well low SED maps to resorption,
|
|
211
|
+
middle SED maps to quiescence, and high SED maps to formation.
|
|
212
|
+
- `CCR_low_threshold`: normalized SED threshold separating the resorption side
|
|
213
|
+
from the lazy zone in the binned CCR analysis.
|
|
214
|
+
- `CCR_high_threshold`: normalized SED threshold separating the lazy zone from
|
|
215
|
+
the formation side in the binned CCR analysis.
|
|
216
|
+
- `binned_lazy_zone_low`, `binned_lazy_zone_high`: aliases of the CCR
|
|
217
|
+
thresholds, reported explicitly as the binned lazy-zone bounds.
|
|
218
|
+
- `logistic_lazy_zone_low`, `logistic_lazy_zone_high`: lazy-zone bounds from
|
|
219
|
+
the smooth logistic probability curves, estimated from R/Q and F/Q curve
|
|
220
|
+
crossings.
|
|
221
|
+
- `OR_F`: percent increase in formation odds per one normalized SED
|
|
222
|
+
percentage-point increase. This is named `OR_F` for reporting compatibility,
|
|
223
|
+
but its value is `100 * (OR_F_ratio - 1)`.
|
|
224
|
+
- `OR_R`: percent increase in resorption odds per one normalized SED
|
|
225
|
+
percentage-point decrease. This is named `OR_R` for reporting compatibility,
|
|
226
|
+
but its value is `100 * (OR_R_ratio - 1)`.
|
|
227
|
+
- `OR_F_CI_low`, `OR_F_CI_high`: bootstrap confidence interval for reported
|
|
228
|
+
percent `OR_F`.
|
|
229
|
+
- `OR_R_CI_low`, `OR_R_CI_high`: bootstrap confidence interval for reported
|
|
230
|
+
percent `OR_R`.
|
|
231
|
+
- `OR_F_ratio`, `OR_R_ratio`: raw logistic odds ratios retained for
|
|
232
|
+
reproducibility.
|
|
233
|
+
- `formation_odds_increase_percent_per_sed_percent`: percent odds increase for
|
|
234
|
+
formation per one normalized SED percentage-point increase, computed as
|
|
235
|
+
`100 * (OR_F_ratio - 1)`. This duplicates reported `OR_F`.
|
|
236
|
+
- `resorption_odds_increase_percent_per_sed_percent_decrease`: percent odds
|
|
237
|
+
increase for resorption per one normalized SED percentage-point decrease,
|
|
238
|
+
computed as `100 * (OR_R_ratio - 1)`. This duplicates reported `OR_R`.
|
|
239
|
+
- `formation_odds_increase_percent_CI_low`,
|
|
240
|
+
`formation_odds_increase_percent_CI_high`: confidence interval for the
|
|
241
|
+
formation percent odds increase.
|
|
242
|
+
- `resorption_odds_increase_percent_CI_low`,
|
|
243
|
+
`resorption_odds_increase_percent_CI_high`: confidence interval for the
|
|
244
|
+
resorption percent odds increase.
|
|
245
|
+
- `n_surface_voxels`: number of baseline surface voxels available before final
|
|
246
|
+
class sampling.
|
|
247
|
+
- `n_sampled_voxels`: number of surface voxels used in the final
|
|
248
|
+
mechanoregulation analysis.
|
|
249
|
+
- `n_formation`, `n_resorption`, `n_quiescence`: final class counts after
|
|
250
|
+
symmetric surface projection.
|
|
251
|
+
- `n_cancelled_overlap`: number of surface voxels where projected formation and
|
|
252
|
+
resorption overlapped and were cancelled to quiescence.
|
|
253
|
+
|
|
254
|
+
## Standalone Usage
|
|
255
|
+
|
|
256
|
+
For synthetic advection folders or one-off debugging, use:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
mechanoregulation analyze /path/to/folder
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The standalone command looks for a baseline image, a remodelling label image or
|
|
263
|
+
T1 follow-up, an optional mask, and a baseline SED image or nearby exported
|
|
264
|
+
ParOSol `fields/sed.nii.gz`. It writes:
|
|
265
|
+
|
|
266
|
+
```text
|
|
267
|
+
<folder>/mechanoregulation/
|
|
268
|
+
<run>_mechanoregulation_summary.csv
|
|
269
|
+
<run>_mechanoregulation_summary.json
|
|
270
|
+
<run>_mechanoregulation_curves.png
|
|
271
|
+
```
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# BoneMechanoregulation
|
|
2
|
+
|
|
3
|
+
Post-timelapse mechanoregulation analysis for HR-pQCT datasets.
|
|
4
|
+
|
|
5
|
+
This package is a downstream addon. Run `TimelapsedHRpQCT` first, then run
|
|
6
|
+
BoneMechanoregulation on the Timelapsed output dataset root. The addon reuses
|
|
7
|
+
the Timelapsed pairwise remodelling label images, solves baseline SED from the
|
|
8
|
+
native baseline segmentation, and writes mechanoregulation summaries next to
|
|
9
|
+
each pairwise case.
|
|
10
|
+
|
|
11
|
+
## Prerequisite
|
|
12
|
+
|
|
13
|
+
First create TimelapsedHRpQCT remodelling outputs.
|
|
14
|
+
|
|
15
|
+
With the core TimelapsedHRpQCT CLI, the pipeline convention is:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
timelapsedhrpqct run /path/to/raw_aim_input --output-root /path/to/TimelapsedHRpQCT
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
In the 3D Slicer toolbox, use the `Timelapsed HR-pQCT` module:
|
|
22
|
+
|
|
23
|
+
1. select the AIM dataset root;
|
|
24
|
+
2. choose a results folder, defaulting to `<dataset_root>/TimelapsedHRpQCT`;
|
|
25
|
+
3. click `Run pipeline`;
|
|
26
|
+
4. inspect the generated remodelling images.
|
|
27
|
+
|
|
28
|
+
The Slicer wrapper is the recommended route for interactive preparation, mask
|
|
29
|
+
review, and visual QA before running this mechanoregulation addon.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
From PyPI:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install bone-mechanoregulation
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For local development:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install -e .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`parosol-py>=0.1.13` must be available in the same Python environment. The
|
|
46
|
+
mechanoregulation workflow writes a standard ParOSol material-label input from
|
|
47
|
+
the native baseline segmentation, then calls the native `parosol-py`
|
|
48
|
+
XtremeCTI/XtremeCTII profile for the finite-element solve.
|
|
49
|
+
|
|
50
|
+
## Install In 3D Slicer
|
|
51
|
+
|
|
52
|
+
BoneMechanoregulation can also be installed into Slicer's Python environment so
|
|
53
|
+
the same command-line analysis is available from Slicer-side workflows or
|
|
54
|
+
scripted modules.
|
|
55
|
+
|
|
56
|
+
From Slicer's Python interactor or a Slicer Python shell:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
import sys
|
|
60
|
+
import subprocess
|
|
61
|
+
|
|
62
|
+
subprocess.check_call([
|
|
63
|
+
sys.executable,
|
|
64
|
+
"-m",
|
|
65
|
+
"pip",
|
|
66
|
+
"install",
|
|
67
|
+
"bone-mechanoregulation",
|
|
68
|
+
])
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
For local development from a checkout:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import sys
|
|
75
|
+
import subprocess
|
|
76
|
+
|
|
77
|
+
subprocess.check_call([
|
|
78
|
+
sys.executable,
|
|
79
|
+
"-m",
|
|
80
|
+
"pip",
|
|
81
|
+
"install",
|
|
82
|
+
"-e",
|
|
83
|
+
"/path/to/BoneMechanoregulation",
|
|
84
|
+
])
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The package supports the same Python version range used by the current
|
|
88
|
+
TimelapsedHRpQCT packaging matrix: Python 3.11, 3.12, and 3.13. If a Slicer
|
|
89
|
+
release ships an older Python, use an external Python environment for the batch
|
|
90
|
+
analysis or install through the matching Slicer toolbox once it provides a
|
|
91
|
+
compatible runtime.
|
|
92
|
+
|
|
93
|
+
## Batch Usage
|
|
94
|
+
|
|
95
|
+
Run this after TimelapsedHRpQCT has produced its derivative tree:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
mechanoregulation run \
|
|
99
|
+
/path/to/TimelapsedHRpQCT \
|
|
100
|
+
--profile XtremeCTII
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The positional `dataset_root` follows the TimelapsedHRpQCT core CLI convention:
|
|
104
|
+
the root path is the main command argument. Here it is the TimelapsedHRpQCT
|
|
105
|
+
output root, not the raw AIM input folder. The addon expects to find pairwise
|
|
106
|
+
remodelling cases under:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
<dataset-root>/derivatives/TimelapsedHRpQCT/sub-*/analysis/pairwise_t0/*/
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Current TimelapsedHRpQCT outputs under
|
|
113
|
+
`sub-*/site-*/analysis/visualize/*remodelling.nii.gz` are also supported. For
|
|
114
|
+
these outputs, the mechanics solve uses the native stack-level baseline
|
|
115
|
+
segmentation and compartment masks under `sub-*/site-*/ses-*/stacks/`.
|
|
116
|
+
|
|
117
|
+
Useful flags:
|
|
118
|
+
|
|
119
|
+
- `--profile XtremeCTI` or `--profile XtremeCTII`: native `parosol-py` scanner
|
|
120
|
+
profile. The generated material image uses the standard profile labels:
|
|
121
|
+
`100` for trabecular baseline bone, `127` for cortical baseline bone, and
|
|
122
|
+
all other labels as non-bone.
|
|
123
|
+
- `--dry-run`: count discoverable cases without writing files.
|
|
124
|
+
- `--overwrite`: recompute outputs even if they already exist.
|
|
125
|
+
- `--verbose`: re-raise case errors instead of counting failed cases.
|
|
126
|
+
|
|
127
|
+
## Outputs
|
|
128
|
+
|
|
129
|
+
For current TimelapsedHRpQCT outputs, results are written into a site-level
|
|
130
|
+
`mechanoregulation` folder beside `analysis`, `ses-*`, and
|
|
131
|
+
`transformed_images`:
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
sub-<id>/site-<site>/
|
|
135
|
+
analysis/
|
|
136
|
+
visualize/
|
|
137
|
+
*_remodelling.nii.gz
|
|
138
|
+
mechanoregulation/
|
|
139
|
+
<case>_sed.nii.gz
|
|
140
|
+
<case>_baseline_material_labels.nii.gz
|
|
141
|
+
<case>_conditional_curves.png
|
|
142
|
+
<case>_mechanoregulation_summary.csv
|
|
143
|
+
<case>_mechanoregulation_summary.json
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Older Timelapsed layouts that already store each pairwise case in its own
|
|
147
|
+
folder keep writing a `mechanoregulation` subfolder beside that pairwise case.
|
|
148
|
+
|
|
149
|
+
Output files:
|
|
150
|
+
|
|
151
|
+
- `<case>_baseline_material_labels.nii.gz`: ParOSol input image built from the
|
|
152
|
+
native baseline segmentation. Label `100` is trabecular baseline bone, label
|
|
153
|
+
`127` is cortical baseline bone, and background plus future formation sites
|
|
154
|
+
are `0`.
|
|
155
|
+
- `<case>_sed.nii.gz`: baseline SED solved with `parosol-py` and aligned to the
|
|
156
|
+
Timelapsed remodelling image grid. If this file already exists, it is reused unless
|
|
157
|
+
`--overwrite` is set.
|
|
158
|
+
- `<case>_conditional_curves.png`: two-panel summary figure. The left panel
|
|
159
|
+
shows Schulte-style binned conditional probability curves for resorption,
|
|
160
|
+
quiescence, and formation. The right panel shows bootstrap logistic
|
|
161
|
+
probability curves.
|
|
162
|
+
- `<case>_mechanoregulation_summary.csv`: one-row table for downstream
|
|
163
|
+
statistics.
|
|
164
|
+
- `<case>_mechanoregulation_summary.json`: full reproducibility payload,
|
|
165
|
+
including curves, settings, sample counts, and confidence intervals.
|
|
166
|
+
|
|
167
|
+
The CSV is intentionally flat and stable. A TimelapsedHRpQCT or Slicer export
|
|
168
|
+
button can merge it into cohort-level exports by scanning each pairwise case's
|
|
169
|
+
`mechanoregulation/*.csv` file and joining by subject/site/session-pair stem.
|
|
170
|
+
That export integration is separate from this package; this package writes the
|
|
171
|
+
per-case CSV files that such an exporter can pick up.
|
|
172
|
+
|
|
173
|
+
## Output Measures
|
|
174
|
+
|
|
175
|
+
The analysis samples baseline SED on the quiescent baseline surface. Formation
|
|
176
|
+
and resorption events are projected symmetrically onto neighbouring baseline
|
|
177
|
+
surface voxels. If projected formation and resorption overlap on the same
|
|
178
|
+
surface voxel, that voxel is counted as quiescent/ambiguous.
|
|
179
|
+
|
|
180
|
+
CSV columns:
|
|
181
|
+
|
|
182
|
+
- `CCR`: maximum correct classification rate from Schulte-style conditional
|
|
183
|
+
probability curves. It summarizes how well low SED maps to resorption,
|
|
184
|
+
middle SED maps to quiescence, and high SED maps to formation.
|
|
185
|
+
- `CCR_low_threshold`: normalized SED threshold separating the resorption side
|
|
186
|
+
from the lazy zone in the binned CCR analysis.
|
|
187
|
+
- `CCR_high_threshold`: normalized SED threshold separating the lazy zone from
|
|
188
|
+
the formation side in the binned CCR analysis.
|
|
189
|
+
- `binned_lazy_zone_low`, `binned_lazy_zone_high`: aliases of the CCR
|
|
190
|
+
thresholds, reported explicitly as the binned lazy-zone bounds.
|
|
191
|
+
- `logistic_lazy_zone_low`, `logistic_lazy_zone_high`: lazy-zone bounds from
|
|
192
|
+
the smooth logistic probability curves, estimated from R/Q and F/Q curve
|
|
193
|
+
crossings.
|
|
194
|
+
- `OR_F`: percent increase in formation odds per one normalized SED
|
|
195
|
+
percentage-point increase. This is named `OR_F` for reporting compatibility,
|
|
196
|
+
but its value is `100 * (OR_F_ratio - 1)`.
|
|
197
|
+
- `OR_R`: percent increase in resorption odds per one normalized SED
|
|
198
|
+
percentage-point decrease. This is named `OR_R` for reporting compatibility,
|
|
199
|
+
but its value is `100 * (OR_R_ratio - 1)`.
|
|
200
|
+
- `OR_F_CI_low`, `OR_F_CI_high`: bootstrap confidence interval for reported
|
|
201
|
+
percent `OR_F`.
|
|
202
|
+
- `OR_R_CI_low`, `OR_R_CI_high`: bootstrap confidence interval for reported
|
|
203
|
+
percent `OR_R`.
|
|
204
|
+
- `OR_F_ratio`, `OR_R_ratio`: raw logistic odds ratios retained for
|
|
205
|
+
reproducibility.
|
|
206
|
+
- `formation_odds_increase_percent_per_sed_percent`: percent odds increase for
|
|
207
|
+
formation per one normalized SED percentage-point increase, computed as
|
|
208
|
+
`100 * (OR_F_ratio - 1)`. This duplicates reported `OR_F`.
|
|
209
|
+
- `resorption_odds_increase_percent_per_sed_percent_decrease`: percent odds
|
|
210
|
+
increase for resorption per one normalized SED percentage-point decrease,
|
|
211
|
+
computed as `100 * (OR_R_ratio - 1)`. This duplicates reported `OR_R`.
|
|
212
|
+
- `formation_odds_increase_percent_CI_low`,
|
|
213
|
+
`formation_odds_increase_percent_CI_high`: confidence interval for the
|
|
214
|
+
formation percent odds increase.
|
|
215
|
+
- `resorption_odds_increase_percent_CI_low`,
|
|
216
|
+
`resorption_odds_increase_percent_CI_high`: confidence interval for the
|
|
217
|
+
resorption percent odds increase.
|
|
218
|
+
- `n_surface_voxels`: number of baseline surface voxels available before final
|
|
219
|
+
class sampling.
|
|
220
|
+
- `n_sampled_voxels`: number of surface voxels used in the final
|
|
221
|
+
mechanoregulation analysis.
|
|
222
|
+
- `n_formation`, `n_resorption`, `n_quiescence`: final class counts after
|
|
223
|
+
symmetric surface projection.
|
|
224
|
+
- `n_cancelled_overlap`: number of surface voxels where projected formation and
|
|
225
|
+
resorption overlapped and were cancelled to quiescence.
|
|
226
|
+
|
|
227
|
+
## Standalone Usage
|
|
228
|
+
|
|
229
|
+
For synthetic advection folders or one-off debugging, use:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
mechanoregulation analyze /path/to/folder
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The standalone command looks for a baseline image, a remodelling label image or
|
|
236
|
+
T1 follow-up, an optional mask, and a baseline SED image or nearby exported
|
|
237
|
+
ParOSol `fields/sed.nii.gz`. It writes:
|
|
238
|
+
|
|
239
|
+
```text
|
|
240
|
+
<folder>/mechanoregulation/
|
|
241
|
+
<run>_mechanoregulation_summary.csv
|
|
242
|
+
<run>_mechanoregulation_summary.json
|
|
243
|
+
<run>_mechanoregulation_curves.png
|
|
244
|
+
```
|