예제 #1
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_plot_waveform(ctx, config, waveforms, name):
    '''
    Plot waveforms.
    '''
    res = None

    ses = ctx.obj['session']
    if ':' in waveforms:
        from pixsim.store import get_last_ids
        total_ids = get_last_ids(ses)['result']

        first_id, last_id, we_got = pythonify(waveforms, total_ids)
        if we_got is None:
            return
        res = [get_result(ses, id=x) for x in range(first_id, last_id+1)]
    else:
        res = [get_result(ses, id=waveforms)]

    if name is None:
        waveforms = [arr.data for r in res for arr in r.data]
    else:
        waveforms = [arr.data for r in res for arr in r.data if name == arr.name.split('_')[-1]]

    import pixsim.plotting as plt
    click.echo("Plotting {} waveforms...".format(len(waveforms)))
    plt.plot_waveforms(waveforms, **ctx.obj['cfg'][config])
예제 #2
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_step(ctx, velocity, geoconfig, config, name):
    """Step through velocity field. Also retrieves the linspace
    from parent raster results."""
    ses = ctx.obj['session']
    vres = get_result(ses, source=velocity)
    if vres is None:
        click.echo("No matching results for ".format(velocity))
        return
    rasres = get_result(ses, id=vres.parent_id)
    if rasres is None:
        click.echo("No matching results for parent ID = {}".format(vres.parent_id))
        return

    vfield = find_data(vres, ['vector'])
    linspace = find_data(rasres, ['linspace'])
    assert vfield is not None and 'Velocity field not found'
    assert linspace is not None and 'linspace not found'

    import pixsim.step as step
    import pixsim.geometry as geometry
    pixcoll = geometry.make_pixels_center(**ctx.obj['cfg'][geoconfig])
    assert len(pixcoll) > 0
    arrays = step.step(vfield, linspace, pixcoll, **ctx.obj['cfg'][config])
    res = Result(name=name, typename='step', data=arrays, parent=vres)
    save_result(ctx, res)
예제 #3
0
def average_paths(ses, name, first_id, last_id):
    from pixsim.store import get_result

    # initialize path names
    result = get_result(ses, id=first_id)
    step_size = 0

    #
    # This assumes each path started at the same time and
    # constant step in time
    #
    import numpy as np
    arrs_to_add = list()
    max_steps = -1
    for resid in range(first_id, last_id + 1):
        result = get_result(ses, id=resid)

        # making no assumption, look for the correct path
        use_this_wvf = None
        for path, wvf in enumerate(result.data):
            use_this_wvf = np.asarray(wvf.data)

            # add waveform to arrs
            if len(use_this_wvf) > max_steps:
                max_steps = len(use_this_wvf)
            arrs_to_add.append(use_this_wvf)

    # assuming we used fixed step size in t, we can easily add them
    avgwvf = np.zeros(max_steps)
    for arr in arrs_to_add:
        step_size = arr[1, 0] - arr[0, 0]
        wvfarr = arr[:, 1]
        resized = np.zeros_like(avgwvf)
        resized[:wvfarr.shape[0]] = wvfarr
        avgwvf = np.add(avgwvf, resized)

    # normalize
    if do_norm(avgwvf):
        avgwvf /= abs(np.sum(avgwvf))
    # for plotting
    new_wvf = list()
    time = 0
    for tick in range(0, avgwvf.shape[0]):
        point = [time, avgwvf[tick]]
        new_wvf.append(np.asarray(point))
        time += step_size

    callit = name + '_avg_waveform'
    return [Array(name=callit, typename='tuples', data=new_wvf)]
예제 #4
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_gen_raster(ctx, config, name, boundary):
    '''
    Generate raster. Used to generate the rasters for
    for a collection of weighting solutions. This is meant
    to run after a gen weight, so results can be passed
    using boundary option.
    '''
    id_range = boundary
    ses = ctx.obj['session']
    from pixsim.store import get_last_ids
    total_ids = get_last_ids(ses)['result']

    first_id, last_id, we_got = pythonify(id_range, total_ids)
    if we_got is None:
        return
    sources = [x for x in range(first_id, last_id+1)]
    do_it = click.prompt("Do range {}-{}? (y/n)".format(first_id, last_id), default='y')
    if 'y' != do_it:
        return
    for src in sources:
        click.echo('Running for {}'.format(str(src)))
        bres = get_result(ses, id=src)
        if bres is None:
            click.echo("No matching results for name = {}".format(src))
            continue
        # we are using a specific naming convention where the domain is the last string
        dom = bres.name.split('_')[-1]
        callit = name+'_weight_raster_domain_'+dom
        ctx.invoke(cmd_raster, config=config, boundary=src, name=callit)
