def main(): parser = _build_arg_parser() args = parser.parse_args() assert_inputs_exist(parser, args.in_tractogram) assert_outputs_exist(parser, args, args.out_tractogram) if args.verbose: logging.basicConfig(level=logging.DEBUG) roi_opt_list, only_filtering_list = prepare_filtering_list(parser, args) o_dict = {} sft = load_tractogram_with_reference(parser, args, args.in_tractogram) # Streamline count before filtering o_dict['streamline_count_before_filtering'] = len(sft.streamlines) for i, roi_opt in enumerate(roi_opt_list): curr_dict = {} # Atlas needs an extra argument (value in the LUT) if roi_opt[0] == 'atlas_roi': filter_type, filter_arg, filter_arg_2, \ filter_mode, filter_criteria = roi_opt else: filter_type, filter_arg, filter_mode, filter_criteria = roi_opt curr_dict['filename'] = os.path.abspath(filter_arg) curr_dict['type'] = filter_type curr_dict['mode'] = filter_mode curr_dict['criteria'] = filter_criteria is_exclude = False if filter_criteria == 'include' else True if filter_type == 'drawn_roi' or filter_type == 'atlas_roi': img = nib.load(filter_arg) if not is_header_compatible(img, sft): parser.error('Headers from the tractogram and the mask are ' 'not compatible.') if filter_type == 'drawn_roi': mask = get_data_as_mask(img) else: atlas = get_data_as_label(img) mask = np.zeros(atlas.shape, dtype=np.uint16) mask[atlas == int(filter_arg_2)] = 1 filtered_sft, indexes = filter_grid_roi(sft, mask, filter_mode, is_exclude) # For every case, the input number must be greater or equal to 0 and # below the dimension, since this is a voxel space operation elif filter_type in ['x_plane', 'y_plane', 'z_plane']: filter_arg = int(filter_arg) _, dim, _, _ = sft.space_attributes mask = np.zeros(dim, dtype=np.int16) error_msg = None if filter_type == 'x_plane': if 0 <= filter_arg < dim[0]: mask[filter_arg, :, :] = 1 else: error_msg = 'X plane ' + str(filter_arg) elif filter_type == 'y_plane': if 0 <= filter_arg < dim[1]: mask[:, filter_arg, :] = 1 else: error_msg = 'Y plane ' + str(filter_arg) elif filter_type == 'z_plane': if 0 <= filter_arg < dim[2]: mask[:, :, filter_arg] = 1 else: error_msg = 'Z plane ' + str(filter_arg) if error_msg: parser.error('{} is not valid according to the ' 'tractogram header.'.format(error_msg)) filtered_sft, indexes = filter_grid_roi(sft, mask, filter_mode, is_exclude) elif filter_type == 'bdo': geometry, radius, center = read_info_from_mb_bdo(filter_arg) if geometry == 'Ellipsoid': filtered_sft, indexes = filter_ellipsoid(sft, radius, center, filter_mode, is_exclude) elif geometry == 'Cuboid': filtered_sft, indexes = filter_cuboid(sft, radius, center, filter_mode, is_exclude) logging.debug('The filtering options {0} resulted in ' '{1} streamlines'.format(roi_opt, len(filtered_sft))) sft = filtered_sft if only_filtering_list: filtering_Name = 'Filter_' + str(i) curr_dict['streamline_count_after_filtering'] = len(sft.streamlines) o_dict[filtering_Name] = curr_dict # Streamline count after filtering o_dict['streamline_count_final_filtering'] = len(sft.streamlines) if args.display_counts: print(json.dumps(o_dict, indent=args.indent)) if not filtered_sft: if args.no_empty: logging.debug("The file {} won't be written (0 streamline)".format( args.out_tractogram)) return logging.debug('The file {} contains 0 streamline'.format( args.out_tractogram)) save_tractogram(sft, args.out_tractogram)
def main(): parser = _buildArgsParser() args = parser.parse_args() assert_inputs_exist(parser, [args.in_tractogram]) assert_outputs_exists(parser, args, [args.out_tractogram]) if args.verbose: logging.basicConfig(level=logging.DEBUG) roi_opt_list = prepare_filtering_list(parser, args) sft = load_tractogram_with_reference(parser, args, args.in_tractogram) for i, roi_opt in enumerate(roi_opt_list): # Atlas needs an extra argument (value in the LUT) if roi_opt[0] == 'atlas_roi': filter_type, filter_arg_1, filter_arg_2, \ filter_mode, filter_criteria = roi_opt else: filter_type, filter_arg, filter_mode, filter_criteria = roi_opt is_not = False if filter_criteria == 'include' else True if filter_type == 'drawn_roi': img = nib.load(filter_arg) if not is_header_compatible(img, sft): parser.error('Headers from the tractogram and the mask are ' 'not compatible.') mask = img.get_data() filtered_streamlines, indexes = filter_grid_roi( sft, mask, filter_mode, is_not) elif filter_type == 'atlas_roi': img = nib.load(filter_arg_1) if not is_header_compatible(img, sft): parser.error('Headers from the tractogram and the mask are ' 'not compatible.') atlas = img.get_data().astype(np.uint16) mask = np.zeros(atlas.shape, dtype=np.uint16) mask[atlas == int(filter_arg_2)] = 1 filtered_streamlines, indexes = filter_grid_roi( sft, mask, filter_mode, is_not) # For every case, the input number must be greater or equal to 0 and # below the dimension, since this is a voxel space operation elif filter_type in ['x_plane', 'y_plane', 'z_plane']: filter_arg = int(filter_arg) _, dim, _, _ = sft.space_attribute mask = np.zeros(dim, dtype=np.int16) error_msg = None if filter_type == 'x_plane': if 0 <= filter_arg < dim[0]: mask[filter_arg, :, :] = 1 else: error_msg = 'X plane ' + str(filter_arg) elif filter_type == 'y_plane': if 0 <= filter_arg < dim[1]: mask[:, filter_arg, :] = 1 else: error_msg = 'Y plane ' + str(filter_arg) elif filter_type == 'z_plane': if 0 <= filter_arg < dim[2]: mask[:, :, filter_arg] = 1 else: error_msg = 'Z plane ' + str(filter_arg) if error_msg: parser.error('{} is not valid according to the ' 'tractogram header.'.format(error_msg)) filtered_streamlines, indexes = filter_grid_roi( sft, mask, filter_mode, is_not) elif filter_type == 'bdo': geometry, radius, center = read_info_from_mb_bdo(filter_arg) if geometry == 'Ellipsoid': filtered_streamlines, indexes = filter_ellipsoid( sft, radius, center, filter_mode, is_not) elif geometry == 'Cuboid': filtered_streamlines, indexes = filter_cuboid( sft, radius, center, filter_mode, is_not) logging.debug('The filtering options {0} resulted in ' '{1} streamlines'.format(roi_opt, len(filtered_streamlines))) data_per_streamline = sft.data_per_streamline[indexes] data_per_point = sft.data_per_point[indexes] sft = StatefulTractogram(filtered_streamlines, sft, Space.RASMM, data_per_streamline=data_per_streamline, data_per_point=data_per_point) if not filtered_streamlines: if args.no_empty: logging.debug("The file {} won't be written (0 streamline)".format( args.out_tractogram)) return logging.debug('The file {} contains 0 streamline'.format( args.out_tractogram)) save_tractogram(sft, args.out_tractogram)