Skip to content

Commit

Permalink
Update JHU and Canon phantom conversions (#281)
Browse files Browse the repository at this point in the history
* update python conversion script for newer phantoms
* Add 3DRP recon; fix phantom conversions


---------

Co-authored-by: Anthony Galassi <[email protected]>
  • Loading branch information
bilgelm and bendhouseart committed Jun 4, 2024
1 parent 1ff4023 commit e49524e
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 89 deletions.
47 changes: 7 additions & 40 deletions metadata/PET_reconstruction_methods.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,46 +107,13 @@
]
},
{
"contents": "3DRP",
"contents": "3DKinahan-Rogers",
"subsets": null,
"iterations": null,
"ReconMethodName": "3D Kinahan-Rogers",
"ReconMethodParameterLabels": [
"none"
],
"ReconMethodParameterValues": [
null,
null
],
"ReconMethodParameterUnits": [
null,
null
],
"ReconMethodParameterValues": [
null,
null
]
},
{
"contents": "3D Kinahan-Rogers",
"subsets": null,
"iterations": null,
"ReconMethodName": "3D Kinahan-Rogers",
"ReconMethodParameterLabels": [
"none"
],
"ReconMethodParameterValues": [
null,
null
],
"ReconMethodParameterUnits": [
null,
null
],
"ReconMethodParameterValues": [
null,
null
]
"ReconMethodName": "3D Reprojection",
"ReconMethodParameterLabels": [],
"ReconMethodParameterValues": [],
"ReconMethodParameterUnits": []
}
],
"reconstruction_names": [
Expand Down Expand Up @@ -211,8 +178,8 @@
"name": "Filtered Back Projection"
},
{
"value": "3DRP",
"name": "3D Kinahan-Rogers"
"value": "Kinahan-Rogers",
"name": "Reprojection"
}
]
}
23 changes: 15 additions & 8 deletions pypet2bids/pypet2bids/helper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,6 @@ def get_recon_method(ReconstructionMethodString: str) -> dict:
contents = ReconstructionMethodString.replace(" ", "")
subsets = None
iterations = None
ReconMethodParameterUnits = ["none", "none"]
ReconMethodParameterLabels = ["subsets", "iterations"]

