def det(m): hm = h.Matrix(m.shape[0], m.shape[1]) for i in range(int(hm.nrow())): hm.setcol(i, h.Vector(m[:, i])) e = h.ref(0) d = hm.det(e) return d * 10.0**e[0]
def expm(m): hm = h.Matrix(m.shape[0], m.shape[1]) for i in range(int(hm.nrow())): hm.setcol(i, h.Vector(m[:, i])) hm = hm.exp() mo = numpy.matrix(m) print m for i in range(int(hm.nrow())): for j in range(int(hm.nrow())): mo[i, j] = hm.getval(i, j) return mo
def run_single_volts(param_set, stim_data, ntimestep = 10000, dt = 0.02): run_file = '../../neuron_genetic_alg/neuron_files/bbp/run_model_cori.hoc' h.load_file(run_file) total_params_num = len(param_set) timestamps = np.array([dt for i in range(ntimestep)]) h.curr_stim = h.Vector().from_python(stim_data) h.transvec = h.Vector(total_params_num, 1).from_python(param_set) h.stimtime = h.Matrix(1, len(timestamps)).from_vector(h.Vector().from_python(timestamps)) h.ntimestep = ntimestep h.runStim() out = h.vecOut.to_python() return np.array(out),np.cumsum(timestamps)
def neuron_run_model(param_set, stim_name_list): h.load_file(run_file) volts_list = [] for elem in stim_name_list: curr_stim = h5py.File(stims_path, 'r')[elem][:] total_params_num = len(param_set) timestamps = np.array([dt for i in range(ntimestep)]) h.curr_stim = h.Vector().from_python(curr_stim) h.transvec = h.Vector(total_params_num, 1).from_python(param_set) h.stimtime = h.Matrix(1, len(timestamps)).from_vector(h.Vector().from_python(timestamps)) h.ntimestep = ntimestep h.runStim() out = h.vecOut.to_python() volts_list.append(out) return np.array(volts_list)
def _get_nrn_voltages(self): """The extracellular data (n_contacts x n_samples).""" if len(self._nrn_voltages) > 0: assert (self._nrn_voltages.size() == self.n_contacts * self._nrn_n_samples) # first reshape to a Neuron Matrix object extmat = h.Matrix(self.n_contacts, self._nrn_n_samples) extmat.from_vector(self._nrn_voltages) # then unpack into 2D python list and return return [ extmat.getrow(ii).to_python() for ii in range(extmat.nrow()) ] else: raise RuntimeError('Simulation not yet run!')
def paranormal0(pt): #print ("paranormal0 ", pt) # return the normal direction from the inner paraboloid that contains pt assert (pt[1] == 0.0) # two dimensional problem due to assertion. x = pt[0] z = pt[2] lam = 0.0 # three equations in three unknowns (x, z) on parboloid (x', z') is pt # unknowns x, z, lam # a*x^2 - c*z = 0 # x + lam*2*a*x - x' = 0 # z - lam*c - z' = 0 # can reduce to single cubic equation in x but might as well solve # by newton method. Jacobian is # [2*a*x , -c, 0 ] # [1 + 2*a*lam, 0 , 2*a*x] # [0 , 1 , -c ] b = h.Vector(3) m = h.Matrix(3, 3) dx = h.Vector(3) iter = 0 for i in range(100): mset(m, x, z, lam) bset(b, x, z, lam, pt[0], pt[2]) m.solv(b, dx) #dx.printf() x += dx.x[0] z += dx.x[1] lam += dx.x[2] iter += 1 if dx.sumsq() < 1e-14: break assert (iter < 100) global maxiter maxiter = iter if iter > maxiter else maxiter return normgrad((x, 0, z))
from neuron import h m = h.Matrix(3, 4, 2) m.setval(1, 2, 100) m.setval(2, 2, 200) def sparse_print(m): j = h.ref(0) for i in range(int(m.nrow())): print(i, end=' ') for jx in range(int(m.sprowlen(i))): x = m.spgetrowval(i, jx, j) print(" %d:%g" % (j[0], x)) print() sparse_print(m)
def _build(self, cvode=None, include_celltypes='all'): """Assemble NEURON objects for calculating extracellular potentials. The handler is set up to maintain a vector of membrane currents at at every inner segment of every section of every cell on each CVODE integration step. In addition, it records a time vector of sample times. Parameters ---------- cvode : instance of h.CVode Multi order variable time step integration method. include_celltypes : str String to match against the cell type of each section. Defaults to ``'all'``: calculate extracellular potential generated by all cells. To restrict this to include only pyramidal cells, use ``'Pyr'``. For basket cells, use ``'Basket'``. NB This argument is currently not exposed in the API. """ secs_on_rank = h.allsec() # get all h.Sections known to this MPI rank _validate_type(include_celltypes, str) _check_option('include_celltypes', include_celltypes, ['all', 'Pyr', 'Basket']) if include_celltypes.lower() != 'all': secs_on_rank = [ s for s in secs_on_rank if include_celltypes in s.name() ] segment_counts = [sec.nseg for sec in secs_on_rank] n_total_segments = np.sum(segment_counts) # pointers assigned to _ref_i_membrane_ at each EACH internal segment self._nrn_imem_ptrvec = h.PtrVector(n_total_segments) # placeholder into which pointer values are read on each sim time step self._nrn_imem_vec = h.Vector(n_total_segments) ptr_idx = 0 for sec in secs_on_rank: for seg in sec: # section end points (0, 1) not included # set Nth pointer to the net membrane current at this segment self._nrn_imem_ptrvec.pset(ptr_idx, sec(seg.x)._ref_i_membrane_) ptr_idx += 1 if ptr_idx != n_total_segments: raise RuntimeError(f'Expected {n_total_segments} imem pointers, ' f'got {ptr_idx}.') # transfer resistances for each segment (keep in Neuron Matrix object) self._nrn_r_transfer = h.Matrix(self.n_contacts, n_total_segments) for row, pos in enumerate(self.array.positions): if self.array.method is not None: transfer_resistance = list() for sec in secs_on_rank: this_xfer_r = _transfer_resistance( sec, pos, conductivity=self.array.conductivity, method=self.array.method, min_distance=self.array.min_distance) transfer_resistance.extend(this_xfer_r) self._nrn_r_transfer.setrow(row, h.Vector(transfer_resistance)) else: # for testing, make a matrix of ones self._nrn_r_transfer.setrow(row, h.Vector(n_total_segments, 1.)) # record time for each array self._nrn_times = h.Vector().record(h._ref_t) # contributions of all segments on this rank to total calculated # potential at electrode (_PC.allreduce called in _simulate_dipole) # NB voltages of all contacts are initialised to 0 mV, i.e., the # potential at time 0.0 ms is defined to be zero. self._nrn_voltages = h.Vector(self.n_contacts, 0.) # NB we must make a copy of the function reference, and keep it for # later decoupling using extra_scatter_gather_remove # (instead of a new function reference) self._recording_callback = self._gather_nrn_voltages # Nb extra_scatter_gather is called _after_ the solver takes a step, # so the initial state is not recorded (initialised to zero above) cvode.extra_scatter_gather(0, self._recording_callback)
from neuron import h from math import cos, sin, fabs h.load_file('nrngui.hoc') cmat = h.Matrix(2,2,2).ident() gmat = h.Matrix(2,2,2) gmat.setval(0,1, -1) gmat.setval(1,0, 1) # not needed unless experimenting with z2 below y = h.Vector(2) y0 = h.Vector(2) b = h.Vector(2) def callback(): #print 'callback t=', h.t z1 = y.x[0] z2 = -fabs(cos(z1)) # jacobian element is db[1]/dy[0] z2 = 0 gmat.setval(1,0, z2) b.x[1] = -sin(z1) + z1*z2 nlm = h.LinearMechanism(callback, cmat, gmat, y, y0, b) dummy = h.Section() trajec = h.Vector() tvec = h.Vector() trajec.record(y._ref_x[0]) tvec.record(h._ref_t)
def constructive_neuronal_geometry(source, n_soma_step, dx): objects = [] source_is_import3d = False # TODO: come up with a better way of checking type if hasattr(source, 'sections'): source_is_import3d = True cell = source # probably an Import3D type num_contours = sum(sec.iscontour_ for sec in cell.sections) if num_contours > 1: raise Exception('more than one contour is not currently supported') if num_contours == 1: # setup the soma # CTNG:soma branches = [] parent_sec_name = [] for sec in cell.sections: if sec.iscontour_: soma_sec = sec.hname() x, y, z = [ sec.raw.getrow(i).to_python() for i in xrange(3) ] # compute the center of the contour based on uniformly spaced points around the perimeter center_vec = sec.contourcenter(sec.raw.getrow(0), sec.raw.getrow(1), sec.raw.getrow(2)) x0, y0, z0 = [center_vec.x[i] for i in xrange(3)] somax, somay, somaz = x0, y0, z0 xshifted = [xx - x0 for xx in x] yshifted = [yy - y0 for yy in y] # this is a hack to pretend everything is on the same z level zshifted = [0] * len(x) # locate the major and minor axis, adapted from import3d_gui.hoc m = h.Matrix(3, 3) for i, p in enumerate([xshifted, yshifted, zshifted]): for j, q in enumerate([xshifted, yshifted, zshifted]): if j < i: continue v = numpy.dot(p, q) m.setval(i, j, v) m.setval(j, i, v) # CTNG:majoraxis tobj = m.symmeig(m) # major axis is the one with largest eigenvalue major = m.getcol(tobj.max_ind()) # minor is normal and in xy plane minor = m.getcol(3 - tobj.min_ind() - tobj.max_ind()) #minor.x[2] = 0 minor.div(minor.mag()) x1 = x0 y1 = y0 x2 = x1 + major.x[0] y2 = y1 + major.x[1] xs_loop = x + [x[0]] ys_loop = y + [y[0]] # locate the extrema of the major axis CTNG:somaextrema # this is defined by the furthest points on it that lie on the minor axis pts = [] pts_sources = {} for x3, y3 in zip(x, y): x4, y4 = x3 + minor.x[0], y3 + minor.x[1] pt = seg_line_intersection(x1, y1, x2, y2, x3, y3, x4, y4, clip=False) if pt is not None: pts.append(pt) if pt not in pts_sources: pts_sources[pt] = [] pts_sources[pt].append((x3, y3)) major_p1, major_p2 = extreme_pts(pts) extreme1 = pts_sources[major_p1] extreme2 = pts_sources[major_p2] major_p1, major_p2 = numpy.array(major_p1), numpy.array( major_p2) del pts_sources if len(extreme1) != 1 or len(extreme2) != 1: raise Exception('multiple most extreme points') extreme1 = extreme1[0] extreme2 = extreme2[0] major_length = linalg.norm(major_p1 - major_p2) delta_x, delta_y = major_p2 - major_p1 delta_x /= n_soma_step delta_y /= n_soma_step f_pts = [major_p1] f_diams = [0] # CTNG:slicesoma for i in xrange(1, n_soma_step): x0, y0 = major_p1[0] + i * delta_x, major_p1[ 1] + i * delta_y # slice in dir of minor axis x1, y1 = x0 + minor.x[0], y0 + minor.x[1] pts = [] for i in xrange(len(x)): pt = seg_line_intersection(xs_loop[i], ys_loop[i], xs_loop[i + 1], ys_loop[i + 1], x0, y0, x1, y1, clip=True) if pt is not None: pts.append(pt) p1, p2 = extreme_pts(pts) p1, p2 = numpy.array(p1), numpy.array(p2) cx, cy = (p1 + p2) / 2. f_pts.append((cx, cy)) f_diams.append(linalg.norm(p1 - p2)) f_pts.append(major_p2) f_diams.append(0) for i in xrange(len(f_pts) - 1): pt1x, pt1y = f_pts[i] pt2x, pt2y = f_pts[i + 1] diam1 = f_diams[i] diam2 = f_diams[i + 1] objects.append( SkewCone(pt1x, pt1y, z0, diam1 * 0.5, pt1x + delta_x, pt1y + delta_y, z0, diam2 * 0.5, pt2x, pt2y, z0)) else: parent_sec_name.append(sec.parentsec.hname()) branches.append(sec) else: h.define_shape() soma_sec = None branches = [] for sec in source: branches.append(sec) # this is ignored in this case, but needs to be same length # so this way no extra memory except the pointer parent_sec_name = branches ##################################################################### # # add the branches # ##################################################################### diam_corrections = {None: None} while diam_corrections: all_cones = [] pts_cones_db = {} diam_db = {} for branch, psec in zip(branches, parent_sec_name): if source_is_import3d: x, y, z = [branch.raw.getrow(i).to_python() for i in xrange(3)] d = branch.d.to_python() else: x = [ h.x3d(i, sec=branch) for i in xrange(int(h.n3d(sec=branch))) ] y = [ h.y3d(i, sec=branch) for i in xrange(int(h.n3d(sec=branch))) ] z = [ h.z3d(i, sec=branch) for i in xrange(int(h.n3d(sec=branch))) ] d = [ h.diam3d(i, sec=branch) for i in xrange(int(h.n3d(sec=branch))) ] # make sure that all the ones that connect to the soma do in fact connect # do this by connecting to local center axis # CTNG:connectdends if psec == soma_sec: pt = (x[1], y[1], z[1]) cp = closest_pt(pt, f_pts, somaz) # NEURON includes the wire point at the center; we want to connect # to the closest place on the soma's axis instead with full diameter x, y, z, d = [cp[0]] + [X for X in x[1:]], [cp[1]] + [ Y for Y in y[1:] ], [somaz] + [Z for Z in z[1:]], [d[1]] + [D for D in d[1:]] for i in xrange(len(x) - 1): d0, d1 = d[i:i + 2] if (x[i] != x[i + 1] or y[i] != y[i + 1] or z[i] != z[i + 1]): # short section check #if linalg.norm((x[i + 1] - x[i], y[i + 1] - y[i], z[i + 1] - z[i])) < (d1 + d0) * 0.5: # short_segs += 1 axisx, axisy, axisz, deltad = x[i + 1] - x[i], y[ i + 1] - y[i], z[i + 1] - z[i], d1 - d0 axislength = (axisx**2 + axisy**2 + axisz**2)**0.5 axisx /= axislength axisy /= axislength axisz /= axislength deltad /= axislength x0, y0, z0 = x[i], y[i], z[i] x1, y1, z1 = x[i + 1], y[i + 1], z[i + 1] if (x0, y0, z0) in diam_corrections: d0 = diam_corrections[(x0, y0, z0)] if (x1, y1, z1) in diam_corrections: d1 = diam_corrections[(x1, y1, z1)] if d0 != d1: all_cones.append( Cone(x0, y0, z0, d0 * 0.5, x1, y1, z1, d1 * 0.5)) else: all_cones.append( Cylinder(x0, y0, z0, x1, y1, z1, d1 * 0.5)) register(pts_cones_db, (x0, y0, z0), all_cones[-1]) register(pts_cones_db, (x1, y1, z1), all_cones[-1]) register(diam_db, (x0, y0, z0), d0) register(diam_db, (x1, y1, z1), d1) # at join, should always be the size of the biggest branch # this is different behavior than NEURON, which continues the size of the # first point away from the join to the join diam_corrections = {} for pt in diam_db: vals = diam_db[pt] if max(vals) != min(vals): diam_corrections[pt] = max(vals) cone_clip_db = {cone: [] for cone in all_cones} join_counts = { '2m': 0, '2s': 0, '3m': 0, '3s': 0, '4m': 0, '4s': 0, '0m': 0, '0s': 0, '1m': 0, '1s': 0 } for cone in all_cones: x1, y1, z1, r1 = cone._x0, cone._y0, cone._z0, cone._r0 x2, y2, z2, r2 = cone._x1, cone._y1, cone._z1, cone._r1 pt1 = numpy.array([x1, y1, z1]) pt2 = numpy.array([x2, y2, z2]) axis = (pt2 - pt1) / linalg.norm(pt2 - pt1) left_neighbors = list(pts_cones_db[(x1, y1, z1)]) right_neighbors = list(pts_cones_db[(x2, y2, z2)]) left_neighbors.remove(cone) right_neighbors.remove(cone) if not left_neighbors: left_neighbors = [None] if not right_neighbors: right_neighbors = [None] for neighbor_left, neighbor_right in itertools.product( left_neighbors, right_neighbors): clips = [] # process the join on the "left" (end 1) if neighbor_left is not None: # any joins are created on the left pass; the right pass will only do clippings x0, y0, z0, r0 = neighbor_left._x0, neighbor_left._y0, neighbor_left._z0, neighbor_left._r0 if x0 == x1 and y0 == y1 and z0 == z1: x0, y0, z0, r0 = neighbor_left._x1, neighbor_left._y1, neighbor_left._z1, neighbor_left._r1 pt0 = numpy.array([x0, y0, z0]) naxis = (pt1 - pt0) / linalg.norm(pt1 - pt0) # no need to clip if the cones are perfectly aligned if any(axis != naxis): if r0 == r1 == r2: # simplest join: two cylinders (no need for all that nastiness below) sp = Sphere(x1, y1, z1, r1) sp.set_clip([ Plane(x0, y0, z0, -naxis[0], -naxis[1], -naxis[2]), Plane(x2, y2, z2, axis[0], axis[1], axis[2]) ]) objects.append(sp) else: # is the turn sharp or not # CTNG:joinangle sharp_turn = numpy.dot(axis, naxis) < 0 # locate key vectors plane_normal = numpy.cross(axis, naxis) radial_vec = numpy.cross(plane_normal, axis) nradial_vec = numpy.cross(plane_normal, naxis) # normalize all of these radial_vec /= linalg.norm(radial_vec) nradial_vec /= linalg.norm(nradial_vec) # count the corners that are inside the other cone (for both ways) # CTNG:outsidecorners my_corner_count = count_outside( neighbor_left, [pt1 + r1 * radial_vec, pt1 - r1 * radial_vec]) corner_count = my_corner_count + count_outside( cone, [pt1 + r1 * nradial_vec, pt1 - r1 * nradial_vec]) # if corner_count == 0, then probably all nan's from size 0 meeting size 0; ignore # if is 1, probably parallel; no joins # if corner_count not in (1, 2, 3, 4): # print 'corner_count: ', corner_count, [pt1 + r1 * radial_vec, pt1 - r1 * radial_vec] + [pt1 + r1 * nradial_vec, pt1 - r1 * nradial_vec] if corner_count == 2: # CTNG:2outside # add clipped sphere; same rule if sharp or mild turn objects += join_outside(x0, y0, z0, r0, x1, y1, z1, r1, x2, y2, z2, r2, dx) elif corner_count == 3: sp = Sphere(x1, y1, z1, r1) if sharp_turn: # CTNG:3outobtuse if my_corner_count == 1: sp.set_clip([ Plane(x1, y1, z1, -naxis[0], -naxis[1], -naxis[2]) ]) else: sp.set_clip([ Plane(x1, y1, z1, axis[0], axis[1], axis[2]) ]) objects.append(sp) else: # CTNG:3outacute objects += join_outside( x0, y0, z0, r0, x1, y1, z1, r1, x2, y2, z2, r2, dx) if my_corner_count == 1: objects.append( tangent_sphere(neighbor_left, 1)) objects[-1].set_clip([ Plane(x2, y2, z2, naxis[0], naxis[1], naxis[2]) ]) else: objects.append(tangent_sphere(cone, 0)) objects[-1].set_clip([ Plane(x0, y0, z0, -axis[0], -axis[1], -axis[2]) ]) elif corner_count == 4: sp = Sphere(x1, y1, z1, r1) if sharp_turn: # CTNG:4outobtuse # join with the portions of a sphere that are outside at least one of the planes sp.set_clip([ Union([ Plane(x1, y1, z1, axis[0], axis[1], axis[2]), Plane(x1, y1, z1, -naxis[0], -naxis[1], -naxis[2]) ]) ]) objects.append(sp) else: # CTNG:4outacute (+ 1 more) # join with the portions of a sphere that are outside both planes objects += join_outside( x0, y0, z0, r0, x1, y1, z1, r1, x2, y2, z2, r2, dx) # AND clip the cone to not extend pass the union of the neighbor's plane and the neighbor if r0 == r1: neighbor_copy = Cylinder( x0, y0, z0, x1, y1, z1, r0) else: neighbor_copy = Cone( x0, y0, z0, r0, x1, y1, z1, r1) clips.append( Union([ Plane(x1, y1, z1, -naxis[0], -naxis[1], -naxis[2]), neighbor_copy ])) join_type = '%d%s' % (corner_count, 's' if sharp_turn else 'm') join_counts[join_type] += 1 if neighbor_right is not None: # any joins are created on the left pass; the right pass will only do clippings x3, y3, z3, r3 = neighbor_right._x0, neighbor_right._y0, neighbor_right._z0, neighbor_right._r0 if x2 == x3 and y2 == y3 and z2 == z3: x3, y3, z3, r3 = neighbor_right._x1, neighbor_right._y1, neighbor_right._z1, neighbor_right._r1 pt3 = numpy.array([x3, y3, z3]) naxis = (pt3 - pt2) / linalg.norm(pt3 - pt2) # no need to clip if the cones are perfectly aligned if any(axis != naxis): # locate key vectors plane_normal = numpy.cross(axis, naxis) radial_vec = numpy.cross(plane_normal, axis) radial_vec_norm = linalg.norm(radial_vec) # we check again because sometimes there are roundoff errors that this catches if radial_vec_norm: # is the turn sharp or not sharp_turn = numpy.dot(axis, naxis) < 0 nradial_vec = numpy.cross(plane_normal, naxis) # normalize all of these radial_vec /= radial_vec_norm nradial_vec /= linalg.norm(nradial_vec) # count the corners that are inside the other cone (for both ways) my_corner_count = count_outside( neighbor_right, [pt2 + r2 * radial_vec, pt2 - r2 * radial_vec]) corner_count = my_corner_count + count_outside( cone, [pt2 + r2 * nradial_vec, pt2 - r2 * nradial_vec]) if corner_count == 2: # no clipping; already joined pass elif corner_count == 3: pass elif corner_count == 4: # CTNG:4outacute (+ 1 more) # already joined; just clip (only in mild turn case) if not sharp_turn: if r2 == r3: neighbor_copy = Cylinder( x2, y2, z2, x3, y3, z3, r3) else: neighbor_copy = Cone( x2, y2, z2, r2, x3, y3, z3, r3) #print 'cc=4: (%g, %g, %g; %g) (%g, %g, %g; %g) (%g, %g, %g; %g) ' % (x1, y1, z1, r1, x2, y2, z2, r2, x3, y3, z3, r3) clips.append( Union([ Plane(x2, y2, z2, naxis[0], naxis[1], naxis[2]), neighbor_copy ])) if clips: cone_clip_db[cone].append(Intersection(clips)) #print 'join_counts:' #print join_counts for cone in all_cones: clip = cone_clip_db[cone] if clip: cone.set_clip([Union(clip)]) ##################################################################### # # add the clipped objects to the list # ##################################################################### objects += all_cones return objects