def set(in_nii, in_csv, in_labels, in_stats, in_limits, in_sort, out_nii): df_stats = pd.read_csv(in_csv) if inArgs.labels is not None: df_stats = df_stats[df_stats['label'].isin(in_labels)] stats_list = ['label'] + sum([in_stats], []) if in_limits is not None: df_limits = df_stats[ (df_stats[in_sort[0]] >= in_limits[0]) & (df_stats[in_sort[0]] <= in_limits[1])] else: df_limits = df_stats df_sorted = df_limits.sort_values(in_sort, ascending=in_sort_direction).reset_index() df_sorted = df_sorted.dropna() in_nii = labels.read_nifti_file(in_in_nii, 'Label file does not exist') in_array = in_nii.get_data() out_array = np.zeros(in_array.shape) for ii_label, ii_value in df_sorted[stats_list].get_values(): out_array[in_array == ii_label] = ii_value nb.save(nb.Nifti1Image(out_array, [], in_nii.get_header()), in_out_nii) return
def keep(in_nii, keep_labels, keep_csv_filename, out_filename, merge=None): in_label_nii = labels.read_nifti_file(in_nii, 'Label file does not exist') in_label_array = in_label_nii.get_data() if len(keep_csv_filename): csv_keep_labels = labels.read_labels_from_csv(keep_csv_filename) else: csv_keep_labels = [] all_labels = set(labels.get_labels(None, in_label_array)) keep_labels = set( labels.get_labels(keep_labels + csv_keep_labels, in_label_array)) remove_labels = sorted(list(all_labels.symmetric_difference(keep_labels))) out_label_array = in_label_array for ii in remove_labels: mask = in_label_array == ii out_label_array[mask] = 0 if merge is not None and merge != 0: # isinstance(map, (int, long, float)) and float(map) !=0: out_label_array = merge * (out_label_array > 0) nb.save(nb.Nifti1Image(out_label_array, None, in_label_nii.get_header()), out_filename)
def remove(in_nii, remove_labels, remove_csv_filename, out_filename, merge=None): in_label_nii = labels.read_nifti_file(in_nii, 'Label file does not exist') in_label_array = in_label_nii.get_data() if len(remove_csv_filename): csv_remove_labels = labels.read_labels_from_csv(remove_csv_filename) else: csv_remove_labels = [] remove_labels = set( labels.get_labels(remove_labels + csv_remove_labels, in_label_array)) out_label_array = in_label_array for ii in remove_labels: mask = in_label_array == ii out_label_array[mask] = 0 if merge is not None and merge != 0: # isinstance(map, (int, long, float)) and float(map) !=0: out_label_array = merge * (out_label_array > 0) nibabel.save( nibabel.Nifti1Image(out_label_array, None, in_label_nii.get_header()), out_filename)
def extract(in_filename, in_csv, in_extract_labels, out_filename, verbose=False, merge=None): # Read in label array in_nii = labels.read_nifti_file(in_filename, 'Label file does not exist') in_array = in_nii.get_data() if len(in_csv): csv_extract_labels = labels.read_labels_from_csv(in_csv) else: csv_extract_labels = [] # print ( inArgs.extract.shape) # print ( csv_extract_labels.shape) requested_labels = in_extract_labels + csv_extract_labels extract_labels = labels.get_labels(requested_labels, in_array) if verbose: print('Requested labels for extraction not found', list(set(requested_labels) - set(extract_labels))) out_array = np.zeros(in_array.shape, dtype=np.int8) for ii in extract_labels: mask = in_array == ii out_array[mask] = in_array[mask] if merge is not None and merge != 0: # isinstance(map, (int, long, float)) and float(map) !=0: out_array = merge * (out_array > 0) nb.save(nb.Nifti1Image(out_array, None, in_nii.get_header()), out_filename) return
def remove(in_nii, remove_labels, remove_csv_filename, out_filename): in_label_nii = labels.read_nifti_file(in_nii, 'Label file does not exist') in_label_array = in_label_nii.get_data() if len(remove_csv_filename): csv_remove_labels = labels.read_labels_from_csv(remove_csv_filename) else: csv_remove_labels = [] remove_labels = set( labels.get_labels(remove_labels + csv_remove_labels, in_label_array)) out_label_array = in_label_array for ii in remove_labels: mask = in_label_array == ii out_label_array[mask] = 0 nibabel.save( nibabel.Nifti1Image(out_label_array, None, in_label_nii.get_header()), out_filename)
def keep(in_nii, keep_labels, keep_csv_filename, out_filename): in_label_nii = labels.read_nifti_file(in_nii, 'Label file does not exist') in_label_array = in_label_nii.get_data() if len(keep_csv_filename): csv_keep_labels = labels.read_labels_from_csv(keep_csv_filename) else: csv_keep_labels = [] all_labels = set(labels.get_labels(None, in_label_array)) keep_labels = set( labels.get_labels(keep_labels + csv_keep_labels, in_label_array)) remove_labels = sorted(list(all_labels.symmetric_difference(keep_labels))) out_label_array = in_label_array for ii in remove_labels: mask = in_label_array == ii out_label_array[mask] = 0 nb.save(nb.Nifti1Image(out_label_array, None, in_label_nii.get_header()), out_filename)
parser.add_argument("-v","--verbose", help="Verbose flag", action="store_true", default=False ) parser.add_argument("--verbose_nlines", help="Number of lines to display (default=10)", default=10 ) parser.add_argument("--debug", help="Debug flag", action="store_true", default=False ) inArgs = parser.parse_args() if inArgs.debug: print("inArgs.in_nii = " + inArgs.in_nii + '\n') print("inArgs.debug = " + str(inArgs.debug)) print("inArgs.verbose = " + str(inArgs.verbose)) label_nii = labels.read_nifti_file( inArgs.in_nii, 'Label file does not exist' ) label_array = label_nii.get_data() labels = labels.get_labels( inArgs.labels, label_array) df_stats = pd.DataFrame(columns=('label', 'com_x', 'com_y', 'com_z', 'label_volume', 'ellipsoid_volume', 'center_x', 'center_y', 'center_z', 'r1', 'r2', 'r3', 'fa' )) if inArgs.stats is not None: stats_list = inArgs.stats else: stats_list = list(df_stats.columns.values) if inArgs.verbose: jj=0
def list_labels(in_filename): in_label_nii = labels.read_nifti_file(in_filename, 'Label file does not exist') label_list = labels.get_labels(None, in_label_nii.get_data()) return label_list
def overlap( label_nii_filename, label2_nii_filename, requested_labels=[], verbose_flag=False, verbose_nlines=10, verbose_all_flag=False ): # Load arrays label_nii = labels.read_nifti_file( label_nii_filename, 'Label file does not exist' ) label2_nii = labels.read_nifti_file( label2_nii_filename, 'Image file does not exist' ) label_single_voxel_volume_mm3 = query_voxel_volume_mm3(label_nii) label2_single_voxel_volume_mm3 = query_voxel_volume_mm3(label2_nii) # System Checks to verify that the Array Size and Dimensions are compatible label_array = label_nii.get_data() label2_array = label2_nii.get_data() if len(label2_array.shape) < 2 or len(label2_array.shape) > 4: sys.exit('Only supports 3D and 4D image arrays') # if not len(label_array.shape) == 3: # sys.exit('Only supports 3D label arrays') label_ndim = len(label_array.shape) label2_ndim = len(label2_array.shape) ndim = min([label_ndim, label2_ndim]) if not label2_array.shape[0:ndim] == label_array.shape[0:ndim]: sys.exit('Image array and label array do not have the same voxel dimensions') # Find a set of acceptable labels label_list = labels.get_labels( requested_labels, label_array) label2_list = labels.get_labels([], label2_array) # Gather stats if verbose_flag: ii_verbose=0 pandas.set_option('expand_frame_repr', False) df_stats = pandas.DataFrame(columns=('label1', 'label2', 'volume1_mm3', 'volume2_mm3', 'volume12_mm3', 'fraction12', 'x12_com', 'y12_com', 'z12_com')) for ii, ii_label in enumerate(label_list): mask1 = label_array[0, ...] == ii_label _, label1_volume_mm3 = measure_volume(mask1, label_single_voxel_volume_mm3) overlap_label2_list = list(numpy.unique(mask1 * label2_array)) print(overlap_label2_list) for jj, jj_label in enumerate(overlap_label2_list): mask2 = label2_array[0,...] == jj_label mask12 = mask1 * mask2 _, label2_volume_mm3 = measure_volume( mask2, label_single_voxel_volume_mm3) _, label12_volume_mm3 = measure_volume(mask12, label_single_voxel_volume_mm3) fraction12 = label12_volume_mm3 / label1_volume_mm3 x12_com, y12_com, z12_com = ndimage.measurements.center_of_mass(mask12) stats = [ii_label, jj_label, label1_volume_mm3, label2_volume_mm3, label2_volume_mm3, fraction12, x12_com, y12_com, z12_com ] if verbose_flag: if ii_verbose==(verbose_nlines-1): df_verbose = df_stats.tail(verbose_nlines) print('\n') print (df_verbose.to_string(formatters={'label1':'{:,.0f}'.format, 'label2':'{:,.0f}'.format 'volume1':'{:,.0f}'.format, 'volume2':'{:,.0f}'.format, 'volume12':'{:,.0f}'.format, 'fraction12':'{:,.3f}'.format, 'x12_com':'{:,.0f}'.format, 'y12_com':'{:,.0f}'.format, 'z12_com':'{:,.0f}'.format} )) ii_verbose = 0 else: ii_verbose += 1 df_stats.loc[len(df_stats)] = stats
def measure(label_nii_filename, image_nii_filename, requested_labels=[], verbose_flag=False, verbose_nlines=10, verbose_all_flag=False): # Load arrays label_nii = labels.read_nifti_file(label_nii_filename, 'Label file does not exist') image_nii = labels.read_nifti_file(image_nii_filename, 'Image file does not exist') # System Checks to verify that the Array Size and Dimensions are compatible image_array = image_nii.get_data() label_array = label_nii.get_data() if len(image_array.shape) < 2 or len(image_array.shape) > 4: sys.exit('Only supports 3D and 4D image arrays') # if not len(label_array.shape) == 3: # sys.exit('Only supports 3D label arrays') label_ndim = len(label_array.shape) image_ndim = len(image_array.shape) ndim = min([label_ndim, image_ndim]) if not image_array.shape[0:ndim] == label_array.shape[0:ndim]: sys.exit( 'Image array and label array do not have the same voxel dimensions' ) # Find a set of acceptable labels label_list = labels.get_labels(requested_labels, label_array) # Permute array or expand so desired stats is along first dimension if image_ndim == 4: nVolumes = int(image_array.shape[3]) image_array = numpy.transpose(image_array, [3, 0, 1, 2]) elif image_ndim == 3: image_array = numpy.transpose(image_array, [2, 0, 1]) else: nVolumes = 1 image_array = numpy.expand_dims(image_array, axis=0) label_array = numpy.expand_dims(label_array, axis=0) # Gather stats if verbose_flag: ii_verbose = 0 pandas.set_option('expand_frame_repr', False) df_stats = pandas.DataFrame(columns=('label', 'x_com', 'y_com', 'z_com', 'time', 'mean', 'std', 'min', 'max')) nlabels = len(label_list) for ii, ii_label in enumerate(label_list): for jj in range(0, nVolumes): if label_ndim == 3: mask = label_array[0, :, :, :] == ii_label else: mask = label_array[0, :, :] == ii_label label_mean = numpy.mean(image_array[jj][mask]) label_std = numpy.std(image_array[jj][mask]) label_min = numpy.min(image_array[jj][mask]) label_max = numpy.max(image_array[jj][mask]) if label_ndim == 3: x_com, y_com, z_com = ndimage.measurements.center_of_mass(mask) else: z_com = 0 x_com, y_com = ndimage.measurements.center_of_mass(mask) stats = [ ii_label, x_com, y_com, z_com, jj, label_mean, label_std, label_min, label_max ] if verbose_flag and nlabels > 3 * verbose_nlines: if ii_verbose == (verbose_nlines - 1): df_verbose = df_stats.tail(verbose_nlines) print('\n') print( df_verbose.to_string( formatters={ 'label': '{:,.0f}'.format, 'volume': '{:,.0f}'.format, 'time': '{:,.0f}'.format, 'mean': '{:,.3f}'.format, 'std': '{:,.3f}'.format, 'min': '{:,.3f}'.format, 'max': '{:,.3f}'.format, 'x_com': '{:,.0f}'.format, 'y_com': '{:,.0f}'.format, 'z_com': '{:,.0f}'.format })) ii_verbose = 0 else: ii_verbose += 1 df_stats.loc[len(df_stats)] = stats if verbose_flag: if verbose_all_flag: pandas.set_option('display.max_rows', len(df_stats)) print('\n') # ['label' 'x_com' 'y_com' 'z_com' 'time' 'mean' 'std' 'min' 'max'] print( df_stats.to_string( formatters={ 'label': '{:,.0f}'.format, 'time': '{:,.0f}'.format, 'mean': '{:,.3f}'.format, 'std': '{:,.3f}'.format, 'min': '{:,.3f}'.format, 'max': '{:,.3f}'.format, 'x_com': '{:,.0f}'.format, 'y_com': '{:,.0f}'.format, 'z_com': '{:,.0f}'.format })) print('\n') return df_stats
def properties(in_label_nii_filename, label_list, background, stats, out_filename, limits_volume_voxels=[0, numpy.inf], limits_bb_volume_voxels=[0, numpy.inf], limits_fill_factor=[0,1], sort='volume', verbose=False, verbose_nlines=20): label_nii = labels.read_nifti_file( in_label_nii_filename, 'labels.properties.py: Label file does not exist. ') single_voxel_volume_mm3 = query_voxel_volume_mm3( label_nii ) label_array = label_nii.get_data() label_list = labels.get_labels(label_list, label_array, background) df_stats = pd.DataFrame(columns=( 'label', 'volume_voxels', 'volume_mm3', 'com_x', 'com_y', 'com_z', 'com_t', 'com_in', 'bb_dx', 'bb_dy', 'bb_dz', 'bb_dt', 'bb_dmin', 'bb_volume_voxels', 'fill_factor')) stats_list = ['label', ] + list(stats) if verbose: jj = 0 pd.set_option('expand_frame_repr', False) for ii in label_list: # Create logical mask mask = (label_array == ii) ndim = len(mask.shape) # Calculate Volume label_volume_voxels = int(numpy.sum(mask)) label_volume_mm3 = single_voxel_volume_mm3 * label_volume_voxels if check_limits(label_volume_voxels, limits_volume_voxels): bb_dx, bb_dy, bb_dz, bb_dt, bb_dmin, bb_volume_voxels = calculate_bounding_box(mask) if check_limits(bb_volume_voxels, limits_bb_volume_voxels): label_x_com, label_y_com, label_z_com, label_t_com = calculate_center_of_mass(mask) if ndim == 4: label_com_in = mask[label_x_com, label_y_com, label_z_com, label_t_com] elif ndim==3: label_t_com = 0 label_com_in = mask[label_x_com, label_y_com, label_z_com] else: label_z_com = label_t_com = 0 label_com_in = mask[label_x_com, label_y_com] fill_factor = label_volume_voxels / bb_volume_voxels if check_limits(fill_factor, limits_fill_factor): label_stats = [ii, label_volume_voxels, label_volume_mm3, label_x_com, label_y_com, label_z_com, label_t_com, label_com_in, bb_dx, bb_dy, bb_dz, bb_dt, bb_dmin, bb_volume_voxels, fill_factor] df_stats.loc[len(df_stats)] = label_stats if verbose: if jj == (verbose_nlines - 1): print('\n') df_verbose = df_stats.tail(verbose_nlines) df_verbose = df_verbose[stats_list] print(df_verbose.to_string( formatters={'volume_voxels': '{:,.0f}'.format, 'volume_mm3': '{:,.3f}'.format, 'com_x': '{:,.0f}'.format, 'com_y': '{:,.0f}'.format, 'com_z': '{:,.0f}'.format, 'com_t': '{:,.0f}'.format, 'com_in': '{:,.0f}'.format, 'bb_dx': '{:,.0f}'.format, 'bb_dy': '{:,.0f}'.format, 'bb_dz': '{:,.0f}'.format, 'bb_dt': '{:,.0f}'.format, 'bb_volume_voxels': '{:,.0f}'.format, 'fill_factor': '{:,.3f}'.format } )) jj = 0 else: jj += 1 df_sorted = df_stats.sort_values([sort], ascending=[1]).reset_index(drop=True) if verbose: print('\n') print(df_sorted[stats_list]) print('\n') if not out_filename == None: df_sorted[stats_list].to_csv(out_filename, index=False)