forked from BRAINSia/BRAINSStandAlone
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ENH: Added segmentation volume support ENH: Added posterior volume support
- Loading branch information
Showing
6 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
__version__ = 'beta' | ||
#import config | ||
#import metrics | ||
|
||
def check_file(filename): | ||
import os.path | ||
fullName = os.path.abspath(filename) | ||
assert os.path.exists(fullName), "File %s cannot be found!" % fullName | ||
return fullName |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from ConfigParser import SafeConfigParser as scp | ||
_config = scp() | ||
|
||
from autoworkup import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from . import _config | ||
|
||
valid_schemes = ['BRAINS', 'Nipype'] | ||
|
||
def writeConfiguration(filename='example.config'): | ||
config = ConfigParser.SafeConfigParser() | ||
config.add_section("Results") | ||
config.set("Results", "directory", "/full/path/to/experiment/directory") | ||
config.set("Results", "segmentations", "SingleRFSegmentations") | ||
config.set("Results", "posteriors", "TissueClassify") | ||
config.set("Results", "scheme", "BRAINS") | ||
with open(filename, 'wb') as configfile: | ||
config.write(configfile) | ||
|
||
|
||
def loadConfiguration(configFile='/dev/null'): | ||
_config.read(configFile) | ||
|
||
#_config = loadConfiguration() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from ..config import loadConfiguration | ||
from segmentations import * | ||
from partials import * | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import numpy as np | ||
import os.path | ||
from warnings import warn | ||
|
||
import SimpleITK as sitk | ||
|
||
from ..config import _config | ||
|
||
posteriors = ['accumben', 'air', 'caudate', 'crblgm', 'crblwm', 'csf', 'globus', 'hippocampus', 'notcsf', 'notgm', 'notvb', 'notwm', 'putamen', 'surfgm', 'thalamus', 'vb', 'wm'] | ||
_tolerance = [0.99, 1.01] | ||
_tolerance_wm = [0.99, 1.01] | ||
|
||
|
||
def _formatPosteriorAssertString(): | ||
assertString = "Posterior label is not recognized: %s\nValid labels are:" | ||
for p in posteriors: | ||
assertString = '\n'.join([assertString, p.upper() + ',']) | ||
assertString = assertString[:-1] | ||
return assertString | ||
|
||
|
||
def _checkPosteriorLabel(label): | ||
errorString = _formatPosteriorAssertString() | ||
assert label.lower() in posteriors, errorString % label | ||
|
||
|
||
def calculateBinaryVolume(dirname, label): | ||
label = label.upper() | ||
_checkPosteriorLabel(label) | ||
labelFile = os.path.join(dirname, 'POSTERIOR_'+ label + '.nii.gz') | ||
assert os.path.exists(labelFile), "File not found: %s" % labelFile | ||
image = sitk.ReadImage(labelFile) | ||
if label == 'WM': | ||
lowerTol, upperTol = _tolerance_wm | ||
warn("Using lower threshold of %g for white matter binary calculations." % lowerTol) | ||
else: | ||
lowerTol, upperTol = _tolerance | ||
binary = sitk.BinaryThreshold(image, lowerTol, upperTol, 1, 0) | ||
nda = sitk.GetArrayFromImage(binary) | ||
maskSum = nda.sum() | ||
## print maskSum | ||
size = image.GetSpacing() | ||
## print size | ||
return maskSum * size[0] * size[1] * size[2] | ||
|
||
|
||
def calculatePartialVolume(dirname, label): | ||
label = label.upper() | ||
_checkPosteriorLabel(label) | ||
labelFile = os.path.join(dirname, 'POSTERIOR_' + label + '.nii.gz') | ||
assert os.path.exists(labelFile), "File not found: %s" % labelFile | ||
image = sitk.ReadImage(labelFile) | ||
nda = sitk.GetArrayFromImage(image) | ||
maskSum = nda.sum() | ||
## print maskSum | ||
size = image.GetSpacing() | ||
## print size | ||
return maskSum * size[0] * size[1] * size[2] | ||
|
||
|
||
def getPartialVolume(args=[], kwds={}): | ||
dirname = labels = project = subject = session = experimentDir = None | ||
experimentDir = _config.get('Results', 'directory') | ||
partialsDir = _config.get('Results', 'posteriors') | ||
for key, value in kwds: | ||
if key == 'dirname': | ||
dirname = check_file(value) | ||
elif key == 'labels': | ||
labels = value | ||
elif key == 'project': | ||
project = value | ||
elif key == 'subject': | ||
subject = value | ||
elif key == 'session': | ||
session = value | ||
if session is None: | ||
session = args.pop() | ||
if subject is None: | ||
subject = args.pop() | ||
if project is None: | ||
project = args.pop() | ||
if labels is None: | ||
labels = args | ||
if dirname is None: | ||
try: | ||
dirname = os.path.join(experimentDir, project, subject, session, partialsDir) | ||
except Exception, err: | ||
raise err | ||
### DEBUGGING ### | ||
#print labels | ||
#print dirname | ||
#print project | ||
#print subject | ||
#print session | ||
### END DEBUG ### | ||
# labels = map(formatLabel, labels) # convert shorthand to human-readable | ||
volume = 0.0 | ||
for label in labels: | ||
volume += calculateBinaryVolume(dirname, label) | ||
return volume | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import numpy as np | ||
import os.path | ||
|
||
import SimpleITK as sitk | ||
|
||
from ..config import _config | ||
labels = ['caudate', 'putamen', 'hippocampus', 'thalamus', 'accumben', 'globus'] | ||
|
||
def constructLabels(labels): | ||
numbers = range(1,((len(labels)*2) + 1)) | ||
full_labels = [] | ||
index = 0 | ||
for label in labels: | ||
full_labels.append('_'.join(['left', label])) | ||
full_labels.append('_'.join(['right', label])) | ||
return full_labels, numbers | ||
|
||
def _moduleCreateLabels(labels): | ||
full_labels, numbers = constructLabels(labels) | ||
labelMap = map(None, full_labels, numbers) | ||
return dict(labelMap) # Use this variable | ||
|
||
|
||
def formatLabel(label): | ||
""" | ||
Assumes that the label can be split by the '_' character. | ||
""" | ||
side, anatomy = label.split('_') | ||
if side.lower() in ['l', 'left']: | ||
side = 'left' | ||
elif side.lower() in ['r', 'right']: | ||
side = 'right' | ||
else: | ||
raise ValueError('Label %s is not recognized: cannot determine side %s' % (label, side)) | ||
label = '_'.join([side,anatomy]) | ||
return label | ||
|
||
|
||
def calculateLabelVolume(dirname, label): | ||
labelFile = os.path.join(dirname, _config.get('Results', 'segmentations'), label + '_seg.nii.gz') | ||
assert os.path.exists(labelFile), "File not found: %s" % labelFile | ||
image = sitk.ReadImage(labelFile) | ||
nda = sitk.GetArrayFromImage(image) | ||
maskSum = nda.sum() | ||
print maskSum | ||
size = image.GetSpacing() | ||
print size | ||
return maskSum * size[0] * size[1] * size[2] | ||
|
||
|
||
def getVolume(args=[], kwds={}): | ||
dirname = labels = project = subject = session = experimentDir = None | ||
experimentDir = _config.get('Results', 'directory') ### HACK | ||
for key, value in kwds: | ||
if key == 'dirname': | ||
dirname = check_file(value) | ||
elif key == 'labels': | ||
labels = value | ||
elif key == 'project': | ||
project = value | ||
elif key == 'subject': | ||
subject = value | ||
elif key == 'session': | ||
session = value | ||
if session is None: | ||
session = args.pop() | ||
if subject is None: | ||
subject = args.pop() | ||
if project is None: | ||
project = args.pop() | ||
if labels is None: | ||
labels = args | ||
if dirname is None: | ||
try: | ||
# config needs to be accessible | ||
dirname = os.path.join(experimentDir, project, subject, session) | ||
except Exception, err: | ||
raise err | ||
### DEBUGGING ### | ||
#print labels | ||
#print dirname | ||
#print project | ||
#print subject | ||
#print session | ||
### END DEBUG ### | ||
# labels = map(formatLabel, labels) # convert shorthand to human-readable | ||
volume = 0.0 | ||
for label in labels: | ||
volume += calculateLabelVolume(dirname, label) | ||
return volume |