LION.data_loaders.LIDC_IDRI¶
Classes
|
The LIDC-IDRI dataset: lung CT scans of 1010 patients with nodules annotated by up to four radiologists, pre-processed into 512x512 slices ( |
Functions
|
One of the annotations, drawn with torch's random numbers (so |
The consensus mask of one nodule on one slice: the pixels that at least a fraction |
|
|
A patient number as LIDC-IDRI writes it, 4 digits: 7 -> "0007". |
|
The contents of the JSON file |
|
None if the .npy file exists and holds all the data its header says, else what is wrong. |
|
Slices to load for one patient, sorted. |
- class LION.data_loaders.LIDC_IDRI.LIDC_IDRI(mode, operator_params=None, parameters=None)[source]¶
Bases:
LIONDatasetThe LIDC-IDRI dataset: lung CT scans of 1010 patients with nodules annotated by up to four radiologists, pre-processed into 512x512 slices (
LIDC_IDRI/pre_process_lidc_idri.py). Patients are split into training, validation and test (mode); each patient’s slices stay in one split.What a sample is depends on
parameters.task:“reconstruction”: (sinogram, image): the image in mass density, and its sinogram with the operator of
operator_params(the geometry), withsinogram_transform(e.g. an experiment’s noise) applied;“segmentation”, “joint”, “end_to_end”: (image, mask): the mask is (background, nodule) channels, from the annotations (
annotation);“diagnostic”: the patient’s diagnosis.
parameters(default_parameters()):training_proportion,validation_proportion: of the patients (0.8, 0.1;testing_proportionis the rest, recorded only);max_num_slices_per_patient: slices taken per patient (5; -1: all);pcg_slices_nodule: the fraction of them with a nodule (0.5; more of the other kind when a patient has too few);legacy_slice_selection,legacy_patient_list: reproduce the selection of LION before October 2026 (False);task,folder(the pre-processed dataset);operator_params: the geometry of the sinograms, for “reconstruction” (default_geometry(), for which the slices are made);annotation: “consensus” (the pixels at leastclevelof the annotations mark; 0.5) or “random” (one annotation per nodule, chosen withannotation_seed; 0).
Samples are on LION’s device (
default_device()). Cite it withcite().The
modesplit (“train”, “validation” or “test”) withparameters(default_parameters(operator_params)if None);operator_params: the CT geometry, replacingparameters.operator_paramsif given.Pixel spacing: the pre-processing resamples every slice to
PIXEL_SPACING_MM(500 mm over 512x512 pixels, the largest field of view in the dataset, so no scan is cropped; smaller ones are surrounded by air), so all images have the same physical size.LIDC_IDRI.default_geometry()is the matching CT geometry. Datasets processed before October 2026 have each scan’s own spacing (0.46 to 0.98 mm) and nopre_processing.json: the loader warns, andpython LION/data_loaders/LIDC_IDRI/pre_process_lidc_idri.py --resample-onlyresamples them in place (no DICOM files needed).Damaged data: the download and pre-processing can leave incomplete files. The loader leaves out, with a warning, selected slices whose files are incomplete or unreadable, and the patients
pre_processing.jsonlists as not resampled.Images: for reconstruction, the CT images (Hounsfield units) are turned into mass density in g/cm^3 (
ct_utils.from_HU_to_density: air 0.0012, water 1.0137, 500 HU 1.52). With LION’s geometries in mm, the sinograms are density line integrals in g/cm^3 * mm, which is what the noise model ofct_utils.sinogram_add_noiseexpects: the experiments (ct_experiments) add the noise.- static patient_list(path_to_processed_dataset, legacy=False)[source]¶
The patients of the dataset, in order, and the number the train/validation/test proportions are taken of.
The patients are the folders named LIDC-IDRI-NNNN, so patients without a scan (0238 and 0585) or that failed pre-processing are not in the list, and other folders (e.g. a leftover
LIDC-IDRI-0002.tmp) are ignored.legacy=Trueis LION’s list before October 2026 (parameter files withoutlegacy_patient_listuse it): patients 1 to N, N the number of entries namedLIDC-IDRI-*, with proportions of N + 1. As 0238 and 0585 have no scan, it leaves out the last two patients (1011 and 1012), and any other entry (a missing patient, a leftover folder) moves the splits.
- static read_not_resampled(path_to_processed_dataset)[source]¶
Patients the pre-processing could not resample (pre_processing.json).
- drop_damaged_slices(slices_to_load)[source]¶
Leave out, with a warning, the slices that cannot be loaded: those of patients the pre-processing could not resample, and incomplete or unreadable files (and, for tasks with masks, their mask files).
A damaged file can come from an interrupted download, pre-processing or copy. Only the selected slices are checked (their headers and sizes), so this is quick unless every slice is selected.
- static read_pixel_spacing(path_to_processed_dataset)[source]¶
The pixel spacing (mm) of the processed slices, or None for a dataset processed before October 2026 (each scan’s own spacing).
- check_geometry()[source]¶
Warn if the geometry’s pixel size is not the data’s pixel spacing: then sizes, and the physical noise model’s path lengths, are wrong.
- static default_geometry(angles=None)[source]¶
The fan-beam geometry of the pre-processed slices: 512x512 pixels of
PIXEL_SPACING_MM(500 mm), source to centre 575 mm, source to detector 1050 mm, as LION’s default geometry, with a 1024 x 1 mm detector: it covers a 504 mm circle, like the ~50 degree fan of a clinical scanner.angles: in radians (None: 360 over 360 degrees).
- static default_parameters(operator_params=None, task='reconstruction')[source]¶
The parameters (see the class), for
task, with the geometryoperator_params: for “reconstruction”,default_geometry()if None.
- get_slices_to_load(patient_list, non_nodule_slices_dict, nodule_slices_dict, num_slices_per_patient, pcg_slices_nodule)[source]¶
The slices to load of each patient of
patient_list:{patient: [slice, ...]},num_slices_per_patientof them (-1: all), a fractionpcg_slices_nodulewith a nodule (select_slices), from each patient’s slices without (non_nodule_slices_dict) and with (nodule_slices_dict) a nodule.
- get_patient_id_to_first_index_dict(patient_with_slices_to_load)[source]¶
The index of each patient’s first sample:
{patient: index}, from the slices to load (patient_with_slices_to_load).
- get_slice_index_to_patient_id_list(patient_with_slices_to_load)[source]¶
The patient of each sample, in order: each patient once per slice it has to load.
- get_reconstruction_tensor(file_path)[source]¶
The slice saved at
file_path, (1, 512, 512), on the dataset’s device.
- set_sinogram_transform(sinogram_transform, seed=None)[source]¶
A function applied to each clean sinogram, e.g. the noise of an experiment.
seed: an integer makes its random numbers depend only on the seed and the slice (patient and slice file): each slice gets the same noisy sinogram in every epoch, run, order and DataLoader worker, as a scan measures it once. None: fresh random numbers each time.
- compute_clean_sinogram(image=None)[source]¶
The sinogram of
imagewith the dataset’s operator (fromoperator_params), without noise.
- get_mask_tensor(patient_id, slice_index)[source]¶
The nodule mask of one slice (
slice_indexofpatient_id): (2, 512, 512), background and nodule channels, from the annotations asannotationsays; empty if the slice has no nodule.
- sample_groups()[source]¶
The group of each sample, in order: its patient. Slices of one patient are near-copies, so a patient’s slices are kept in one split, and evaluations check that no test patient was trained on.
- sample_files()[source]¶
The files the samples are read from, in order: each slice, and for tasks with masks the slice’s mask files.
- LION.data_loaders.LIDC_IDRI.choose_random_annotation(nodule_annotations_list)[source]¶
One of the annotations, drawn with torch’s random numbers (so
rng.seededmakes the choice reproducible).
- LION.data_loaders.LIDC_IDRI.create_consensus_annotation(path_to_patient_folder, slice_index, nodule_index, nodule_annotations_list, clevel)[source]¶
The consensus mask of one nodule on one slice: the pixels that at least a fraction
clevelof its annotations (nodule_annotations_list) mark.
- LION.data_loaders.LIDC_IDRI.format_index(index)[source]¶
A patient number as LIDC-IDRI writes it, 4 digits: 7 -> “0007”.
- LION.data_loaders.LIDC_IDRI.load_json(file_path)[source]¶
The contents of the JSON file
file_path(FileNotFoundError if there is none).
- LION.data_loaders.LIDC_IDRI.npy_problem(path)[source]¶
None if the .npy file exists and holds all the data its header says, else what is wrong. Reads the header only.
- LION.data_loaders.LIDC_IDRI.select_slices(non_nodule_slices, nodule_slices, max_slices, pcg_slices_nodule, legacy=False)[source]¶
Slices to load for one patient, sorted.
Takes up to
max_slicesslices (all of them if -1), a fractionpcg_slices_noduleof them with a nodule. If the patient has too few slices of one kind, more of the other kind are taken; patients without nodule slices contribute non-nodule slices.legacy=Truereproduces LION before October 2026: at most min(max_slices, #non-nodule, #nodule) slices, so patients without nodule slices contributed none, and -1 meant at most 1000 of each.