diff --git a/docs/customization.rst b/docs/customization.rst index 1bbd5ee0..7a9f4afb 100644 --- a/docs/customization.rst +++ b/docs/customization.rst @@ -190,14 +190,21 @@ Feature Extractor Level *Resegmentation* -- ``resegmentRange`` [None]: List of 2 floats, specifies the lower and upper threshold, respectively. Segmented voxels - outside this range are removed from the mask prior to feature calculation. When the value is None (default), no - resegmentation is performed. Resegemented size is checked (using parameter ``minimumROISize``, default 1) and upon - fail, an error is logged and the mask is reset to the original mask. - -.. note:: - This only affects first order and texture classes. No resegmentation is performed prior to calculating shape - features. +- ``resegmentRange`` [None]: List of 1 or 2 floats, specifies the lower and and optionally upper threshold, + respectively. Segmented voxels outside this range are removed from the mask prior to feature calculation. When the + value is None (default), no resegmentation is performed. Resegemented size is checked (using parameter + ``minimumROISize``, default 1) and upon fail, an error is logged and extraction is skipped for this case. +- ``resegmentMode`` ['absolute']: string, specifying the method to use for defining the resegmentation thresholds: + - 'absolute': The resegmentRange values are treated as absolute values, i.e. used directly to perform resegmentation. + - 'relative': The resegmentRange values are treated as relative to the maximum in the ROI, i.e. the actual threshold + used is defined as :math:`\text{threshold} = \text{value} * X_{max}`. + - 'sigma': The resegmentRange values indicate a distance from the mean of the ROI in standard deviations. E.g. to + exclude outliers farther from the mean than 3 sigma, specify mode 'sigma' and range [-3, 3]. Threshold is defined as + :math:`\text{threshold} = \mu + \text{value} * \sigma`. +- ``resegmentShape`` [False]: Boolean, if set to True, the resegmented mask is also used for shape calculation. If set + to False (default), only first order and texture classes are calculated using the resegmented mask (known in IBSI as + the intensity mask). Shape is then calculated using the mask after any optional resampling and corrections (known in + IBSI as the morphologic mask). *Mask validation* diff --git a/radiomics/featureextractor.py b/radiomics/featureextractor.py index a31bf9d5..c93b1636 100644 --- a/radiomics/featureextractor.py +++ b/radiomics/featureextractor.py @@ -357,6 +357,8 @@ def execute(self, imageFilepath, maskFilepath, label=None, voxelBased=False): """ geometryTolerance = self.settings.get('geometryTolerance') additionalInfo = self.settings.get('additionalInfo', False) + resegmentShape = self.settings.get('resegmentShape', False) + if label is not None: self.settings['label'] = label else: @@ -413,6 +415,11 @@ def execute(self, imageFilepath, maskFilepath, label=None, voxelBased=False): if self.generalInfo is not None: self.generalInfo.addMaskElements(image, resegmentedMask, label, 'resegmented') + # if resegmentShape is True and resegmentation has been enabled, update the mask here to also use the + # resegmented mask for shape calculation (e.g. PET resegmentation) + if resegmentShape and resegmentedMask is not None: + mask = resegmentedMask + if not voxelBased: # 3. Add the additional information if enabled if self.generalInfo is not None: @@ -435,8 +442,9 @@ def execute(self, imageFilepath, maskFilepath, label=None, voxelBased=False): newFeatureName = 'original_shape_%s' % featureName featureVector[newFeatureName] = featureValue - # Only use resegemented mask for feature classes other than shape - if resegmentedMask is not None: + # (Default) Only use resegemented mask for feature classes other than shape + # can be overridden by specifying `resegmentShape` = True + if not resegmentShape and resegmentedMask is not None: mask = resegmentedMask # 6. Calculate other enabled feature classes using enabled image types diff --git a/radiomics/schemas/paramSchema.yaml b/radiomics/schemas/paramSchema.yaml index 6d77e2ea..eccf30aa 100644 --- a/radiomics/schemas/paramSchema.yaml +++ b/radiomics/schemas/paramSchema.yaml @@ -73,6 +73,8 @@ mapping: resegmentMode: type: str enum: ['absolute', 'relative', 'sigma'] + resegmentShape: + type: bool preCrop: type: bool sigma: