Skip to content

Commit bd88725

Browse files
author
=
committed
Revised rescale_by_neighborhood(); added rescale_by_label().
1. Rescale the scalar values of a VTK file by a percentile value in each vertex's surface mesh neighborhood. 2. Rescale scalars for each label (such as depth values within each fold). default calls #1. Former-commit-id: f5b94eb
1 parent f7b573e commit bd88725

File tree

2 files changed

+124
-85
lines changed

2 files changed

+124
-85
lines changed

mindboggle/features/folds.py

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -411,83 +411,3 @@ def extract_subfolds(depth_file, folds, min_subfold_size=50, depth_factor=0.25,
411411
subfolds_file = None
412412

413413
return subfolds.tolist(), n_subfolds, subfolds_file
414-
415-
#===============================================================================
416-
# Normalize depths in each fold
417-
#===============================================================================
418-
def normalize_fold_depths(depth_file, folds_or_file, save_file=False):
419-
420-
"""
421-
Normalize depths in each fold.
422-
423-
Parameters
424-
----------
425-
depth_file : string
426-
name of VTK file with a depth value for each vertex
427-
folds_or_file : list or string
428-
fold number for each vertex or name of VTK file containing folds scalars
429-
save_file : Boolean
430-
save output VTK file?
431-
432-
Returns
433-
-------
434-
depth_folds : list of floats
435-
depth values for fold numbers >-1, normalized for each fold
436-
depth_folds_file : string (if save_file)
437-
name of output VTK file with normalized depth values in each fold
438-
439-
Examples
440-
--------
441-
>>> import os
442-
>>> from mindboggle.utils.io_vtk import read_scalars
443-
>>> from mindboggle.features.folds import normalize_fold_depths
444-
>>> path = os.environ['MINDBOGGLE_DATA']
445-
>>> depth_file = os.path.join(path, 'arno', 'measures', 'lh.pial.depth.vtk')
446-
>>> folds_file = os.path.join(path, 'arno', 'features', 'folds.vtk')
447-
>>> folds, name = read_scalars(folds_file)
448-
>>> #
449-
>>> normalize_fold_depths(depth_file, folds, save_file=True)
450-
>>> # View:
451-
>>> depth_folds_file = os.path.join(os.getcwd(),
452-
>>> os.path.basename(depth_file).strip('vtk') + 'norm.vtk')
453-
>>> os.system('mayavi2 -m Surface -d ' + depth_folds_file + '&')
454-
455-
"""
456-
import os
457-
import numpy as np
458-
from mindboggle.utils.io_vtk import read_scalars, rewrite_scalars
459-
460-
# Load fold numbers if folds_or_file is a string
461-
if isinstance(folds_or_file, str):
462-
folds, name = read_scalars(folds_or_file)
463-
elif isinstance(folds_or_file, list):
464-
folds = folds_or_file
465-
466-
depths, name = read_scalars(depth_file, True, True)
467-
468-
depth_folds = -1 * np.ones(len(folds))
469-
470-
unique_fold_IDs = np.unique(folds)
471-
unique_fold_IDs = [x for x in unique_fold_IDs if x >= 0]
472-
473-
for fold_ID in unique_fold_IDs:
474-
indices_fold = [i for i,x in enumerate(folds) if x == fold_ID]
475-
if indices_fold:
476-
477-
# Normalize fold depth values
478-
depth_folds[indices_fold] = depths[indices_fold] / np.max(depths[indices_fold])
479-
480-
#---------------------------------------------------------------------------
481-
# Return folds with normalized depth, number of folds, file name
482-
#---------------------------------------------------------------------------
483-
if save_file:
484-
485-
depth_folds_file = os.path.join(os.getcwd(),
486-
os.path.basename(depth_file).strip('vtk') + 'norm.folds.vtk')
487-
rewrite_scalars(depth_file, depth_folds_file,
488-
depth_folds, 'depth_folds', depth_folds)
489-
490-
else:
491-
depth_folds_file = None
492-
493-
return depth_folds.tolist(), depth_folds_file

mindboggle/shapes/measure.py

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ def volume_per_label(labels, input_file):
402402
return volumes.tolist(), labels
403403

404404
def rescale_by_neighborhood(scalars, indices, neighbor_lists, nedges=10, p=99,
405-
set_max_to_1=True):
405+
set_max_to_1=True, return_list=True):
406406
"""
407407
Rescale the scalar values of a VTK file by a percentile value
408408
in each vertex's surface mesh neighborhood.
@@ -421,6 +421,8 @@ def rescale_by_neighborhood(scalars, indices, neighbor_lists, nedges=10, p=99,
421421
percentile used to normalize each scalar
422422
set_max_to_1 : Boolean
423423
set all rescaled values greater than 1 to 1.0?
424+
return_list : Boolean
425+
return list or numpy array?
424426
425427
Returns
426428
-------
@@ -443,9 +445,10 @@ def rescale_by_neighborhood(scalars, indices, neighbor_lists, nedges=10, p=99,
443445
>>> nedges = 10
444446
>>> p = 99
445447
>>> set_max_to_1 = True
448+
>>> return_list = True
446449
>>> #
447450
>>> rescaled_scalars = rescale_by_neighborhood(scalars, indices,
448-
>>> neighbor_lists, nedges, p)
451+
>>> neighbor_lists, nedges, p, set_max_to_1, return_list)
449452
>>> #
450453
>>> # View rescaled scalar values on folds:
451454
>>> from mindboggle.utils.io_vtk import rewrite_scalars
@@ -461,11 +464,10 @@ def rescale_by_neighborhood(scalars, indices, neighbor_lists, nedges=10, p=99,
461464
# Make sure arguments are numpy arrays
462465
if not isinstance(scalars, np.ndarray):
463466
scalars = np.asarray(scalars)
467+
rescaled_scalars = scalars.copy()
464468

465469
# Loop through all vertices:
466-
rescaled_scalars = -1 * np.ones(len(scalars))
467470
for index in indices:
468-
print('{0} of {1})'.format(index, len(indices)))
469471

470472
# Determine the scalars in the vertex's neighborhood:
471473
neighborhood = find_neighborhood(neighbor_lists, [index], nedges)
@@ -481,4 +483,121 @@ def rescale_by_neighborhood(scalars, indices, neighbor_lists, nedges=10, p=99,
481483
if rescaled_scalars[index] > 1:
482484
rescaled_scalars[index] = 1.0
483485

484-
return rescaled_scalars.tolist()
486+
if return_list:
487+
rescaled_scalars = rescaled_scalars.tolist()
488+
489+
return rescaled_scalars
490+
491+
def rescale_by_label(input_vtk, labels_or_file, by_neighborhood=True,
492+
nedges=10, p=99, set_max_to_1=True, save_file=False,
493+
output_filestring='rescaled_scalars'):
494+
"""
495+
Rescale scalars for each label (such as depth values within each fold).
496+
497+
Default is to normalize the scalar values of a VTK file by
498+
a percentile value in each vertex's surface mesh neighborhood for each label.
499+
500+
Parameters
501+
----------
502+
input_vtk : string
503+
name of VTK file with a scalar value for each vertex
504+
labels_or_file : list or string
505+
label number for each vertex or name of VTK file with index scalars
506+
by_neighborhood : Boolean
507+
rescale by a percentile value in each vertex's surface neighborhood?
508+
nedges : integer (if norm_by_neighborhood)
509+
number or edges from vertex, defining the size of its neighborhood
510+
p : float in range of [0,100] (if norm_by_neighborhood)
511+
percentile used to rescale each scalar
512+
set_max_to_1 : Boolean
513+
set all rescaled values greater than 1 to 1.0?
514+
save_file : Boolean
515+
save output VTK file?
516+
output_filestring : string (if save_file)
517+
name of output file
518+
519+
Returns
520+
-------
521+
rescaled_scalars : list of floats
522+
scalar values rescaled for each label, for label numbers not equal to -1
523+
rescaled_scalars_file : string (if save_file)
524+
name of output VTK file with rescaled scalar values for each label
525+
526+
Examples
527+
--------
528+
>>> # Rescale depths by neighborhood within each subfold:
529+
>>> import os
530+
>>> from mindboggle.shapes.measure import rescale_by_label
531+
>>> path = os.environ['MINDBOGGLE_DATA']
532+
>>> input_vtk = os.path.join(path, 'arno', 'measures', 'lh.pial.depth.vtk')
533+
>>> labels_or_file = os.path.join(path, 'arno', 'features', 'subfolds.vtk')
534+
>>> by_neighborhood = True
535+
>>> nedges = 10
536+
>>> p = 99
537+
>>> set_max_to_1 = True
538+
>>> save_file = True
539+
>>> output_filestring = 'rescaled_scalars'
540+
>>> #
541+
>>> rescaled_scalars, rescaled_scalars_file = rescale_by_label(input_vtk,
542+
>>> labels_or_file, by_neighborhood, nedges, p, set_max_to_1,
543+
>>> save_file, output_filestring)
544+
>>> #
545+
>>> # View rescaled scalar values per fold:
546+
>>> from mindboggle.utils.mesh import plot_vtk
547+
>>> plot_vtk(rescaled_scalars_file)
548+
549+
"""
550+
import os
551+
import numpy as np
552+
from mindboggle.utils.io_vtk import read_scalars, rewrite_scalars
553+
from mindboggle.utils.mesh import find_neighbors_from_file
554+
from mindboggle.shapes.measure import rescale_by_neighborhood
555+
556+
# Load scalars and vertex neighbor lists:
557+
scalars, name = read_scalars(input_vtk, True, True)
558+
if by_neighborhood:
559+
neighbor_lists = find_neighbors_from_file(input_vtk)
560+
print(" Rescaling scalar values by neighborhood within each label...")
561+
else:
562+
print(" Rescaling scalar values within each label...")
563+
564+
# Load label numbers:
565+
if isinstance(labels_or_file, str):
566+
labels, name = read_scalars(labels_or_file, True, True)
567+
elif isinstance(labels_or_file, list):
568+
labels = labels_or_file
569+
unique_labels = np.unique(labels)
570+
unique_labels = [x for x in unique_labels if x >= 0]
571+
572+
# Loop through labels:
573+
for label in unique_labels:
574+
#print(" Rescaling scalar values within label {0} of {1} labels...".format(
575+
# int(label), len(unique_labels)))
576+
indices = [i for i,x in enumerate(labels) if x == label]
577+
if indices:
578+
579+
# Rescale by neighborhood:
580+
if by_neighborhood:
581+
scalars = rescale_by_neighborhood(scalars,
582+
indices, neighbor_lists, nedges, p,
583+
set_max_to_1=True, return_list=False)
584+
585+
# Rescale by the maximum label scalar value:
586+
else:
587+
scalars[indices] = scalars[indices] / np.max(scalars[indices])
588+
589+
rescaled_scalars = scalars.tolist()
590+
591+
#---------------------------------------------------------------------------
592+
# Return rescaled scalars, number of labels, file name
593+
#---------------------------------------------------------------------------
594+
if save_file:
595+
596+
rescaled_scalars_file = os.path.join(os.getcwd(), output_filestring + '.vtk')
597+
rewrite_scalars(input_vtk, rescaled_scalars_file,
598+
rescaled_scalars, 'rescaled_scalars', labels)
599+
600+
else:
601+
rescaled_scalars_file = None
602+
603+
return rescaled_scalars, rescaled_scalars_file

0 commit comments

Comments
 (0)