Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update PyRadiomics Logging #220

Merged
merged 3 commits into from
Mar 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 51 additions & 21 deletions bin/Notebooks/helloRadiomics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@
"## Setting up logging"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Regulate verbosity of PyRadiomics (outputs to stderr)"
]
},
{
"cell_type": "code",
"execution_count": 2,
Expand All @@ -48,20 +55,35 @@
},
"outputs": [],
"source": [
"logger = logging.getLogger('radiomics') # Parent logger for the radiomics package\n",
"# Uncomment line below to output debug and info log messaging to stderr (is added to Jupyter notbook output)\n",
"# radiomics.debug() # Switch on radiomics logging to stderr output from level=DEBUG (default level=WARNING)\n",
"\n",
"# Enable writing out the log using radiomics logger\n",
"radiomics.debug() # Switch on radiomics logging from level=DEBUG (default level=WARNING)\n",
"# Alternative; set logging to a specific level\n",
"# logger.setLevel(logging.INFO)\n",
"\n",
"# Prevent radiomics logger from printing out log entries with level < WARNING to the console\n",
"logger.handlers[0].setLevel(logging.WARNING) # This limits the log messages printed to stdErr to level warning or higher\n",
"logger.propagate = False # Do not pass log messages on to root logger\n",
"# Alternative: regulate verbosity with radiomics.verbosity\n",
"# radiomics.setVerbosity(logging.INFO)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Set up logging to a log file"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# Get the PyRadiomics logger (default log-level = INFO)\n",
"logger = radiomics.logger\n",
"logger.setLevel(logging.DEBUG) # set level to DEBUG to include debug log messages in log file\n",
"\n",
"# Write out all log entries to a file, overwrite previous log\n",
"# Write out all log entries to a file\n",
"handler = logging.FileHandler(filename='testLog.txt', mode='w')\n",
"formatter = logging.Formatter(\"%(levelname)s:%(name)s: %(message)s\") # This determines how a log message should be formatted\n",
"formatter = logging.Formatter(\"%(levelname)s:%(name)s: %(message)s\")\n",
"handler.setFormatter(formatter)\n",
"logger.addHandler(handler)"
]
Expand All @@ -86,7 +108,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -119,7 +141,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 5,
"metadata": {
"collapsed": false
},
Expand All @@ -144,7 +166,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 6,
"metadata": {
"collapsed": false
},
Expand Down Expand Up @@ -188,9 +210,9 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 7,
"metadata": {
"collapsed": true
"collapsed": false
},
"outputs": [],
"source": [
Expand All @@ -213,7 +235,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 8,
"metadata": {
"collapsed": false,
"scrolled": true
Expand Down Expand Up @@ -412,7 +434,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 9,
"metadata": {
"collapsed": false
},
Expand All @@ -422,14 +444,13 @@
"output_type": "stream",
"text": [
"Calculating features\n",
"\t\tComputing firstorder\n",
"Computed general_info_BoundingBox: (162; 84; 11; 47; 70; 7)\n",
"Computed general_info_GeneralSettings: {'additionalInfo': True; 'verbose': True; 'binWidth': 25; 'enableCExtensions': True; 'label': 1; 'interpolator': 'sitkBSpline'; 'resampledPixelSpacing': None; 'padDistance': 5}\n",
"Computed general_info_GeneralSettings: {'normalize': False; 'additionalInfo': True; 'verbose': True; 'removeOutliers': None; 'binWidth': 25; 'enableCExtensions': True; 'label': 1; 'interpolator': 'sitkBSpline'; 'resampledPixelSpacing': None; 'padDistance': 5; 'normalizeScale': 1}\n",
"Computed general_info_ImageHash: 5c9ce3ca174f0f8324aa4d277e0fef82dc5ac566\n",
"Computed general_info_ImageSpacing: (0.7812499999999999; 0.7812499999999999; 6.499999999999998)\n",
"Computed general_info_InputImages: {'Original': {}}\n",
"Computed general_info_MaskHash: 9dc2c3137b31fd872997d92c9a92d5178126d9d3\n",
"Computed general_info_Version: v1.0.1.post69.dev0+gc00bfe2\n",
"Computed general_info_Version: 1.1.0.post9.dev0+g409cdcd\n",
"Computed general_info_VolumeNum: 2\n",
"Computed general_info_VoxelNum: 4137\n",
"Computed original_firstorder_InterquartileRange: 253.0\n",
Expand Down Expand Up @@ -461,6 +482,15 @@
"for featureName in featureVector.keys():\n",
" print(\"Computed %s: %s\" % (featureName, featureVector[featureName]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
1 change: 0 additions & 1 deletion bin/Params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ setting:
label: 1
interpolator: 'sitkBSpline' # This is an enumerated value, here None is not allowed
resampledPixelSpacing: # This disables resampling, as it is interpreted as None, to enable it, specify spacing in x, y, z as [x, y , z]
verbose: True
weightingNorm: # If no value is specified, it is interpreted as None

# Input images to use: original for unfiltered image and/or any other filters, see documentation of featureextractor.py
Expand Down
3 changes: 1 addition & 2 deletions bin/addClassToBaseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ def main():

testCases = []

kwargs = {'verbose': False,
'binWidth': 25,
kwargs = {'binWidth': 25,
'interpolator': None,
'resampledPixelSpacing': None,
'padDistance': 5,
Expand Down
58 changes: 33 additions & 25 deletions bin/batchExamples/batchprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,29 @@ def main():
outputFilepath = outPath + os.path.sep + "radiomics_features.csv"
progress_filename = outPath + os.path.sep + "pyrad_log.txt"

# Enable writing out the log using radiomics logger
logging.getLogger().setLevel(logging.INFO) # Prints out log messages in this script
# Configure logging
rLogger = logging.getLogger('radiomics')

# Write out all log entries to log file
# Set logging level
# rLogger.setLevel(logging.INFO) # Not needed, default log level of logger is INFO

# Create handler for writing to log file
handler = logging.FileHandler(filename=progress_filename, mode='w')
formatter = logging.Formatter("%(levelname)s:%(name)s: %(message)s")
handler.setFormatter(formatter)
logging.getLogger().addHandler(handler)
handler.setFormatter(logging.Formatter("%(levelname)s:%(name)s: %(message)s"))
rLogger.addHandler(handler)

# Package logging
# radiomics.debug() # Switch on radiomics logging from level=DEBUG (default level=WARNING)
# Alternative: specify level
radiomics.logger.setLevel(logging.INFO)
# Initialize logging for batch log messages
logger = rLogger.getChild('batch')

# Prevent radiomics logger from printing out log entries with level < WARNING to the console
radiomics.logger.handlers[0].setLevel(logging.WARNING)
# Set verbosity level for output to stderr (default level = WARNING)
# radiomics.setVerbosity(logging.INFO)

logging.info('Loading CSV')
logger.info('Loading CSV')
print("Loading CSV")

flists = []
try:
with open(inputCSV, 'rb') as inFile:
with open(inputCSV, 'r') as inFile:
cr = csv.reader(inFile, lineterminator='\n')
flists = [row for row in cr]
except Exception:
Expand All @@ -55,20 +55,22 @@ def main():
kwargs['binWidth'] = 25
kwargs['resampledPixelSpacing'] = None # [3,3,3]
kwargs['interpolator'] = sitk.sitkBSpline
kwargs['verbose'] = True
kwargs['enableCExtensions'] = False

logging.info('pyradiomics version: %s', radiomics.__version__)
logging.info('Extracting features with kwarg settings: %s', str(kwargs))
logger.info('pyradiomics version: %s', radiomics.__version__)
logger.info('Extracting features with kwarg settings: %s', str(kwargs))

extractor = featureextractor.RadiomicsFeaturesExtractor(**kwargs)
extractor.enableInputImages(Original={})
# extractor.enableInputImages(wavelet= {'level': 2})

headers = None

for idx, entry in enumerate(flists, start=1):

print("(%d/%d) Processing Patient: %s, Study: %s, Reader: %s" % (idx, len(flists), entry[0], entry[1], entry[2]))
logging.info("(%d/%d) Processing Patient: %s, Study: %s, Reader: %s", idx, len(flists), entry[0], entry[1],
entry[2])
logger.info("(%d/%d) Processing Patient: %s, Study: %s, Reader: %s", idx, len(flists), entry[0], entry[1],
entry[2])

imageFilepath = entry[3]
maskFilepath = entry[4]
Expand All @@ -84,12 +86,18 @@ def main():
try:
featureVector.update(extractor.execute(imageFilepath, maskFilepath))

with open(outputFilepath, 'ab') as outputFile:
with open(outputFilepath, 'a') as outputFile:
writer = csv.writer(outputFile, lineterminator='\n')
if idx == 1: writer.writerow(featureVector.keys())
writer.writerow(featureVector.values())
if headers is None:
headers = list(featureVector.keys())
writer.writerow(headers)

row = []
for h in headers:
row.append(featureVector.get(h, "N/A"))
writer.writerow(row)
except Exception:
logging.error('FEATURE EXTRACTION FAILED:\n%s', traceback.format_exc())

logger.error('FEATURE EXTRACTION FAILED:\n%s', traceback.format_exc())

main()
if __name__ == '__main__':
main()
3 changes: 1 addition & 2 deletions bin/helloFeatureClass.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@
# Can be enabled by setting 'resampledPixelSpacing' to a list of 3 floats (new voxel size in mm for x, y and z)
kwargs = {'binWidth': 25,
'interpolator': sitk.sitkBSpline,
'resampledPixelSpacing': None,
'verbose': True}
'resampledPixelSpacing': None}

#
# If enabled, resample image (resampled image is automatically cropped.
Expand Down
31 changes: 16 additions & 15 deletions bin/helloRadiomics.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,28 @@
print('Error: problem finding input labelmap', maskName)
exit()

# Uncomment line below to output debug and info log messaging to stderr
# radiomics.debug() # Switch on radiomics logging to stderr output from level=DEBUG (default level=WARNING)

# Alternative: regulate verbosity with radiomics.verbosity
# radiomics.setVerbosity(logging.INFO)

# Get the PyRadiomics logger (default log-level = INFO
logger = radiomics.logger
logger.setLevel(logging.DEBUG) # set level to DEBUG to include debug log messages in log file

# Write out all log entries to a file
handler = logging.FileHandler(filename='testLog.txt', mode='w')
formatter = logging.Formatter("%(levelname)s:%(name)s: %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)

# Define settings for signature calculation
# These are currently set equal to the respective default values
kwargs = {}
kwargs['binWidth'] = 25
kwargs['resampledPixelSpacing'] = None # [3,3,3] is an example for defining resampling (voxels with size 3x3x3mm)
kwargs['interpolator'] = sitk.sitkBSpline
kwargs['verbose'] = True

# Initialize wrapperClass to generate signature
extractor = featureextractor.RadiomicsFeaturesExtractor(**kwargs)
Expand All @@ -46,20 +61,6 @@
# Only enable mean and skewness in firstorder
extractor.enableFeaturesByName(firstorder=['Mean', 'Skewness'])

# Enable writing out the log using radiomics logger
radiomics.debug() # Switch on radiomics logging from level=DEBUG (default level=WARNING)

# Prevent radiomics logger from printing out log entries with level < WARNING to the console
logger = logging.getLogger('radiomics')
logger.handlers[0].setLevel(logging.WARNING)
logger.propagate = False # Do not pass log messages on to root logger

# Write out all log entries to a file
handler = logging.FileHandler(filename='testLog.txt', mode='w')
formatter = logging.Formatter("%(levelname)s:%(name)s: %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)

print("Active features:")
for cls, features in six.iteritems(extractor.enabledFeatures):
if len(features) == 0:
Expand Down
2 changes: 0 additions & 2 deletions data/paramSchema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ mapping:
setting: &settings
type: map
mapping:
verbose:
type: bool
enableCExtensions:
type: bool
additionalInfo:
Expand Down
Loading