예제 #5
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_gen_vtx(ctx, source, geoconfig, name, dirname, dmap):
    '''
    Generate step vertices for electrode array.
    This will create new step vertices in global coordinates based on
    electrode domain IDs and relative starting positions in the template step file.
    Will create a directory of step files to use for stepping in
    the corresponding weighting field.
    Template file should have something similar to:\n
    domains 8 9 10 11 \n
    0.75 0 0
    '''
    import pixsim.geometry as geometry
    pixcoll = geometry.make_pixels_center(**ctx.obj['cfg'][geoconfig])

    do_domains, do_pos = list(), list()
    with open(source) as tmpfile:
        domainline = tmpfile.readline().split()
        assert domainline[0] == 'domains' and 'Header assumed to be \'domains\''
        do_domains = [int(dom) for dom in domainline[1:]]
        while True:
            linevec = tmpfile.readline().split()
            if len(linevec) < 1:
                break
            pos = [float(x) for x in linevec]
            assert len(pos) == 3
            do_pos.append(pos)

    ses = ctx.obj['session']
    gres = get_result(ses, name=dmap)
    if gres is None:
        click.echo("No matching results for name = {}".format(dmap))
        return
    domap = gres.data[0].data

    # generate
    import os
    os.mkdir(dirname)

    arrs = list()
    for did in do_domains:
        # find the center position of this domain
        cent = None
        # dmap entries => (domainid, pid, center)
        for entry in domap:
            if entry[0] == did:
                cent = entry[2]
                break
        assert cent is not None

        filename = name+'genvtx_domain_'+str(did)+'.txt'
        path = os.path.join(dirname, filename)
        with open(path, 'w') as f:
            for count, rpos in enumerate(do_pos, 1):
                callit = name+'vtx'+str(count)
                gpos = [rpos[i]+cent[i] for i in range(0, 3)]
                out = [callit, str(gpos[0]), str(gpos[1]), str(gpos[2])]
                out = ' '.join(out)
                f.write(out+'\n')
예제 #6
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_gen_response(ctx, config, name, waveforms, step):
    '''
    Generate response.
    '''
    ses = ctx.obj['session']
    curres = get_result(ses, id=waveforms)
    if curres is None:
        click.echo("No matching results for id = {}".format(waveforms))
        return
    stepres = get_result(ses, id=step)
    if stepres is None:
        click.echo("No matching results for id = {}".format(stepres))
        return

    import pixsim.response as rsp
    arrays = rsp.response(stepres.data, curres.data, **ctx.obj['cfg'][config])
    res = Result(name=name, typename='current', data=arrays, parent=curres)
    save_result(ctx, res)
예제 #7
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_current(ctx, step, raster, config, name):
    """Calculate the current waveforms."""
    ses = ctx.obj['session']
    sres = get_result(ses, source=step)
    if sres is None:
        click.echo("No matching results for name = {}".format(step))
        return
    rasres = get_result(ses, source=raster)
    if rasres is None:
        click.echo("No matching results for name = {}".format(raster))
        return
    assert(sres.typename == 'step' and rasres.typename == 'raster')

    efield, linspaces = find_data(rasres, ['vector', 'linspace'])
    paths = [p.data for p in sres.data if 'tuples' in p.typename]
    pnames = [p.name for p in sres.data if 'tuples' in p.typename]

    import pixsim.current as current
    arrays = current.compute(efield, linspaces, paths, pnames)
    res = Result(name=name, typename='current', data=arrays, parent=rasres)
    save_result(ctx, res)
예제 #8
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_ana(ctx, result):
    """Entry to drift sim."""

    ses = ctx.obj['session']
    click.echo("Loading data...")
    res = get_result(ses, source=result)
    if res is None:
        click.echo("No matching results for name = {}".format(result))
        return

    import pixsim.analyze as ana
    ana.analyze(res.data)
예제 #9
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_plot_efield(ctx, result_id, config):
    '''
    Plot efield.
    '''
    ses = ctx.obj['session']
    res = get_result(ses, id=result_id)
    if res is None:
        click.echo("No matching results for id = {}".format(result_id))
        return

    points, linspaces, pot, grad = find_data(res, ['points', 'linspace', 'scalar', 'vector'])
    import pixsim.plotting as plt
    plt.plot_efield(ctx.obj['mesh_filename'], grad, **ctx.obj['cfg'][config])
