9  Example of using the PyRadiomics toolbox in Python

First, import some built-in Python modules needed to get our testing data. Second, import the toolbox, only the featureextractor is needed, this module handles the interaction with other parts of the toolbox.

Code
from __future__ import print_function
import six
import os  # needed navigate the system to get the input data

import radiomics
from radiomics import featureextractor  # This module is used for interaction with pyradiomics

9.0.1 Setting up data

Test cases can be downloaded to temporary files. This is handled by the radiomics.getTestCase() function, which checks if the requested test case is available and if not, downloads it. It returns a tuple with the location of the image and mask of the requested test case, or (None, None) if it fails.

Alternatively, if the data is available somewhere locally, this directory can be passed as a second argument to radiomics.getTestCase(). If that directory does not exist or does not contain the testcase, functionality reverts to default and tries to download the test data.

If getting the test case fails, PyRadiomics will log an error explaining the cause.

Code
# Get the testCase
imagePath, maskPath = radiomics.getTestCase('brain1')

if imagePath is None or maskPath is None:  # Something went wrong, in this case PyRadiomics will also log an error
    raise Exception('Error getting testcase!')  # Raise exception to prevent cells below from running in case of "run all"

# Additonally, store the location of the example parameter file, stored in \pyradiomics\examples/exampleSettings
paramPath = os.path.join("setting", 'Params.yaml')
print('Parameter file, absolute path:', os.path.abspath(paramPath))
Parameter file, absolute path: /Users/kittipos/my_book/radio-ds-notes/content/pyradiomics/setting/Params.yaml

9.0.2 Instantiating the extractor

Now that we have our input, we need to define the parameters and instantiate the extractor. For this there are three possibilities:

  1. Use defaults, don’t define custom settings

  2. Define parameters in a dictionary, control filters and features after initialisation

  3. Use a parameter file

9.0.2.0.1 Method 1, use defaults
Code
# Instantiate the extractor
extractor = featureextractor.RadiomicsFeatureExtractor()

print('Extraction parameters:\n\t', extractor.settings)
print('Enabled filters:\n\t', extractor.enabledImagetypes)
print('Enabled features:\n\t', extractor.enabledFeatures)
Extraction parameters:
     {'minimumROIDimensions': 2, 'minimumROISize': None, 'normalize': False, 'normalizeScale': 1, 'removeOutliers': None, 'resampledPixelSpacing': None, 'interpolator': 'sitkBSpline', 'preCrop': False, 'padDistance': 5, 'distances': [1], 'force2D': False, 'force2Ddimension': 0, 'resegmentRange': None, 'label': 1, 'additionalInfo': True}
Enabled filters:
     {'Original': {}}
Enabled features:
     {'firstorder': [], 'glcm': [], 'gldm': [], 'glrlm': [], 'glszm': [], 'ngtdm': [], 'shape': []}
9.0.2.0.2 Method 2, hard-coded settings:
Code
# First define the settings
settings = {}
settings['binWidth'] = 20
settings['sigma'] = [1, 2, 3]

# Instantiate the extractor
extractor = featureextractor.RadiomicsFeatureExtractor(**settings)  # ** 'unpacks' the dictionary in the function call

print('Extraction parameters:\n\t', extractor.settings)
print('Enabled filters:\n\t', extractor.enabledImagetypes)  # Still the default parameters
print('Enabled features:\n\t', extractor.enabledFeatures)  # Still the default parameters
Extraction parameters:
     {'minimumROIDimensions': 2, 'minimumROISize': None, 'normalize': False, 'normalizeScale': 1, 'removeOutliers': None, 'resampledPixelSpacing': None, 'interpolator': 'sitkBSpline', 'preCrop': False, 'padDistance': 5, 'distances': [1], 'force2D': False, 'force2Ddimension': 0, 'resegmentRange': None, 'label': 1, 'additionalInfo': True, 'binWidth': 20, 'sigma': [1, 2, 3]}
Enabled filters:
     {'Original': {}}
