<s> """<STR_LIT>""" <EOL> import warnings <EOL> import numbers <EOL> import numpy as np <EOL> from scipy import ndimage <EOL> from . . _utils . ndimage import largest_connected_component <EOL> from . . image import new_img_like <EOL> from . . _utils . extmath import fast_abs_percentile <EOL> from . . _utils . numpy_conversions import as_ndarray <EOL> from . . _utils import check_niimg_3d <EOL> from . . _utils . niimg import _safe_get_data <EOL> from . . image . resampling import get_mask_bounds , coord_transform <EOL> from . . image . image import _smooth_array <EOL> def find_xyz_cut_coords ( img , mask = None , activation_threshold = None ) : <EOL> """<STR_LIT>""" <EOL> img = check_niimg_3d ( img ) <EOL> data = _safe_get_data ( img ) <EOL> offset = np . zeros ( <NUM_LIT:3> ) <EOL> if hasattr ( data , '<STR_LIT>' ) : <EOL> not_mask = np . logical_not ( data . mask ) <EOL> if mask is None : <EOL> mask = not_mask <EOL> else : <EOL> mask *= not_mask <EOL> data = np . asarray ( data ) <EOL> data = as_ndarray ( data ) <EOL> my_map = data . copy ( ) <EOL> if mask is not None : <EOL> if mask . sum ( ) == <NUM_LIT:0.> : <EOL> warnings . warn ( <EOL> "<STR_LIT>" ) <EOL> cut_coords = ndimage . center_of_mass ( np . abs ( my_map ) ) + offset <EOL> x_map , y_map , z_map = cut_coords <EOL> return np . asarray ( coord_transform ( x_map , y_map , z_map , <EOL> img . get_affine ( ) ) ) . tolist ( ) <EOL> slice_x , slice_y , slice_z = ndimage . find_objects ( mask ) [ <NUM_LIT:0> ] <EOL> my_map = my_map [ slice_x , slice_y , slice_z ] <EOL> mask = mask [ slice_x , slice_y , slice_z ] <EOL> my_map *= mask <EOL> offset += [ slice_x . start , slice_y . start , slice_z . start ] <EOL> if ( my_map . max ( ) == <NUM_LIT:0> ) and ( my_map . min ( ) == <NUM_LIT:0> ) : <EOL> return <NUM_LIT> * np . array ( data . shape ) <EOL> if activation_threshold is None : <EOL> activation_threshold = fast_abs_percentile ( my_map [ my_map != <NUM_LIT:0> ] . ravel ( ) , <EOL> <NUM_LIT> ) <EOL> mask = np . abs ( my_map ) > activation_threshold - <NUM_LIT> <EOL> if mask . max ( ) == <NUM_LIT:0> : <EOL> return <NUM_LIT> * np . array ( data . shape ) <EOL> mask = largest_connected_component ( mask ) <EOL> slice_x , slice_y , slice_z = ndimage . find_objects ( mask ) [ <NUM_LIT:0> ] <EOL> my_map = my_map [ slice_x , slice_y , slice_z ] <EOL> mask = mask [ slice_x , slice_y , slice_z ] <EOL> my_map *= mask <EOL> offset += [ slice_x . start , slice_y . start , slice_z . start ] <EOL> second_threshold = np . abs ( np . mean ( my_map [ mask ] ) ) <EOL> second_mask = ( np . abs ( my_map ) > second_threshold ) <EOL> if second_mask . sum ( ) > <NUM_LIT:50> : <EOL> my_map *= largest_connected_component ( second_mask ) <EOL> cut_coords = ndimage . center_of_mass ( np . abs ( my_map ) ) <EOL> x_map , y_map , z_map = cut_coords + offset <EOL> return np . asarray ( coord_transform ( x_map , y_map , z_map , <EOL> img . get_affine ( ) ) ) . tolist ( ) <EOL> def _get_auto_mask_bounds ( img ) : <EOL> """<STR_LIT>""" <EOL> data = _safe_get_data ( img ) <EOL> affine = img . get_affine ( ) <EOL> if hasattr ( data , '<STR_LIT>' ) : <EOL> mask = np . logical_not ( data . mask ) <EOL> data = np . asarray ( data ) <EOL> else : <EOL> edge_value = float ( data [ <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ] + data [ <NUM_LIT:0> , - <NUM_LIT:1> , <NUM_LIT:0> ] <EOL> + data [ - <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:0> ] + data [ <NUM_LIT:0> , <NUM_LIT:0> , - <NUM_LIT:1> ] <EOL> + data [ - <NUM_LIT:1> , - <NUM_LIT:1> , <NUM_LIT:0> ] + data [ - <NUM_LIT:1> , <NUM_LIT:0> , - <NUM_LIT:1> ] <EOL> + data [ <NUM_LIT:0> , - <NUM_LIT:1> , - <NUM_LIT:1> ] + data [ - <NUM_LIT:1> , - <NUM_LIT:1> , - <NUM_LIT:1> ] <EOL> ) <EOL> edge_value /= <NUM_LIT:6> <EOL> mask = np . abs ( data - edge_value ) > <NUM_LIT> * data . ptp ( ) <EOL> xmin , xmax , ymin , ymax , zmin , zmax = get_mask_bounds ( new_img_like ( img , mask , affine ) ) <EOL> return ( xmin , xmax ) , ( ymin , ymax ) , ( zmin , zmax ) <EOL> def _transform_cut_coords ( cut_coords , direction , affine ) : <EOL> """<STR_LIT>""" <EOL> axis = '<STR_LIT>' . index ( direction ) <EOL> kwargs = { } <EOL> for name in '<STR_LIT>' : <EOL> kwargs [ name ] = np . zeros ( len ( cut_coords ) ) <EOL> kwargs [ direction ] = cut_coords <EOL> kwargs [ '<STR_LIT>' ] = affine <EOL> cut_coords = coord_transform ( ** kwargs ) [ axis ] <EOL> return np . atleast_1d ( cut_coords ) <EOL> def find_cut_slices ( img , direction = '<STR_LIT:z>' , n_cuts = <NUM_LIT:7> , spacing = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if not direction in '<STR_LIT>' : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % ( <EOL> direction ) ) <EOL> axis = '<STR_LIT>' . index ( direction ) <EOL> affine = img . get_affine ( ) <EOL> orig_data = np . abs ( _safe_get_data ( img ) ) <EOL> this_shape = orig_data . shape [ axis ] <EOL> if not isinstance ( n_cuts , numbers . Number ) : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % n_cuts ) <EOL> if n_cuts > this_shape : <EOL> warnings . warn ( '<STR_LIT>' <EOL> '<STR_LIT>' % ( n_cuts , this_shape ) ) <EOL> return _transform_cut_coords ( np . arange ( this_shape ) , direction , affine ) <EOL> data = orig_data . copy ( ) <EOL> if data . dtype . kind == '<STR_LIT:i>' : <EOL> data = data . astype ( np . float ) <EOL> data = _smooth_array ( data , affine , fwhm = '<STR_LIT>' ) <EOL> epsilon = np . finfo ( np . float32 ) . eps <EOL> difference = abs ( round ( n_cuts ) - n_cuts ) <EOL> if round ( n_cuts ) < <NUM_LIT:1.> or difference > epsilon : <EOL> message = ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( <EOL> this_shape , direction , this_shape , n_cuts ) ) <EOL> raise ValueError ( message ) <EOL> else : <EOL> n_cuts = int ( round ( n_cuts ) ) <EOL> if spacing == '<STR_LIT>' : <EOL> spacing = max ( int ( <NUM_LIT> / n_cuts * data . shape [ axis ] ) , <NUM_LIT:1> ) <EOL> slices = [ slice ( None , None ) , slice ( None , None ) , slice ( None , None ) ] <EOL> cut_coords = list ( ) <EOL> for _ in range ( n_cuts ) : <EOL> max_along_axis = np . unravel_index ( np . abs ( data ) . argmax ( ) , <EOL> data . shape ) [ axis ] <EOL> start = max ( <NUM_LIT:0> , max_along_axis - spacing ) <EOL> stop = max_along_axis + spacing <EOL> slices [ axis ] = slice ( start , stop ) <EOL> data [ slices ] *= <NUM_LIT> <EOL> cut_coords . append ( max_along_axis ) <EOL> cut_coords = np . unique ( cut_coords ) . tolist ( ) <EOL> while len ( cut_coords ) < n_cuts : <EOL> slice_below = min ( cut_coords ) - <NUM_LIT:2> <EOL> slice_above = max ( cut_coords ) + <NUM_LIT:2> <EOL> candidates = [ slice_above ] <EOL> if len ( cut_coords ) > <NUM_LIT:1> : <EOL> middle_idx = np . argmax ( np . diff ( cut_coords ) ) <EOL> slice_middle = int ( <NUM_LIT> * ( cut_coords [ middle_idx ] <EOL> + cut_coords [ middle_idx + <NUM_LIT:1> ] ) ) <EOL> if not slice_middle in cut_coords : <EOL> candidates . append ( slice_middle ) <EOL> if slice_below >= <NUM_LIT:0> : <EOL> candidates . append ( slice_below ) <EOL> best_weight = - <NUM_LIT:10> <EOL> for candidate in candidates : <EOL> if candidate >= this_shape : <EOL> this_weight = <NUM_LIT:0> <EOL> else : <EOL> this_weight = np . sum ( np . rollaxis ( orig_data , axis ) [ candidate ] ) <EOL> if this_weight > best_weight : <EOL> best_candidate = candidate <EOL> best_weight = this_weight <EOL> cut_coords . append ( best_candidate ) <EOL> cut_coords = np . unique ( cut_coords ) . tolist ( ) <EOL> cut_coords = np . array ( cut_coords ) <EOL> cut_coords . sort ( ) <EOL> return _transform_cut_coords ( cut_coords , direction , affine ) </s>
