def _load_grid(directory): if not os.path.isdir(directory): raise IOError('directory not found: {0}'.format(directory)) for filename in ( directory + os.sep + 'elem.dat', directory + os.sep + 'elec.dat', ): if not os.path.isfile(filename): raise IOError('filename not found: {0}'.format(filename)) cells = [] grid = CRGrid.crt_grid() grid.load_elem_file(directory + os.sep + 'elem.dat') grid.load_elec_file(directory + os.sep + 'elec.dat') gx = grid.grid['x'] gz = grid.grid['z'] for x, z in zip(gx, gz): # find all cell that touch this cell coords = [(xi, zi) for xi, zi in zip(x, z)] p2 = Polygon(coords) cells.append(p2) rhofile = directory + os.sep + 'rho.dat' if os.path.isfile(rhofile): rho = np.loadtxt(rhofile, skiprows=1) else: rho = None return gx, gz, cells, rho
def get_grid(key): """Return a :class:`crtomo.grid.crt_grid` instance, with a debug grid that is distributed with the crtomo package. Multiple grids are available: * key=20 - a 20 electrode grid with 1m spacing, 4 elements between electrodes, rectangular elements. * key=40 - a 40 electrode grid with 1m spacing, 4 elements between electrodes, rectangular elements. Parameters ---------- key: string key that identifies the grid Returns ------- grid: :class:`crtomo.grid.crt_grid` instance loaded grid object """ rbase = grid_files[key] elem_file = pk.resource_filename('crtomo', rbase['elem']) elec_file = pk.resource_filename('crtomo', rbase['elec']) grid = CRGrid.crt_grid(elem_file=elem_file, elec_file=elec_file) return grid
def main(): if not os.path.isfile('elem.dat'): raise Exception('elem.dat not found!') grid = CRGrid.crt_grid() grid.load_elem_file('elem.dat') fig, ax = grid.analyze_internal_angles(return_plot=True) fig.savefig('plot_element_angles.jpg', dpi=300)
def main(): if os.path.basename(os.getcwd()) == 'exe': os.chdir('..') options = handle_options() matplotlib.style.use('default') mpl_style.general_settings() # load grid grid = CRGrid.crt_grid('grid/elem.dat', 'grid/elec.dat') plotman = CRPlot.plotManager(grid=grid) # get alpha alpha, plotman = alpha_from_cov(plotman, options.alpha_cov) # make tomodir overview plot if not options.single and not options.aniso and not options.hlam: [datafiles, filetype] = list_datafiles() [cov, mag, pha, pha_fpi] = read_datafiles( datafiles, filetype, options.column) create_tdplot(plotman, cov, mag, pha, pha_fpi, alpha, options) # make individual plots elif options.single and not options.aniso and not options.hlam: [datafiles, filetype] = list_datafiles() [cov, mag, pha, pha_fpi] = read_datafiles( datafiles, filetype, options.column) create_singleplots(plotman, cov, mag, pha, pha_fpi, alpha, options) # make plots of anisotropic results elif options.aniso and not options.single and not options.hlam: filename = read_iter(False) x = load_rho(filename, 2) y = load_rho(filename, 3) z = load_rho(filename, 4) create_anisomagplot(plotman, x, y, z, alpha, options) x = load_rho(filename[:-3] + 'pha', 2) y = load_rho(filename[:-3] + 'pha', 3) z = load_rho(filename[:-3] + 'pha', 4) create_anisophaplot(plotman, x, y, z, alpha, options) elif options.hlam and not options.single and not options.aniso: filename = read_iter(False) hor = load_rho(filename, 2) lam = load_rho(filename, 3) create_hlammagplot(plotman, hor, lam, alpha, options) hor = load_rho(filename[:-3] + 'pha', 2) ver = load_rho(filename[:-3] + 'pha', 4) create_hlamphaplot(plotman, hor, ver, alpha, options) else: print( 'You can only use one option out of these: ' '"single", "hlam" or "aniso", not two at the same time.' ) exit()
def main(): options = handle_cmd_options() # put in dummy center coordinates options.center_x = 0.0 options.center_y = 0.0 grid = CRGrid.crt_grid() grid.load_elem_file(options.elem_file) rotated_nodes = translate_nodes(grid.nodes['raw'][:, 1:3], options.dx, options.dz) grid.nodes['raw'][:, 1:3] = rotated_nodes grid.save_elem_file(options.output)
def main(): options = handle_cmd_options() check_options(options) grid = CRGrid.crt_grid() grid.load_elem_file(options.elem_file) extra_lines = np.atleast_2d(np.loadtxt(options.linefile)) fids = [] fids.append(open('debug_search_nodes.dat', 'wb')) fids.append(open('debug_dist.dat', 'wb')) neighbors = None if options.line_nr is None: lines = extra_lines else: print('processing only line: {0}'.format(options.line_nr)) lines = (extra_lines[options.line_nr], ) for line in lines: data = get_decouplings_for_line(grid, line, { 'eps': options.eps, 'eta': options.eta, }, fids) if neighbors is None: neighbors = data else: try: neighbors = np.vstack((neighbors, data)) except: import IPython IPython.embed() for fid in fids: fid.close() with open(options.output, 'w') as fid: fid.write('{0}\n'.format(neighbors.shape[0])) with open(options.output, 'ab') as fid: np.savetxt(fid, np.array(neighbors), fmt='%i %i %.2f') if options.debug_plot: debug_plot( grid=grid, extra_lines=extra_lines, decoupling_elements=np.array(neighbors), options=options, )
def load_grid(self, alpha): '''Load grid and calculate alpha values from the coverage/2.5. ''' grid = CRGrid.crt_grid(self.dirs[0] + '/grid/elem.dat', self.dirs[0] + '/grid/elec.dat') self.plotman = CRPlot.plotManager(grid=grid) name = self.dirs[0] + '/inv/coverage.mag' content = np.genfromtxt(name, skip_header=1, skip_footer=1, usecols=([2])) abscov = np.abs(content) if alpha: normcov = np.divide(abscov, 2.5) normcov[np.where(normcov > 1)] = 1 mask = np.subtract(1, normcov) self.alpha = self.plotman.parman.add_data(mask) else: self.alpha = self.plotman.parman.add_data(np.ones(len(abscov)))
def __init__(self, **kwargs): """initialize the plot manager. Multiple combinations are possible for the kwargs. Parameters ---------- grid: crtomo.grid.crt_grid, optional a fully initialized grid object. If not provided, elem and elec files must be provided! elem_file: file path file path to an elem.dat FE grid file. If no grid is provided, a new crt_grid oject is initialized elec_file: file path file path to an elec.dat FE electrode file nm: crtomo.nodeManager.nodeMan instance, optional node manager for node data. If none is provided, an empty one is initialized pm: crtomo.parManager.parMan instance, optional parameter manager for element data. If none is provided, an empty one is initialized """ # initialize grid grid = kwargs.get('grid', None) if grid is None: elem_file = kwargs.get('elem_file', None) if elem_file is None: raise Exception('No grid object and no elem path provided!') elec_file = kwargs.get('elec_file', None) grid = CRGrid.crt_grid() grid.load_grid(elem_file, elec_file) self.grid = grid # node manager nodeman = kwargs.get('nm', None) if nodeman is None: nodeman = nM.NodeMan(self.grid) self.nodeman = nodeman # par manager self.parman = kwargs.get('pm', pM.ParMan(self.grid))
def main(): options = handle_cmd_options() decfunc = get_func_decoupling_at_z( options.dec_file, options.output + '.png' ) grid = CRGrid.crt_grid() grid.load_elem_file(options.elem_file) nx = grid.nodes['sorted'][:, 1] ny = grid.nodes['sorted'][:, 2] nxy = np.vstack((nx, ny)).T decoupling_items = [] for elmnr, element in enumerate(grid.elements): neighbors = find_neighbors(grid, elmnr) for neighbor in neighbors: xz = np.array([nxy[i] for i in neighbor[1:]]) # we are only interested in z-coordinates z = xz[:, 1] if z.min() == z.max(): # add decoupling decoupling = decfunc((z[0], ))[0] # print('decoupling', decoupling) decoupling_items.append((elmnr + 1, neighbor[0] + 1, decoupling)) else: # print('vertical side') continue final_decouplings = np.array(decoupling_items) with open(options.output, 'w') as fid: fid.write('{0}\n'.format(final_decouplings.shape[0])) np.savetxt(fid, final_decouplings, fmt='%i %i %f')
def compute_K_factors(elem_file, elec_file, config_file): grid = CRGrid.crt_grid() grid.load_grid(elem_file, elec_file) configs = np.loadtxt(config_file, skiprows=1) A = np.round(configs[:, 0] / 1e4).astype(int) - 1 B = np.mod(configs[:, 0], 1e4).astype(int) - 1 M = np.round(configs[:, 1] / 1e4).astype(int) - 1 N = np.mod(configs[:, 1], 1e4).astype(int) - 1 # we assume that electrodes are positioned on the surface # therefore we only need X coordinates Exz = grid.get_electrode_positions() Ex = Exz[:, 0] # make sure Ez are all the same if np.any(Exz[:, 1] - Exz[0, 1] != 0): print('Are you sure that the grid approximates a halfspace?') exit() # get coordinates Xa = Ex[A] Xb = Ex[B] Xm = Ex[M] Xn = Ex[N] r_am = np.abs(Xa - Xm) r_bm = np.abs(Xb - Xm) r_an = np.abs(Xa - Xn) r_bn = np.abs(Xb - Xn) geom = (1 / r_am - 1 / r_bm - 1 / r_an + 1 / r_bn) K = (2 * np.pi) * (geom)**(-1) return K, np.vstack((A + 1, B + 1, M + 1, N + 1)).T
def test_number_nodes(): grid = CRGrid.crt_grid() grid.load_grid('data/elem.dat', 'data/elec.dat') assert grid.nr_of_nodes == 48
def load_grid(options): grid = CRGrid.crt_grid() grid.load_grid(options.elem_file, options.elec_file) return grid
def plot_wireframe(options): grid = CRGrid.crt_grid() grid.load_elem_file(options.elem_file) grid.load_elec_file(options.elec_file) xmin = grid.grid['x'].min() xmax = grid.grid['x'].max() zmin = grid.grid['z'].min() zmax = grid.grid['z'].max() fig, ax = plt.subplots(1, 1, frameon=False) all_xz = [] for x, z in zip(grid.grid['x'], grid.grid['z']): tmp = np.vstack((x, z)).T all_xz.append(tmp) collection = mpl.collections.PolyCollection( all_xz, edgecolor='k', facecolor='none', linewidth=cell_line_width, ) ax.add_collection(collection) # plot electrodes ax.scatter( grid.electrodes[:, 1], grid.electrodes[:, 2], edgecolors='none', clip_on=False, label='electrodes', s=elec_size ) if options.plot_elec_nr: for nr, xy in enumerate(grid.electrodes[:, 1:3]): ax.text( xy[0], xy[1], '{}'.format(nr + 1), bbox=dict(boxstyle='circle', facecolor='red', alpha=0.8) ) # mark nodes if options.mark_node is not None: xy = grid.nodes['sorted'][options.mark_node] ax.scatter( xy[1], xy[2], s=node_mark_size, color='r', edgecolors='none', label='marked node', ) if options.mark_cell is not None: index = options.mark_cell x = grid.grid['x'][index] z = grid.grid['z'][index] label = 'marked cell' for i in range(0, x.size): i1 = (i + 1) % x.size ax.plot( x[[i, i1]], z[[i, i1]], color='r', linewidth=cell_mark_size, label=label, ) label = '' polygon = mpl.patches.Polygon( [(a, b) for a, b in zip(x, z)], closed=True, color='r', alpha=1.0, ) ax.add_patch(polygon) if os.path.isfile(options.decoupling_file): decouplings = np.loadtxt(options.decoupling_file, skiprows=1) # plot decouplings label = 'decoupling line' for (el1, el2, coef) in decouplings: n1 = grid.elements[int(el1) - 1] n2 = grid.elements[int(el2) - 1] ints = np.intersect1d(n1, n2) x = grid.nodes['presort'][ints, 1] z = grid.nodes['presort'][ints, 2] ax.plot( x, z, '.-', color='b', linestyle='dashed', label=label, ) label = '' ax.autoscale_view() ax.set_aspect('equal') if options.plot_fancy: ax.set_xlabel('x [m]') ax.set_ylabel('z [m]') ax.legend( loc="lower center", ncol=4, bbox_to_anchor=(0, 0, 1, 1), bbox_transform=fig.transFigure ) else: ax.axis('off') ax.xaxis.set_visible(False) ax.yaxis.set_visible(False) ax.set_xlim(xmin, xmax) ax.set_ylim(zmin, zmax) fig.savefig(options.output, dpi=dpi, bbox_inches='tight')
def setup(self): grid = CRGrid.crt_grid() grid.load_elem_file('tomodir/grid/elem.dat') self.nodeMan = nM.NodeMan(grid)
def __init__(self, **kwargs): """ Data/frequency input: Note that only one of the parameters seitdir, crt_data_dir, seit_data will be used during initialization, in the stated priority. Initialization diagram: .. blockdiag:: diagram { group g_grid { par_grid -> a_grid [label="loads"]; group g_elmc { par_elem -> a_grid [label="loads"]; par_elec -> a_grid [label="loads"]; } } a_grid [label="grid"] seitdir[label="sEIT inversion directory"]; seitdir -> a_grid [label="grid"]; seitdir -> frequencies [label="loads"]; seitdir -> inv_results [label="loads"]; seitdir -> seit_data [label="loads"]; crt_data_dir -> seit_data [label="loads"]; inv_results[label="loads"]; crt_data_dir[label="CRTomo style multi-frequency data"]; crt_data_dir -> frequencies [label="loads"]; crt_data_dir -> seit_data [label="loads"]; dict_seit_data [label="data dictionary"]; par_frequencies -> frequencies [label="loads"]; } Parameters ---------- seitdir : string, optional Load frequencies, grid, and data from an existing sEIT directory. Honors the shallow_import parameter. shallow_import : bool, optional In combination with seitdir, only import the last iteration inversion results (faster). crt_data_dir : string, optional if given, then try to load data from this directory. Expect a 'frequencies.dat' file and corresponding 'volt_*.dat' files. only_frequency_ids : numpy.ndarray|None Load only the frequencies associated with these indices (zero-based). Only works with crt_data_dir. seit_data : dict A dictionary with frequencies as keys, and numpy arrays as items. Each array must have 6 columns: a,b,m,n,magnitude[Ohm],phase[mrad] frequencies : numpy.ndarray, optional frequencies that we work with grid : crtomo.crt_grid.crt_grid, optional A grid instance elem_file : string, optional Path to elem file elec_file : string, optional Path to elec file decouplings_file : str, optional Path to decoupling file: For not will be copied to the exe/ subdir of each tomodir written crmod_cfg : ?, optional crtomo_cfg : ?, optional parman : ?, optional """ # the following variables will be partially duplicated in the tomodir # instances down below. Thus, they are used primarily to store blue # prints or "parent" files for the various frequencies. For example: # mask-files that are then parameterized using some kind of SIP model # such as the Cole-Cole model. self.crmod_cfg = kwargs.get('crmod_cfg', None) self.crtomo_cfg = kwargs.get('crtomo_cfg', CRcfg.crtomo_config()) self.parman = kwargs.get('parman', None) self.noise_model = kwargs.get('noise_model', None) self.decoupling_file = kwargs.get('decouplings_file', None) # for each frequency we have a separate tomodir object self.tds = {} # when we load data from inversion results, we need to store the # corresponding parameter ids for the various quantities self.assigments = { 'rmag': {}, 'rpha': {}, 'cre': {}, 'cim': {}, 'forward_rmag': {}, 'forward_rpha': {}, } # shortcut self.a = self.assigments self.frequencies = kwargs.get('frequencies', None) # # now load data/initialize things seit_dir = kwargs.get('seitdir', None) crt_data_dir = kwargs.get('crt_data_dir', None) seit_data = kwargs.get('seit_data', None) # load/assign grid if 'grid' in kwargs: self.grid = kwargs.get('grid') elif 'elem_file' in kwargs and 'elec_file' in kwargs: grid = crt_grid() grid.load_grid( kwargs['elem_file'], kwargs['elec_file'], ) self.grid = grid else: self.grid = None # these are the principle ways to add data if seit_dir is not None: # load the grid from the first invmod subdirectory tdirs = sorted(glob(seit_dir + '/invmod/*')) grid = crt_grid(elem_file=tdirs[0] + '/grid/elem.dat', elec_file=tdirs[0] + '/grid/elec.dat') self.grid = grid self.load_inversion_results(seit_dir, shallow_import=kwargs.get( 'shallow_import', False)) elif crt_data_dir is not None: data_files = {} data_files['frequencies'] = '{}/frequencies.dat'.format( crt_data_dir) files = sorted(glob('{}/volt_*.crt'.format(crt_data_dir))) only_frequency_ids = kwargs.get('only_use_frequency_ids', None) data_files['crt'] = files self.load_data_crt_files(data_files, only_frequency_ids=only_frequency_ids) elif seit_data is not None: frequencies = sorted(seit_data.keys()) self._init_frequencies(frequencies) for frequency in frequencies: abmn = seit_data[frequency][:, 0:4] rmag = seit_data[frequency][:, 4] rpha = seit_data[frequency][:, 5] self.tds[frequency].configs.add_to_configs(abmn) self.tds[frequency].register_measurements(rmag, rpha) else: # initialize frequency tomodirs if 'frequencies' in kwargs: self._init_frequencies(kwargs.get('frequencies'), kwargs.get('configs_abmn', None)) if self.grid is None: raise Exception('You must provide either a grid instance or ' 'elem_file/elec_file file paths')
def setup(self): grid = CRGrid.crt_grid() grid.load_elem_file('tomodir/grid/elem.dat') self.parman = pM.ParMan(grid)
def test_number_elements(): grid = CRGrid.crt_grid() grid.load_grid('data/elem.dat', 'data/elec.dat') assert grid.nr_of_elements == 74
def test_loading_of_elem_only(): grid = CRGrid.crt_grid() grid.load_elem_file('data/elem.dat')
def test_loading_of_grid(): grid = CRGrid.crt_grid() grid.load_grid('data/elem.dat', 'data/elec.dat')