def fix_axon(hobj): ''' Replace reconstructed axon with a stub Parameters ---------- hobj: instance of a Biophysical template NEURON's cell object ''' for sec in hobj.axon: h.delete_section(sec=sec) h.execute('create axon[2]', hobj) for sec in hobj.axon: sec.L = 30 sec.diam = 1 hobj.axonal.append(sec=sec) hobj.all.append(sec=sec) # need to remove this comment hobj.axon[0].connect(hobj.soma[0], 0.5, 0) hobj.axon[1].connect(hobj.axon[0], 1, 0) h.define_shape()
def splitmitral(mgid, cell, piecelist): ''' split a mitral cell into secondary dendrites and the soma/priden/axon and destroy pieces not on this cpu and connect pieces with multisplit. Note that -1 is the piece that includes the soma. Also note that secondary dendrites have branches and the piecelist is for the indices of secondary dentrites that connect to the soma. The {mgid:cell} is added to mgid2piece so the assumption is that piecelist is not empty. ''' isecden = secden_indices_connected_to_soma(cell) #disconnect all secden and destroy what is not supposed to exist for i in isecden: s = cell.secden[i] h.disconnect(sec = s) if i not in piecelist: subtree = h.SectionList() subtree.wholetree(sec = s) for ss in subtree: h.delete_section(sec = ss) rest = h.SectionList() rest.wholetree(sec = cell.soma) if -1 not in piecelist: for s in rest: h.delete_section(sec = s) #multisplit connect using mgid for i in piecelist: if i == -1: pc.multisplit(0.5, mgid, sec = cell.soma) else: pc.multisplit(0.0, mgid, sec=cell.secden[i]) # add to piece dictionary model.mgid2piece.update({mgid:cell})
def fix_axon_allactive_granule(hobj): """Replace reconstructed axon with a stub Parameters ---------- hobj: instance of a Biophysical template NEURON's cell object """ # find the start and end diameter of the original axon, this is different from the perisomatic cell model # where diameter == 1. axon_diams = [hobj.axon[0].diam, hobj.axon[0].diam] h.distance(sec=hobj.soma[0]) # need this to set all distances relative to soma (not sure if from center?) for sec in hobj.all: section_name = sec.name().split(".")[1][:4] if section_name == 'axon': for seg in sec: if h.distance(seg.x) > 60: axon_diams[1] = sec.diam #if h.distance(0.5, sec) > 60: # axon_diams[1] = sec.diam for sec in hobj.axon: h.delete_section(sec=sec) h.execute('create axon[2]', hobj) for index, sec in enumerate(hobj.axon): sec.L = 30 sec.diam = axon_diams[index] # 1 hobj.axonal.append(sec=sec) hobj.all.append(sec=sec) # need to remove this comment hobj.axon[0].connect(hobj.soma[0], 1.0, 0) hobj.axon[1].connect(hobj.axon[0], 1.0, 0) h.define_shape()
def initialize_neuron(swc_path, file_paths): h.load_file("stdgui.hoc") h.load_file("import3d.hoc") swc = h.Import3d_SWC_read() swc.input(swc_path) imprt = h.Import3d_GUI(swc, 0) h("objref this") imprt.instantiate(h.this) print file_paths for sec in h.allsec(): if sec.name().startswith("axon"): h.delete_section(sec=sec) axon = h.Section() axon.L = 60 axon.diam = 1 axon.connect(h.soma[0], 0.5, 0) h.define_shape() for sec in h.allsec(): sec.insert('pas') for seg in sec: seg.pas.e = 0 for file_path in file_paths: h.load_file(file_path.encode("ascii", "ignore"))
def cleanup(): global ig for sec in h.allsec(): h.delete_section(sec=sec) if ig: ig.box.unmap() ig = None
def _fix_axon(self): """Removes and refixes axon""" axon_diams = [self._hobj.axon[0].diam, self._hobj.axon[0].diam] axon_indices = [] for i, sec in enumerate(self._hobj.all): section_name = sec.name().split(".")[1][:4] if section_name == 'axon': axon_diams[1] = sec.diam axon_indices.append(i) for sec in self._hobj.axon: h.delete_section(sec=sec) h.execute('create axon[2]', self._hobj) for index, sec in enumerate(self._hobj.axon): sec.L = 30 sec.diam = 1 self._hobj.axonal.append(sec=sec) self._hobj.all.append(sec=sec) # need to remove this comment self._hobj.axon[0].connect(self._hobj.soma[0], 1.0, 0) self._hobj.axon[1].connect(self._hobj.axon[0], 1.0, 0) h.define_shape()
def splitmitral(mgid, cell, piecelist): ''' split a mitral cell into secondary dendrites and the soma/priden/axon and destroy pieces not on this cpu and connect pieces with multisplit. Note that -1 is the piece that includes the soma. Also note that secondary dendrites have branches and the piecelist is for the indices of secondary dentrites that connect to the soma. The {mgid:cell} is added to mgid2piece so the assumption is that piecelist is not empty. ''' isecden = secden_indices_connected_to_soma(cell) #disconnect all secden and destroy what is not supposed to exist for i in isecden: s = cell.secden[i] h.disconnect(sec=s) if i not in piecelist: subtree = h.SectionList() subtree.wholetree(sec=s) for ss in subtree: h.delete_section(sec=ss) rest = h.SectionList() rest.wholetree(sec=cell.soma) if -1 not in piecelist: for s in rest: h.delete_section(sec=s) #multisplit connect using mgid for i in piecelist: if i == -1: pc.multisplit(0.5, mgid, sec=cell.soma) else: pc.multisplit(0.0, mgid, sec=cell.secden[i]) # add to piece dictionary model.mgid2piece.update({mgid: cell})
def fix_axon_perisomatic_directed(hobj): # io.log_info('Fixing Axon like perisomatic') all_sec_names = [] for sec in hobj.all: all_sec_names.append(sec.name().split(".")[1][:4]) if 'axon' not in all_sec_names: io.log_exception('There is no axonal recostruction in swc file.') else: beg1, end1, beg2, end2 = get_axon_direction(hobj) for sec in hobj.axon: h.delete_section(sec=sec) h.execute('create axon[2]', hobj) h.pt3dadd(beg1[0], beg1[1], beg1[2], 1, sec=hobj.axon[0]) h.pt3dadd(end1[0], end1[1], end1[2], 1, sec=hobj.axon[0]) hobj.all.append(sec=hobj.axon[0]) h.pt3dadd(beg2[0], beg2[1], beg2[2], 1, sec=hobj.axon[1]) h.pt3dadd(end2[0], end2[1], end2[2], 1, sec=hobj.axon[1]) hobj.all.append(sec=hobj.axon[1]) hobj.axon[0].connect(hobj.soma[0], 0.5, 0) hobj.axon[1].connect(hobj.axon[0], 1.0, 0) hobj.axon[0].L = 30.0 hobj.axon[1].L = 30.0 h.define_shape() for sec in hobj.axon: # print "sec.L:", sec.L if np.abs(30 - sec.L) > 0.0001: io.log_exception('Axon stub L is less than 30')
def fix_axon_allactive(hobj): """Replace reconstructed axon with a stub Parameters ---------- hobj: instance of a Biophysical template NEURON's cell object """ # find the start and end diameter of the original axon, this is different from the perisomatic cell model # where diameter == 1. axon_diams = [hobj.axon[0].diam, hobj.axon[0].diam] for sec in hobj.all: section_name = sec.name().split(".")[1][:4] if section_name == 'axon': axon_diams[1] = sec.diam for sec in hobj.axon: h.delete_section(sec=sec) h.execute('create axon[2]', hobj) for index, sec in enumerate(hobj.axon): sec.L = 30 print axon_diams[index] sec.diam = axon_diams[index] # 1 hobj.axonal.append(sec=sec) hobj.all.append(sec=sec) # need to remove this comment # original allen sdk: hobj.soma[0], 0.5, 0 hobj.axon[0].connect(hobj.soma[0], 1.0, 0) hobj.axon[1].connect(hobj.axon[0], 1, 0) h.define_shape()
def importCell (fileName, cellName, cellArgs = None, cellInstance = False): h.initnrn() varList = mechVarList() # list of properties for all density mechanisms and point processes origGlob = getGlobals(list(varList['mechs'].keys())+list(varList['pointps'].keys())) origGlob['v_init'] = -65 # add by hand since won't be set unless load h.load_file('stdrun') if cellArgs is None: cellArgs = [] # Define as empty list if not otherwise defined ''' Import cell from HOC template or python file into framework format (dict of sections, with geom, topol, mechs, syns)''' if fileName.endswith('.hoc') or fileName.endswith('.tem'): h.load_file(fileName) if not cellInstance: if isinstance(cellArgs, dict): cell = getattr(h, cellName)(**cellArgs) # create cell using template, passing dict with args else: cell = getattr(h, cellName)(*cellArgs) # create cell using template, passing list with args else: try: cell = getattr(h, cellName) except: cell = None elif fileName.endswith('.py'): filePath,fileNameOnly = os.path.split(fileName) # split path from filename if filePath not in sys.path: # add to path if not there (need to import module) sys.path.insert(0, filePath) removeFilePath = True else: removeFilePath = False moduleName = fileNameOnly.split('.py')[0] # remove .py to obtain module name tempModule = importlib.import_module(moduleName) modulePointer = tempModule if isinstance(cellArgs, dict): cell = getattr(modulePointer, cellName)(**cellArgs) # create cell using template, passing dict with args else: cell = getattr(modulePointer, cellName)(*cellArgs) # create cell using template, passing list with args if removeFilePath: sys.path.remove(filePath) else: print("File name should be either .hoc or .py file") return secDic, secListDic, synMechs, globs = getCellParams(cell, varList, origGlob) if fileName.endswith('.py'): _delete_module(moduleName) _delete_module('tempModule') del modulePointer elif fileName.endswith('.hoc'): for sec in h.allsec(): try: if h.cas()!=sec: sec.push() h.delete_section() h.pop_section() except: pass h.initnrn() setGlobals(origGlob) # restore original globals return secDic, secListDic, synMechs, globs
def test_1(): hl = hlist() npo = hl.count() # compare against this. Previous tests may leave some. h("objref po") h.po = {} assert hl.count() == (npo + 1) h.po = h.Vector() assert hl.count() == npo h.po = None assert hl.count() == npo h("po = new PythonObject()") assert hl.count() == (npo + 1) h("po = po.list()") assert type(h.po) == type([]) assert hl.count() == (npo + 1) h("objref po") assert hl.count() == npo h("""obfunc test_hoc_po() { localobj foo foo = new PythonObject() return foo.list() } po = test_hoc_po() """) assert hl.count() == (npo + 1) h.po = None assert hl.count() == npo assert type(h.test_hoc_po()) == type([]) assert hl.count() == npo # nrn.Section tests for sec in h.allsec(): h.delete_section(sec=sec) h("""create soma""") h.po = h.soma assert h.po == h.soma assert hl.count() == (npo + 1) h.po = None assert hl.count() == npo h.po = h.soma h.delete_section(sec=h.soma) assert str(h.po) == "<deleted section>" h.po = None assert hl.count() == npo h.po = h.Section(name="pysoma") h("po.L = 5") assert h.po.L == 5 assert hl.count() == (npo + 1) h.po = None assert hl.count() == npo assert len([sec for sec in h.allsec()]) == 0
def _create_AIS(self): """Replica of "Replace axon" in: https://bluepyopt.readthedocs.io/en/latest/_modules/bluepyopt/ephys/morphologies.html#Morphology """ temp = [] for sec in h.allsec(): if sec.name().find('axon') >= 0: temp.append(sec) # specify diameter based on blu if len(temp) == 0: ais_diams = [1, 1] elif len(temp) == 1: ais_diams = [temp[0].diam, temp[0].diam] else: ais_diams = [temp[0].diam, temp[0].diam] # Define origin of distance function h.distance(0, 0.5, sec=self.soma) for section in h.allsec(): if section.name().find('axon') >= 0: # If distance to soma is larger than 60, store diameter if h.distance(1, 0.5, sec=section) > 60: ais_diams[1] = section.diam break # delete old axon for section in temp: h.delete_section(sec=section) # Create new axon sections a0 = h.Section(name='axon[0]') a1 = h.Section(name='axon[1]') # populate axonlist for sec in h.allsec(): if sec.name().find('axon') >= 0: self.axonlist.append(sec=sec) # connect axon sections to soma and eachother a0.connect(self.soma) a1.connect(a0) # set axon params for index, section in enumerate([a0,a1]): section.nseg = 1 section.L = 30 section.diam = ais_diams[index] # this line is needed to prevent garbage collection of axon self.axon = [a0,a1] logger.debug('Replace axon with AIS')
def close(self): """Clean up the hoc when we delete the object""" # This is to prevent remanescence of the synapse # Otherwise you can become crazy!! if len(self.syn) >= 1: for key in self.syn.keys(): del self.syn[key] # Delete all the sections for sec in h.allsec(): h.delete_section(sec=sec)
def test(): sec = h.Section(name='dend') for sec in h.allsec(): h.disconnect(sec=sec) sref = h.SectionRef(sec=sec) #defeated the guards against deleting the Section pointed to by # a PythonSection sref.rename('delete') h.disconnect(sec=sec) #used to be allowed only for hoc sections (create ...) h.delete_section(sec=sec)
def neuron_instance(neuron_import): """Sets/Resets the rxd test environment. Provides 'data', a dictionary used to store voltages and rxd node values for comparisons with the 'correct_data'. """ h, rxd = neuron_import data = {'record_count': 0, 'data': []} h.load_file('stdrun.hoc') cvode = h.CVode() cvode.active(False) cvode.atol(1e-3) h.dt = 0.025 h.stoprun = False def gather(): return collect_data(h, rxd, data) cvode.extra_scatter_gather(0, gather) yield (h, rxd, data) rxd.region._all_regions = [] rxd.region._region_count = 0 rxd.region._c_region_lookup = None for r in rxd.rxd._all_reactions[:]: if r(): rxd.rxd._unregister_reaction(r) for s in rxd.species._all_species: if s(): s().__del__() rxd.species._species_counts = 0 rxd.section1d._rxd_sec_lookup = {} rxd.section1d._purge_cptrs() rxd.initializer.has_initialized = False rxd.rxd.free_conc_ptrs() rxd.rxd.free_curr_ptrs() rxd.rxd.rxd_include_node_flux1D(0, None, None, None) for sec in h.allsec(): h.disconnect(sec=sec) sref = h.SectionRef(sec=sec) sref.rename('delete') h.delete_section(sec=sec) rxd.species._has_1d = False rxd.species._has_3d = False rxd.rxd._memb_cur_ptrs = [] rxd.rxd._rxd_induced_currents = None rxd.rxd._curr_indices = None rxd.rxd._zero_volume_indices = numpy.ndarray(0, dtype=numpy.int_) rxd.set_solve_type(dimension=1) cvode.extra_scatter_gather_remove(gather)
def AddSpines_callback(mode='button_callback'): # !! Check if adding spines when dist_='Freeze' keeps synapse locations and just puts spines there UpdateEntryParams(Simulator, GUI) UpdateSynLocs() if Simulator.spines_exist: # Either in the case of removing spines or just updating location (will be False for adding new spines) for spine in h.allsec(): if 'spine' in spine.name(): h.delete_section(sec=spine) if (mode == 'update' and Simulator.spines_exist) or ( mode == 'button_callback' and GUI.Buttons['AddSpines']['text'] == 'Add Spines'): Simulator.spine_heads, Simulator.spine_necks = PutSpines( 'cable', Simulator.dend, Simulator.exc_locs, neck_diam=float(GUI.Entries['spines']['neck_diam']['Var'].get()), neck_len=float(GUI.Entries['spines']['neck_L']['Var'].get()), head_radius=float( GUI.Entries['spines']['head_radius']['Var'].get()), Ra=float(GUI.Entries['spines']['neck_Ra']['Var'].get()), cm=Simulator.dend.cm, e_pas=Simulator.dend.e_pas, g_pas=4.6716e-5) Simulator.spines_exist = True GUI.Buttons['AddSpines']['text'] = 'Remove Spines' h.define_shape() # Unlock spine-related radio buttons GUI.RadioButtons['syn_loc']['Buttons'][0].config(state='normal') GUI.RadioButtons['volt_loc']['Buttons'][0].config(state='normal') elif mode == 'button_callback' and GUI.Buttons['AddSpines'][ 'text'] == 'Remove Spines': Simulator.spine_heads, Simulator.spine_necks = [], [] Simulator.spines_exist = False GUI.Buttons['AddSpines']['text'] = 'Add Spines' # Make sure user can't put synapses on non-existing spines GUI.RadioButtons['syn_loc']['Var'].set(2) GUI.RadioButtons['syn_loc']['Buttons'][0].config(state='disabled') GUI.RadioButtons['volt_loc']['Var'].set(2) GUI.RadioButtons['volt_loc']['Buttons'][0].config(state='disabled') Simulator.PlaceSynapses('exc') GUI.DrawSections(colors) UpdatePresentedValues(GUI.ChangingLabels)
def model(): pc.gid_clear() for s in h.allsec(): h.delete_section(sec=s) s = h.Section() s.L = 10 s.diam = 10 s.insert("hh") ic = h.IClamp(s(0.5)) ic.delay = 0.1 ic.dur = 0.1 ic.amp = 0.5 * 0 syn = h.ExpSyn(s(0.5)) nc = h.NetCon(None, syn) nc.weight[0] = 0.001 return {"s": s, "ic": ic, "syn": syn, "nc": nc}
def fix_axon(hobj): """Replace reconstructed axon with a stub :param hobj: NEURON's cell object """ for sec in hobj.axon: h.delete_section(sec=sec) h.execute('create axon[2]', hobj) for sec in hobj.axon: sec.L = 30 sec.diam = 1 hobj.axonal.append(sec=sec) hobj.all.append(sec=sec) # need to remove this comment hobj.axon[0].connect(hobj.soma[0], 0.5, 0) hobj.axon[1].connect(hobj.axon[0], 1, 0) h.define_shape()
def test_func_call(): for sec in h.allsec(): h.delete_section(sec=sec) soma = h.Section(name="soma") dend = h.Section(name="dend") axon = h.Section(name="axon") dend.connect(soma(0)) dend.nseg = 5 axon.connect(soma(1)) axon.nseg = 3 h.topology() invoke = False def f(x): y = x**2 if invoke: if h.cas() == dend and x == 1.0: 1 / 0 if h.cas() == dend and x > 0.6: sys.exit(0) print("{}({})".format(h.cas(), x)) return y # all points exist rvp = h.RangeVarPlot(f, dend(1.0), axon(1.0)) vec = h.Vector() rvp.to_vector(vec) invoke = True # but no errors as those are marked non-existent h.RangeVarPlot(f, dend(1.0), axon(1.0)) # now an error expect_err("rvp.to_vector(vec)") if __name__ == "__main__": invoke = False rvp = h.RangeVarPlot(f, dend(0.9), axon(1.0)) invoke = True rvp.to_vector(vec) print("this test_func_call line gets printed in interactive mode") del soma, dend, axon, rvp, vec locals()
def test_HocObject_no_deferred_unref(): #previous tests should really destroy the model they created for sec in h.allsec(): h.delete_section(sec=sec) sl = h.SectionList() cell = h.Cell() assert (len(list(cell.all)) == 2) del cell # When deferred deletion was in effect, following for loop would segfault # because actual deletion of the HOC Cell object would not occur til the next # h.functioncall(). I.e. the first call to sl.append below would destroy # the HOC Cell which would destroy the two Sections and invalidate the # iterator causing a segfault. for sec in h.allsec(): print(sec) sl.append(sec=sec) assert (len([s for s in sl]) == 0)
def test_push_section(): h("""create hCable1, hCable2""") h.push_section("hCable1") assert h.secname() == "hCable1" h.pop_section() h.push_section("hCable2") assert h.secname() == "hCable2" h.pop_section() h.delete_section(sec=h.hCable1) h.delete_section(sec=h.hCable2) sections = [h.Section(name="pCable%d" % i) for i in range(2)] sections.append(h.Section()) # Anonymous in the past for sec in sections: name_in_hoc = h.secname(sec=sec) h.push_section(name_in_hoc) assert h.secname() == name_in_hoc h.pop_section() s = sections[-1] h.delete_section(sec=s) # but not yet freed (though the name is now "") # not [no longer] a section pointer expect_err( "s.hoc_internal_name()" ) # this is what is generating the error in the next statement. expect_err('h.push_section(int(s.hoc_internal_name().replace("__nrnsec_", ""), 0))') # not a sectionname expect_hocerr(h.push_section, ("not_a_sectionname",))
def test_push_section(): h('''create hCable1, hCable2''') h.push_section("hCable1") assert (h.secname() == "hCable1") h.pop_section() h.push_section("hCable2") assert (h.secname() == "hCable2") h.pop_section() h.delete_section(sec=h.hCable1) h.delete_section(sec=h.hCable2) sections = [h.Section(name="pCable%d" % i) for i in range(2)] sections.append(h.Section()) # Anonymous in the past for sec in sections: name_in_hoc = h.secname(sec=sec) h.push_section(name_in_hoc) assert (h.secname() == name_in_hoc) h.pop_section() s = sections[-1] h.delete_section(sec=s) # but not yet freed (though the name is now "") # not [no longer] a section pointer expect_hocerr(h.push_section, (int(s.hoc_internal_name().replace("__nrnsec_", ""), 0), )) # not a sectionname expect_hocerr(h.push_section, ("not_a_sectionname", ))
def fix_axon_allactive_directed(hobj): all_sec_names = [] for sec in hobj.all: all_sec_names.append(sec.name().split(".")[1][:4]) if 'axon' not in all_sec_names: io.log_exception('There is no axonal recostruction in swc file.') else: beg1, end1, beg2, end2 = get_axon_direction(hobj) axon_diams = [hobj.axon[0].diam, hobj.axon[0].diam] for sec in hobj.all: section_name = sec.name().split(".")[1][:4] if section_name == 'axon': axon_diams[1] = sec.diam for sec in hobj.axon: h.delete_section(sec=sec) h.execute('create axon[2]', hobj) hobj.axon[0].connect(hobj.soma[0], 1.0, 0) hobj.axon[1].connect(hobj.axon[0], 1.0, 0) h.pt3dadd(beg1[0], beg1[1], beg1[2], axon_diams[0], sec=hobj.axon[0]) h.pt3dadd(end1[0], end1[1], end1[2], axon_diams[0], sec=hobj.axon[0]) hobj.all.append(sec=hobj.axon[0]) h.pt3dadd(beg2[0], beg2[1], beg2[2], axon_diams[1], sec=hobj.axon[1]) h.pt3dadd(end2[0], end2[1], end2[2], axon_diams[1], sec=hobj.axon[1]) hobj.all.append(sec=hobj.axon[1]) hobj.axon[0].L = 30.0 hobj.axon[1].L = 30.0 h.define_shape() for sec in hobj.axon: # io.log_info('sec.L: {}'.format(sec.L)) if np.abs(30 - sec.L) > 0.0001: io.log_exception('Axon stub L is less than 30')
def AddSoma_callback(): s = ttk.Style() s.configure('Gray.TEntry', background='gray') if GUI.Buttons['AddSoma']['text'] == 'Add Soma': soma_size = float(GUI.Entries['soma']['soma.diam']['Var'].get()) soma_cm = float(GUI.Entries['soma']['soma.cm']['Var'].get()) Simulator.CreateCompartment('soma', L=soma_size, diam=soma_size, Ra=110, e_pas=h.v_init, g_pas=1.0 / 1500.0, nseg=int(soma_size) * 5, cm=soma_cm) h.disconnect(sec=Simulator.soma) Simulator.dend.connect( Simulator.soma, 1, 0 ) # Disconnect from parents if exist (following weird bug in which soma was created as child of last created section (spine head)) h.define_shape() # !Explain this GUI.Buttons['AddSoma'][ 'text'] = 'Remove Soma' #!Toggle soma function inside GUI GUI.RadioButtons['volt_loc']['Buttons'][2].config(state='normal') elif GUI.Buttons['AddSoma']['text'] == 'Remove Soma': h.delete_section(sec=Simulator.soma) Simulator.soma = None GUI.Buttons['AddSoma']['text'] = 'Add Soma' GUI.RadioButtons['volt_loc']['Var'].set(2) GUI.RadioButtons['volt_loc']['Buttons'][2].config(state='disabled') GUI.DrawSections(colors) UpdatePresentedValues(GUI.ChangingLabels)
def initialize_neuron(swc_path, file_paths): """ Initialize neuron with morphology and load hoc files Parameters ---------- swc_path : str Path to SWC file file_paths : list List of str file paths of files for NEURON to load """ h.load_file("stdgui.hoc") h.load_file("import3d.hoc") swc = h.Import3d_SWC_read() swc.input(swc_path) imprt = h.Import3d_GUI(swc, 0) h("objref this") imprt.instantiate(h.this) for sec in h.allsec(): if sec.name().startswith("axon"): h.delete_section(sec=sec) axon = h.Section() axon.L = 60 axon.diam = 1 axon.connect(h.soma[0], 0.5, 0) h.define_shape() for sec in h.allsec(): sec.insert('pas') for seg in sec: seg.pas.e = 0 for file_path in file_paths: h.load_file(file_path.encode("ascii", "ignore"))
def test_disconnect(): print("test_disconnect") for sec in h.allsec(): h.delete_section(sec=sec) h.topology() n = 5 def setup(n): sections = [h.Section(name="s%d" % i) for i in range(n)] for i, sec in enumerate(sections[1:]): sec.connect(sections[i]) return sections sl = setup(n) def chk(sections, i): print(sections, i) h.topology() x = len(sections[0].wholetree()) assert x == i chk(sl, n) h.disconnect(sec=sl[2]) chk(sl, 2) sl = setup(n) sl[2].disconnect() chk(sl, 2) sl = setup(n) expect_err("h.disconnect(sl[2])") expect_err("h.delete_section(sl[2])") del sl locals()
from neuron import h, gui h('create axon') import __main__ import sys def e(stmt) : try: print stmt exec stmt in __main__.__dict__ except: print sys.exc_info()[0], ': ', sys.exc_info()[1] e('print h.axon.i_membrane_') e('print h.axon(.5).i_membrane_') h.delete_section() h.load_file("imemaxon2.hoc") for seg in h.axon: print seg.x, seg.i_membrane*seg.area()*(0.01), seg.i_membrane_ for seg in h.axon.allseg(): print seg.x, seg._ref_i_membrane_[0], seg.i_membrane_ print h.axon.i_membrane, h.axon(.5).i_membrane print h.axon.i_membrane_
def test_deleted_sec(): for sec in h.allsec(): h.delete_section(sec=sec) s = h.Section() s.insert("hh") seg = s(0.5) ic = h.IClamp(seg) mech = seg.hh rvlist = [rv for rv in mech] vref = seg._ref_v gnabarref = mech._ref_gnabar sec_methods_ok = set([s.cell, s.name, s.hname, s.same, s.hoc_internal_name]) sec_methods_chk = set( [ getattr(s, n) for n in dir(s) if "__" not in n and type(getattr(s, n)) == type(s.x3d) and getattr(s, n) not in sec_methods_ok ] ) seg_methods_chk = set( [ getattr(seg, n) for n in dir(seg) if "__" not in n and type(getattr(seg, n)) == type(seg.area) ] ) mech_methods_chk = set( [ getattr(mech, n) for n in dir(mech) if "__" not in n and type(getattr(mech, n)) == type(mech.segment) ] ) rv_methods_chk = set( [ getattr(rvlist[0], n) for n in dir(rvlist[0]) if "__" not in n and type(getattr(rvlist[0], n)) == type(rvlist[0].name) ] ) rv_methods_chk.remove(rvlist[0].name) h.delete_section(sec=s) for methods in [sec_methods_chk, seg_methods_chk, mech_methods_chk, rv_methods_chk]: for m in methods: # Most would fail because of no args, but expect a check # for valid section first. words = str(m).split() print("m is " + words[4] + "." + words[2]) expect_err("m()") assert str(s) == "<deleted section>" assert str(seg) == "<segment of deleted section>" assert str(mech) == "<mechanism of deleted section>" expect_err("h.sin(0.0, sec=s)") expect_err("print(s.L)") expect_err("s.L = 100.") expect_err("s.nseg") expect_err("s.nseg = 5") expect_err("print(s.v)") expect_err("print(s.orientation())") expect_err("s.insert('pas')") expect_err("s.insert(h.pas)") expect_err("s(.5)") expect_err("s(.5).v") expect_err("seg.v") expect_err("seg._ref_v") expect_err("s(.5).v = -65.") expect_err("seg.v = -65.") expect_err("seg.gnabar_hh") expect_err("mech.gnabar") expect_err("seg.gnabar_hh = .1") expect_err("mech.gnabar = .1") expect_err("rvlist[0][0]") expect_err("rvlist[0][0] = .1") expect_err("for sg in s: pass") expect_err("for m in seg: pass") expect_err("for r in mech: pass") assert s == s # See https://github.com/neuronsimulator/nrn/issues/1343 if sys.version_info >= (3, 8): expect_err("dir(s)") expect_err("dir(seg)") expect_err("dir(mech)") assert type(dir(rvlist[0])) == list expect_err("help(s)") expect_err("help(seg)") expect_err("help(mech)") help(rvlist[0]) # not an error since it does not access s dend = h.Section() expect_err("dend.connect(s)") expect_err("dend.connect(seg)") # Note vref and gnabarref if used may cause segfault or other indeterminate result assert ic.get_segment() == None assert ic.has_loc() == 0.0 expect_err("ic.get_loc()") expect_err("ic.amp") expect_err("ic.amp = .001") ic.loc(dend(0.5)) assert ic.get_segment() == dend(0.5) imp = h.Impedance() expect_err("imp.loc(seg)") expect_err("h.distance(0, seg)") expect_hocerr(imp.loc, (seg,)) expect_hocerr(h.distance, (0, seg)) del ic, imp, dend locals() return s, seg, mech, rvlist, vref, gnabarref
def subtree_reductor(original_cell, synapses_list, netcons_list, reduction_frequency, model_filename='model.hoc', total_segments_manual=-1, PP_params_dict=None, mapping_type='impedance'): ''' Receives an instance of a cell with a loaded full morphology, a list of synapse objects, a list of NetCon objects (the i'th netcon in the list should correspond to the i'th synapse), the filename (string) of the model template hoc file that the cell was instantiated from, the desired reduction frequency as a float, optional parameter for the approximate desired number of segments in the new model (if this parameter is empty, the number of segments will be such that there is a segment for every 0.1 lambda), and an optional param for the point process to be compared before deciding on whethet to merge a synapse or not and reduces the cell (using the given reduction_frequency). Creates a reduced instance using the model template in the file whose filename is given as a parameter, and merges synapses of the same type that get mapped to the same segment (same "reduced" synapse object for them all, but different NetCon objects). Returns the new reduced cell, a list of the new synapses, and the list of the inputted netcons which now have connections with the new synapses. note #0: a default template is available, one can use: model_filename=model.hoc note #1: The original cell instance, synapses and Netcons given as arguments are altered by the function and cannot be used outside of it in their original context. note #2: Synapses are determined to be of the same type and mergeable if their reverse potential, tau1 and tau2 values are identical. note #3: Merged synapses are assigned a single new synapse object that represents them all, but keep their original NetCon objects. Each such NetCon now connects the original synapse's NetStim with the reduced synapse. ''' if PP_params_dict is None: PP_params_dict = {} h.init() model_obj_name = load_model(model_filename) # finds soma properties soma = original_cell.soma[0] if original_cell.soma.hname( )[-1] == ']' else original_cell.soma soma_cable = CableParams(length=soma.L, diam=soma.diam, space_const=None, cm=soma.cm, rm=1.0 / soma.g_pas, ra=soma.Ra, e_pas=soma.e_pas, electrotonic_length=None) has_apical = len(list(original_cell.apical)) != 0 soma_ref = h.SectionRef(sec=soma) axon_section, axon_is_parent = find_and_disconnect_axon(soma_ref) roots_of_subtrees, num_of_subtrees = gather_subtrees(soma_ref) sections_to_delete, section_per_subtree_index, mapping_sections_to_subtree_index = \ gather_cell_subtrees(roots_of_subtrees) # preparing for reduction # remove active conductances and get seg_to_mech dictionary segment_to_mech_vals = create_segments_to_mech_vals(sections_to_delete) # disconnects all the subtrees from the soma for subtree_root in roots_of_subtrees: h.disconnect(sec=subtree_root) # reducing the subtrees new_cable_properties = [ reduce_subtree(roots_of_subtrees[i], reduction_frequency) for i in num_of_subtrees ] if total_segments_manual != -1: new_cables_nsegs = calculate_nsegs_from_manual_arg( new_cable_properties, total_segments_manual) else: new_cables_nsegs = calculate_nsegs_from_lambda(new_cable_properties) cell, basals = create_reduced_cell(soma_cable, has_apical, original_cell, model_obj_name, new_cable_properties, new_cables_nsegs) new_synapses_list, subtree_ind_to_q = merge_and_add_synapses( num_of_subtrees, new_cable_properties, PP_params_dict, synapses_list, mapping_sections_to_subtree_index, netcons_list, has_apical, roots_of_subtrees, original_cell, basals, cell, reduction_frequency) # create segment to segment mapping original_seg_to_reduced_seg, reduced_seg_to_original_seg = create_seg_to_seg( original_cell, section_per_subtree_index, roots_of_subtrees, mapping_sections_to_subtree_index, new_cable_properties, has_apical, cell.apic, basals, subtree_ind_to_q, mapping_type, reduction_frequency) # copy active mechanisms copy_dendritic_mech(original_seg_to_reduced_seg, reduced_seg_to_original_seg, cell.apic, basals, segment_to_mech_vals, mapping_type) # Connect axon back to the soma if len(axon_section) > 0: if axon_is_parent: soma.connect(axon_section[0]) else: axon_section[0].connect(soma) # Now we delete the original model for section in sections_to_delete: with push_section(section): h.delete_section() cell.axon = axon_section cell.dend = cell.hoc_model.dend with push_section(cell.hoc_model.soma[0]): h.delete_section() return cell, new_synapses_list, netcons_list
from neuron import h import matplotlib.pyplot as plt import numpy as np h.load_file('init_models_with_ca/init_model2.hoc') h.delete_section(sec=h.axon) h.delete_section(sec=h.iseg) h.delete_section(sec=h.hillock) # Set up stimulus stim = h.SEClamp(h.apical(1)) stim.amp1 = -70 stim.amp2 = -40 stim.amp3 = -70 stim.dur1 = 500 stim.dur3 = 100 # Set up recording vectors apical_end_v_vec = h.Vector() apical_end_v_vec.record(h.apical(1)._ref_v) tuft_v_vec = h.Vector() tuft_v_vec.record(h.tuft(.5)._ref_v) t_vec = h.Vector() t_vec.record(h._ref_t) # Simulation parameters dt = 0.025 h.tstop = 1000 - dt h.tuft.gbar_sca = 0
def subtree_reductor(original_cell, synapses_list, netcons_list, reduction_frequency, model_filename='model.hoc', total_segments_manual=-1, PP_params_dict=None, mapping_type='impedance', return_seg_to_seg=False ): ''' Receives an instance of a cell with a loaded full morphology, a list of synapse objects, a list of NetCon objects (the i'th netcon in the list should correspond to the i'th synapse), the filename (string) of the model template hoc file that the cell was instantiated from, the desired reduction frequency as a float, optional parameter for the approximate desired number of segments in the new model (if this parameter is empty, the number of segments will be such that there is a segment for every 0.1 lambda), and an optional param for the point process to be compared before deciding on whether to merge a synapse or not and reduces the cell (using the given reduction_frequency). Creates a reduced instance using the model template in the file whose filename is given as a parameter, and merges synapses of the same type that get mapped to the same segment (same "reduced" synapse object for them all, but different NetCon objects). model_filename : model.hoc will use a default template total_segments_manual: sets the number of segments in the reduced model can be either -1, a float between 0 to 1, or an int if total_segments_manual = -1 will do automatic segmentation if total_segments_manual>1 will set the number of segments in the reduced model to total_segments_manual if 0>total_segments_manual>1 will automatically segment the model but if the automatic segmentation will produce a segment number that is lower than original_number_of_segments*total_segments_manual it will set the number of segments in the reduced model to: original_number_of_segments*total_segments_manual return_seg_to_seg: if True the function will also return a textify version of the mapping between the original segments to the reduced segments Returns the new reduced cell, a list of the new synapses, and the list of the inputted netcons which now have connections with the new synapses. Notes: 1) The original cell instance, synapses and Netcons given as arguments are altered by the function and cannot be used outside of it in their original context. 2) Synapses are determined to be of the same type and mergeable if their reverse potential, tau1 and tau2 values are identical. 3) Merged synapses are assigned a single new synapse object that represents them all, but keep their original NetCon objects. Each such NetCon now connects the original synapse's NetStim with the reduced synapse. ''' if PP_params_dict is None: PP_params_dict = {} h.init() model_obj_name = load_model(model_filename) # finds soma properties soma = original_cell.soma[0] if original_cell.soma.hname()[-1] == ']' else original_cell.soma soma_cable = CableParams(length=soma.L, diam=soma.diam, space_const=None, cm=soma.cm, rm=1.0 / soma.g_pas, ra=soma.Ra, e_pas=soma.e_pas, electrotonic_length=None) has_apical = len(list(original_cell.apical)) != 0 soma_ref = h.SectionRef(sec=soma) axon_section, axon_is_parent, soma_axon_x = find_and_disconnect_axon(soma_ref) roots_of_subtrees, num_of_subtrees = gather_subtrees(soma_ref) sections_to_delete, section_per_subtree_index, mapping_sections_to_subtree_index = \ gather_cell_subtrees(roots_of_subtrees) # preparing for reduction # remove active conductances and get seg_to_mech dictionary segment_to_mech_vals = create_segments_to_mech_vals(sections_to_delete) # disconnects all the subtrees from the soma subtrees_xs = [] for subtree_root in roots_of_subtrees: subtrees_xs.append(subtree_root.parentseg().x) h.disconnect(sec=subtree_root) # reducing the subtrees new_cable_properties = [reduce_subtree(roots_of_subtrees[i], reduction_frequency) for i in num_of_subtrees] if total_segments_manual > 1: new_cables_nsegs = calculate_nsegs_from_manual_arg(new_cable_properties, total_segments_manual) else: new_cables_nsegs = calculate_nsegs_from_lambda(new_cable_properties) if total_segments_manual > 0: original_cell_seg_n = (sum(i.nseg for i in list(original_cell.basal)) + sum(i.nseg for i in list(original_cell.apical)) ) min_reduced_seg_n = int(round((total_segments_manual * original_cell_seg_n))) if sum(new_cables_nsegs) < min_reduced_seg_n: logger.debug("number of segments calculated using lambda is {}, " "the original cell had {} segments. " "The min reduced segments is set to {}% of reduced cell segments".format( sum(new_cables_nsegs), original_cell_seg_n, total_segments_manual * 100)) logger.debug("the reduced cell nseg is set to %s" % min_reduced_seg_n) new_cables_nsegs = calculate_nsegs_from_manual_arg(new_cable_properties, min_reduced_seg_n) cell, basals = create_reduced_cell(soma_cable, has_apical, original_cell, model_obj_name, new_cable_properties, new_cables_nsegs, subtrees_xs) new_synapses_list, subtree_ind_to_q = merge_and_add_synapses( num_of_subtrees, new_cable_properties, PP_params_dict, synapses_list, mapping_sections_to_subtree_index, netcons_list, has_apical, roots_of_subtrees, original_cell, basals, cell, reduction_frequency) # create segment to segment mapping original_seg_to_reduced_seg, reduced_seg_to_original_seg = create_seg_to_seg( original_cell, section_per_subtree_index, roots_of_subtrees, mapping_sections_to_subtree_index, new_cable_properties, has_apical, cell.apic, basals, subtree_ind_to_q, mapping_type, reduction_frequency) # copy active mechanisms copy_dendritic_mech(original_seg_to_reduced_seg, reduced_seg_to_original_seg, cell.apic, basals, segment_to_mech_vals, mapping_type) if return_seg_to_seg: original_seg_to_reduced_seg_text = textify_seg_to_seg(original_seg_to_reduced_seg) # Connect axon back to the soma if len(axon_section) > 0: if axon_is_parent: soma.connect(axon_section[0]) else: axon_section[0].connect(soma, soma_axon_x) # Now we delete the original model for section in sections_to_delete: with push_section(section): h.delete_section() cell.axon = axon_section cell.dend = cell.hoc_model.dend with push_section(cell.hoc_model.soma[0]): h.delete_section() if return_seg_to_seg: return cell, new_synapses_list, netcons_list, original_seg_to_reduced_seg_text else: return cell, new_synapses_list, netcons_list