<s> import logging <EOL> from collections import defaultdict <EOL> from itertools import combinations <EOL> import os . path as op <EOL> import numpy as np <EOL> from . . transforms import _polar_to_cartesian , _cartesian_to_sphere <EOL> from . . bem import fit_sphere_to_headshape <EOL> from . . io . pick import pick_types <EOL> from . . io . constants import FIFF <EOL> from . . io . meas_info import Info <EOL> from . . utils import _clean_names <EOL> from . . externals . six . moves import map <EOL> class Layout ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , box , pos , names , ids , kind ) : <EOL> self . box = box <EOL> self . pos = pos <EOL> self . names = names <EOL> self . ids = ids <EOL> self . kind = kind <EOL> def save ( self , fname ) : <EOL> """<STR_LIT>""" <EOL> x = self . pos [ : , <NUM_LIT:0> ] <EOL> y = self . pos [ : , <NUM_LIT:1> ] <EOL> width = self . pos [ : , <NUM_LIT:2> ] <EOL> height = self . pos [ : , <NUM_LIT:3> ] <EOL> if fname . endswith ( '<STR_LIT>' ) : <EOL> out_str = '<STR_LIT>' % self . box <EOL> elif fname . endswith ( '<STR_LIT>' ) : <EOL> out_str = '<STR_LIT>' <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> for ii in range ( x . shape [ <NUM_LIT:0> ] ) : <EOL> out_str += ( '<STR_LIT>' % ( self . ids [ ii ] , <EOL> x [ ii ] , y [ ii ] , width [ ii ] , height [ ii ] , self . names [ ii ] ) ) <EOL> f = open ( fname , '<STR_LIT:w>' ) <EOL> f . write ( out_str ) <EOL> f . close ( ) <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . kind , <EOL> '<STR_LIT:U+002CU+0020>' . join ( self . names [ : <NUM_LIT:3> ] ) ) <EOL> def plot ( self , show = True ) : <EOL> """<STR_LIT>""" <EOL> from . . viz . topomap import plot_layout <EOL> return plot_layout ( self , show = show ) <EOL> def _read_lout ( fname ) : <EOL> """<STR_LIT>""" <EOL> with open ( fname ) as f : <EOL> box_line = f . readline ( ) <EOL> box = tuple ( map ( float , box_line . split ( ) ) ) <EOL> names , pos , ids = [ ] , [ ] , [ ] <EOL> for line in f : <EOL> splits = line . split ( ) <EOL> if len ( splits ) == <NUM_LIT:7> : <EOL> cid , x , y , dx , dy , chkind , nb = splits <EOL> name = chkind + '<STR_LIT:U+0020>' + nb <EOL> else : <EOL> cid , x , y , dx , dy , name = splits <EOL> pos . append ( np . array ( [ x , y , dx , dy ] , dtype = np . float ) ) <EOL> names . append ( name ) <EOL> ids . append ( int ( cid ) ) <EOL> pos = np . array ( pos ) <EOL> return box , pos , names , ids <EOL> def _read_lay ( fname ) : <EOL> """<STR_LIT>""" <EOL> with open ( fname ) as f : <EOL> box = None <EOL> names , pos , ids = [ ] , [ ] , [ ] <EOL> for line in f : <EOL> splits = line . split ( ) <EOL> if len ( splits ) == <NUM_LIT:7> : <EOL> cid , x , y , dx , dy , chkind , nb = splits <EOL> name = chkind + '<STR_LIT:U+0020>' + nb <EOL> else : <EOL> cid , x , y , dx , dy , name = splits <EOL> pos . append ( np . array ( [ x , y , dx , dy ] , dtype = np . float ) ) <EOL> names . append ( name ) <EOL> ids . append ( int ( cid ) ) <EOL> pos = np . array ( pos ) <EOL> return box , pos , names , ids <EOL> def read_layout ( kind , path = None , scale = True ) : <EOL> """<STR_LIT>""" <EOL> if path is None : <EOL> path = op . join ( op . dirname ( __file__ ) , '<STR_LIT:data>' , '<STR_LIT>' ) <EOL> if not kind . endswith ( '<STR_LIT>' ) and op . exists ( op . join ( path , kind + '<STR_LIT>' ) ) : <EOL> kind += '<STR_LIT>' <EOL> elif not kind . endswith ( '<STR_LIT>' ) and op . exists ( op . join ( path , kind + '<STR_LIT>' ) ) : <EOL> kind += '<STR_LIT>' <EOL> if kind . endswith ( '<STR_LIT>' ) : <EOL> fname = op . join ( path , kind ) <EOL> kind = kind [ : - <NUM_LIT:5> ] <EOL> box , pos , names , ids = _read_lout ( fname ) <EOL> elif kind . endswith ( '<STR_LIT>' ) : <EOL> fname = op . join ( path , kind ) <EOL> kind = kind [ : - <NUM_LIT:4> ] <EOL> box , pos , names , ids = _read_lay ( fname ) <EOL> kind . endswith ( '<STR_LIT>' ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> if scale : <EOL> pos [ : , <NUM_LIT:0> ] -= np . min ( pos [ : , <NUM_LIT:0> ] ) <EOL> pos [ : , <NUM_LIT:1> ] -= np . min ( pos [ : , <NUM_LIT:1> ] ) <EOL> scaling = max ( np . max ( pos [ : , <NUM_LIT:0> ] ) , np . max ( pos [ : , <NUM_LIT:1> ] ) ) + pos [ <NUM_LIT:0> , <NUM_LIT:2> ] <EOL> pos /= scaling <EOL> pos [ : , : <NUM_LIT:2> ] += <NUM_LIT> <EOL> pos [ : , : <NUM_LIT:2> ] *= <NUM_LIT> / <NUM_LIT> <EOL> pos [ : , <NUM_LIT:2> : ] *= <NUM_LIT> <EOL> return Layout ( box = box , pos = pos , names = names , kind = kind , ids = ids ) <EOL> def make_eeg_layout ( info , radius = <NUM_LIT:0.5> , width = None , height = None , exclude = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if not ( <NUM_LIT:0> <= radius <= <NUM_LIT:0.5> ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if width is not None and not ( <NUM_LIT:0> <= width <= <NUM_LIT:1.0> ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if height is not None and not ( <NUM_LIT:0> <= height <= <NUM_LIT:1.0> ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> picks = pick_types ( info , meg = False , eeg = True , ref_meg = False , <EOL> exclude = exclude ) <EOL> loc2d = _auto_topomap_coords ( info , picks ) <EOL> names = [ info [ '<STR_LIT>' ] [ i ] [ '<STR_LIT>' ] for i in picks ] <EOL> loc2d_min = np . min ( loc2d , axis = <NUM_LIT:0> ) <EOL> loc2d_max = np . max ( loc2d , axis = <NUM_LIT:0> ) <EOL> loc2d = ( loc2d - ( loc2d_max + loc2d_min ) / <NUM_LIT> ) / ( loc2d_max - loc2d_min ) <EOL> if width is None or height is None : <EOL> width , height = _box_size ( loc2d , width , height , padding = <NUM_LIT:0.1> ) <EOL> loc2d *= <NUM_LIT:2> * radius <EOL> scaling = min ( <NUM_LIT:1> / ( <NUM_LIT:1.> + width ) , <NUM_LIT:1> / ( <NUM_LIT:1.> + height ) ) <EOL> loc2d *= scaling <EOL> width *= scaling <EOL> height *= scaling <EOL> loc2d += <NUM_LIT:0.5> <EOL> n_channels = loc2d . shape [ <NUM_LIT:0> ] <EOL> pos = np . c_ [ loc2d [ : , <NUM_LIT:0> ] - <NUM_LIT:0.5> * width , <EOL> loc2d [ : , <NUM_LIT:1> ] - <NUM_LIT:0.5> * height , <EOL> width * np . ones ( n_channels ) , <EOL> height * np . ones ( n_channels ) ] <EOL> box = ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:1> ) <EOL> ids = <NUM_LIT:1> + np . arange ( n_channels ) <EOL> layout = Layout ( box = box , pos = pos , names = names , kind = '<STR_LIT>' , ids = ids ) <EOL> return layout <EOL> def make_grid_layout ( info , picks = None , n_col = None ) : <EOL> """<STR_LIT>""" <EOL> if picks is None : <EOL> picks = pick_types ( info , misc = True , ref_meg = False , exclude = '<STR_LIT>' ) <EOL> names = [ info [ '<STR_LIT>' ] [ k ] [ '<STR_LIT>' ] for k in picks ] <EOL> if not names : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> ids = list ( range ( len ( picks ) ) ) <EOL> size = len ( picks ) <EOL> if n_col is None : <EOL> n_row = n_col = np . sqrt ( size ) <EOL> if n_col % <NUM_LIT:1> : <EOL> n_col , n_row = int ( n_col + <NUM_LIT:1> ) , int ( n_row ) <EOL> if n_col * n_row < size : <EOL> n_row += <NUM_LIT:1> <EOL> else : <EOL> n_row = int ( np . ceil ( size / float ( n_col ) ) ) <EOL> x , y = np . meshgrid ( np . linspace ( - <NUM_LIT:0.5> , <NUM_LIT:0.5> , n_col ) , <EOL> np . linspace ( - <NUM_LIT:0.5> , <NUM_LIT:0.5> , n_row ) ) <EOL> x , y = x . ravel ( ) [ : size ] , y . ravel ( ) [ : size ] <EOL> width , height = _box_size ( np . c_ [ x , y ] , padding = <NUM_LIT:0.1> ) <EOL> border_x , border_y = ( <NUM_LIT> , <NUM_LIT> ) <EOL> x_scaling = <NUM_LIT:1> / ( <NUM_LIT:1.> + width + border_x ) <EOL> y_scaling = <NUM_LIT:1> / ( <NUM_LIT:1.> + height + border_y ) <EOL> x = x * x_scaling <EOL> y = y * y_scaling <EOL> width *= x_scaling <EOL> height *= y_scaling <EOL> x += <NUM_LIT:0.5> <EOL> y += <NUM_LIT:0.5> <EOL> pos = np . c_ [ x - <NUM_LIT:0.5> * width , y - <NUM_LIT:0.5> * height , <EOL> width * np . ones ( size ) , height * np . ones ( size ) ] <EOL> box = ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> , <NUM_LIT:1> ) <EOL> layout = Layout ( box = box , pos = pos , names = names , kind = '<STR_LIT>' , ids = ids ) <EOL> return layout <EOL> def find_layout ( info , ch_type = None , exclude = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> our_types = '<STR_LIT>' . join ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> if ch_type not in ( None , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' % ( ch_type , our_types ) ) <EOL> chs = info [ '<STR_LIT>' ] <EOL> coil_types = set ( [ ch [ '<STR_LIT>' ] for ch in chs ] ) <EOL> channel_types = set ( [ ch [ '<STR_LIT>' ] for ch in chs ] ) <EOL> has_vv_mag = any ( k in coil_types for k in <EOL> [ FIFF . FIFFV_COIL_VV_MAG_T1 , FIFF . FIFFV_COIL_VV_MAG_T2 , <EOL> FIFF . FIFFV_COIL_VV_MAG_T3 ] ) <EOL> has_vv_grad = any ( k in coil_types for k in [ FIFF . FIFFV_COIL_VV_PLANAR_T1 , <EOL> FIFF . FIFFV_COIL_VV_PLANAR_T2 , <EOL> FIFF . FIFFV_COIL_VV_PLANAR_T3 ] ) <EOL> has_vv_meg = has_vv_mag and has_vv_grad <EOL> has_vv_only_mag = has_vv_mag and not has_vv_grad <EOL> has_vv_only_grad = has_vv_grad and not has_vv_mag <EOL> is_old_vv = '<STR_LIT:U+0020>' in chs [ <NUM_LIT:0> ] [ '<STR_LIT>' ] <EOL> has_4D_mag = FIFF . FIFFV_COIL_MAGNES_MAG in coil_types <EOL> ctf_other_types = ( FIFF . FIFFV_COIL_CTF_REF_MAG , <EOL> FIFF . FIFFV_COIL_CTF_REF_GRAD , <EOL> FIFF . FIFFV_COIL_CTF_OFFDIAG_REF_GRAD ) <EOL> has_CTF_grad = ( FIFF . FIFFV_COIL_CTF_GRAD in coil_types or <EOL> ( FIFF . FIFFV_MEG_CH in channel_types and <EOL> any ( k in ctf_other_types for k in coil_types ) ) ) <EOL> n_kit_grads = sum ( ch [ '<STR_LIT>' ] == FIFF . FIFFV_COIL_KIT_GRAD <EOL> for ch in chs ) <EOL> has_any_meg = any ( [ has_vv_mag , has_vv_grad , has_4D_mag , has_CTF_grad , <EOL> n_kit_grads ] ) <EOL> has_eeg_coils = ( FIFF . FIFFV_COIL_EEG in coil_types and <EOL> FIFF . FIFFV_EEG_CH in channel_types ) <EOL> has_eeg_coils_and_meg = has_eeg_coils and has_any_meg <EOL> has_eeg_coils_only = has_eeg_coils and not has_any_meg <EOL> if ch_type == "<STR_LIT>" and not has_any_meg : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> if ch_type == "<STR_LIT>" and not has_eeg_coils : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> if ( ( has_vv_meg and ch_type is None ) or <EOL> ( any ( [ has_vv_mag , has_vv_grad ] ) and ch_type == '<STR_LIT>' ) ) : <EOL> layout_name = '<STR_LIT>' <EOL> elif has_vv_only_mag or ( has_vv_meg and ch_type == '<STR_LIT>' ) : <EOL> layout_name = '<STR_LIT>' <EOL> elif has_vv_only_grad or ( has_vv_meg and ch_type == '<STR_LIT>' ) : <EOL> if info [ '<STR_LIT>' ] [ <NUM_LIT:0> ] . endswith ( '<STR_LIT:X>' ) : <EOL> layout_name = '<STR_LIT>' <EOL> else : <EOL> layout_name = '<STR_LIT>' <EOL> elif ( ( has_eeg_coils_only and ch_type in [ None , '<STR_LIT>' ] ) or <EOL> ( has_eeg_coils_and_meg and ch_type == '<STR_LIT>' ) ) : <EOL> if not isinstance ( info , ( dict , Info ) ) : <EOL> raise RuntimeError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> return make_eeg_layout ( info , exclude = exclude ) <EOL> elif has_4D_mag : <EOL> layout_name = '<STR_LIT>' <EOL> elif has_CTF_grad : <EOL> layout_name = '<STR_LIT>' <EOL> elif n_kit_grads <= <NUM_LIT> : <EOL> layout_name = '<STR_LIT>' <EOL> elif n_kit_grads > <NUM_LIT> : <EOL> layout_name = '<STR_LIT>' <EOL> else : <EOL> return None <EOL> layout = read_layout ( layout_name ) <EOL> if not is_old_vv : <EOL> layout . names = _clean_names ( layout . names , remove_whitespace = True ) <EOL> if has_CTF_grad : <EOL> layout . names = _clean_names ( layout . names , before_dash = True ) <EOL> return layout <EOL> def _box_size ( points , width = None , height = None , padding = <NUM_LIT:0.0> ) : <EOL> """<STR_LIT>""" <EOL> from scipy . spatial . distance import pdist <EOL> def xdiff ( a , b ) : <EOL> return np . abs ( a [ <NUM_LIT:0> ] - b [ <NUM_LIT:0> ] ) <EOL> def ydiff ( a , b ) : <EOL> return np . abs ( a [ <NUM_LIT:1> ] - b [ <NUM_LIT:1> ] ) <EOL> points = np . asarray ( points ) <EOL> all_combinations = list ( combinations ( points , <NUM_LIT:2> ) ) <EOL> if width is None and height is None : <EOL> if len ( points ) <= <NUM_LIT:1> : <EOL> width = <NUM_LIT:1.0> <EOL> height = <NUM_LIT:1.0> <EOL> else : <EOL> a , b = all_combinations [ np . argmin ( pdist ( points ) ) ] <EOL> w , h = xdiff ( a , b ) , ydiff ( a , b ) <EOL> if w > h : <EOL> width = w <EOL> else : <EOL> height = h <EOL> if height is None : <EOL> hdist = pdist ( points , xdiff ) <EOL> candidates = [ all_combinations [ i ] for i , d in enumerate ( hdist ) <EOL> if d < width ] <EOL> if len ( candidates ) == <NUM_LIT:0> : <EOL> height = <NUM_LIT:1.0> <EOL> else : <EOL> height = np . min ( [ ydiff ( * c ) for c in candidates ] ) <EOL> elif width is None : <EOL> vdist = pdist ( points , ydiff ) <EOL> candidates = [ all_combinations [ i ] for i , d in enumerate ( vdist ) <EOL> if d < height ] <EOL> if len ( candidates ) == <NUM_LIT:0> : <EOL> width = <NUM_LIT:1.0> <EOL> else : <EOL> width = np . min ( [ xdiff ( * c ) for c in candidates ] ) <EOL> width *= <NUM_LIT:1> - padding <EOL> height *= <NUM_LIT:1> - padding <EOL> return width , height <EOL> def _find_topomap_coords ( info , picks , layout = None ) : <EOL> """<STR_LIT>""" <EOL> if len ( picks ) == <NUM_LIT:0> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if layout is not None : <EOL> chs = [ info [ '<STR_LIT>' ] [ i ] for i in picks ] <EOL> pos = [ layout . pos [ layout . names . index ( ch [ '<STR_LIT>' ] ) ] for ch in chs ] <EOL> pos = np . asarray ( pos ) <EOL> else : <EOL> pos = _auto_topomap_coords ( info , picks ) <EOL> return pos <EOL> def _auto_topomap_coords ( info , picks , ignore_overlap = False ) : <EOL> """<STR_LIT>""" <EOL> from scipy . spatial . distance import pdist , squareform <EOL> chs = [ info [ '<STR_LIT>' ] [ i ] for i in picks ] <EOL> locs3d = np . array ( [ ch [ '<STR_LIT>' ] [ : <NUM_LIT:3> ] for ch in chs ] ) <EOL> if len ( locs3d ) == <NUM_LIT:0> or np . allclose ( locs3d , <NUM_LIT:0> ) : <EOL> logging . warning ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> for ch in chs : <EOL> if ch [ '<STR_LIT>' ] != FIFF . FIFFV_EEG_CH : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> eeg_ch_names = [ ch [ '<STR_LIT>' ] for ch in info [ '<STR_LIT>' ] <EOL> if ch [ '<STR_LIT>' ] == FIFF . FIFFV_EEG_CH ] <EOL> if info [ '<STR_LIT>' ] is None or len ( info [ '<STR_LIT>' ] ) == <NUM_LIT:0> : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> locs3d = np . array ( [ point [ '<STR_LIT:r>' ] for point in info [ '<STR_LIT>' ] <EOL> if point [ '<STR_LIT>' ] == FIFF . FIFFV_POINT_EEG ] ) <EOL> if len ( locs3d ) == <NUM_LIT:0> : <EOL> raise RuntimeError ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> % FIFF . FIFFV_POINT_EEG ) <EOL> if len ( locs3d ) != len ( eeg_ch_names ) : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( len ( locs3d ) , len ( eeg_ch_names ) ) ) <EOL> dig_kinds = ( FIFF . FIFFV_POINT_CARDINAL , <EOL> FIFF . FIFFV_POINT_EEG , <EOL> FIFF . FIFFV_POINT_EXTRA ) <EOL> _ , origin_head , _ = fit_sphere_to_headshape ( info , dig_kinds , units = '<STR_LIT:m>' ) <EOL> locs3d -= origin_head <EOL> eeg_ch_locs = dict ( zip ( eeg_ch_names , locs3d ) ) <EOL> locs3d = np . array ( [ eeg_ch_locs [ ch [ '<STR_LIT>' ] ] for ch in chs ] ) <EOL> dist = pdist ( locs3d ) <EOL> if np . min ( dist ) < <NUM_LIT> and not ignore_overlap : <EOL> problematic_electrodes = [ <EOL> chs [ elec_i ] [ '<STR_LIT>' ] <EOL> for elec_i in squareform ( dist < <NUM_LIT> ) . any ( axis = <NUM_LIT:0> ) . nonzero ( ) [ <NUM_LIT:0> ] <EOL> ] <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' + str ( problematic_electrodes ) + '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> x , y , z = locs3d . T <EOL> az , el , r = _cartesian_to_sphere ( x , y , z ) <EOL> locs2d = np . c_ [ _polar_to_cartesian ( az , np . pi / <NUM_LIT:2> - el ) ] <EOL> return locs2d <EOL> def _topo_to_sphere ( pos , eegs ) : <EOL> """<STR_LIT>""" <EOL> xs , ys = np . array ( pos ) . T <EOL> sqs = np . max ( np . sqrt ( ( xs [ eegs ] ** <NUM_LIT:2> ) + ( ys [ eegs ] ** <NUM_LIT:2> ) ) ) <EOL> xs /= sqs <EOL> ys /= sqs <EOL> xs += <NUM_LIT:0.5> - np . mean ( xs [ eegs ] ) <EOL> ys += <NUM_LIT:0.5> - np . mean ( ys [ eegs ] ) <EOL> xs = xs * <NUM_LIT> - <NUM_LIT:1.> <EOL> ys = ys * <NUM_LIT> - <NUM_LIT:1.> <EOL> rs = np . clip ( np . sqrt ( xs ** <NUM_LIT:2> + ys ** <NUM_LIT:2> ) , <NUM_LIT:0.> , <NUM_LIT:1.> ) <EOL> alphas = np . arccos ( rs ) <EOL> zs = np . sin ( alphas ) <EOL> return np . column_stack ( [ xs , ys , zs ] ) <EOL> def _pair_grad_sensors ( info , layout = None , topomap_coords = True , exclude = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> pairs = defaultdict ( list ) <EOL> grad_picks = pick_types ( info , meg = '<STR_LIT>' , ref_meg = False , exclude = exclude ) <EOL> for i in grad_picks : <EOL> ch = info [ '<STR_LIT>' ] [ i ] <EOL> name = ch [ '<STR_LIT>' ] <EOL> if name . startswith ( '<STR_LIT>' ) : <EOL> if name . endswith ( ( '<STR_LIT:2>' , '<STR_LIT:3>' ) ) : <EOL> key = name [ - <NUM_LIT:4> : - <NUM_LIT:1> ] <EOL> pairs [ key ] . append ( ch ) <EOL> pairs = [ p for p in pairs . values ( ) if len ( p ) == <NUM_LIT:2> ] <EOL> if len ( pairs ) == <NUM_LIT:0> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> grad_chs = sum ( pairs , [ ] ) <EOL> ch_names = info [ '<STR_LIT>' ] <EOL> picks = [ ch_names . index ( c [ '<STR_LIT>' ] ) for c in grad_chs ] <EOL> if topomap_coords : <EOL> shape = ( len ( pairs ) , <NUM_LIT:2> , - <NUM_LIT:1> ) <EOL> coords = ( _find_topomap_coords ( info , picks , layout ) <EOL> . reshape ( shape ) . mean ( axis = <NUM_LIT:1> ) ) <EOL> return picks , coords <EOL> else : <EOL> return picks <EOL> def _pair_grad_sensors_from_ch_names ( ch_names ) : <EOL> """<STR_LIT>""" <EOL> pairs = defaultdict ( list ) <EOL> for i , name in enumerate ( ch_names ) : <EOL> if name . startswith ( '<STR_LIT>' ) : <EOL> if name . endswith ( ( '<STR_LIT:2>' , '<STR_LIT:3>' ) ) : <EOL> key = name [ - <NUM_LIT:4> : - <NUM_LIT:1> ] <EOL> pairs [ key ] . append ( i ) <EOL> pairs = [ p for p in pairs . values ( ) if len ( p ) == <NUM_LIT:2> ] <EOL> grad_chs = sum ( pairs , [ ] ) <EOL> return grad_chs <EOL> def _merge_grad_data ( data ) : <EOL> """<STR_LIT>""" <EOL> data = data . reshape ( ( len ( data ) // <NUM_LIT:2> , <NUM_LIT:2> , - <NUM_LIT:1> ) ) <EOL> data = np . sqrt ( np . sum ( data ** <NUM_LIT:2> , axis = <NUM_LIT:1> ) / <NUM_LIT:2> ) <EOL> return data <EOL> def generate_2d_layout ( xy , w = <NUM_LIT> , h = <NUM_LIT> , pad = <NUM_LIT> , ch_names = None , <EOL> ch_indices = None , name = '<STR_LIT>' , bg_image = None ) : <EOL> """<STR_LIT>""" <EOL> from scipy . ndimage import imread <EOL> if ch_indices is None : <EOL> ch_indices = np . arange ( xy . shape [ <NUM_LIT:0> ] ) <EOL> if ch_names is None : <EOL> ch_names = [ '<STR_LIT>' . format ( i ) for i in ch_indices ] <EOL> if len ( ch_names ) != len ( ch_indices ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> if len ( ch_names ) != len ( xy ) : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> x , y = xy . copy ( ) . astype ( float ) . T <EOL> if bg_image is not None : <EOL> if isinstance ( bg_image , str ) : <EOL> img = imread ( bg_image ) <EOL> else : <EOL> img = bg_image <EOL> x /= img . shape [ <NUM_LIT:1> ] <EOL> y /= img . shape [ <NUM_LIT:0> ] <EOL> else : <EOL> for i_dim in [ x , y ] : <EOL> i_dim -= i_dim . min ( <NUM_LIT:0> ) <EOL> i_dim /= ( i_dim . max ( <NUM_LIT:0> ) - i_dim . min ( <NUM_LIT:0> ) ) <EOL> box = _box_size ( np . vstack ( [ x , y ] ) . T , padding = pad ) <EOL> box = ( <NUM_LIT:0> , <NUM_LIT:0> , box [ <NUM_LIT:0> ] , box [ <NUM_LIT:1> ] ) <EOL> w , h = [ np . array ( [ i ] * x . shape [ <NUM_LIT:0> ] ) for i in [ w , h ] ] <EOL> loc_params = np . vstack ( [ x , y , w , h ] ) . T <EOL> layout = Layout ( box , loc_params , ch_names , ch_indices , name ) <EOL> return layout </s>
