matlab
- matlab.get_pet_metadata(varargin)
Routine that outputs PET scanner metadata following BIDS.
The metadata generated here are passed along imaging data to the converters, ecat2nii.m or dcm2niix4pet.m allowing to produce a .nii file with a BIDS compliant json file.
- Parameters
Default – (acquisition and reconstruction parameters) can be stored in a *_parameters.txt seating on disk next to this function or passed as argument in. Replace * by the name of your scanner - for now we tested ‘SiemensBiograph’, ‘SiemensHRRT’, ‘GEAdvance’, ‘PhillipsVereos’, ‘PhillipsIngenuityPETMR’,’PhillipsIngenuityPETCT’. (see templates, as some info can be recovered from ecat or dcm - ie not all info is necessarily needed)
inputs – a series of key/value pairs are expected
- Returns metadata
a structure with BIDS fields filled (such structure is ready to be written as json file using e.g. the bids matlab jsonwrite function, typically associated with the *_pet.nii file)
- Format
metadata = get_pet_metadata(key,value)
Note
Mandatory inputs are as follows:
Scanner name of scanner, map to a *parameters.txt file e.g. ‘Scanner’, ‘SiemensBiograph’
TimeZero when was the tracer injected e.g. ‘TimeZero’,’11:05:01’
ModeOfAdministration e.g. ‘ModeOfAdministration’, ‘bolus’
TracerName which tracer was used e.g. ‘TracerName’,’DASB’
TracerRadionuclide which nuclide was used e.g. ‘TracerRadionuclide’,’C11’
+ at least 2 of those key/value arguments to infer others:
InjectedRadioactivity value in MBq e.g. ‘InjectedRadioactivity’, 605.3220
InjectedMass Value in ug e.g. ‘InjectedMass’, 1.5934
MolarActivity value in GBq/umol e.g. ‘MolarActivity’, 107.66
MolecularWeight value in g/mol e.g. ‘MolecularWeight’, 15.02
SpecificRadioactivity in Bq/g or Bq/mol e.g. ‘SpecificRadioactivity’, 3.7989e+14
Here is an example of such defaults, used at NRU for our SiemensBiograph_parameters.txt
InstitutionName = 'Rigshospitalet, NRU, DK'; BodyPart = 'Phantom'; AcquisitionMode = 'list mode'; ImageDecayCorrected = 'true'; ImageDecayCorrectionTime = 0; ReconFilterType = 'none'; ReconFilterSize = 0; AttenuationCorrection = '10-min transmission scan'; FrameDuration = 1200; FrameTimesStart = 0;
Note
TimeZero also can be [] or ‘ScanStart’ indicating that the scanning time should be used as TimeZero. If TimeZero is not the scan time, we strongly advice to input ScanStart and InjectionStart making sure timing is correct
Note
OPTIONAL INPUTS ARE ALL OTHER BIDS FIELDS
Example
meta = get_pet_metadata('Scanner','SiemensBiograph','TimeZero','ScanStart',... 'TracerName','CB36','TracerRadionuclide','C11', ... 'ModeOfAdministration','infusion','SpecificRadioactivity', ... 605.3220,'InjectedMass', 1.5934,'MolarActivity', 107.66); --> will issue warnings without a SiemensBiographparameters.txt next to this function meta = get_pet_metadata('Scanner','SiemensBiograph','TimeZero','ScanStart',... 'TracerName','CB36','TracerRadionuclide','C11', 'ModeOfAdministration',... 'infusion','SpecificRadioactivity', 605.3220,'InjectedMass', 1.5934,... 'MolarActivity', 107.66, 'InstitutionName','Rigshospitalet, NRU, DK',... 'AcquisitionMode','list mode','ImageDecayCorrected','true',... 'ImageDecayCorrectionTime' ,0,'ReconMethodName','OP-OSEM',... 'ReconMethodParameterLabels',{'subsets','iterations'},... 'ReconMethodParameterUnits',{'none','none'}, ... 'ReconMethodParameterValues',[21 3], 'ReconFilterType','XYZGAUSSIAN',... 'ReconFilterSize',2, 'AttenuationCorrection','MR-based attenuation correction'); --> works without txt file because all arguments are passed
Neurobiology Research Unit, RigshospitaletMartin Nørgaard & Cyril Pernet - 2021Copyright Open NeuroPET team
- matlab.dcm2niix4pet(FolderList, MetaList, varargin)
- Converts dicom image file to nifti+json calling dcm2niix augmenting the
json file to be BIDS compliant. Note that you are always right when it comes to metadata! DICOM values to be used in the json will be ignored, always using the meta data provided - BUT DICOM values are checked and the code tells you if there is inconsistency between your inputs and what DICOM says.
- format
fileout = dcm2bids4pet(FolderList,MetaList)
fileout = dcm2bids4pet(FolderList,MetaList,options)
- param FolderList
Cell array of char strings with filenames and paths
- param MetaList
Cell array of structures for metadata
- param varargin
deletedcm to be ‘on’ or ‘off’
- o the output directory or cell arrays of directories
IF the folder is BIDS sub-xx files are renamed automatically
gz = 6; % -1..-9 : gz compression level (1=fastest..9=smallest, default 6)
a = ‘n’; % -a : adjacent DICOMs (images from same series always in same folder) for faster conversion (n/y, default n)
ba = ‘y’; % -ba : anonymize BIDS (y/n, default y)
d = 5; % directory search depth. Convert DICOMs in sub-folders of in_folder? (0..9, default 5)
f = ‘%f_%p_%t_%s’; % filename (%a=antenna (coil) name, %b=basename, %c=comments, %d=description, %e=echo number, %f=folder name, %g=accession number, %i=ID of patient, %j=seriesInstanceUID, %k=studyInstanceUID, %m=manufacturer, %n=name of patient, %o=mediaObjectInstanceUID, %p=protocol, %r=instance number, %s=series number, %t=time, %u=acquisition number, %v=vendor, %x=study ID; %z=sequence name; default ‘%f_%p_%t_%s’)
g = ‘n’; % generate defaults file (y/n/o/i [o=only: reset and write defaults; i=ignore: reset defaults], default n)
i = ‘n’; % ignore derived, localizer and 2D images (y/n, default n)
l = ‘n’; % losslessly scale 16-bit integers to use dynamic range (y/n/o [yes=scale, no=no, but uint16->int16, o=original], default n)
m = ‘2’; % merge 2D slices from same series regardless of echo, exposure, etc. (n/y or 0/1/2, default 2) [no, yes, auto]
p = ‘y’; % Philips precise float (not display) scaling (y/n, default y)
v = 1; % verbose (n/y or 0/1/2, default 0) [no, yes, logorrheic]
w = 2; % write behavior for name conflicts (0,1,2, default 2: 0=skip duplicates, 1=overwrite, 2=add suffix)
x = ‘n’; % crop 3D acquisitions (y/n/i, default n, use ‘i’gnore to neither crop nor rotate 3D acquisitions)
z = ‘n’; % gz compress images (y/o/i/n/3, default y) [y=pigz, o=optimal pigz, i=internal:miniz, n=no, 3=no,3D]
notrack Opt-out of sending tracking information of this run to the PET2BIDS developers. This information helps to improve PET2BIDS and provides an indicator of real world usage crucial for obtaining funding.”
Example meta = get_pet_metadata('Scanner','SiemensBiograph','TimeZero','ScanStart','TracerName','CB36','TracerRadionuclide','C11', ... 'ModeOfAdministration','infusion','SpecificRadioactivity', 605.3220,'InjectedMass', 1.5934,'MolarActivity', 107.66); dcm2niix4pet(folder1,meta,'gz',9,'o','mynewfolder','v',1); % change dcm2nii default dcm2niix4pet({folder1,folder2,folder3},{meta}); % use the same PET meta for all subjects dcm2niix4pet({folder1,folder2,folder3},{meta1,meta2,meta3}); % each subject has specific metadata info
Note
- See also get_pet_metadata.m to generate the metadata structure
updatejsonpetfile to see how the json file gets updated and checked against DICOM tags
Cyril Pernet 2022Copyright Open NeuroPET team
- matlab.updatejsonpetfile(varargin)
generic function that updates PET json file with missing PET-BIDS information, if only the jsonfile is provided, it only checks if valid (and possibly updates some fields from scalar to array)
- Format
status = updatejsonpetfile(jsonfilename,newfields,dcminfo)
- Parameters
jsonfilename – json file to check or update update can also be the json structure (add field filename to ensure update on disk)
newfields – (optional) a structure with the newfields to go into the json file
dcminfo – (optional) a dcmfile or the dicominfo structure from a representative dicom file. This information is used to also update the json file, and if a conflict exists, it returns warning messages, assumnimg the newfield provided is correct (i.e. as a user you know better than default dicom, presumably)
- Returns status
the state of the updating (includes warning messages returned if any)
jsonfilename = fullfile(pwd,'DBS_Gris_13_FullCT_DBS_Az_2mm_PRR_AC_Images_20151109090448_48.json') metadata = get_SiemensBiograph_metadata('TimeZero','ScanStart','tracer','AZ10416936','Radionuclide','C11', ... 'ModeOfAdministration','bolus','Radioactivity', 605.3220,'InjectedMass', 1.5934,'MolarActivity', 107.66) dcminfo = dicominfo('DBSGRIS13.PT.PETMR_NRU.48.13.2015.11.11.14.03.16.226.61519201.dcm') status = updatejsonpetfile(jsonfilename,metadata,dcminfo)
Cyril Pernet 2022Copyright Open NeuroPET team
- matlab.ecat2nii(FileListIn, MetaList, varargin)
Converts ECAT 7 image file from hrrt pet scanner (ecat format) to nifti image files + json
- Format
FileListOut = ecat2nii(FileListIn,MetaList)
FileListOut = ecat2nii(FileListIn,MetaList,options)
- Parameters
FileListIn – a name or a Cell array of characters with paths and filenames
MetaList – a structure or Cell array of structures for metadata (a single structure can be use other many FileListIn - see examples) options are name/value pairs
FileListOut – a name or cell array of characters with filenames (with path if the path out is different)
sifout – is true or false (default) to output a sif file, default = false, 0/1 to indicate SIF is a simple ascii file that contains the PET frame start and end times, and the numbers of observed events during each PET time frame.
gz – is true (default) or false to output .nii.gz or .nii
savemat – is true or false (default) to save the ecat data as .mat
- Returns FileListOut
is the name or a cell array of names of the nifti files created (should be the same as FileListOut entered as option with the added proper extension .nii or .nii.gz)
Example Meta = get_pet_metadata('Scanner','SiemensHRRT','TimeZero','ScanStart','TracerName','DASB','TracerRadionuclide','C11', ... 'ModeOfAdministration','bolus','InjectedRadioactivity', 605.3220,'InjectedMass', 1.5934,'MolarActivity', 107.66) FileListOut = ecat2nii(EcatFile,Meta,'FileListOut',ConvertedRenamedFile1); FileListOut = ecat2nii({EcatFile1,EcatFile2},Meta,'gz',false,'sifout',true); FileListOut = ecat2nii({EcatFile1,EcatFile2},{Meta1,Meta2},'FileListOut',{ConvertedRenamedFile1,ConvertedRenamedFile2}));``
Note
- Uses: readECAT7.m (Raymond Muzic, 2002)
jsonwrite.m (Guillaume Flandin, 2020) nii_tool.m (Xiangrui Li, 2016)
See also get_pet_metadata.m to generate the metadata structure
Claus Svarer, Martin Nørgaard, Chris Rorden & Cyril Pernet - 2021Copyright Open NeuroPET team
- matlab.check_metaradioinputs(varargin)
Routine to check input consistency, possibly generate new ones from PET BIDS metadata - this only makes sense if you respect the input units as indicated
- Format
dataout = check_metaradioinputs(varargin)
Note
arguments in are provided via the following params (key/value pairs) e.g. - ‘InjectedRadioctivity’,81.24 - ‘SpecificRadioactivity’,1.3019e+04
- Parameters
InjectedRadioactivity – in MBq
InjectedMass – in ug
SpecificRadioactivity – in Bq/g or MBq/ug
MolarActivity – in GBq/umol
MolecularWeight – in g/mol
- Returns
a structure with the original and updated field, including expected units
Claus Svarer, Martin Nørgaard & Cyril Pernet - 2021Copyright Open NeuroPET team
- matlab.get_recon_method(headervalue)
from the dicom value of the PET reconstruction method, it returns the actual name of the method and the number of iterations and subsets if any
- Format
[method,iteration,subset] = get_recon_method(headervalue)
- Parameters
headervalue – the name in the ecat or dicom field of the reconstrusction method
- Returns method
the full name of the reconstrucrtion method or empty if no match found
- Returns iteration
the number of iterations or ‘none’
- Returns subset
the number of subsets or ‘none’
Cyril Pernet 2022Copyright Open NeuroPET team
- matlab.flattenstruct(structin)
- routine that take a structure with nested subfileds
and output all fields in a flat structure
- format
structout = flattenstruct(structin)
- param structin
a structure with nested fields
- returns structout
a flat structure with all the fields
Note
there is an exception handling for the fieldname ‘Item_1’ which is a DICOM name used by manufacturers to store various items
Cyril Pernet Novembre 2021Copyright Open NeuroPET team
- matlab.readECAT7(fs, matrix, varargin)
Read the main header, subheaders, and image/sinogram data from ECAT v 7.x *.v, *.i, *.S, and *.a files.
- format
[mh,sh,data] = readECAT(fs, [matrix], [‘Calibrated’, ‘on’])
- param fs
(optional) file specification (name/path) of file to read. if file specification is not given, then user is prompted to select a file.
- param matrix
(optional) vector of matrix numbers to read. Default = all matrices in file.
- param Calibrated’
‘on’ or ‘off’, if on it calibrates to pixel values in units given in mh.data_units. When ‘Calibrated’ is ‘on’, pixel values are stored as doubles; otherwise, pixels are int16. Calibration is achieved by multiplication of pixels by ecat_calibration_factor (in mh) and the scale_factor (in sh). The default is uncalibrated in which case pixels are int16.
- Returns
mh - main header
sh - cell array of subheaders. sh{i} is subheader for matrix(i).
- data - cell array containing pixel data. data{i} is a
[rows, cols, planes] or [proj, views, planes] array with the data of matrix i. The data are stored in the file as 2 byte signed integers.
Note
To convert data from cell array of 3D arrays to a 4D array: d=double(cat(4,data{:})); This could be helpful to convert a time-sequence of image volumes to something that can be more easily manipulated.
This should work for the entire line of ECAT scanners running 7.x of the software.
Original version written by BT Christian, 12/10/98
Overhaul by RF Muzic, 20000726
Revised by RF Muzic, 20010916
Revised by RF Muzic, 20011221 add support for 3D sinogram files (prev only images supported)
Revised by RF Muzic, 20021017 generalize support from multiple frames to multiple matrices. The distinction is that a matrix could correspond to different bed position or different frame.
Revised by RF Muzic, 20021029 correct length of last fill block in image file subheader. It is actually 49 shorts (to make a 512 byte sh block) whereas CTI docs says 48. Add support for .a files.
Copyright ? 2002 Raymond F. Muzic, Jr.
Not intended for clinical/diagnostic use. User assumes all risk.
- matlab.jsonwrite(varargin)
Serialize a JSON (JavaScript Object Notation) structure
- : format: - jsonwrite(filename,json,options)
S = jsonwrite(json)
- Parameters
filename – the name of the JSON file to write
json – the JSON structure
options –
prettyPrint true or false to indent output [Default: true]
- replacementStyle string to control how non-alphanumeric characters
are replaced {‘underscore’,’hex’,’delete’,’nop’} [Default: ‘underscore’]
convertInfAndNaN encode NaN, Inf and -Inf as “null” [Default: true]
- Returns
S the serialized JSON structure (string)
- References:
JSON Standard: https://www.json.org/ jsonencode: https://www.mathworks.com/help/matlab/ref/jsonencode.html
Note
Guillaume Flandin $Id: spm_jsonwrite.m 8031 2020-12-10 13:37:00Z guillaume $