예제 #10
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_gen_current(ctx, config, name, raster, step):
    '''
    Generate current.
    '''
    ses = ctx.obj['session']
    from pixsim.store import get_last_ids
    total_ids = get_last_ids(ses)['result']

    first_id, last_id, we_got = pythonify(raster, total_ids)
    if we_got is None:
        return
    rasres = {x:get_result(ses, id=x) for x in range(first_id, last_id+1)}
    first_id, last_id, we_got = pythonify(step, total_ids)
    if we_got is None:
        return
    stepres = {x:get_result(ses, id=x) for x in range(first_id, last_id+1)}

    # mapping raster results to step by matching domain_##
    for sid, sres in stepres.iteritems():
        if sres is None:
            click.echo("No matching results for id = {}".format(sid))
            continue
        matching_this = sres.name.split('_')[-1]
        usethisras = None
        for rid, rres in rasres.iteritems():
            if rres is None:
                click.echo("No matching results for id = {}".format(rid))
                continue
            domainid = rres.name.split('_')[-1]
            if domainid == matching_this:
                usethisras = rres
                break
        # make sure we found a match
        if usethisras is None:
            raise AssertionError('Could not find matching domain ID')

        click.echo('Running for weight {} and step {}'.format(usethisras.parent.name, sres.name))
        callit = name+'_waveforms_for_domain_'+domainid
        ctx.invoke(cmd_current, step=sres.id, raster=usethisras.id, config=config, name=callit)
예제 #11
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_sim(ctx, response, config):
    """Entry to drift sim."""

    ses = ctx.obj['session']
    rres = get_result(ses, source=response)
    if rres is None:
        click.echo("No matching results for name = {}".format(response))
        return

    import pixsim.driftsim as dsim
    arrs = dsim.sim(rres, **ctx.obj['cfg'][config])
    res = Result(name='simwaveforms', typename='current', data=arrs)
    save_result(ctx, res)
예제 #12
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_velocity(ctx, raster, config, name):
    """Evaluating velocity on raster"""
    ses = ctx.obj['session']
    rasres = get_result(ses, source=raster)
    if rasres is None:
        click.echo("No matching results for {}".format(raster))
        return

    potential, linspace = find_data(rasres, ['scalar', 'linspace'])
    assert(potential is not None and linspace is not None)

    import pixsim.velocity as velocity
    arrays = velocity.drift(potential, linspace, **ctx.obj['cfg'][config])
    res = Result(name=name, typename='velocity', data=arrays, parent=rasres)
    save_result(ctx, res)
예제 #13
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_raster(ctx, boundary, config, name):
    """Evaluate solution on a raster of points"""
    ses = ctx.obj['session']
    bres = None
    bres = get_result(ses, source=boundary)
    if bres is None:
        click.echo("No matching results for {}".format(boundary))
        return

    sol = find_data(bres, ['scalar'])

    from pixsim.raster import linear
    arrays = linear(ctx.obj['mesh_filename'], sol, **ctx.obj['cfg'][config])
    res = Result(name=name, typename='raster', data=arrays, parent=bres)
    save_result(ctx, res)
예제 #14
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_play(ctx, result_id):
    """Used for editing or experimenting"""

    ses = ctx.obj['session']
    if result_id is not None:
        result = get_result(ses, id=result_id)
        if result is None:
            click.echo("No matching result result_id = {}".format(result_id))
            return
        vtx_1, vtx_108 = None, None
        for arr in result.data:
            if 'vtx1' in arr.name:
                vtx_1 = arr.data
            if 'vtx108' in arr.name:
                vtx_108 = arr.data
        assert vtx_1 is not None and vtx_108 is not None
        print vtx_108
