#!/usr/bin/env python
# coding: utf-8
# In[1]:
#Lets load some packages
from netpyne import sim, specs
#!pip install matplotlib==3.4.2 --user
import matplotlib
get_ipython().run_line_magic('matplotlib', 'inline')
from neuron import gui #this line is absolutely necessary if importing cells from hoc templates
from neuron import h
#from neuron.units import um, mV, ms, cm
import math as math #for the sin function
import numpy as np
from numpy import random, exp, sqrt, log, pi
from random import shuffle, sample
h.load_file("stdrun.hoc")
#Lets load in Guillem's parameters for the neurons
N=1 #Params for 100 Neurons
params = np.loadtxt("neurons/params.dat"); # Parameters: EL, Rin and tauv, gNaf, rat (=gKf/gNaf), thm1, thh2, thn1, and gkv7f, tha1
ELs, Rins, tauvs, gNafs, rats, thm1s, thh2s, thn1s, gkv7fs, tha1s = params[:,:N];
Caps = tauvs/Rins
#To get a length from net capacitence
#most literature assumes neurons have 1uf/cm^2
#this capacitence is in nF
SA=Caps*1e-3
#neuron does length in um so lets make it um^2
SAum=SA*100000000
#we're going to assume a diameter of 20um to get a radius of 10um
#SA of a cyclinder(not including ends)=2*pi*r*L
lengths=SAum/(20*pi)
# Active conductances
# Heterogeneous peak conductances for active currents. Above are loaded normalized to Golomb values times capacitance
#this gave me nanosiemens I need siemens/cm^2 for it's conductance, so I need to multiple by e-9 to get nanosiemens then
#divide by the surface area in cm^2
gNas=np.array(gNafs)*112.5e+3*Caps*1e-9/SA
gKv3s=np.array(gNafs)*np.array(rats)*225.e+3*Caps*1e-9/SA
gkv7s=np.array(gkv7fs)*225.e+3*Caps*1e-9/SA
#Leak conductance is inverse of input resistance
gLs=1/Rins
#But that's in Mega Ohms and I need siemens
gLs=gLs*1e-6
#And I need it per cm^2
gLs=gLs/SA
# Network parameters
netParams = specs.NetParams() # object of class NetParams to store the network parameters
netParams.stimSourceParams['iclamp'] = {'type': 'IClamp', 'amp': 0.0, 'dur': 2.0e3, 'delay': 0}
#I'm not happy with how I'm doing this, I don't think its the best way
#Normally I'd be able to make a cell type in cellParams and then make a population of that cell type with popParams
#But that's difficult to do in netpyne with trying to make them have different conductances and such
#For now it's making each individual cell a population
#there should be a way to fix this with cell lists, but the documentation on that's a little too limited for me to figure it out
for i in range(N):
soma = {'geom': {}, 'mechs': {}} # soma properties
soma['geom'] = {'diam': 20, 'L': lengths[i], 'cm': 1}
soma['mechs']['pas'] = {'g': gLs[i], 'e': ELs[i]}
leak_conduct=gLs[i]
soma['mechs']['naG'] = {'gbar': gNas[i], 'thm1': thm1s[i], 'thh2':thh2s[i] }
soma['mechs']['kv7'] = {'gbar': gkv7s[i], 'tha1': tha1s[i] }
soma['mechs']['kv3'] = {'gbar': gKv3s[i], 'thn1': thn1s[i] }
soma['threshold'] = -10.0
FS_dict = {'secs': {'soma': soma}}
netParams.cellParams['FS'+str(i)] = FS_dict # add rule dict to list of cell property rules
netParams.stimTargetParams['iclamp->FS'+str(i)] = {'source': 'iclamp', 'conds': {'pop': 'FS'+str(i)}, 'sec': 'soma', 'loc': 0.5}
# In[2]:
dt = 0.01
# square pulse with 'IPSP' ramp
delay = 100.0
max_amplitude = 0.375 #0.41 #
reduction = 0.266 # between 0 and 1
recovery = 200 # ramp duration
pre_duration = 1000.0
post_duration = 2000.0
min_amplitude = 0
backbaseline_duration = 0
print('stim delay = ' + str(delay) + ' ms')
print('stim max amplitude = ' + str(max_amplitude) + ' nA')
print('stim reduction = ' + str(reduction))
print('stim recovery ramp = ' + str(recovery) + ' ms')
print('stim pre_duration = ' + str(pre_duration) + ' ms')
print('stim post_duration = ' + str(post_duration) + ' ms')
stim_amplitude = []
baseline_bins = int(delay / dt + 0.5)
for i in range(baseline_bins):
stim_amplitude.append(0.0)
pre_duration_bins = int(pre_duration / dt + 0.5)
for i in range(pre_duration_bins):
stim_amplitude.append(max_amplitude)
ipsp_duration_bins = int(recovery / dt + 0.5)
for i in range(ipsp_duration_bins):
rel_duration = 1.0 * i / ipsp_duration_bins
tmp_amplitude = (1 - reduction) * max_amplitude + rel_duration * reduction * max_amplitude
stim_amplitude.append(tmp_amplitude)
post_duration_bins = int(post_duration / dt + 0.5)
for i in range(post_duration_bins):
stim_amplitude.append(max_amplitude)
backbaseline_duration_bins = int(backbaseline_duration / dt + 0.5)
for i in range(backbaseline_duration_bins):
stim_amplitude.append(0.0)
stim_vec = h.Vector(stim_amplitude)
t_vec_stim = h.Vector([i * dt for i in range(len(stim_vec))])
noise_mean, noise_std_dev = 0, 0.1*(0.41)
tvec = h.Vector(np.linspace(0.0, 3300, int(3300/0.01)))
noise_current = np.random.normal(noise_mean, noise_std_dev, len(tvec))
noise_current_vector = h.Vector()
noise_current_vector.from_python(noise_current)
# In[3]:
for i in range(N):
netParams.popParams['CurrentClamp_pop'] = {'cellModel': 'FS'+str(i), 'cellType': 'FS'+str(i), 'numCells': 1}
netParams.stimSourceParams['iclamp'] = {'type': 'IClamp', 'dur': 1e9, 'del':0}
netParams.stimTargetParams['iclamp->CurrentClamp_pop'] = {
'source': 'iclamp',
'sec': 'soma',
'loc': 0.5,
'conds': {'pop':'CurrentClamp_pop'}}
netParams.stimSourceParams['iclamp2'] = {'type': 'IClamp', 'dur': 1e9, 'del':0}
netParams.stimTargetParams['iclamp2->CurrentClamp_pop'] = {
'source': 'iclamp2',
'sec': 'soma',
'loc': 0.5,
'conds': {'pop':'CurrentClamp_pop'}}
simConfig = specs.SimConfig() # object of class SimConfig to store simulation configuration
simConfig.duration = 3300
simConfig.dt = 0.01
simConfig.recordStep = 0.01
simConfig.verbose = False
simConfig.recordTraces = {'V_soma':{'sec':'soma','loc':0.5,'var':'v'},
'a_soma':{'sec':'soma','loc':0.5,'var':'a','mech':'kv7'},
'm_soma':{'sec':'soma','loc':0.5,'var':'m','mech':'naG'},
'h_soma':{'sec':'soma','loc':0.5,'var':'h','mech':'naG'},
'n_soma':{'sec':'soma','loc':0.5,'var':'n','mech':'kv3'}}
simConfig.analysis['plotTraces'] = {'include':['all'],'saveFig': "interrupt/cell"+str(i)+".png"}#,'timeRange':[1100,1700]
sim.create(netParams=netParams, simConfig=simConfig)
for cell in sim.net.cells:
stim_vec.play(cell.stims[0]['hObj']._ref_amp, t_vec_stim, True)
#noise_current_vector.play(cell.stims[1]['hObj']._ref_amp, tvec, True)
sim.simulate()
sim.analyze()
# In[4]:
import pandas as pd
n=sim.allSimData['a_soma']['cell_0']
v=sim.allSimData['V_soma']['cell_0']
df = pd.DataFrame({'n':n, 'v':v}) #, 'n2':n2})
df.to_csv('nandvno_noise.csv')
df2 = pd.DataFrame({'i':stim_amplitude,'noise':noise_current,'t':(i * dt for i in range(len(stim_vec)))})
df2.to_csv("current_nonoise.csv")
df3 = pd.DataFrame({'i':stim_amplitude,'t':(i * dt for i in range(len(stim_vec)))})
df3.to_csv("current.csv")
#df3 = pd.DataFrame({'i':noise_current_vector,'t':(i * dt for i in range(len(noise_current_vector)))})
#df3.to_csv("currentnoise.csv")
# In[ ]: