From 7bd25011aa996b11381d0ffa4be3bfb4badaee6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Coussat?= Date: Tue, 15 Sep 2026 17:04:39 +0200 Subject: [PATCH] ENH: Remove json dependency Remove the dependency on the json library also unifies how LUTs are stored and loaded (using NumPy interface instead). --- applications/pctdoublelut/pctdoublelut.py | 1 - applications/pctpairprotons/pctpairprotons.py | 4 +- applications/pctweplfit/pctweplfit.py | 6 +-- documentation/docs/wepl_calibration.md | 10 ++--- test/pct_application_test.py | 43 +++++++++---------- 5 files changed, 27 insertions(+), 37 deletions(-) diff --git a/applications/pctdoublelut/pctdoublelut.py b/applications/pctdoublelut/pctdoublelut.py index 1ed7189..e1c4f64 100644 --- a/applications/pctdoublelut/pctdoublelut.py +++ b/applications/pctdoublelut/pctdoublelut.py @@ -1,6 +1,5 @@ #!/usr/bin/env python import argparse -import json import sys from multiprocessing import Pool, Manager import os diff --git a/applications/pctpairprotons/pctpairprotons.py b/applications/pctpairprotons/pctpairprotons.py index d925916..ebceaad 100644 --- a/applications/pctpairprotons/pctpairprotons.py +++ b/applications/pctpairprotons/pctpairprotons.py @@ -1,6 +1,5 @@ #!/usr/bin/env python import argparse -import json import itk from itk import PCT as pct import numpy as np @@ -311,8 +310,7 @@ def load_tree_as_df(root_file, tree_name): if args_info.fit is not None: # Single LUT verbose("Converting energy loss or TOF to WEPL using single LUT technique…") - with open(args_info.fit, encoding="utf-8") as f: - p = json.load(f) + p = np.loadtxt(f) if args_info.fit_kind == "tof": xs = pairs["PreGlobalTime_out"] - pairs["PreGlobalTime_in"] elif args_info.fit_kind == "energy": diff --git a/applications/pctweplfit/pctweplfit.py b/applications/pctweplfit/pctweplfit.py index c4b8595..74cbd14 100644 --- a/applications/pctweplfit/pctweplfit.py +++ b/applications/pctweplfit/pctweplfit.py @@ -1,6 +1,5 @@ #!/usr/bin/env python import argparse -import json import sys from multiprocessing import Pool, Manager import warnings @@ -323,10 +322,7 @@ def fit(xs, ys, xlabel, ylabel): plt.show() for d, p in ps.items(): - with open( - f"{output}/{xlabel}_to_{ylabel}_fit_deg{d}.json", "w", encoding="utf-8" - ) as f: - json.dump(p, f) + np.savetxt(f"{output}/{xlabel}_to_{ylabel}_fit_deg{d}.txt", p) fit(tofs, wepls, "tof", "wepl") fit(elosses, wepls, "eloss", "wepl") diff --git a/documentation/docs/wepl_calibration.md b/documentation/docs/wepl_calibration.md index b29b4f8..daf7dc9 100644 --- a/documentation/docs/wepl_calibration.md +++ b/documentation/docs/wepl_calibration.md @@ -16,7 +16,7 @@ pctweplfit \ -v ``` -In the resulting `output` folder, along with all intermediate results (ROOT files from the GATE simulations) will be two files `eloss_to_wepl_fit_deg3.json` and `tof_to_wepl_fit_deg3.json` that contain the coefficients of the polynomials. These files can then be passed to `pctpairprotons` with the corresponding `--fit-kind` parameters. +In the resulting `output` folder, along with all intermediate results (ROOT files from the GATE simulations) will be two files `eloss_to_wepl_fit_deg3.txt` and `tof_to_wepl_fit_deg3.txt` that contain the coefficients of the polynomials. These files can then be passed to `pctpairprotons` with the corresponding `--fit-kind` parameters. Here is an example of a `pctpairprotons` invocations with energy-loss fit: ```bash @@ -26,7 +26,7 @@ pctpairprotons \ -o pairs.mhd \ --plane-in -110 \ --plane-out 110 \ - --fit output/eloss_to_wepl_fit_deg3.json \ + --fit output/eloss_to_wepl_fit_deg3.txt \ --fit-kind energy ``` @@ -42,7 +42,7 @@ pctdoublelut \ -v ``` -In the resulting `output` folder, along with all intermediate results (ROOT files from the GATE simulations) will be files named `tof_coeffs_X.json` and `vel_coeffs_X.json` that contain the coefficients of the polynomials, where `X` is the polynomial degree. These files can then be passed to `pctpairprotons` with the appropriate parameters. +In the resulting `output` folder, along with all intermediate results (ROOT files from the GATE simulations) will be files named `tof_coeffs_X.txt` and `vel_coeffs_X.txt` that contain the coefficients of the polynomials, where `X` is the polynomial degree. These files can then be passed to `pctpairprotons` with the appropriate parameters. Here is an example of a `pctpairprotons` invocations that uses the double LUT fits with polynomials of degree 9: ```bash @@ -52,8 +52,8 @@ pctpairprotons \ -o pairs.mhd \ --plane-in -110 \ --plane-out 110 \ - --lut-tof output/tof_coeffs_9.json \ - --lut-vel output/vel_coeffs_9.json \ + --lut-tof output/tof_coeffs_9.txt \ + --lut-vel output/vel_coeffs_9.txt \ --quadric 1 0 1 0 0 0 0 0 0 -10000 \ --angle 0 ``` diff --git a/test/pct_application_test.py b/test/pct_application_test.py index 9043d9c..623b7eb 100644 --- a/test/pct_application_test.py +++ b/test/pct_application_test.py @@ -1,4 +1,3 @@ -import json import pytest import itk import urllib.request @@ -53,28 +52,26 @@ def test_weplfit_application(tmp_path): f"-o {output} --path-type phantom_length -d 220 -e 200 -l 220 --seed 1234 -v" ) - with open(output / "tof_to_wepl_fit_deg3.json", encoding="utf-8") as f: - tof_to_wepl_fit = np.array(json.load(f)) - reference = np.array( - [ - 8507.18830081492, - -38342.09213481464, - 58268.25904916112, - -29633.875319259325, - ] - ) - assert np.allclose(tof_to_wepl_fit, reference) - with open(output / "eloss_to_wepl_fit_deg3.json", encoding="utf-8") as f: - eloss_to_wepl_fit = np.array(json.load(f)) - reference = np.array( - [ - -5.4569381663242e-06, - -0.003455118013641362, - 2.236667157315751, - -0.1768424416075149, - ] - ) - assert np.allclose(eloss_to_wepl_fit, reference) + tof_to_wepl_fit = np.loadtxt(output / "tof_to_wepl_fit_deg3.txt") + reference = np.array( + [ + 8507.18830081492, + -38342.09213481464, + 58268.25904916112, + -29633.875319259325, + ] + ) + assert np.allclose(tof_to_wepl_fit, reference) + eloss_to_wepl_fit = np.loadtxt(output / "eloss_to_wepl_fit_deg3.txt") + reference = np.array( + [ + -5.4569381663242e-06, + -0.003455118013641362, + 2.236667157315751, + -0.1768424416075149, + ] + ) + assert np.allclose(eloss_to_wepl_fit, reference) def test_doublelut_application(tmp_path):