예제 #15
0
def save_raster_vtk(ses, outname, res_id):
    '''
    Save a drift result into a VTK file.
    '''
    print 'Saving raster results...'
    #res_id = input('Enter the raster result ID: ')
    result = get_result(ses, id=res_id)
    if result is None:
        print 'No matching results for ID = {}'.format(res_id)
        return
    arrs = result.array_data_by_name()
    points = arrs['points'].T

    from tvtk.api import tvtk, write_data

    for thing in ['pfield','efield']:
        values = arrs[thing]
        npoints = len(points)

        ug = tvtk.UnstructuredGrid()
        point_type = tvtk.Vertex().cell_type

        cell_types = numpy.array([point_type]*npoints)
        cell_array = tvtk.CellArray()
        cells = numpy.array([npoints]+range(npoints))
        cell_array.set_cells(point_type, cells)

        ug.set_cells(1, cell_array)
        if thing == 'pfield':
            ug.points = points
            ug.point_data.scalars = values.reshape(npoints)
            ug.point_data.scalars.name = thing
        else:
            ug.points = points
            field = numpy.asarray([[x,y,z] for x,y,z in zip(values[0,:,:,:].reshape(npoints),values[1,:,:,:].reshape(npoints),values[2,:,:,:].reshape(npoints))])
            ug.point_data.vectors = field
            ug.point_data.vectors.name = thing

        fname = '%s-%s.vtk' % (outname, thing)
        write_data(ug, fname)
예제 #16
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_rename(ctx, result_id, array_id, name):
    '''
    Rename result in the store.
    '''
    ses = ctx.obj['session']
    if result_id is not None:
        result = get_result(ses, id=result_id)
        if result is None:
            click.echo("No matching result result_id = {}".format(result_id))
            return
        click.echo("rename %d %s %s to %s" % (result.id, result.name, result.typename, name))
        result.name = name
        ses.add(result)
        ses.commit()
    elif array_id is not None:
        array = get_array(ses, None, array_id)
        if array is None:
            click.echo("No matching array for array_id = {}".format(array_id))
            return
        click.echo("rename %d %s %s to %s" % (array.id, array.name, array.typename, name))
        array.name = name
        ses.add(array)
        ses.commit()
예제 #17
0
파일: cli.py 프로젝트: hcsullivan12/pixsim
def cmd_gen_weight(ctx, config, name, dmap, domains):
    '''
    Generate weights. Used to generate the weighting fields
    for a collection of electrodes (gen weight). Expecting
    a domain_map in the store.
    '''
    ses = ctx.obj['session']
    gres = get_result(ses, name=dmap, id=None)
    if gres is None:
        click.echo("No matching results for name = {}".format(dmap))
        return

    domap = gres.data[0].data
    for entry in domap:
        dom, elect, pos = entry[0], entry[1], entry[2]
        if dom not in domains:
            continue
        par = ['weight:domain='+str(dom)]

        click.echo('Running boundary for electrode {} domain = {}'.format(elect, dom))
        add_params(ctx, par)
        callit = name+'_weight_domain_'+str(dom)
        ctx.invoke(cmd_boundary, config=config, name=callit)
예제 #18
0
def save_boundary_vtk(ses, mshfile, outname, res_id):
    '''
    Save a boundary result into a VTK file.
    '''
    print 'Saving boundary results...'
    #res_id = input('Enter the boundary result ID: ')
    result = get_result(ses, id=res_id)
    if result is None:
        print 'No matching results for ID = {}'.format(res_id)
        return
    mesh = meshio.read(mshfile)
    barrs = result.array_data_by_name()

    from tvtk.api import tvtk, write_data
    pd = tvtk.PolyData()
    pd.points = mesh.points
    pd.polys = mesh.cells['triangle']
    pd.cell_data.add_array(mesh.cell_data['triangle']['gmsh:physical'])
    pd.cell_data.get_array(0).name = 'domains'
    for count, name in enumerate(['dirichlet', 'neumann']):
        pd.cell_data.add_array(barrs[name])
        pd.cell_data.get_array(count + 1).name = name
    outname = outname+'.vtk'
    write_data(pd, outname)