Enabled features:
     {'firstorder': [], 'glcm': [], 'gldm': [], 'glrlm': [], 'glszm': [], 'ngtdm': [], 'shape': []}
Code
# Enable a filter (in addition to the 'Original' filter already enabled)
extractor.enableImageTypeByName('LoG')
print('')
print('Enabled filters:\n\t', extractor.enabledImagetypes)

# Disable all feature classes, save firstorder
extractor.disableAllFeatures()
extractor.enableFeatureClassByName('firstorder')
print('')
print('Enabled features:\n\t', extractor.enabledFeatures)

# Specify some additional features in the GLCM feature class
extractor.enableFeaturesByName(glcm=['Autocorrelation', 'Homogeneity1', 'SumSquares'])
print('')
print('Enabled features:\n\t', extractor.enabledFeatures)

Enabled filters:
     {'Original': {}, 'LoG': {}}

Enabled features:
     {'firstorder': []}

Enabled features:
     {'firstorder': [], 'glcm': ['Autocorrelation', 'Homogeneity1', 'SumSquares']}
9.0.2.0.3 Method 3, using a parameter file
Code
# Instantiate the extractor
extractor = featureextractor.RadiomicsFeatureExtractor(paramPath)

print('Extraction parameters:\n\t', extractor.settings)
print('Enabled filters:\n\t', extractor.enabledImagetypes)
print('Enabled features:\n\t', extractor.enabledFeatures)
Extraction parameters:
     {'minimumROIDimensions': 2, 'minimumROISize': None, 'normalize': False, 'normalizeScale': 1, 'removeOutliers': None, 'resampledPixelSpacing': None, 'interpolator': 'sitkBSpline', 'preCrop': False, 'padDistance': 5, 'distances': [1], 'force2D': False, 'force2Ddimension': 0, 'resegmentRange': None, 'label': 1, 'additionalInfo': True, 'binWidth': 25, 'weightingNorm': None}
Enabled filters:
     {'Original': {}}
Enabled features:
     {'shape': None, 'firstorder': [], 'glcm': ['Autocorrelation', 'JointAverage', 'ClusterProminence', 'ClusterShade', 'ClusterTendency', 'Contrast', 'Correlation', 'DifferenceAverage', 'DifferenceEntropy', 'DifferenceVariance', 'JointEnergy', 'JointEntropy', 'Imc1', 'Imc2', 'Idm', 'Idmn', 'Id', 'Idn', 'InverseVariance', 'MaximumProbability', 'SumEntropy', 'SumSquares'], 'glrlm': None, 'glszm': None, 'gldm': None}

9.0.3 Extract features

Now that we have our extractor set up with the correct parameters, we can start extracting features:

Code
result = extractor.execute(imagePath, maskPath)
Code
print('Result type:', type(result))  # result is returned in a Python ordered dictionary)
print('')
print('Calculated features')
for key, value in six.iteritems(result):
    print('\t', key, ':', value)
Result type: <class 'collections.OrderedDict'>

