예제 #1
0
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=',')
예제 #2
0
파일: nii2msh.py 프로젝트: wqhot/simnibs
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)
예제 #3
0
파일: maskmesh.py 프로젝트: wqhot/simnibs
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)
예제 #4
0
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')
예제 #5
0
 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)
예제 #6
0
 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)
예제 #7
0
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')
예제 #8
0
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]
예제 #9
0
def cube_lr():
    fn = os.path.join(os.path.dirname(os.path.realpath(
        __file__)), '..', 'testing_files', 'cube.msh')
    return mesh_io.read_msh(fn)
예제 #10
0
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)
예제 #11
0
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])
예제 #12
0
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)
예제 #13
0
def sphere3_msh():
    return mesh_io.read_msh(
        os.path.join(os.path.dirname(os.path.realpath(__file__)), '..',
                     'testing_files', 'sphere3.msh'))
예제 #14
0
    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