def main(): args = parse_arguments(sys.argv[1:]) msh = mesh_io.read_msh(os.path.abspath(os.path.realpath(os.path.expanduser(args.mesh)))) fn_csv = os.path.expanduser(args.csv) if args.l is not None: labels = [int(n) for n in args.l[0].split(',')] msh = msh.crop_mesh(tags=labels) points = np.atleast_2d(np.loadtxt(fn_csv, delimiter=',', dtype=float)) if points.shape[1] != 3: raise IOError('CSV file should have 3 columns') csv_basename, _ = os.path.splitext(fn_csv) for ed in msh.elmdata: fn_out = '{0}_{1}.csv'.format(csv_basename, ed.field_name) logger.info('Interpolating field: {0} and writing to file: {1}'.format( ed.field_name, fn_out)) f = ed.interpolate_scattered( points, out_fill=args.out_fill, method=args.method, continuous=False, squeeze=False) if f.ndim == 1: f = f[:, None] np.savetxt(fn_out, f, delimiter=',') for nd in msh.nodedata: fn_out = '{0}_{1}.csv'.format(csv_basename, nd.field_name) logger.info('Interpolating field: {0} and writing to file: {1}'.format( nd.field_name, fn_out)) f = nd.interpolate_scattered( points, out_fill=args.out_fill, squeeze=False) if f.ndim == 1: f = f[:, None] np.savetxt(fn_out, f, delimiter=',')
def main(): args = parseArguments(sys.argv[1:]) if not os.path.isfile(args.fn_nifti): raise IOError('Could not find file: {0}'.format(args.fn_nifti)) if not os.path.isfile(args.fn_mesh): raise IOError('Could not find file: {0}'.format(args.fn_mesh)) image = nibabel.load(args.fn_nifti) mesh = mesh_io.read_msh(args.fn_mesh) vol = image.dataobj affine = image.affine if args.ev: logger.info('Creating tensor visualization') mesh = mesh.crop_mesh([1, 2, 1001, 1002]) cond_list = [c.value for c in cond.standard_cond()] sigma = cond.cond2elmdata(mesh, cond_list, anisotropy_volume=vol, affine=affine, aniso_tissues=[1, 2]) views = cond.TensorVisualization(sigma, mesh) mesh.nodedata = [] mesh.elmdata = views mesh_io.write_msh(mesh, args.fn_out) else: logger.info('Interpolating data in NifTI file to mesh') if args.type == 'elements': ed = mesh_io.ElementData.from_data_grid(mesh, vol, affine, 'from_volume') mesh.elmdata.append(ed) if args.type == 'nodes': nd = mesh_io.NodeData.from_data_grid(mesh, vol, affine, 'from_volume') mesh.nodedata.append(nd) mesh_io.write_msh(mesh, args.fn_out)
def main(): args = parseArguments(sys.argv[1:]) if not os.path.isfile(args.fn_mask): raise IOError('Could not find file: {0}'.format(args.fn_mask)) if not os.path.isfile(args.fn_mesh): raise IOError('Could not find file: {0}'.format(args.fn_mesh)) image = nibabel.load(args.fn_mask) mesh = mesh_io.read_msh(args.fn_mesh) vol = image.dataobj if not np.issubdtype(vol.dtype, np.integer): logger.warn('Volume is not an integer type, masking may fail') affine = image.affine logger.info('Applying Mask') ed = mesh_io.ElementData.from_data_grid(mesh, vol, affine, 'from_volume') # Re-label tetrahedra mesh.elm.tag1[(ed.value > 0) * mesh.elm.elm_type == 4] = args.tag mesh.elm.tag2[(ed.value > 0) * mesh.elm.elm_type == 4] = args.tag # Remove triangles mesh.elm.tag1[(ed.value > 0) * mesh.elm.elm_type == 2] = 99999 mesh.elm.tag2[(ed.value > 0) * mesh.elm.elm_type == 2] = 99999 mesh = mesh.remove_from_mesh(99999) logger.info(f'Writing {args.fn_out}') mesh_io.write_msh(mesh, args.fn_out)
def main(): if len(sys.argv) not in [3, 5]: print("Incorrect number of arguments") usage() sys.exit(1) # check extension if os.path.splitext(sys.argv[1])[1] != '.msh': print('1st argument must have a .msh extension') sys.exit(1) if os.path.splitext(sys.argv[2])[1] != '.msh': print('2nd argument must have a .msh extension') sys.exit(1) m = mesh_io.read_msh(sys.argv[1]) m.fn = sys.argv[2] logger.info( "Relabeled ventricle regions to CSF and cerebellum regions to WM") m.elm.tag1[m.elm.tag1 == 6] = 1 m.elm.tag1[m.elm.tag1 == 7] = 3 m.elm.tag2[m.elm.tag2 == 6] = 1 m.elm.tag2[m.elm.tag2 == 7] = 3 logger.info("Fixing surface labeling") m.fix_surface_labels() logger.info("Fixing thin tetrahedra") m.fix_thin_tetrahedra() logger.info("Fixing tetrahedra node ordering") m.fix_th_node_ordering() logger.info("Fixing triangle node ordering") m.fix_tr_node_ordering() mesh_io.write_msh(m, mode='binary')
def test_tms_coil_parallel(self, mock_set_up, tms_sphere): if sys.platform == 'win32': '''Won't run on windows because Mock does not work through multiprocessing ''' assert True return m, cond, dAdt, E_analytical = tms_sphere mock_set_up.return_value = dAdt.node_data2elm_data() matsimnibs = 'MATSIMNIBS' didt = 6 fn_out = [ tempfile.NamedTemporaryFile(delete=False).name for i in range(4) ] fem.tms_coil(m, cond, 'coil.ccd', 'EJ', 4 * [matsimnibs], 4 * [didt], fn_out, n_workers=2) for f in fn_out: E = mesh_io.read_msh(f).field['E'].value os.remove(f) assert rdm(E, E_analytical) < .2 assert np.abs(mag(E, E_analytical)) < np.log(1.1)
def test_tms_coil(self, mock_set_up, tms_sphere): m, cond, dAdt, E_analytical = tms_sphere mock_set_up.return_value = dAdt.node_data2elm_data() matsimnibs = 'MATSIMNIBS' didt = 6 fn_out = tempfile.NamedTemporaryFile(delete=False).name fem.tms_coil(m, cond, 'coil.ccd', 'EJ', [matsimnibs], [didt], [fn_out]) E = mesh_io.read_msh(fn_out).field['E'].value os.remove(fn_out) mock_set_up.assert_called_once_with(m, 'coil.ccd', matsimnibs, didt, fn_geo=None) assert rdm(E, E_analytical) < .2 assert np.abs(mag(E, E_analytical)) < np.log(1.1)
def main(): args = parseArguments(sys.argv) print("Reading Mesh") mesh = mesh_io.read_msh(args.m) print("Reference points:") print("Nz:", args.Nz) print("Iz:", args.Iz) print("LPA:", args.LPA) print("RPA:", args.RPA) surf = surface.Surface(mesh, [5, 1005]) eeg = FindPositions(args.Nz, args.Iz, args.LPA, args.RPA, surf) eeg = FindPositions(args.Nz, args.Iz, args.LPA, args.RPA, surf, args.NE_cap) print("Printing positions to file", args.o + '.csv') eeg.print2csv(args.o + '.csv') eeg.print2geo(args.o + '.geo')
def get_field_subset(field_msh, tag_list): ''' From a .msh file outputted from running a TMS field simulation extract the field magnitude values of elements provided for in tag_list field_msh -- Path to .msh file result from TMS simulation tag_list -- List of element tags to use as subset Output: normE -- List of electric field norms (magnitudes) subsetted according to tag_list ''' msh = mesh_io.read_msh(field_msh) norm_E = msh.elmdata[1].value del msh gc.collect() return norm_E[tag_list]
def cube_lr(): fn = os.path.join(os.path.dirname(os.path.realpath( __file__)), '..', 'testing_files', 'cube.msh') return mesh_io.read_msh(fn)
def sphere_el_msh(): fn = os.path.join(os.path.dirname(os.path.realpath( __file__)), '..', 'testing_files', 'sphere_w_electrodes.msh') return mesh_io.read_msh(fn)
def sphere_vol(): fn = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'testing_files', 'sphere3.msh') return mesh_io.read_msh(fn).crop_mesh([4, 5])
def main(): p = argparse.ArgumentParser(description="Run a SimNIBS simulation " "at the coordinates specified at a given " "orientation") p.add_argument("mesh", type=str, help="Realistic head model " ".msh file") p.add_argument("orientation", type=str, help="Input parameters to evaluate " "objective function on") p.add_argument("centroid", type=str, help="Coordinate .txt file pointing " "to centroid for parameteric mesh seeding") p.add_argument("weights", type=str, help="Weight function used to " "evaluate the objective function") p.add_argument("coil", type=str, help="Coil to use for running a " "simulation, .ccd physical model or .nii.gz dA/dt file") p.add_argument("out_fields", type=str, help="Output gmsh simulation .msh file") p.add_argument("out_coil", type=str, help="Output coil position .geo file") p.add_argument("out_coords", type=str, help="Output transformed coil coordinate file in RAS") args = p.parse_args() # Parse arguments msh = args.mesh orientation = np.genfromtxt(args.orientation) centroid = np.genfromtxt(args.centroid) wf = np.load(args.weights) coil = args.coil out_fields = args.out_fields out_coil = args.out_coil out_coords = args.out_coords # Construct the objective function fem = FieldFunc(msh, initial_centroid=centroid, tet_weights=wf, coil=coil, field_dir=os.getcwd(), cpus=2) # Get position and anterior facing direction of coil matsimnibs = fem._transform_input(*orientation) a = matsimnibs[:3, 1] # Coil adjustment methodology # We never want anterior facing coil orientations if a[1] < 0: orientation[2] = (orientation[2] + 180) % 360 _, matsimnibs = fem.run_simulation(orientation, out_fields, out_coil) # Save matsimnibs matrix np.save(out_coords, matsimnibs) # Write in weight function M = mesh_io.read_msh(out_fields) gm = np.where(M.elm.tag1 == 2) wf_field = np.zeros_like(M.elmdata[1].value) wf_field[gm] = wf M.add_element_field(wf_field, 'weightfunction') M.write(out_fields)
def sphere3_msh(): return mesh_io.read_msh( os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'testing_files', 'sphere3.msh'))
def __init__(self, mesh_file, initial_centroid, tet_weights, field_dir, coil, span=35, local_span=8, distance=1, didt=1e6, cpus=1, solver_options=None): ''' Standard constructor Arguments: mesh_file Path to FEM model initial_centroid Initial point to grow sampling region tet_weights Weighting scores for each tetrahedron (1D array ordered by node ID) field_dir Directory to perform simulation experiments in coil TMS coil file (either dA/dt volume or coil geometry) span Radius of points to include in sampling surface local_span Radius of points to include in construction of local geometry for normal and curvature estimation distance Distance from coil to head surface didt Intensity of stimulation cpus Number of cpus to use for simulation ''' self.mesh = mesh_file self.tw = tet_weights self.field_dir = field_dir self.coil = coil self.didt = didt logger.info(f"Configured to use {cpus} cpus...") self.cpus = cpus self.geo_radius = local_span self.distance = distance self.solver_opt = solver_options logger.info('Loading in coordinate data from mesh file...') self.nodes, self.coords, _ = geolib.load_gmsh_nodes(self.mesh, (2, 5)) _, _, trigs = geolib.load_gmsh_elems(self.mesh, (2, 5)) self.trigs = np.array(trigs).reshape(-1, 3) logger.info('Successfully pulled in node and element data!') # Construct basis of sampling space using centroid logger.info('Constructing initial sampling surface...') C, iR, bounds = self._initialize(initial_centroid, span) self.C = C self.iR = iR self.bounds = bounds logger.info('Successfully constructed initial sampling surface') # Store single read in memory, this will prevent GC issues logger.info('Caching mesh file on instance construction...') self.cached_mesh = mesh_io.read_msh(mesh_file) self.cached_mesh.fix_surface_labels() logger.info('Successfully cached mesh file') logger.info('Storing standard conductivity values...') condlist = [c.value for c in cond.standard_cond()] self.cond = cond.cond2elmdata(self.cached_mesh, condlist) logger.info('Successfully stored conductivity values...') # Control for coil file-type and SimNIBS changing convention if self.coil.endswith('.ccd'): self.normflip = 1 else: self.normflip = -1