LION.data_loaders.deteCT¶
Classes
|
The 2DeteCT dataset: 5,000 slices of 109 scanned samples (fruit, nuts and other objects), each measured in three modes. |
- class LION.data_loaders.deteCT.deteCT(mode, operator_params=None, parameters=None)[source]¶
Bases:
LIONDatasetThe 2DeteCT dataset: 5,000 slices of 109 scanned samples (fruit, nuts and other objects), each measured in three modes:
| mode1 | mode2 | mode3 Tube Voltage | 90kV | 90kV | 60kV Tube power | 3W | 90W | 60W Filter | Thoraeus | Thoraeus | No Filter Meaning | Low Dose | High Dose| Beam hardening
Detectors: the data were acquired with two detectors, recorded in the
detectorcolumn of the data record. Detector 1: samples 1-63 (slices 1-2830, mixes 1-2); detector 2: samples 64-109 (slices 2831-5000, mixes 2-3). Their noise differs: with the same tube settings, detector 2 gets about a third of the photons of detector 1 (MODE1_I0_PER_DETECTOR). Samples are split in order (training_proportion, validation_proportion), so with the default 0.8/0.1/0.1 the validation and test sets are all detector 2, and the training set is mostly detector 1.Added noise (
add_noiseandnoise_params):add_sinogram_noiseadds Poisson noise and detector cross-talk to the measured (already noisy) sinograms, as in Kiss et al. 2024.noise_params.I0is eithera number: the same I0 for every slice, as LION did before October 2026 and as Kiss et al. 2024 did (I0 = 200 to look like mode1); or
a dict {detector: I0}: one I0 per detector, so that the simulated noise follows each detector’s real noise.
deteCT.noise_parameters()givesMODE1_I0_PER_DETECTOR, which looks like mode1 on each detector.
Samples are returned on LION’s selected device,
default_device()(read and given their added noise on the CPU, so the noise doesn’t depend on the device).The
modesplit (“train”, “validation” or “test”) withparameters(default_parameters()if None).operator_params: the geometry, replacingparameters.operator_paramsif given.parameters(default_parameters()):path_to_dataset: the pre-processed dataset (2deteCT/pre_process_2deteCT.py);input_mode,target_mode: “mode1”, “mode2” or “mode3” (“mode2”, “mode2”);task: what a sample is: “sino2recon” (default), “sino2sino”, “recon2recon”, “recon2sino”, “recon2seg”, “sino2seg”, “joint” or “groundtruth”;training_proportion,validation_proportion,test_proportion: of the samples, split in order (0.8, 0.1, 0.1);do_recon: reconstruct the images here, withrecon_algo(“nag_ls” or “fdk”), instead of loading the dataset’s (False);flat_field_correction,dark_field_correction,log_transform: of the raw projections (True);query: a pandas query of the data record, to select slices (e.g. “detector==1”; “”: all);add_noise: add noise to the sinograms (False), withnoise_params(noise_parameters());operator_params: the geometry: 2DeteCT’s (get_default_geometry()), or one with a subset of its angles (the sinograms are subsampled to match; others are refused, as the data are measured).
- static default_parameters()[source]¶
The parameters (see
__init__): mode 2 sinograms to mode 2 reconstructions, corrected and log-transformed, no added noise.
- static get_default_geometry()[source]¶
The 2DeteCT geometry (from Max Kiss’s code): fan beam, 3600 angles over 360 degrees, a 956-pixel detector (2x subsampled), 1024x1024 images, lengths in voxels.
- sample_groups()[source]¶
The group of each sample, in order: the physical sample (mix) its slice is from, by which the splits are made.
- sample_files()[source]¶
The files the samples are read from, in order: those of each slice’s input and target modes.
- compute_sample_dataframe()[source]¶
self.sample_dataframe: the first and last slice of each physical sample (mix), from the slice table.
- static noise_parameters(I0=None, cross_talk=0.05)[source]¶
noise_params for
add_noise: by default the I0 of each detector that makes mode2 plus the added noise look like that detector’s mode1 (MODE1_I0_PER_DETECTOR). I0 can be a number (the same for every slice, LION’s behaviour before October 2026) or a dict {detector: I0}. cross_talk: fraction of the signal of the neighbouring detector pixels (0.05, from XCIST).
- noise_I0(index)[source]¶
The I0 of the added noise for the slice at index: noise_params.I0 if it is a number, else the I0 of the slice’s detector.
- add_sinogram_noise(sinogram, I0, cross_talk=0.05)[source]¶
The measured
sinogram(flat-field corrected and log transformed) with more noise, as if measured withI0photons per detector pixel (Kiss et al. 2024).LION’s noise simulation (
ct_utils.sinogram_add_noise) assumes a noiseless sinogram; a measured one already has noise. Here the measured sinogram is taken to have photon counts high enough that its own Poisson noise can be ignored: the noise added is the Poisson noise atI0counts, P, convolved with the detector’s cross-talk (each pixel leakingcross_talkinto its two neighbours), so in counts the noisy measurement isI0 exp(-sinogram) + crosstalk(P). An approximation.The data loader passes
noise_I0(index): one I0 per detector whennoise_params.I0is a dict (see the class docstring).