Skip to content

Commit 6dc9f14

Browse files
committed
consistent one import logger across the whole toolbox
1 parent c69316d commit 6dc9f14

21 files changed

Lines changed: 915 additions & 242 deletions

‎TPTBox/__init__.py‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,20 @@
2929
from TPTBox.core.poi_fun.poi_global import POI_Global
3030
from TPTBox.core.vert_constants import ZOOMS, Location, Vertebra_Instance, v_idx2name, v_idx_order, v_name2idx
3131

32-
# Logger
33-
from TPTBox.logger import Log_Type, Logger, Logger_Interface, Print_Logger, String_Logger
32+
# Logger — everything goes through `configure_logging()` and the `logger` proxy.
33+
from TPTBox.logger import (
34+
Log_Type,
35+
Logger,
36+
Logger_Interface,
37+
Print_Logger,
38+
Reflection_Logger,
39+
String_Logger,
40+
configure_logging,
41+
get_default_logger,
42+
log,
43+
logger,
44+
loguru_logger,
45+
)
3446
from TPTBox.logger.log_file import No_Logger
3547

3648
Centroids = POI
@@ -57,8 +69,13 @@
5769
"calc_centroids",
5870
"calc_poi_from_subreg_vert",
5971
"calc_poi_from_two_segs",
72+
"configure_logging",
6073
"core",
74+
"get_default_logger",
6175
"load_poi",
76+
"log",
77+
"logger",
78+
"loguru_logger",
6279
"np_utils",
6380
"to_nii",
6481
"v_idx2name",

‎TPTBox/core/bids_files.py‎

Lines changed: 43 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import numpy as np
1515

1616
import TPTBox
17+
from TPTBox.logger import logger
1718