예제 #19
0
def average_identical_paths(ses, first_id, last_id):
    from pixsim.store import get_result

    # initialize path names
    result = get_result(ses, id=first_id)
    path_names = [str(w.name) for w in result.data]
    waveforms = list()
    step_size = 0

    #
    # We will loop over each path name, store the data from
    # each result, fill an array which has length max(data)
    #
    # This assumes each path started at the same time and
    # constant step in time
    #
    import numpy as np
    for name in path_names:
        arrs_to_add = list()
        max_steps = -1
        for resid in range(first_id, last_id + 1):
            result = get_result(ses, id=resid)

            # making no assumption, look for the correct path
            use_this_wvf = None
            for path, wvf in enumerate(result.data):
                if str(wvf.name) == name:
                    use_this_wvf = np.asarray(wvf.data)
                    break
            if use_this_wvf is None:
                click.echo(
                    'Skipping result {} - Could not find waveform named {}'.
                    format(resid, nm))
                continue

            # add waveform to arrs
            if len(use_this_wvf) > max_steps:
                max_steps = len(use_this_wvf)
            arrs_to_add.append(use_this_wvf)

        # assuming we used fixed step size in t, we can easily add them
        avgwvf = np.zeros(max_steps)
        for arr in arrs_to_add:
            step_size = arr[1, 0] - arr[0, 0]
            wvfarr = arr[:, 1]
            resized = np.zeros_like(avgwvf)
            resized[:wvfarr.shape[0]] = wvfarr
            avgwvf = np.add(avgwvf, resized)

        waveforms.append(avgwvf)

    # normalize
    for wvf in waveforms:
        wvf /= np.sum(wvf)
    # for plotting
    wvf_with_t = list()
    for wvf in waveforms:
        new_wvf = list()
        time = 0
        for tick in range(0, wvf.shape[0]):
            point = [time, wvf[tick]]
            new_wvf.append(np.asarray(point))
            time += step_size
        wvf_with_t.append(np.asarray(new_wvf))

    arrs = list()
    for wvf, nm in zip(wvf_with_t, path_names):
        callit = 'avg_waveform_for_' + nm
        arrs.append(Array(name=callit, typename='tuples', data=wvf))
예제 #20
0
def save_step_vtk(ses, outname, res_id):
    '''
    Save a step result into a VTK file.
    '''
    print 'Saving stepping results...'
    #res_id = input('Enter the step result ID: ')
    step_res = get_result(ses, id=res_id)
    if step_res is None:
        print 'No matching results for ID = {}'.format(res_id)
        return

    # we need the raster data
    vel_res = get_result(ses, id=step_res.parent_id)
    if vel_res is None:
        print 'No matching results for ID = {}'.format(step_res.parent_id)
        return
    rast_res = get_result(ses, id=vel_res.parent_id)
    if rast_res is None:
        print 'No matching results for ID = {}'.format(vel_res.parent_id)
        return
    # get the field and linspaces
    field, linspaces = None, None
    for arr in rast_res.data:
        if arr.typename == 'scalar':
            field = arr.data
        if arr.typename == 'linspace':
            linspaces = arr.data
    assert(field is not None and linspaces is not None)

    field = Scalar(field, linspaces)

    # exporting initial position
    vtxs = [x for x in step_res.data if 'points' in x.typename]
    points = list()
    pot    = list()
    for vtx in vtxs:
        for pt in vtx.data:
            points.append(pt)
            pot.append(field(pt))
    points = numpy.asarray(points)
    pot = numpy.asarray(pot)

    from tvtk.api import tvtk, write_data
    if len(vtxs):
        ug = tvtk.UnstructuredGrid()    
        point_type = tvtk.Vertex().cell_type
        npoints = len(points)
        cell_types = numpy.array([point_type]*npoints)
        cell_array = tvtk.CellArray()
        cells = numpy.array([npoints]+range(npoints))
        cell_array.set_cells(point_type, cells)

        ug.set_cells(1, cell_array)
        ug.points = points
        ug.point_data.scalars = pot
        ug.point_data.scalars.name = 'potential'

        fname = '%s-%s.vtk' % (outname, 'vtxs')
        write_data(ug, fname)

    # exporting paths
    paths = [x for x in step_res.data if 'tuples' in x.typename]
    points = list()
    pot    = list()
    vel    = list()
    for path in paths:
        for pt in path.data:
            xyz = pt[0:3]
            uvw = pt[3:6]
            points.append(xyz)
            pot.append(field(xyz))
            mag = numpy.sqrt(uvw.dot(uvw))
            vel.append(mag)
    points = numpy.asarray(points)
    pot = numpy.asarray(pot)
    vel = numpy.asarray(vel)

    if len(paths):
        for flv,data in {'potential':pot, 'velocity':vel}.iteritems():
            ug = tvtk.UnstructuredGrid()    
            point_type = tvtk.Vertex().cell_type
            npoints = len(points)
            cell_types = numpy.array([point_type]*npoints)
            cell_array = tvtk.CellArray()
            cells = numpy.array([npoints]+range(npoints))
            cell_array.set_cells(point_type, cells)

            ug.set_cells(1, cell_array)
            ug.points = points
            ug.point_data.scalars = data
            ug.point_data.scalars.name = flv

            fname = '%s-%s-%s.vtk' % (outname, 'paths', flv)
            write_data(ug, fname)