Calculated features
     diagnostics_Versions_PyRadiomics : v3.0.1
     diagnostics_Versions_Numpy : 1.26.4
     diagnostics_Versions_SimpleITK : 2.3.1-g42ce2
     diagnostics_Versions_PyWavelet : 1.5.0
     diagnostics_Versions_Python : 3.10.10
     diagnostics_Configuration_Settings : {'minimumROIDimensions': 2, 'minimumROISize': None, 'normalize': False, 'normalizeScale': 1, 'removeOutliers': None, 'resampledPixelSpacing': None, 'interpolator': 'sitkBSpline', 'preCrop': False, 'padDistance': 5, 'distances': [1], 'force2D': False, 'force2Ddimension': 0, 'resegmentRange': None, 'label': 1, 'additionalInfo': True, 'binWidth': 25, 'weightingNorm': None}
     diagnostics_Configuration_EnabledImageTypes : {'Original': {}}
     diagnostics_Image-original_Hash : 5c9ce3ca174f0f8324aa4d277e0fef82dc5ac566
     diagnostics_Image-original_Dimensionality : 3D
     diagnostics_Image-original_Spacing : (0.7812499999999999, 0.7812499999999999, 6.499999999999998)
     diagnostics_Image-original_Size : (256, 256, 25)
     diagnostics_Image-original_Mean : 385.6564080810547
     diagnostics_Image-original_Minimum : 0.0
     diagnostics_Image-original_Maximum : 3057.0
     diagnostics_Mask-original_Hash : 9dc2c3137b31fd872997d92c9a92d5178126d9d3
     diagnostics_Mask-original_Spacing : (0.7812499999999999, 0.7812499999999999, 6.499999999999998)
     diagnostics_Mask-original_Size : (256, 256, 25)
     diagnostics_Mask-original_BoundingBox : (162, 84, 11, 47, 70, 7)
     diagnostics_Mask-original_VoxelNum : 4137
     diagnostics_Mask-original_VolumeNum : 2
     diagnostics_Mask-original_CenterOfMassIndex : (186.98549673676578, 106.3562968334542, 14.38917089678511)
     diagnostics_Mask-original_CenterOfMass : (46.47304432559825, 16.518518098863908, 15.529610829103234)
     original_shape_Elongation : 0.5621171627174116
     original_shape_Flatness : 0.46105975346582595
     original_shape_LeastAxisLength : 28.584423185376497
     original_shape_MajorAxisLength : 61.997220469808795
     original_shape_Maximum2DDiameterColumn : 49.490854979101925
     original_shape_Maximum2DDiameterRow : 65.88905951721043
     original_shape_Maximum2DDiameterSlice : 53.59397776919529
     original_shape_Maximum3DDiameter : 69.60099030590368
     original_shape_MeshVolume : 16147.511800130298
     original_shape_MinorAxisLength : 34.849701666854756
     original_shape_Sphericity : 0.47982345362314927
     original_shape_SurfaceArea : 6438.821603779402
     original_shape_SurfaceVolumeRatio : 0.3987500788652432
     original_shape_VoxelVolume : 16412.658691406243
     original_firstorder_10Percentile : 632.0
     original_firstorder_90Percentile : 1044.4
     original_firstorder_Energy : 2918821481.0
     original_firstorder_Entropy : 4.601935553903786
     original_firstorder_InterquartileRange : 253.0
     original_firstorder_Kurtosis : 2.1807729393860265
     original_firstorder_Maximum : 1266.0
     original_firstorder_MeanAbsoluteDeviation : 133.44726195252767
     original_firstorder_Mean : 825.2354363065023
     original_firstorder_Median : 812.0
     original_firstorder_Minimum : 468.0
     original_firstorder_Range : 798.0
     original_firstorder_RobustMeanAbsoluteDeviation : 103.00138343026683
     original_firstorder_RootMeanSquared : 839.9646448180755
     original_firstorder_Skewness : 0.27565085908587594
     original_firstorder_TotalEnergy : 11579797135.314934
     original_firstorder_Uniformity : 0.045156963555862184
     original_firstorder_Variance : 24527.07920837261
     original_glcm_Autocorrelation : 289.5436994017259
     original_glcm_JointAverage : 16.55380772442751
     original_glcm_ClusterProminence : 27995.937591943148
     original_glcm_ClusterShade : 19.605083427286676
     original_glcm_ClusterTendency : 108.73139325453903
     original_glcm_Contrast : 47.492125114429776
     original_glcm_Correlation : 0.3917522006696661
     original_glcm_DifferenceAverage : 5.284468789866316
     original_glcm_DifferenceEntropy : 3.74406097806642
     original_glcm_DifferenceVariance : 16.65563705027098
     original_glcm_JointEnergy : 0.002893149242988865
     original_glcm_JointEntropy : 8.799696270248813
     original_glcm_Imc1 : -0.09438938808738298
     original_glcm_Imc2 : 0.6942249020670357
     original_glcm_Idm : 0.20022255640475703
     original_glcm_Idmn : 0.961402169623227
     original_glcm_Id : 0.28722572382985156
     original_glcm_Idn : 0.8726052157397169
     original_glcm_InverseVariance : 0.19881884197093194
     original_glcm_MaximumProbability : 0.007352392266290182
     original_glcm_SumEntropy : 5.354241321485615
     original_glcm_SumSquares : 39.05587959224222
     original_glrlm_GrayLevelNonUniformity : 175.6351923150419
     original_glrlm_GrayLevelNonUniformityNormalized : 0.04514123814981055
     original_glrlm_GrayLevelVariance : 39.118151021979244
     original_glrlm_HighGrayLevelRunEmphasis : 281.066493908972
     original_glrlm_LongRunEmphasis : 1.2268440382584342
     original_glrlm_LongRunHighGrayLevelEmphasis : 341.2865790983503
     original_glrlm_LongRunLowGrayLevelEmphasis : 0.010601170478748765
     original_glrlm_LowGrayLevelRunEmphasis : 0.008600397891661503
     original_glrlm_RunEntropy : 4.915038003159503
     original_glrlm_RunLengthNonUniformity : 3500.0432315746298
     original_glrlm_RunLengthNonUniformityNormalized : 0.8950494659480998
     original_glrlm_RunPercentage : 0.9404064632491029
     original_glrlm_RunVariance : 0.08479457789590625
     original_glrlm_ShortRunEmphasis : 0.9559391731405504
     original_glrlm_ShortRunHighGrayLevelEmphasis : 268.9741798411307
     original_glrlm_ShortRunLowGrayLevelEmphasis : 0.008229766244155428
     original_glszm_GrayLevelNonUniformity : 82.38716577540107
     original_glszm_GrayLevelNonUniformityNormalized : 0.044057307901283996
     original_glszm_GrayLevelVariance : 40.60313992393263
     original_glszm_HighGrayLevelZoneEmphasis : 288.6235294117647
     original_glszm_LargeAreaEmphasis : 13.615508021390374
     original_glszm_LargeAreaHighGrayLevelEmphasis : 3514.7614973262034
     original_glszm_LargeAreaLowGrayLevelEmphasis : 0.12723841553344326
     original_glszm_LowGrayLevelZoneEmphasis : 0.009100942027706215
     original_glszm_SizeZoneNonUniformity : 747.5967914438503
     original_glszm_SizeZoneNonUniformityNormalized : 0.3997843804512568
     original_glszm_SmallAreaEmphasis : 0.6564478999587141
     original_glszm_SmallAreaHighGrayLevelEmphasis : 193.438051925864
     original_glszm_SmallAreaLowGrayLevelEmphasis : 0.006416982055097711
     original_glszm_ZoneEntropy : 6.5082149861981895
     original_glszm_ZonePercentage : 0.4520183708000967
     original_glszm_ZoneVariance : 8.721239097486347
     original_gldm_DependenceEntropy : 6.885019899269458
     original_gldm_DependenceNonUniformity : 936.6601401982113
     original_gldm_DependenceNonUniformityNormalized : 0.22641047623838803
     original_gldm_DependenceVariance : 2.1619872286911965
     original_gldm_GrayLevelNonUniformity : 186.8143582306019
     original_gldm_GrayLevelVariance : 39.19271419906397
     original_gldm_HighGrayLevelEmphasis : 280.4065748126662
     original_gldm_LargeDependenceEmphasis : 8.661590524534686
     original_gldm_LargeDependenceHighGrayLevelEmphasis : 2335.0519700265895
     original_gldm_LargeDependenceLowGrayLevelEmphasis : 0.07650590736710827
     original_gldm_LowGrayLevelEmphasis : 0.00860027409479837
     original_gldm_SmallDependenceEmphasis : 0.37960167130711403
     original_gldm_SmallDependenceHighGrayLevelEmphasis : 110.30563945728201
     original_gldm_SmallDependenceLowGrayLevelEmphasis : 0.0035453562622343696