|
19 | 19 |
|
20 | 20 | from collections import Counter |
21 | 21 | from multiprocessing.dummy import Pool as ThreadPool |
| 22 | +from multiprocessing.pool import Pool |
22 | 23 | import os |
| 24 | +from typing import Literal, Optional |
23 | 25 |
|
24 | 26 | import numpy as np |
25 | 27 | import nibabel as nib |
@@ -131,27 +133,23 @@ def norm_transformation(input_mat): |
131 | 133 |
|
132 | 134 |
|
133 | 135 | def template_convergence( |
134 | | - mat_file, mat_type="matrix", convergence_threshold=np.finfo(np.float64).eps |
135 | | -): |
| 136 | + mat_file: str, |
| 137 | + mat_type: Literal["matrix", "ITK"] = "matrix", |
| 138 | + convergence_threshold: float | np.float64 = np.finfo(np.float64).eps, |
| 139 | +) -> bool: |
136 | 140 | """Check that the deistance between matrices is smaller than the threshold. |
137 | 141 |
|
138 | 142 | Calculate the distance between transformation matrix with a matrix of no transformation. |
139 | 143 |
|
140 | 144 | Parameters |
141 | 145 | ---------- |
142 | | - mat_file : str |
| 146 | + mat_file |
143 | 147 | path to an fsl flirt matrix |
144 | | - mat_type : str |
145 | | - 'matrix'(default), 'ITK' |
| 148 | + mat_type |
146 | 149 | The type of matrix used to represent the transformations |
147 | | - convergence_threshold : float |
148 | | - (numpy.finfo(np.float64).eps (default)) threshold for the convergence |
| 150 | + convergence_threshold |
149 | 151 | The threshold is how different from no transformation is the |
150 | 152 | transformation matrix. |
151 | | -
|
152 | | - Returns |
153 | | - ------- |
154 | | - bool |
155 | 153 | """ |
156 | 154 | if mat_type == "matrix": |
157 | 155 | translation, oth_transform = read_mat(mat_file) |
@@ -347,50 +345,51 @@ def flirt_node(in_img, output_img, output_mat): |
347 | 345 |
|
348 | 346 |
|
349 | 347 | def template_creation_flirt( |
350 | | - input_brain_list, |
351 | | - input_skull_list, |
352 | | - init_reg=None, |
353 | | - avg_method="median", |
354 | | - dof=12, |
355 | | - interp="trilinear", |
356 | | - cost="corratio", |
357 | | - mat_type="matrix", |
358 | | - convergence_threshold=-1, |
359 | | - thread_pool=2, |
360 | | - unique_id_list=None, |
361 | | -): |
| 348 | + input_brain_list: list[str], |
| 349 | + input_skull_list: list[str], |
| 350 | + init_reg: Optional[list[pe.Node]] = None, |
| 351 | + avg_method: Literal["median", "mean", "std"] = "median", |
| 352 | + dof: Literal[12, 9, 7, 6] = 12, |
| 353 | + interp: Literal["trilinear", "nearestneighbour", "sinc", "spline"] = "trilinear", |
| 354 | + cost: Literal[ |
| 355 | + "corratio", "mutualinfo", "normmi", "normcorr", "leastsq", "labeldiff", "bbr" |
| 356 | + ] = "corratio", |
| 357 | + mat_type: Literal["matrix", "ITK"] = "matrix", |
| 358 | + convergence_threshold: float | np.float64 = -1, |
| 359 | + max_iter: int = 5, |
| 360 | + thread_pool: int | Pool = 2, |
| 361 | + unique_id_list: Optional[list[str]] = None, |
| 362 | +) -> tuple[str, str, list[str], list[str], list[str]]: |
362 | 363 | """Create a temporary template from a list of images. |
363 | 364 |
|
364 | 365 | Parameters |
365 | 366 | ---------- |
366 | | - input_brain_list : list of str |
| 367 | + input_brain_list |
367 | 368 | list of brain images paths |
368 | | - input_skull_list : list of str |
| 369 | + input_skull_list |
369 | 370 | list of skull images paths |
370 | | - init_reg : list of Node |
| 371 | + init_reg |
371 | 372 | (default None so no initial registration performed) |
372 | 373 | the output of the function register_img_list with another reference |
373 | 374 | Reuter et al. 2012 (NeuroImage) section "Improved template estimation" |
374 | 375 | doi:10.1016/j.neuroimage.2012.02.084 uses a ramdomly |
375 | 376 | selected image from the input dataset |
376 | | - avg_method : str |
377 | | - function names from numpy library such as 'median', 'mean', 'std' ... |
378 | | - dof : integer (int of long) |
379 | | - number of transform degrees of freedom (FLIRT) (12 by default) |
380 | | - interp : str |
381 | | - ('trilinear' (default) or 'nearestneighbour' or 'sinc' or 'spline') |
| 377 | + avg_method |
| 378 | + function names from numpy library |
| 379 | + dof |
| 380 | + number of transform degrees of freedom (FLIRT) |
| 381 | + interp |
382 | 382 | final interpolation method used in reslicing |
383 | | - cost : str |
384 | | - ('mutualinfo' or 'corratio' (default) or 'normcorr' or 'normmi' or |
385 | | - 'leastsq' or 'labeldiff' or 'bbr') |
| 383 | + cost |
386 | 384 | cost function |
387 | | - mat_type : str |
388 | | - 'matrix'(default), 'ITK' |
| 385 | + mat_type |
389 | 386 | The type of matrix used to represent the transformations |
390 | | - convergence_threshold : float |
| 387 | + convergence_threshold |
391 | 388 | (numpy.finfo(np.float64).eps (default)) threshold for the convergence |
392 | 389 | The threshold is how different from no transformation is the |
393 | 390 | transformation matrix. |
| 391 | + max_iter |
| 392 | + Maximum number of iterations if transformation does not converge |
394 | 393 | thread_pool : int or multiprocessing.dummy.Pool |
395 | 394 | (default 2) number of threads. You can also provide a Pool so the |
396 | 395 | node will be added to it to be run. |
@@ -496,7 +495,14 @@ def template_creation_flirt( |
496 | 495 | and the loop stops when this temporary template is close enough (with a transformation |
497 | 496 | distance smaller than the threshold) to all the images of the precedent iteration. |
498 | 497 | """ |
499 | | - while not converged: |
| 498 | + iterator = 1 |
| 499 | + iteration = 0 |
| 500 | + if max_iter == -1: |
| 501 | + # make iteration < max_iter always True |
| 502 | + iterator = 0 |
| 503 | + iteration = -2 |
| 504 | + while not converged and iteration < max_iter: |
| 505 | + iteration += iterator |
500 | 506 | temporary_brain_template, temporary_skull_template = create_temporary_template( |
501 | 507 | input_brain_list=output_brain_list, |
502 | 508 | input_skull_list=output_skull_list, |
@@ -628,6 +634,7 @@ def subject_specific_template( |
628 | 634 | "cost", |
629 | 635 | "mat_type", |
630 | 636 | "convergence_threshold", |
| 637 | + "max_iter", |
631 | 638 | "thread_pool", |
632 | 639 | "unique_id_list", |
633 | 640 | ], |
|
0 commit comments