# determine order of recon iterations and subsets, this is not a surefire way to determine this...
iter_sub_combos = {
Expand Down Expand Up @@ -836,11 +834,20 @@ def get_recon_method(ReconstructionMethodString: str) -> dict:
ReconMethodName = dimension + " " * len(dimension) + expanded_name.rstrip()
ReconMethodName = " ".join(ReconMethodName.split())

if ReconMethodName in ["Filtered Back Projection", "3D Reprojection"]:
ReconMethodParameterLabels = []
ReconMethodParameterUnits = []
ReconMethodParameterValues = []
else: # assume it is OSEM or a variant
ReconMethodParameterLabels = ["subsets", "iterations"]
ReconMethodParameterUnits = ["none", "none"]
ReconMethodParameterValues = [subsets, iterations]

reconstruction_dict = {
"ReconMethodName": ReconMethodName,
"ReconMethodParameterUnits": ReconMethodParameterUnits,
"ReconMethodParameterLabels": ReconMethodParameterLabels,
"ReconMethodParameterValues": [subsets, iterations],
"ReconMethodParameterValues": ReconMethodParameterValues,
}

if None in reconstruction_dict["ReconMethodParameterValues"]:
Expand Down Expand Up @@ -952,11 +959,11 @@ def ad_hoc_checks(
if items_that_should_be_checked is None:
items_that_should_be_checked = {}
hardcoded_items = {
"InjectedRadioactivityUnits": "MBq",
"SpecificRadioactivityUnits": ["Bq/g", "MBq/ug"],
"InjectedMassUnits": "ug",
"MolarActivityUnits": "GBq/umolug",
"MolecularWeightUnits": "g/mol",
'InjectedRadioactivityUnits': ['MBq', 'mCi'],
'SpecificRadioactivityUnits': ['Bq/g', 'MBq/ug'],
'InjectedMassUnits': 'ug',
'MolarActivityUnits': 'GBq/umolug',
'MolecularWeightUnits': 'g/mol'
}

# if none are
Expand Down
145 changes: 133 additions & 12 deletions scripts/matlab_conversions.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
% note that usually we use the *parameter.txt file facilitating the metadata
% information but here it is done fully for completeness
%
% cyril pernet - may 2022
% cyril pernet - Nov 2023

%% set paths where the repo is
%source = 'D:\BIDS\ONP\OpenNeuroPET-Phantoms\sourcedata\';
%destination = 'D:\BIDS\ONP\OpenNeuroPET-Phantoms\';
%% set paths where the repo is to bypass the path/env parts below
% source = 'D:\BIDS\ONP\OpenNeuroPET-Phantoms\sourcedata\';
% destination = 'D:\BIDS\ONP\OpenNeuroPET-Phantoms\';

%% get the path to this script
matlab_conversions_script_path = mfilename('fullpath');
Expand All @@ -20,7 +20,9 @@
source = strjoin({phantoms_folder_path, 'sourcedata'}, filesep);
destination = strjoin({phantoms_folder_path, 'matlab'}, filesep);

mkdir(destination)
if ~exist(destination,'dir')
mkdir(destination)
end
copyfile(strjoin({phantoms_folder_path, 'dataset_description.json'}, filesep), strjoin({destination, 'dataset_description.json'}, filesep))

%% sets the environment variable so that matlab can reach dcm2niix on posix
Expand Down Expand Up @@ -49,6 +51,7 @@

message = 'Failed to convert subject, moving onto next.';


%%% Neurobiology Research Unit - Copenhagen
%% ----------------------------------------
%
Expand Down Expand Up @@ -436,13 +439,14 @@
end

try
meta.AttenuationCorrection = 'measured' ; % some how the field is not there
meta.ReconMethodParameterLabels = ["none", "none"];
meta.ReconMethodParameterUnits = ["none", "none"];
meta.ReconMethodParameterValues = [0, 0];
meta.FrameDuration = 98000
dcm2niix4pet(fullfile(source,['GeneralElectricAdvance-NIMH' filesep ...
'long_trans']),meta,'o',fullfile(destination,['sub-GeneralElectricAdvanceLongNIMH' filesep 'pet']));
meta.AttenuationCorrection = 'measured' ; % some how the field is not there
meta.ReconMethodParameterLabels = ["none", "none"];
meta.ReconMethodParameterUnits = ["none", "none"];
meta.ReconMethodParameterValues = [0, 0];
meta.FrameDuration = 98000;

dcm2niix4pet(fullfile(source,['GeneralElectricAdvance-NIMH' filesep ...
'long_trans']),meta,'o',fullfile(destination,['sub-GeneralElectricAdvanceLongNIMH' filesep 'pet']));
catch
disp(message);
end
Expand Down Expand Up @@ -476,6 +480,123 @@
out = ecat2nii(fullfile(source,['SiemensHRRT-JHU' filesep 'Hoffman.v']),...
meta,'gz',true,'FileListOut',fullfile(destination,['sub-SiemensHRRTJHU' filesep 'pet' filesep 'sub-SiemensHRRTJHU.nii']));


%% Johns Hopkins University
% ----------------------------------------------

% Siemens HRRT
% ------------
try
clear meta
meta.TimeZero = 'ScanStart';
meta.Manufacturer = 'Siemens';
meta.ManufacturersModelName = 'HRRT';
meta.InstitutionName = 'Johns Hopkins University, USA';
meta.BodyPart = 'Phantom';
meta.Units = 'Bq/mL';
meta.TracerName = 'FDG';
meta.TracerRadionuclide = 'F18';
meta.InjectedRadioactivity = 0.788;
meta.InjectedRadioactivityUnits = 'mCi';
meta.SpecificRadioactivity = 'n/a';
meta.SpecificRadioactivityUnits = 'n/a';
meta.ModeOfAdministration = 'infusion';
meta.AcquisitionMode = 'list mode';
meta.ImageDecayCorrected = true; % when passing this as string it fails validation
meta.ImageDecayCorrectionTime = 0;
meta.ReconFilterType = 'Gaussian';
meta.ReconFilterSize = 2;
meta.AttenuationCorrection = 'transmission scan with a 137Cs point source';
meta.ScatterCorrectionMethod = 'Single-scatter simulation';
meta.ScanStart = 0;
meta.InjectionStart = -2183;
meta.ReconMethodParameterLabels = ["subsets" "iterations"];
meta.ReconMethodParameterLabels = ["none" "none"];
meta.ReconMethodParameterValues = [16 2];

out = ecat2nii(fullfile(source,['SiemensHRRT-JHU' filesep 'Hoffman.v']),...
meta,'gz',true,'FileListOut',fullfile(destination,['sub-SiemensHRRTJHU' filesep 'pet' filesep 'sub-SiemensHRRTJHU.nii']));

catch
disp(message);
end


% General Electric Medical Systems Advance
% -----------------------------------------
try
clear meta
meta.TimeZero = 'ScanStart';
meta.Manufacturer = 'GE MEDICAL SYSTEMS';
meta.ManufacturersModelName = 'GE Advance';
meta.InstitutionName = 'Johns Hopkins University, USA';
meta.BodyPart = 'Phantom';
meta.Units = 'Bq/mL';
meta.TracerName = 'FDG';
meta.TracerRadionuclide = 'F18';
meta.InjectedRadioactivity = 0.788;
meta.InjectedRadioactivityUnits = 'mCi';
meta.SpecificRadioactivity = 'n/a';
meta.SpecificRadioactivityUnits = 'n/a';
meta.ModeOfAdministration = 'infusion';
meta.ScanStart = 0;
meta.InjectionStart = -5336;
meta.FrameTimesStart = 0;
meta.AcquisitionMode = 'list mode';
meta.ImageDecayCorrected = 'true';
meta.ImageDecayCorrectionTime = 0;
meta.ScatterCorrectionMethod = 'Single-scatter simulation';
meta.ReconMethodName = '3D Reprojection';
meta.ReconMethodParameterLabels = ["none"];
meta.ReconParameterUnits = ["none"];
meta.ReconMethodParameterValues = [0];
meta.ReconFilterType = "none";
meta.ReconFilterSize = 0;
meta.AttenuationCorrection = '2D-acquired transmission scan with a 68Ge pin';

dcm2niix4pet(fullfile(source,'GeneralElectricAdvance-JHU'),...
meta,'o',fullfile(destination,['sub-GeneralElectricAdvanceJHU' filesep 'pet']));

catch
disp(message);
end

%% Chesapeake Medical Imaging
% ----------------------------------------------

% Canon Cartesion Prime PET-CT
% ----------------------

try
clear meta
meta.TimeZero = 'ScanStart';
meta.Manufacturer = 'Canon Medical Systems';
meta.ManufacturersModelName = 'Cartesion Prime';
meta.InstitutionName = 'Chesapeake Medical Imaging, USA';
meta.BodyPart = 'Phantom';
meta.Units = 'Bq/mL';
meta.TracerName = 'FDG';
meta.TracerRadionuclide = 'F18';
meta.InjectedRadioactivity = 0.87;
meta.InjectedRadioactivityUnits = 'mCi';
meta.SpecificRadioactivity = 'n/a';
meta.SpecificRadioactivityUnits = 'n/a';
meta.ModeOfAdministration = 'infusion';
meta.ScanStart = 0;
meta.InjectionStart = -2312;
meta.FrameTimesStart = [0 300 600 900];
meta.AcquisitionMode = 'list mode';
meta.ImageDecayCorrected = 'true';
meta.ImageDecayCorrectionTime = 0;
meta.ReconMethodParameterLabels = ["subsets" "iterations"];
meta.ReconMethodParameterLabels = ["none" "none"];
meta.ReconMethodParameterValues = [24 5];
meta.ReconFilterType = "Gaussian";
meta.ReconFilterSize = 4;

dcm2niix4pet(fullfile(source,'CanonCartesionPrimePETCT-NIA'),...
meta,'o',fullfile(destination,['sub-CanonCartesionPrimeNIA' filesep 'pet']));

catch
disp(message);
end
Loading

0 comments on commit e49524e

Please sign in to comment.