def create_pn_kc_conn(fd, pn_vecstim_dict, kc_name_sec_dict, path=pn_kc_syn_path, config=None): """Create PN->KC connection from dataset at specified path pn_vecstim_list should be a dict from pn name to corresponding vecstim kc_name_sec_dict should be a dict from kc soma section names to the sections themselves returns a dict containing kc names mapped to their synapses and a list of all netcons from PNs to KCs. """ global model_dict cfg.logger.info('Started PN->KC connections') if config is None: config = {} syn_dict = {} netcons = [] ncdict = {} syn_data = fd[path] # This is to take care of discrepancy between NSDF saving synapses # as dataset of dim [nx1] vs my kc removal code saving them as dim # [n] if len(syn_data.shape) == 2: syn_data = syn_data[:, 0] for ii, row in enumerate(syn_data): if row['post'] not in syn_dict: target = kc_name_sec_dict[row['post']] syn = h.Exp2Syn(target(row['postpos'])) syn.e = row['e'] syn.tau1 = row['tau1'] syn.tau2 = row['tau2'] syn_dict[row['post']] = syn else: syn = syn_dict[row['post']] vecstim = pn_vecstim_dict[row['pre']] if 'delay' in row.dtype.names: delay = row['delay'] else: delay = config.get('delay', '0.0ms') delay = cfg.Q_(delay).to('ms').m thresh = -20.0 nc = h.NetCon(vecstim, syn, thresh, delay, row['gmax']) netcons.append((row['pre'], row['post'], nc)) assert (vecstim, syn) not in ncdict ncdict[(vecstim, syn)] = nc # print(ii, nc, nc.pre(), nc.syn()) # sys.stdout.flush() model_dict['pn_kc_conn'] = (netcons, syn_dict) cfg.logger.info('Finished PN->KC connections') return netcons, syn_dict
def connect_kcs_to_ig(kcs=None, params=None): """Connect single compartmental KCs to IG""" global model_dict if isinstance(kcs, h5.File): fd = kcs kc_name_sec_dict = {kc.soma.name(): kc.soma for kc in model_dict['kc']} threshold = -20.0 if params is not None: threshold = cfg.Q_(params['threshold']).to('mV').m units = fd[kc_ig_syn_path].attrs['unit'][-1] syn_data = fd[kc_ig_syn_path] if len(syn_data.shape) == 2: syn_data = syn_data[:, 0] # for row_arr in fd[kc_ig_syn_path].value: # row = row_arr[0] for row in syn_data: cfg.logger.debug('{}'.format(row)) presec = kc_name_sec_dict[row['pre']] # TODO not using the unit attribute from dataset - assuming NEURON compatible units # ignoring 'prepos' field as KCs are single compartmental # - important data are weight and delay model_dict['ig'].connect_ampa_sec(presec, 0.5, threshold=threshold, delay=row['delay'], weight=row['gmax']) else: # no explicit synapse info, use constant values from config weight = float(params['weight']) if weight <= 0: cfg.logger.info('No connection from KCs to IG') return threshold = cfg.Q_(params['threshold']).to('mV').m delay = cfg.Q_(params['delay']).to('ms').m for kc in kcs: model_dict['ig'].connect_ampa_sec(kc.soma, 0.5, threshold=threshold, delay=delay, weight=weight) cfg.logger.info('Completed creation of synapse from KCs to IG')
def setup_ig(fd, ggn_name_sec_dict, config=None): """Skipping model structure and just create IG from config""" global model_dict if config is None: config = {} if 'ig' not in config: return ig = IGIzhi(inject=config['ig']['inject'], gbarGABA=cfg.Q_(config['ggn_ig_syn']['gmax']).to('uS').m) ig.vmidGraded = cfg.Q_(config['ggn_ig_syn']['vmid']).to('mV').m ig.vslopeGraded = cfg.Q_(config['ggn_ig_syn']['vslope']).to('mV').m ggn = model_dict['ggn'] # presec = ggn_name_sec_dict[config['ggn_ig_syn']['source']] presec = eval('ggn.{}'.format(config['ggn_ig_syn']['source'])) h.setpointer(presec(0.5)._ref_v, 'vpreGraded', ig.izhi) cfg.logger.info('Created IG with injection {}'.format(config['ig']['inject'])) model_dict['ig'] = ig # post_sec = ggn_name_sec_dict[config['ig_ggn_syn']['target']] post_sec = eval('ggn.{}'.format(config['ig_ggn_syn']['target'])) make_ig_ggn_syn(ig, config['ig_ggn_syn'], post_sec) if kc_ig_syn_path in fd: connect_kcs_to_ig(fd, config['kc_ig_syn']) else: connect_kcs_to_ig(model_dict['kc'], config['kc_ig_syn'])
def create_kc_ggn_conn(fd, kc_name_sec_dict, ggn_name_sec_dict, path=kc_ggn_alphaL_syn_path, config=None): """Created excitatory synapses from KCs to GGN segments""" global model_dict cfg.logger.info('Started KC->GGN connection') if config is None: config = {} model_dict['kc_ggn_syn'] = [] model_dict['kc_ggn_nc'] = [] model_dict['kc_ggn_conn'] = [] syn_dict = {} nc_dict = {} syn_data = fd[path] if len(syn_data.shape) == 2: syn_data = syn_data[:, 0] # for row_arr in fd[kc_ggn_alphaL_syn_path]: # row = row_arr[0] for row in syn_data: postsec = ggn_name_sec_dict[row['post']] syn = h.Exp2Syn(postsec(row['postpos'])) syn.e = row['e'] syn.tau1 = row['tau1'] syn.tau2 = row['tau2'] presec = kc_name_sec_dict[row['pre']] if 'delay' in row.dtype.names: delay = row['delay'] else: delay = config.get('delay', '1.0ms') delay = cfg.Q_(delay).to('ms').m nc = h.NetCon(presec(row['prepos'])._ref_v, syn, -20.0, delay, row['gmax'], sec=presec) syn_dict[row['pre']] = syn nc_dict[row['pre']] = nc model_dict['kc_ggn_syn'].append(syn) model_dict['kc_ggn_nc'].append(nc) model_dict['kc_ggn_conn'].append({'pre': row['pre'], 'prepos': row['prepos'], 'post': row['post'], 'postpos': row['postpos'], 'nc': nc, 'syn': syn}) cfg.logger.info('Finished KC->GGN connection') return syn_dict, nc_dict
def make_ig_ggn_syn(ig, params, sec): # This is ugly but only once global model_dict ig_syn = h.Exp2Syn(sec(0.5)) ig_syn.tau1 = cfg.Q_(params['tau1']).to('ms').m ig_syn.tau2 = cfg.Q_(params['tau2']).to('ms').m ig_syn.e = cfg.Q_(params['e']).to('mV').m ig_nc = h.NetCon(ig.izhi._ref_V, ig_syn, cfg.Q_(params['threshold']).to('mV').m, cfg.Q_(params['delay']).to('ms').m, cfg.Q_(params['gmax']).to('uS').m, sec=ig.sec) model_dict['ig_ggn_syn'] = ig_syn model_dict['ig_ggn_nc'] = ig_nc cfg.logger.info('Completed creation of synapse from IG to GGN') cfg.logger.info('tau1: {}, tau2: {}, e: {}, thresh: {}, delay: {}, gmax: {}'.format(ig_syn.tau1, ig_syn.tau2, ig_syn.e, ig_nc.threshold, ig_nc.delay, ig_nc.weight[0]))
def run_model(args): """setup and run a model with templates and other parameters specified in args (parsed arguments). List of arguments: template_filename: HDF5 file containing the network template and PN spike trains. These data should be at paths in constants specified at the top of this file. output_directory: directory to dump simulated data into. pn_shift: shift the assignment of spike trains to PNs by this amount, i.e., if pn_shift is 2, then the spike train of pn_0 is assigned to pn_2, and pn_{i+2} gets the spike train of pn_{i}, with wrapping around the edge. pn_dither: The maximum magnitude of time shift when dithering the PN spike times. n_kc_vm: number of KCs to record Vm from n_ggn_vm: number of GGN sections to record Vm from for each of basal, calyceal and alpha lobe regions. recstep: number of integration steps between each recording point. simtime: total simulation time """ global model_dict output_filename = os.path.join(args.output_directory, 'fixed_net_UTC{}-PID{}-JID{}.h5'.format( cfg.timestamp.strftime('%Y_%m_%d__%H_%M_%S'), cfg.mypid, cfg.myjobid)) ggn = create_ggn() ggn_name_sec_dict = {sec.name(): sec for sec in ggn.all} with h5.File(args.template_filename, 'r') as template_fd: config = yaml.load(template_fd.attrs['config'].decode()) pn_spikes = load_pn_spikes(template_fd) pns, spike_trains = zip(*pn_spikes) spike_trains = dither_spiketrain(spike_trains, cell_shift=args.pn_shift, dither=args.pn_dither) pn_spike_vecs, vecstims = create_pn_output(spike_trains) kcs = create_kcs(template_fd, config=config['kc']) if args.test_kc >= 0: delay = cfg.Q_(config['stimulus']['onset']) if 'delay' in config['pn_kc_syn']: delay += cfg.Q_(config['pn_kc_syn']['delay']) duration = cfg.Q_(config['stimulus']['duration']) amplitude = cfg.Q_(args.kc_current) iclamp = ephys.setup_current_clamp(kcs[args.test_kc].soma, delay=delay, duration=duration, amplitude=amplitude) # test_kc_vvec = ephys.setup_sec_rec(kcs[args.test_kc].soma, 'v')[0] # this is added in setup recording model_dict['kc_iclamp'] = iclamp model_dict['test_kc'] = kcs[args.test_kc] kc_name_sec_dict = {kc.soma.name(): kc.soma for kc in kcs} nc_pn_kc, syn_pn_kc = create_pn_kc_conn(template_fd, dict(zip(pns, vecstims)), kc_name_sec_dict, config=config['pn_kc_syn']) syn_ggn_kc = create_ggn_kc_conn(template_fd, kc_name_sec_dict, ggn_name_sec_dict, config=config['ggn_kc_syn']) syn_kc_ggn, nc_kc_ggn = create_kc_ggn_conn(template_fd, kc_name_sec_dict, ggn_name_sec_dict, config=config['kc_ggn_alphaL_syn']) setup_ig(template_fd, ggn_name_sec_dict, config=config) data = setup_recording(kcs, ggn, n_kc_vm=args.n_kc_vm, n_ggn_vm=args.n_ggn_vm, t=h.dt * args.recstep) h.tstop = args.simtime start = datetime.utcnow() h.init() for v in pn_spike_vecs: if np.any(np.array(v.x) <= 0): print('negative pn spike time', v) cfg.logger.info('Finished init. Starting simulation of {} ms'.format( h.tstop)) if h.tstop > 0: nu.block_run(logger=cfg.logger) else: cfg.logger.info('Dry run. Skipping simulation') end = datetime.utcnow() delta = end - start data['tstart'] = start data['tend'] = end data['pn_spikes'] = dict(zip(pns, spike_trains)) cfg.logger.info('Finished running simulation in {} s'.format( delta.days * 86400 + delta.seconds + delta.microseconds * 1e-6)) cfg.logger.info('Starting data save in {}'.format(output_filename)) ig_vm = model_dict.get('ig_vm', None) data['ig_vm'] = ig_vm save(args.template_filename, output_filename, data, model_dict, args.savesyn, config) cfg.logger.info('Finished')