1819
if TYPE_CHECKING:
1920
from TPTBox.core.nii_poi_abstract import Grid
@@ -66,28 +67,29 @@ def validate_entities(key: str, value: str, name: str, verbose: bool) -> bool:
6667
return True
6768
try:
6869
key = key.lower()
70+
log = logger
6971
if key not in entities_keys:
70-
print(
71-
f"[!] {key} is not in list of legal keys. This name '{name}' is invalid. Legal keys are: {list(entities_keys.keys())}. \nFor use see https://bids-specification.readthedocs.io/en/stable/99-appendices/09-entities.html"
72+
log.on_fail(
73+
f"{key} is not in list of legal keys. This name '{name}' is invalid. Legal keys are: {list(entities_keys.keys())}. \nFor use see https://bids-specification.readthedocs.io/en/stable/99-appendices/09-entities.html"
7274
)
7375
entities_keys[key] = key
7476
return False
7577
if key in entity_alphanumeric and not value.isalnum():
76-
print(f"[!] value for {key} must be alphanumeric. This name '{name}' is invalid, with value {value}")
78+
log.on_fail(f"value for {key} must be alphanumeric. This name '{name}' is invalid, with value {value}")
7779
return False
7880
if key in entity_decimal and not value.isdecimal():
79-
print(f"[!] value for {key} must be decimal. This name '{name}' is invalid, with value {value}")
81+
log.on_fail(f"value for {key} must be decimal. This name '{name}' is invalid, with value {value}")
8082
return False
8183
# if int(value) == 0:
82-
# print(f"[!] value for {key} must be not 0. This name '{name}' is invalid, with value {value}")
84+
# log.on_fail(f"value for {key} must be not 0. This name '{name}' is invalid, with value {value}")
8385
if key in entity_format and value not in formats_relaxed:
84-
print(f"[!] value for {key} must be a format. This name '{name}' is invalid, with value {value}")
86+
log.on_fail(f"value for {key} must be a format. This name '{name}' is invalid, with value {value}")
8587
return False
8688
if key in entity_on_off and value not in ["on", "off"]:
87-
print(f"[!] value for {key} must be in {['on', 'off']}. This name '{name}' is invalid, with value {value}")
89+
log.on_fail(f"value for {key} must be in {['on', 'off']}. This name '{name}' is invalid, with value {value}")
8890
return False
8991
if key in entity_left_right and value not in ["L", "R"]:
90-
print(f"[!] value for {key} must be in {['L', 'R']}. This name '{name}' is invalid, with value {value}")
92+
log.on_fail(f"value for {key} must be in {['L', 'R']}. This name '{name}' is invalid, with value {value}")
9193
return False
9294
# parts = [
9395
# "mag",
@@ -117,7 +119,7 @@ def validate_entities(key: str, value: str, name: str, verbose: bool) -> bool:
117119
else:
118120
return True
119121
except Exception as e:
120-
print(e)
122+
logger.on_fail(e)
121123
return False
122124

123125

@@ -148,29 +150,30 @@ def get_values_from_name(path: Path | str, verbose: bool) -> tuple[str, dict[str
148150

149151
keys = bids_key.split("_")
150152
bids_format = keys[-1]
153+
log = logger
151154
if bids_format not in formats_relaxed and verbose:
152-
print(f"[!] Unknown format {bids_format} in file {name}", formats)
155+
log.on_fail(f"Unknown format {bids_format} in file {name}", formats)
153156
formats_relaxed.append(bids_format)
154157
if file_type not in file_types and verbose:
155-
print(f"[!] Unknown file_type {file_type} in file {name}")
158+
log.on_fail(f"Unknown file_type {file_type} in file {name}")
156159

157160
dic = {}
158161
for idx, s in enumerate(keys[:-1]):
159162
try:
160163
key, value = s.split("-", maxsplit=1)
161164
if idx == 0 and key != "sub" and verbose:
162-
print(f"[!] First key must be sub not {key}. This name '{name}' is invalid")
165+
log.on_fail(f"First key must be sub not {key}. This name '{name}' is invalid")
163166
if idx != 1 and key == "ses" and verbose:
164-
print(f"[!] Session must be second key. This name '{name}' is invalid")
167+
log.on_fail(f"Session must be second key. This name '{name}' is invalid")
165168

166169
if key in dic and verbose:
167-
print(f"[!] {bids_key} contains copies of the same key twice. This name '{name}' is invalid")
170+
log.on_fail(f"{bids_key} contains copies of the same key twice. This name '{name}' is invalid")
168171

169172
validate_entities(key, value, name, verbose)
170173
dic[key] = value
171174
except Exception:
172175
if verbose:
173-
print(f'[!] "{s}" is not a valid key/value pair. Expected "KEY-VALUE" in {name}')
176+
log.on_fail(f'"{s}" is not a valid key/value pair. Expected "KEY-VALUE" in {name}')
174177
return bids_format, dic, bids_key, file_type
175178

176179

@@ -231,9 +234,10 @@ def save_buffer(f: Path, buffer_name: str) -> list[Path]:
231234
try:
232235
with open(str(f / buffer_name), "wb") as b:
233236
pickle.dump(new_buffer, b)
234-
print("\n[ ] Save Buffer:", f) if verbose else None
237+
if verbose:
238+
logger.on_neutral("Save Buffer:", f)
235239
except OSError:
236-
print("Saving not allowed")
240+
logger.on_fail("Saving not allowed")
237241

238242
_cont = 0
239243
return new_buffer
@@ -243,7 +247,8 @@ def save_buffer(f: Path, buffer_name: str) -> list[Path]:
243247
assert "/" not in parent, "only top parent folder allowed"
244248
folder = Path(dataset, parent)
245249
if not folder.exists():
246-
print("[ ] Dose not exist:", (folder), f"{' ':20}") if verbose else None
250+
if verbose:
251+
logger.on_neutral("Dose not exist:", (folder), f"{' ':20}")
247252
continue
248253
if (folder / buffer_name).exists():
249254
import datetime
@@ -253,40 +258,31 @@ def save_buffer(f: Path, buffer_name: str) -> list[Path]:
253258

254259
age = today - file_mod_time
255260
if age.days >= int(max_age_days):
256-
(
257-
print(
258-
"[ ] Delete Buffer - to old:",
261+
if verbose:
262+
logger.on_neutral(
263+
"Delete Buffer - to old:",
259264
(folder / buffer_name),
260265
f"{' ':20}",
261266
)
262-
if verbose
263-
else None
264-
)
265267
(folder / buffer_name).unlink()
266268
if (folder / buffer_name).exists() and parent not in recompute_parents:
267269
with open((folder / buffer_name), "rb") as b:
268270
l = pickle.load(b)
269-
(
270-
print(
271-
f"[{len(l):8}] Read Buffer:",
271+
if verbose:
272+
logger.on_neutral(
273+
f"Read Buffer [{len(l):8}]:",
272274
(folder / buffer_name),
273275
f"{' ':20}",
274276
)
275-
if verbose
276-
else None
277-
)
278277
files[dataset] += l
279278
else:
280-
(
281-
print(
282-
f"[{_cont:8}] Create new Buffer:",
279+
if verbose:
280+
logger.on_neutral(
281+
f"Create new Buffer [{_cont:8}]:",
283282
(folder / buffer_name),
284283
f"{' ':20}",
285284
end="\r",
286285
)
287-
if verbose
288-
else None
289-
)
290286
files[dataset] += save_buffer((folder), buffer_name)
291287
if filter_file is not None:
292288
files: dict[Path | str, list[Path]] = {d: [g for g in f if filter_file(g)] for d, f in files.items()}
@@ -315,7 +311,7 @@ def _scan_tree(path, lvl=1, filter_folder=lambda _x, _y: True, verbose=False):
315311
yield from _scan_tree(entry.path, lvl=lvl + 1, verbose=verbose)
316312
elif entry.name[0] != ".":
317313
if verbose:
318-
print(f"[{_cont:8}]", end="\r")
314+
logger.on_neutral(f"[{_cont:8}]", end="\r", ignore_prefix=True)
319315
_cont += 1
320316

321317
yield entry
@@ -365,10 +361,10 @@ def __init__(
365361
for ds in datasets:
366362
ds_path = Path(ds) if isinstance(ds, str) else ds
367363
if not ds_path.name.startswith("dataset-"):
368-
print(f"[!] Dataset {ds_path.name} does not start with 'dataset-'")
364+
logger.on_fail(f"Dataset {ds_path.name} does not start with 'dataset-'")
369365
for ps in parents:
370366
if not any(ps.startswith(lp) for lp in parents):
371-
print(f"[!] Parentfolder {ps} is not a legal name")
367+
logger.on_fail(f"Parentfolder {ps} is not a legal name")
372368

373369
self.datasets = datasets
374370
self.parents = parents
@@ -437,7 +433,7 @@ def add_file_2_subject(self, bids: BIDS_FILE | Path, ds: Path | str | None = Non
437433
bids_key, file_type = str(bids).rsplit("/", maxsplit=1)[-1].split(".", maxsplit=1)
438434
# print(bids_key)
439435
except Exception:
440-
print("[!] skip file with out a type declaration:", bids.name)
436+
logger.on_fail("skip file with out a type declaration:", bids.name)
441437
# raise e
442438
return
443439

@@ -455,14 +451,12 @@ def add_file_2_subject(self, bids: BIDS_FILE | Path, ds: Path | str | None = Non
455451
if subject not in self.subjects:
456452
self.subjects[subject] = Subject_Container(subject, self.sequence_splitting_keys)
457453
self.count_file += 1
458-
(
459-
print(
454+
if self.verbose:
455+
logger.on_neutral(
460456
f"Found: {subject}, total file keys {(self.count_file)}, total subjects = {len(self.subjects)} ",
461457
end="\r",
458+
ignore_prefix=True,
462459
)
463-
if self.verbose
464-
else None
465-
)
466460
self.subjects[subject].add(bids)
467461

468462
def enumerate_subjects(self, sort: bool = False, shuffle: bool = False) -> list[tuple[str, Subject_Container]]:
@@ -1093,13 +1087,10 @@ def get_changed_path( # noqa: C901
10931087
for key, value in info.items():
10941088
# New Keys are getting checked!
10951089
if non_strict_mode:
1096-
(
1097-
print(
1098-
f"[!] {key} is not in list of legal keys. This name '{key}' is invalid. Legal keys are: {list(entities_keys.keys())}. \nFor use see https://bids-specification.readthedocs.io/en/stable/99-appendices/09-entities.html"
1090+
if key not in entities_keys:
1091+
logger.on_fail(
1092+
f"{key} is not in list of legal keys. This name '{key}' is invalid. Legal keys are: {list(entities_keys.keys())}. \nFor use see https://bids-specification.readthedocs.io/en/stable/99-appendices/09-entities.html"
10991093
)
1100-
if key not in entities_keys
1101-
else None
1102-
)
11031094
else:
11041095
assert key in entities_keys, (
11051096
f"[!] {key} is not in list of legal keys. This name '{key}' is invalid. Legal keys are: {list(entities_keys.keys())}. \nFor use see https://bids-specification.readthedocs.io/en/stable/99-appendices/09-entities.html"
@@ -1601,7 +1592,7 @@ def get_identifier(self, sequence_splitting_keys: list[str]) -> str:
16011592
sequence_splitting_keys (list[str]): list of keys to use for splitting
16021593
"""
16031594
if "sub" not in self.info:
1604-
print(f"family_id, no sub-key, got {self.info}")
1595+
logger.on_fail(f"family_id, no sub-key, got {self.info}")
16051596
identifier = "sub-404"
16061597
else:
16071598
identifier = "sub-" + self.info["sub"]

‎TPTBox/core/dicom/dicom_extract.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def dicom_to_nifti_multiframe(ds: pydicom.FileDataset, nii_path: str | Path) ->
201201
# }
202202
# ],
203203
# --- No geometry info (e.g. RGB screen captures or video frames) ---
204-
print("⚠️ No spatial metadata found — assuming pixel size = 1mm and identity orientation.")
204+
logger.on_warning("No spatial metadata found — assuming pixel size = 1mm and identity orientation.")
205205
affine = np.eye(4)
206206
affine[0, 0] = 1.0
207207
affine[1, 1] = 1.0
@@ -332,7 +332,7 @@ def _extract_nii_from_dicom(dicom_out_path, nii_path):
332332

333333
return False
334334
except Exception:
335-
print(nii_path)
335+
logger.on_fail(nii_path)
336336

337337
return True
338338

@@ -525,7 +525,7 @@ def _add_grid_info_to_json(nii_path: Path | str, simp_json: Path | str, force_up
525525
json_dict = load_json(simp_json) if Path(simp_json).exists() else {}
526526
if "grid" in json_dict and not force_update:
527527
return json_dict
528-
print("Read Grid info", Path(simp_json).exists(), "grid" in json_dict)
528+
logger.on_neutral("Read Grid info", Path(simp_json).exists(), "grid" in json_dict)
529529
nii = NII.load(nii_path, False)
530530
gird = {
531531
"shape": nii.shape,

‎TPTBox/core/internal/elastic_deform.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from numpy.typing import NDArray
66

77
from TPTBox import NII
8+
from TPTBox.logger import logger
89

910

1011
def deformed_nii(
@@ -51,7 +52,7 @@ def deformed_nii(
5152
if sigma is None or points is None:
5253
sigma, points = get_random_deform_parameter(deform_factor=deform_factor)
5354

54-
print("deformation parameter sigma = ", round(sigma, 4), "; n_points = ", points)
55+
logger.on_neutral("deformation parameter sigma = ", round(sigma, 4), "; n_points = ", points)
5556
t = time.time()
5657
values = list(nii_dic.values())
5758
# Deform
@@ -73,7 +74,7 @@ def deformed_nii(
7374
out2: dict[str, NII] = {}
7475
for (k, nii), arr in zip(nii_dic.items(), out, strict=True):
7576
out2[k] = nii.set_array(arr[p:-p, p:-p, p:-p])
76-
print("Deformation took", round(time.time() - t, 1), "Seconds")
77+
logger.on_neutral("Deformation took", round(time.time() - t, 1), "Seconds")
7778
return out2
7879

7980

‎TPTBox/core/nii_poi_abstract.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from TPTBox.core.np_utils import np_count_nonzero
1414
from TPTBox.core.vert_constants import COORDINATE
15-
from TPTBox.logger import Log_Type
15+
from TPTBox.logger import Log_Type, logger
1616

1717
from .vert_constants import (
1818
AFFINE,
@@ -95,7 +95,7 @@ def __str__(self) -> str:
9595
try:
9696
zoom = "(" + ",".join([f"{a:.2f}" for a in self.zoom]) + ")"
9797
except Exception as e:
98-
print(e)
98+
logger.on_warning(e)
9999
zoom = self.zoom
100100

101101
return f"shape={self.shape_int},spacing={zoom}, origin={origin}, ori={self.orientation}" # type: ignore

‎TPTBox/core/np_utils.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
from TPTBox.core.compat import zip_strict
3131
from TPTBox.core.vert_constants import COORDINATE, LABEL_MAP, LABEL_REFERENCE
32+
from TPTBox.logger import logger
3233

3334
UINT = TypeVar("UINT", bound=np.unsignedinteger[Any])
3435
INT = TypeVar("INT", bound=np.signedinteger[Any])
@@ -110,7 +111,7 @@ def cc3dstatistics(arr: UINTARRAY, use_crop: bool = True) -> dict:
110111
arrc = arr[crop]
111112
return _cc3dstats(arrc)
112113
except ValueError as e:
113-
print(e)
114+
logger.on_warning(e)
114115
return _cc3dstats(arr)
115116

116117

@@ -1317,7 +1318,8 @@ def _convex_hull(
13171318
"""
13181319
points = np.transpose(np.where(arr))
13191320
if len(points) <= 3:
1320-
print("To few points") if verbose else None
1321+
if verbose:
1322+
logger.on_warning("To few points")
13211323
return np.zeros_like(arr, dtype=arr.dtype)
13221324
hull = scipy.spatial.ConvexHull(points)
13231325
deln = scipy.spatial.Delaunay(points[hull.vertices])
@@ -1401,7 +1403,6 @@ def infect(x, y, z):
14011403
infect(*infect_list.pop())
14021404
boundary[boundary == 0] = 2
14031405
boundary -= 1
1404-
print(boundary.sum())
14051406
return boundary
14061407

14071408

@@ -1449,7 +1450,7 @@ def np_betti_numbers(img: np.ndarray, verbose=False) -> tuple[int, int, int]:
14491450
b2 -= 1
14501451
b1 = b0 + b2 - euler_char_num # Euler number = Betti:0 - Betti:1 + Betti:2
14511452
if verbose:
1452-
print(f"Betti number: b0 = {b0}, b1 = {b1}, b2 = {b2}")
1453+
logger.on_neutral(f"Betti number: b0 = {b0}, b1 = {b1}, b2 = {b2}")
14531454
return b0, b1, b2
14541455

14551456

0 commit comments

Comments
 (0)