copying to personal repo

This commit is contained in:
Alan
2022-06-19 13:45:53 -05:00
commit bf2ffa7315
287 changed files with 54032 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

1
project/__init__.py Normal file
View File

@@ -0,0 +1 @@
from network_pauser_prototype import NetworkSimulation

167
project/graphs.py Normal file
View File

@@ -0,0 +1,167 @@
"""
These are the graphs that can be used to present certain graphs through the pyqtgraph window
"""
import pyqtgraph as pg
import numpy as np
import cnmodel.util.pynrnutilities as PU
def stimulus_graph(win, stim, row, col):
"""
Presents a graph of
win: pg.GraphicsWindow()
stim:(list) dummy sgc stim results
"""
p1 = win.addPlot(
title="Stimulus", row=row, col=col, labels={"bottom": "T (ms)", "left": "V"}
)
data = zip(stim.time, stim.sound)
time = []
stim = []
for x, y in data:
if 0.1 < x < 0.25:
time.append(x * 1000)
stim.append(y)
p1.plot(time, stim, pen=pg.mkPen("k", width=0.75))
return p1
def an_spike_graph(win, pre_cells, row, col):
"""
Displays the spikes over time as lines with each cell representing a single row a single trial presentation
:param win: pg.GraphicsWindow()
:param pre_cells: (list) spike train time values
:return: exists to allow for further modifications on the pg.GraphicsWindow object
"""
p2 = win.addPlot(
title="AN spikes",
row=row,
col=col,
labels={"bottom": "T (ms)", "left": "AN spikes (first trial)"},
)
xan = []
yan = []
for k in range(len(pre_cells[0])):
r = pre_cells[0][k]
xan.extend(r)
yr = k + np.zeros_like(r) + 0.2
yan.extend(yr)
c = pg.PlotCurveItem()
xp = np.repeat(np.array(xan), 2)
yp = np.repeat(np.array(yan), 2)
yp[1::2] = yp[::2] + 0.6
c.setData(
xp.flatten(),
yp.flatten(),
connect="pairs",
width=1.0,
pen=pg.mkPen("k", width=1.5),
)
p2.addItem(c)
return p2
def spike_graph(win, time, vms, row, col, title="cell"):
"""
Displays the spikes over time as lines with each cell representing a single row a single trial presentation
:param win: pg.GraphicsWindow()
:param time: (list) of time that lines up with Vms
:param vms: voltage trace data as a list
:return: exists to allow for further modifications on the pg.GraphicsWindow object
"""
p3 = win.addPlot(
title=f"{title} Spikes",
row=row,
col=col,
labels={"bottom": "T (ms)", "left": "Trial #"},
)
xcn = []
ycn = []
for k in range(len(time)):
bspk = PU.findspikes(time[k], vms[k], -35.0)
xcn.extend(bspk)
yr = k + np.zeros_like(bspk) + 0.2
ycn.extend(yr)
d = pg.PlotCurveItem()
xp = np.repeat(np.array(xcn), 2)
yp = np.repeat(np.array(ycn), 2)
yp[1::2] = yp[::2] + 0.6
d.setData(xp.flatten(), yp.flatten(), connect="pairs", pen=pg.mkPen("k", width=1.5))
p3.addItem(d)
return p3
def voltage_graph(win, time, vms, row, col):
"""
Actually displays the voltage trace
:param win: pg.GraphicsWindow()
:param time: (list) of time that lines up with Vms
:param vms: voltage trace data as a list
:return: exists to allow for further modifications on the pg.GraphicsWindow object
"""
p4 = win.addPlot(
title="Pyramidal Vm",
row=row,
col=col,
labels={"bottom": "T (ms)", "left": "Vm (mV)"},
)
nrep = len(time)
if nrep > 3:
display = 3
else:
display = nrep
for nr in range(display):
p4.plot(
time[nr], vms[nr], pen=pg.mkPen(pg.intColor(nr, nrep), hues=nrep, width=1.0)
)
return p4
def an_psth_graph(win, pre_cells, row, col):
p6 = win.addPlot(
title="AN PSTH",
row=row,
col=col,
labels={"bottom": "T (ms)", "left": "Sp/ms/trial"},
)
bins = np.arange(100, 250, 1)
all_xan = []
for x in range(len(pre_cells)):
for y in range(len(pre_cells[x])):
all_xan.extend(pre_cells[x][y])
(hist, binedges) = np.histogram(all_xan, bins)
curve6 = p6.plot(
binedges,
hist,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
return p6
def cell_psth_graph(win, time, vms, row, col, title="cell"):
p7 = win.addPlot(
title=f"{title} PSTH",
row=row,
col=col,
labels={"bottom": "T (ms)", "left": "Sp/ms/trial"},
)
spike_times = []
for k in range(len(time)):
bspk = PU.findspikes(time[k], vms[k], -35.0)
spike_times.extend(bspk)
bins = np.arange(100, 250, 0.1)
(hist, binedges) = np.histogram(spike_times, bins)
curve7 = p7.plot(
binedges,
hist,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
return p7

View File

@@ -0,0 +1,160 @@
from multiprocessing import Pool
from random import randint
from neuron import h
from cnmodel import cells
def run(run_input, processes):
results = []
if processes == 1:
for r_input in run_input:
results.append(_run_trial(r_input))
else:
p = Pool(processes)
for res in p.imap_unordered(_run_trial, run_input):
results.append(res)
return results
def add_pyramidal_cell():
pyramidal = cells.Pyramidal.create(species="rat")
pyramidal.add_dendrites()
apical = pyramidal.maindend[0]
basal = pyramidal.maindend[1]
return pyramidal
def add_tuberculoventral_cell():
tuberculoventral_1 = cells.Tuberculoventral.create()
tuberculoventral_2 = cells.Tuberculoventral.create()
return tuberculoventral_1, tuberculoventral_2
def add_dstellate_cell():
dstel1ate = cells.DStellateEager.create()
return dstel1ate
def add_cartwheel_cell():
cartwheel = cells.Cartwheel.create()
return cartwheel
def _run_trial(run_input):
seed, info, run_number = run_input
"""
info is a dict
"""
pyramidal = add_pyramidal_cell()
tuberculoventral_1, tuberculoventral_2 = add_tuberculoventral_cell()
dstellate = add_dstellate_cell()
cartwheel = add_cartwheel_cell()
auditory_nerve_cells = []
synapses = []
inhib_synapses = []
# auditory nerve attachments
# attach to pyramidal cell
for nsgc in range(48):
auditory_nerve_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(auditory_nerve_cells[-1].connect(pyramidal, type="multisite"))
auditory_nerve_cells[-1].set_sound_stim(
info["stim"],
seed=seed + nsgc + randint(0, 80000),
simulator=info["simulator"],
)
# attach to tuberculoventral 1
for nsgc in range(18):
# attach to tb cell
auditory_nerve_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(auditory_nerve_cells[-1].connect(tuberculoventral_1, type=info["synapse_type"]))
auditory_nerve_cells[-1].set_sound_stim(
info["stim"],
seed=seed + nsgc + randint(0, 80000),
simulator=info["simulator"],
)
# attach to tuberculoventral 2
for nsgc in range(18):
# attach to tb cell
auditory_nerve_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(auditory_nerve_cells[-1].connect(tuberculoventral_2, type="multisite"))
auditory_nerve_cells[-1].set_sound_stim(
info["stim"],
seed=seed + nsgc + randint(0, 80000),
simulator=info["simulator"],
)
for nsgc in range(24):
# attach to dstellate cell
auditory_nerve_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(auditory_nerve_cells[-1].connect(dstellate, type="multisite"))
auditory_nerve_cells[-1].set_sound_stim(
info["stim"],
seed=seed + nsgc + randint(0, 80000),
simulator=info["simulator"],
)
# Connections between network cells
for _ in range(5):
inhib_synapses.append(cartwheel.connect(pyramidal, type='simple'))
for _ in range(21):
inhib_synapses.append(tuberculoventral_1.connect(pyramidal, type="simple"))
inhib_synapses.append(tuberculoventral_2.connect(pyramidal, type="simple"))
for _ in range(15):
inhib_synapses.append(dstellate.connect(pyramidal, type="simple"))
inhib_synapses.append(dstellate.connect(tuberculoventral_1, type='simple'))
inhib_synapses.append(dstellate.connect(tuberculoventral_2, type='simple'))
for _ in range(3):
inhib_synapses.append(dstellate.connect(dstellate, type="simple"))
stim = insert_current_clamp(cartwheel.soma)
# set up our recording vectors for each cell
Vm = h.Vector()
Vm.record(pyramidal.soma(0.5)._ref_v)
Vmtb = h.Vector()
Vmtb.record(tuberculoventral_1.soma(0.5)._ref_v)
Vmds = h.Vector()
Vmds.record(dstellate.soma(0.5)._ref_v)
Vmcar = h.Vector()
Vmcar.record(cartwheel.soma(0.5)._ref_v)
rtime = h.Vector()
rtime.record(h._ref_t)
# initialize
init_cells([pyramidal, cartwheel, tuberculoventral_1, tuberculoventral_2, dstellate])
info["init"]()
# hoc trial run
h.tstop = 1e3 * info["run_duration"] # duration of a run
h.celsius = info["temp"]
h.dt = info["dt"]
h.t = 0.0
h.run()
# dtime = time.time() - start
# print(f"Trial {run_number} completed after {dtime} secs")
return {
"time": list(rtime),
"vm": list(Vm),
"auditory_nerve_cells": [x._spiketrain.tolist() for x in auditory_nerve_cells],
"vmtb": list(Vmtb),
"vmds": list(Vmds),
"vmcar": list(Vmcar),
}
def insert_current_clamp(sec):
"""
:param sec: to attach too
dur: ms
amp: nA
delay: ms
:return: stim needs to be put in a variable to stay alive
"""
stim = h.IClamp(0.5, sec=sec)
stim.dur = 1
stim.amp = 0.5
stim.delay = 100
return stim
def init_cells(cells: list):
for x in cells:
x.cell_initialize()

View File

@@ -0,0 +1,150 @@
from multiprocessing import Pool
from random import randint
from cnmodel import cells
from neuron import h
from tqdm import tqdm
def run(run_input, processes):
results = []
if processes == 1:
for input in run_input:
results.append(_run_trial(input))
else:
p = Pool(processes)
for res in tqdm(p.imap_unordered(_run_trial, run_input)):
results.append(res)
return results
def add_pyramidal_cell():
pyramidal = cells.Pyramidal.create(species="rat")
pyramidal.add_dendrites()
apical_dend = pyramidal.maindend[0]
basal_dend = pyramidal.maindend[1]
return pyramidal
def add_tuberculoventral_cell():
tuberculoventral_1 = cells.Tuberculoventral.create()
tuberculoventral_2 = cells.Tuberculoventral.create()
return tuberculoventral_1, tuberculoventral_2
def add_dstellate_cell():
dstel1ate = cells.DStellateEager.create()
return dstel1ate
def _run_trial(run_input):
seed, info, run_number = run_input
"""
info is a dict
"""
pyramidal = add_pyramidal_cell()
tuberculoventral_1, tuberculoventral_2 = add_tuberculoventral_cell()
dstellate = add_dstellate_cell()
auditory_nerve_cells = []
synapses = []
inhib_synapses = []
# auditory nerve attachments
# attach to pyramidal cell
for nsgc in range(48):
auditory_nerve_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(auditory_nerve_cells[-1].connect(pyramidal, type="multisite"))
auditory_nerve_cells[-1].set_sound_stim(
info["stim"],
seed=seed + nsgc + randint(0, 80000),
simulator=info["simulator"],
)
# attach to tuberculoventral 1
for nsgc in range(18):
# attach to tb cell
auditory_nerve_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(auditory_nerve_cells[-1].connect(tuberculoventral_1, type=info["synapse_type"]))
auditory_nerve_cells[-1].set_sound_stim(
info["stim"],
seed=seed + nsgc + randint(0, 80000),
simulator=info["simulator"],
)
# attach to tuberculoventral 2
for nsgc in range(18):
# attach to tb cell
auditory_nerve_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(auditory_nerve_cells[-1].connect(tuberculoventral_2, type="multisite"))
auditory_nerve_cells[-1].set_sound_stim(
info["stim"],
seed=seed + nsgc + randint(0, 80000),
simulator=info["simulator"],
)
for nsgc in range(24):
# attach to dstellate cell
auditory_nerve_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(auditory_nerve_cells[-1].connect(dstellate, type="multisite"))
auditory_nerve_cells[-1].set_sound_stim(
info["stim"],
seed=seed + nsgc + randint(0, 80000),
simulator=info["simulator"],
)
# Connections between network cells
# for _ in range(5):
# inhib_synapses.append(cartwheel.connect(pyramidal, type="simple"))
for _ in range(21):
inhib_synapses.append(tuberculoventral_1.connect(pyramidal, type="simple"))
inhib_synapses.append(tuberculoventral_2.connect(pyramidal, type="simple"))
for _ in range(15):
inhib_synapses.append(dstellate.connect(pyramidal, type="simple"))
inhib_synapses.append(dstellate.connect(tuberculoventral_1, type='simple'))
inhib_synapses.append(dstellate.connect(tuberculoventral_2, type='simple'))
for _ in range(3):
inhib_synapses.append(dstellate.connect(dstellate, type="simple"))
stim = insert_current_clamp(pyramidal.soma)
# set up our recording vectors for each cell
Vm = h.Vector()
Vm.record(pyramidal.soma(0.5)._ref_v)
Vmtb = h.Vector()
Vmtb.record(tuberculoventral_1.soma(0.5)._ref_v)
Vmds = h.Vector()
Vmds.record(dstellate.soma(0.5)._ref_v)
rtime = h.Vector()
rtime.record(h._ref_t)
# hoc trial run
h.tstop = 1e3 * info["run_duration"] # duration of a run
h.celsius = info["temp"]
h.dt = info["dt"]
init_cells([pyramidal, tuberculoventral_1, tuberculoventral_2, dstellate])
info["init"]()
h.t = 0.0
h.run()
# dtime = time.time() - start
# print(f"Trial {run_number} completed after {dtime} secs")
return {
"time": list(rtime),
"vm": list(Vm),
"auditory_nerve_cells": [x._spiketrain.tolist() for x in auditory_nerve_cells],
"vmtb": list(Vmtb),
"vmds": list(Vmds),
}
def insert_current_clamp(sec):
"""
:param sec: to attach too
dur: ms
amp: nA
delay: ms
:return: stim needs to be put in a variable to stay alive
"""
stim = h.IClamp(0.5, sec=sec)
stim.dur = 30
stim.amp = -0.2
stim.delay = 120
return stim
def init_cells(cell: list):
for x in cell:
x.cell_initialize()

View File

@@ -0,0 +1,311 @@
"""
Layout:
if __name__==__main__ handles cmd args, instantiates test, runs it, displays results
run_trial(): defines a model and then runs the test using preset params in hoc and return the info to the class
SGCInputTest:
__init__ : defines many static variables
run(): calls delivers information to the run_trial() function and the recieved information of a single run
back and stores it as an extensible list in the class
show(): displays graphs depending on the graph options selected below it and displayed in a printout
"""
import argparse
import json
import os
import sys
import time
from random import randint
import gooey
from cnmodel.protocols import Protocol
from cnmodel.util import custom_init
from cnmodel.util import sound
from graphs import *
from hoc_trial_run_cartwheel import run
class NetworkSimulation(Protocol):
"""
Tests a Single cell with input recieved from the SGC
__init__: almost all parameters can be modified
run(): simply loops over the run_trial() function and stores the results just
show(): constructs the graphs using other functions
"""
def __init__(
self,
temp=34.0,
seed=randint(2500, 400000),
nrep=10,
stimulus="tone",
simulator="cochlea",
debug=True,
dt=0.025
):
"""
:param temp: (float) must be at 34 for default pyramidal cells
:param dt: (float) determine hoc resolution
:param seed: (int) contributes to randomization, needs to be changed to see different results (reduce this
number if you keep getting a timeout error
:param nrep: (int) number of presentations !!must be changed in the __name__ function if not calling from cmd line!!
:param stimulus: (str) must be 'tone'
:param simulator: (str) currently using cochlea instead of matlab
:param n_sgc:(int) This is the number of SGC fibers that connect to the post synaptic cell
:param debug: (bool) controls most of the terminal printouts is on by default
:param cell: (str) cell type !!must be changed in the __name__ function if not calling from cmd line!!
"""
super().__init__()
#
self.debug = debug
self.nrep = nrep
self.stimulus = stimulus
self.run_duration = 0.3 # in seconds
# stim parameters
self.pip_duration = 0.05 # in seconds
self.pip_start = [0.14] # in seconds
self.Fs = 100e3 # in Hz
self.f0 = 14013.0 # stimulus in Hz
self.cf = 14013.0 # SGCs in Hz
self.fMod = 100.0 # mod freq, Hz
self.dMod = 0.0 # % mod depth, Hz
self.dbspl = 55.0
# usually cochlea
self.simulator = simulator
self.sr = 2 # set SR group
self.seed = seed
# physiological parameters
self.temp = temp
self.dt = dt
self.synapse_type = "multisite"
self.species = "rat"
if self.stimulus == "tone":
self.stim = sound.TonePip(
rate=self.Fs,
duration=self.run_duration,
f0=self.f0,
dbspl=self.dbspl,
ramp_duration=5e-3,
pip_duration=self.pip_duration,
pip_start=self.pip_start,
)
# result containers
self.vms = []
self.vmtbs = []
self.vmdss = []
self.vmcar = []
self.synapses = []
self.auditory_nerve_cells = []
self.time = []
# debug function reports a print out of various information about the run
if self.debug:
print("Small Network Test Created")
print("#" * 70)
print(f"Running Test of Network with Simulated SGC fibers")
print()
print(f"Run Conditions: Run Time: {self.run_duration}s,")
print(f" Run Temp: {self.temp} ")
print(f" Number of Presentations: {nrep}")
print()
print(f"Stimulus Conditions: Type: {stimulus}")
print(f" Stim Duration: {self.pip_duration}s")
print(f" Characteristic F: {self.cf}hz")
print(f" Stim Start:{str(self.pip_start)}s")
def run(self, processes=1, **kwargs):
"""
Runs the trials with the number of nreps set for the trial, calls a multiprocess run of however many trials
are needed.
If processes set to one then the it will run without the multiprocessing library(more reliable)
"""
super().run()
info = {
"stim": self.stim,
"simulator": self.simulator,
"cf": self.cf,
"sr": self.sr,
"run_duration": self.run_duration,
"synapse_type": self.synapse_type,
"temp": self.temp,
"dt": self.dt,
"init": custom_init,
}
# Generate inputs
b = [(self.seed + randint(0, 80000)) for _ in range(self.nrep)]
c = [info for _ in range(self.nrep)]
d = range(1, self.nrep+1)
run_input = zip(b, c, d)
self.all_results = run(run_input, processes=processes)
self.unpack_data(self.all_results)
def unpack_data(self, run_data):
len_of_data = 0
for nr, res in enumerate(run_data):
try:
len_of_data += 1
# res contains: {'time': time, 'vm': list(Vm), 'auditory_nerve_cells': auditory_nerve_cells._spiketrain,'vmtb': list(Vmtb)}
self.auditory_nerve_cells.append(res["auditory_nerve_cells"])
self.time.append(res["time"])
self.vms.append(res["vm"])
self.vmtbs.append(res["vmtb"])
self.vmdss.append(res["vmds"])
self.vmcar.append(res["vmcar"])
except(KeyError):
continue
self.nrep = len_of_data
def show(self):
"""
Creates a single page graph that contains all of the graphs based on the graphical functions in the class
"""
self.win = pg.GraphicsWindow()
self.win.setBackground("w")
p2 = an_spike_graph(self.win, self.auditory_nerve_cells, 0, 0)
p3 = spike_graph(self.win, self.time, self.vms, 1, 0, title="Pyramidal")
p5 = spike_graph(
self.win, self.time, self.vmtbs, 2, 0, title="Tuberculoventral"
)
p6 = spike_graph(self.win, self.time, self.vmdss, 3, 0, title="D-Stellate")
p9 = spike_graph(self.win, self.time, self.vmcar, 4, 0, title="Cartwheel")
p1 = stimulus_graph(self.win, self.stim, 0, 1)
p4 = voltage_graph(self.win, self.time, self.vms, 1, 1)
p7 = an_psth_graph(
self.win, self.auditory_nerve_cells, 2, 1
)
p8 = cell_psth_graph(
self.win, self.time, self.vms, 3, 1, title="Pyramidal"
)
# links x axis
p1.setXLink(p1)
p2.setXLink(p1)
p3.setXLink(p1)
p4.setXLink(p1)
p5.setXLink(p1)
p6.setXLink(p1)
p7.setXLink(p1)
p8.setXLink(p1)
p9.setXLink(p1)
self.win.show()
if self.debug:
print("finished")
def export(self):
if self.debug:
print("Exporting File Binary")
t = time.gmtime()
destination_name = f"{os.path.basename(__file__).strip('.py')}_{t.tm_mday}-{t.tm_mon}-{t.tm_year}_{t.tm_hour}_{t.tm_min}.json"
os.scandir()
dirname = os.path.join(os.path.dirname(__file__), "run_data")
if not os.path.isdir(dirname):
os.mkdir(dirname)
filepath = os.path.join(dirname, destination_name)
with open(filepath, "w") as f:
json.dump(self.all_results, f)
if self.debug:
print(f"Run saved to {filepath}")
def load(self, load_file=None):
with open(load_file, "r") as file_in:
data_list = json.load(file_in)
self.unpack_data(data_list)
@gooey.Gooey
def interface():
parser = argparse.ArgumentParser(
description="Compute Neuron response for small network of DCN"
)
# parser.add_argument(type=str, dest='cell', default='pyramidal',
# choices=['bushy', 'tstellate', 'dstellate', 'octopus',
# 'tuberculoventral', 'pyramidal'],
# help='Select target cell')
parser.add_argument(
"-n",
"--nrep",
type=int,
dest="nrep",
default=4,
help="Set number of repetitions",
)
parser.add_argument(
"-l",
"--load",
type=str,
dest="load_file",
default=None,
help="Load data from a previous run json",
)
parser.add_argument(
"-s",
"--save",
type=str,
dest="save_flag",
default=True,
help="If you do not want to export file set flag to False",
)
parser.add_argument(
"-d",
"--debug",
type=str,
dest="debug_flag",
default=True,
help="If you do not want to see debug text or GUI set to False",
)
parser.add_argument(
"-p",
"--process",
type=int,
dest="processes",
default=1,
help="Set the number of processes that the run will be run across",
)
args = parser.parse_args()
start = time.time()
nrep = args.nrep
processes = args.processes
load_file = args.load_file
# manages how options affect the class that is created to manage the trial run
if args.save_flag == "False":
save = False
else:
save = True
if args.debug_flag == "False":
debug_flag = False
else:
debug_flag = True
if load_file:
if os.path.exists(load_file):
test = NetworkSimulation(nrep=nrep, debug=False)
test.load(load_file)
test.show()
else:
raise FileNotFoundError(f"{load_file} does not exist")
else:
test = NetworkSimulation(nrep=nrep, debug=debug_flag)
test.run(processes=processes)
if debug_flag:
test.show()
if save:
test.export()
dtime = time.time() - start
print("#" * 70)
print(f"Total Elapsed Time {dtime/60} mins")
if sys.flags.interactive == 0:
pg.QtGui.QApplication.exec_()
if __name__ == "__main__":
interface()

View File

@@ -0,0 +1,298 @@
"""
Layout:
if __name__==__main__ handles cmd args, instantiates test, runs it, displays results
run_trial(): defines a model and then runs the test using preset params in hoc and return the info to the class
SGCInputTest:
__init__ : defines many static variables
run(): calls delivers information to the run_trial() function and the recieved information of a single run
back and stores it as an extensible list in the class
show(): displays graphs depending on the graph options selected below it and displayed in a printout
"""
import os
import argparse
import time
import json
import sys
from random import randint
from cnmodel.protocols import Protocol
from cnmodel.util import sound
from cnmodel.util import custom_init
from graphs import *
from hoc_trial_run_dendrites import run
class NetworkSimulation(Protocol):
"""
Tests a Single cell with input recieved from the SGC
__init__: almost all parameters can be modified
run(): simply loops over the run_trial() function and stores the results just
show(): constructs the graphs using other functions
"""
def __init__(
self,
temp=34.0,
seed=randint(2500, 400000),
nrep=10,
stimulus="tone",
simulator="cochlea",
debug=True,
dt=0.025
):
"""
:param temp: (float) must be at 34 for default pyramidal cells
:param dt: (float) determine hoc resolution
:param seed: (int) contributes to randomization, needs to be changed to see different results (reduce this
number if you keep getting a timeout error
:param nrep: (int) number of presentations !!must be changed in the __name__ function if not calling from cmd line!!
:param stimulus: (str) must be 'tone'
:param simulator: (str) currently using cochlea instead of matlab
:param n_sgc:(int) This is the number of SGC fibers that connect to the post synaptic cell
:param debug: (bool) controls most of the terminal printouts is on by default
:param cell: (str) cell type !!must be changed in the __name__ function if not calling from cmd line!!
"""
super().__init__()
#
self.debug = debug
self.nrep = nrep
self.stimulus = stimulus
self.run_duration = 0.3 # in seconds
# stim parameters
self.pip_duration = 0.05 # in seconds
self.pip_start = [0.14] # in seconds
self.Fs = 100e3 # in Hz
self.f0 = 14013.0 # stimulus in Hz
self.cf = 14013.0 # SGCs in Hz
self.fMod = 100.0 # mod freq, Hz
self.dMod = 0.0 # % mod depth, Hz
self.dbspl = 55.0
# usually cochlea
self.simulator = simulator
self.sr = 2 # set SR group
self.seed = seed
# physiological parameters
self.temp = temp
self.dt = dt
self.synapse_type = "multisite"
self.species = "rat"
if self.stimulus == "tone":
self.stim = sound.TonePip(
rate=self.Fs,
duration=self.run_duration,
f0=self.f0,
dbspl=self.dbspl,
ramp_duration=5e-3,
pip_duration=self.pip_duration,
pip_start=self.pip_start,
)
# result containers
self.vms = []
self.vmtbs = []
self.vmdss = []
self.vmcar = []
self.synapses = []
self.auditory_nerve_cells = []
self.time = []
# debug function reports a print out of various information about the run
if self.debug:
print("Small Network Test Created")
print("#" * 70)
print(f"Running Test of Network with Simulated SGC fibers")
print()
print(f"Run Conditions: Run Time: {self.run_duration}s,")
print(f" Run Temp: {self.temp} ")
print(f" Number of Presentations: {nrep}")
print()
print(f"Stimulus Conditions: Type: {stimulus}")
print(f" Stim Duration: {self.pip_duration}s")
print(f" Characteristic F: {self.cf}hz")
print(f" Stim Start:{str(self.pip_start)}s")
def run(self, processes=1, **kwargs):
"""
Runs the trials with the number of nreps set for the trial, calls a multiprocess run of however many trials
are needed.
If processes set to one then the it will run without the multiprocessing library(more reliable)
"""
super().run()
info = {
"stim": self.stim,
"simulator": self.simulator,
"cf": self.cf,
"sr": self.sr,
"run_duration": self.run_duration,
"synapse_type": self.synapse_type,
"temp": self.temp,
"dt": self.dt,
"init": custom_init,
}
# Generate inputs
b = [(self.seed + randint(0, 80000)) for _ in range(self.nrep)]
c = [info for _ in range(self.nrep)]
d = range(1, self.nrep+1)
run_input = zip(b, c, d)
self.all_results = run(run_input, processes=processes)
self.unpack_data(self.all_results)
def unpack_data(self, run_data):
len_of_data = 0
for nr, res in enumerate(run_data):
try:
len_of_data += 1
# res contains: {'time': time, 'vm': list(Vm), 'auditory_nerve_cells': auditory_nerve_cells._spiketrain,'vmtb': list(Vmtb)}
self.auditory_nerve_cells.append(res["auditory_nerve_cells"])
self.time.append(res["time"])
self.vms.append(res["vm"])
self.vmtbs.append(res["vmtb"])
self.vmdss.append(res["vmds"])
self.vmcar.append(res["vmcar"])
except(KeyError):
continue
self.nrep = len_of_data
def show(self):
"""
Creates a single page graph that contains all of the graphs based on the graphical functions in the class
"""
self.win = pg.GraphicsWindow()
self.win.setBackground("w")
p2 = an_spike_graph(self.win, self.auditory_nerve_cells, 0, 0)
p3 = spike_graph(self.win, self.time, self.vms, 1, 0, title="Pyramidal")
p5 = spike_graph(
self.win, self.time, self.vmtbs, 2, 0, title="Tuberculoventral"
)
p6 = spike_graph(self.win, self.time, self.vmdss, 3, 0, title="D-Stellate")
p1 = stimulus_graph(self.win, self.stim, 0, 1)
p4 = voltage_graph(self.win, self.time, self.vms, 1, 1)
p7 = an_psth_graph(
self.win, self.auditory_nerve_cells, 2, 1
)
p8 = cell_psth_graph(
self.win, self.time, self.vms, 3, 1, title="Pyramidal"
)
# links x axis
p1.setXLink(p1)
p2.setXLink(p1)
p3.setXLink(p1)
p4.setXLink(p1)
p5.setXLink(p1)
p6.setXLink(p1)
p7.setXLink(p1)
p8.setXLink(p1)
self.win.show()
if self.debug:
print("finished")
def export(self):
if self.debug:
print("Exporting File Binary")
t = time.gmtime()
destination_name = f"{os.path.basename(__file__).strip('.py')}_{t.tm_mday}-{t.tm_mon}-{t.tm_year}_{t.tm_hour}_{t.tm_min}.json"
os.scandir()
dirname = os.path.join(os.path.dirname(__file__), "run_data")
if not os.path.isdir(dirname):
os.mkdir(dirname)
filepath = os.path.join(dirname, destination_name)
with open(filepath, "w") as f:
json.dump(self.all_results, f)
if self.debug:
print(f"Run saved to {filepath}")
def load(self, load_file=None):
with open(load_file, "r") as file_in:
data_list = json.load(file_in)
self.unpack_data(data_list)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Compute Neuron response for small network of DCN"
)
# parser.add_argument(type=str, dest='cell', default='pyramidal',
# choices=['bushy', 'tstellate', 'dstellate', 'octopus',
# 'tuberculoventral', 'pyramidal'],
# help='Select target cell')
parser.add_argument(
"-n",
"--nrep",
type=int,
dest="nrep",
default=4,
help="Set number of repetitions",
)
parser.add_argument(
"-l",
"--load",
type=str,
dest="load_file",
default=None,
help="Load data from a previous run pickle",
)
parser.add_argument(
"-s",
"--save",
type=str,
dest="save_flag",
default=True,
help="If you do not want to export file set flag to False",
)
parser.add_argument(
"-d",
"--debug",
type=str,
dest="debug_flag",
default=True,
help="If you do not want to see debug text or GUI set to False",
)
parser.add_argument(
"-p",
"--process",
type=int,
dest="processes",
default=1,
help="Set the number of processes that the run will be run across",
)
args = parser.parse_args()
start = time.time()
nrep = args.nrep
processes = args.processes
load_file = args.load_file
# manages how options affect the class that is created to manage the trial run
if args.save_flag == "False":
save = False
else:
save = True
if args.debug_flag == "False":
debug_flag = False
else:
debug_flag = True
if not load_file:
test = NetworkSimulation(nrep=nrep, debug=debug_flag)
test.run(processes=processes)
if debug_flag:
test.show()
if save:
test.export()
else:
if os.path.exists(load_file):
test = NetworkSimulation(nrep=nrep, debug=False)
test.load(load_file)
test.show()
else:
raise FileNotFoundError(f"{load_file} does not exist")
dtime = time.time() - start
print("#" * 70)
print(f"Total Elapsed Time {dtime/60} mins")
if sys.flags.interactive == 0:
pg.QtGui.QApplication.exec_()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
# coding: utf-8
# In[1]:
import os
import sys
import pyqtgraph as pg
import numpy as np
# In[7]:
dir_path = os.path.abspath("")
win = pg.GraphicsWindow()
win.setBackground("w")
p1 = win.addPlot(
title="Pauser PSTH",
row=0,
col=0,
labels={"bottom": "T (ms)", "left": "# of spikes"},
)
p2 = win.addPlot(
title="Buildup PSTH",
row=1,
col=0,
labels={"bottom": "T (ms)", "left": "# of spikes"},
)
p3 = win.addPlot(
title="Wide Chopper PSTH",
row=2,
col=0,
labels={"bottom": "T (ms)", "left": "# of spikes"},
)
# In[ ]:
bins = np.arange(0, 80, 0.5)
PB_spike_data = []
with open("Ad081098_065_PauserBuildup_psth.txt", "r+") as df:
for x in df:
x = x.strip("\n").strip()
x = float(x) * 1e-3
if x:
PB_spike_data.append(x)
histogram, binedges = np.histogram(PB_spike_data, bins)
p1.plot(
binedges,
histogram,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
B_spike_data = []
with open("Ad041599_062_Buildup_psth.txt", "r+") as df:
for x in df:
x = x.strip("\n").strip()
x = float(x) * 1e-3
if x:
B_spike_data.append(x)
histogram, binedges = np.histogram(B_spike_data, bins)
p2.plot(
binedges,
histogram,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
C_spike_data = []
with open("Ad081998_199_WideChopper_psth.txt", "r+") as df:
for x in df:
x = x.strip("\n").strip()
x = float(x) * 1e-3
if x:
C_spike_data.append(x)
histogram, binedges = np.histogram(C_spike_data, bins)
p3.plot(
binedges,
histogram,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
# In[ ]:
win.show()
print("finished")
if sys.flags.interactive == 0:
pg.QtGui.QApplication.exec_()

View File

@@ -0,0 +1,451 @@
"""
Layout:
if __name__==__main__ handles cmd args, instantiates test, runs it, displays results
run_trial(): defines a model and then runs the test using preset params in hoc and return the info to the class
SGCInputTest:
__init__ : defines many static variables
run(): calls delivers information to the run_trial() function and the recieved information of a single run
back and stores it as an exstensible list in the class
show(): displays graphs depending on the graph options selected below it and displayed in a printout
"""
import argparse
import numpy as np
import pyqtgraph as pg
from neuron import h
from cnmodel.protocols import Protocol
from cnmodel import cells
from cnmodel.util import sound
from cnmodel.util import custom_init
import cnmodel.util.pynrnutilities as PU
from cnmodel import data
try:
from tqdm import trange
except ImportError:
raise ImportError("Please 'pip install tqdm' to allow for progress bar")
species = "rat" # tables for other species do not yet exist
def run_trial(cell, info):
"""
info is a dict
"""
assert cell == "pyramidal"
post_cell = cells.Pyramidal.create(species=species)
inhib_cell = cells.Tuberculoventral.create()
inhib_cell2 = cells.Tuberculoventral.create()
# dstell = cells.DStellate.create()
pre_cells = []
synapses = []
inhib_synapses = []
for nsgc in range(48):
# attach to pyramidal cell
pre_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(pre_cells[-1].connect(post_cell, type=info["synapse_type"]))
pre_cells[-1].set_sound_stim(
info["stim"], seed=info["seed"] + nsgc, simulator=info["simulator"]
)
synapses[
-1
].terminal.relsite.Dep_Flag = False # no depression in these simulations
for nsgc in range(16):
pre_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
inhib_synapses.append(
pre_cells[-1].connect(inhib_cell, type=info["synapse_type"])
)
inhib_synapses.append(
pre_cells[-1].connect(inhib_cell2, type=info["synapse_type"])
)
pre_cells[-1].set_sound_stim(
info["stim"], seed=info["seed"] + nsgc + 48, simulator=info["simulator"]
)
synapses[
-1
].terminal.relsite.Dep_Flag = False # no depression in these simulations
# for nsgc in range(20):
# pre_cells.append(cells.DummySGC(cf=info['cf'], sr=info['sr']))
# inhib_synapses.append(pre_cells[-1].connect(dstell, type=info['synapse_type']))
# pre_cells[-1].set_sound_stim(info['stim'], seed=info['seed'] + nsgc + 16 + 48, simulator=info['simulator'])
# synapses[-1].terminal.relsite.Dep_Flag = False # no depression in these simulations
for _ in range(21):
inhib_synapses.append(inhib_cell.connect(post_cell, type="simple"))
inhib_synapses.append(inhib_cell2.connect(post_cell, type="simple"))
# for _ in range(15):
# inhib_synapses.append(inhib_cell.connect(dstell, type='simple'))
Vm = h.Vector()
Vm.record(post_cell.soma(0.5)._ref_v)
Vmtb = h.Vector()
Vmtb.record(inhib_cell.soma(0.5)._ref_v)
rtime = h.Vector()
rtime.record(h._ref_t)
h.tstop = 1e3 * info["run_duration"] # duration of a run
h.celsius = info["temp"]
h.dt = info["dt"]
post_cell.cell_initialize()
info["init"]()
h.t = 0.0
h.run()
# package data
pre_cells_data = [x._spiketrain for x in pre_cells]
Vm_list = np.array(Vm)
Vmtb_list = np.array(Vmtb)
time_list = np.array(rtime)
# clean up
del (
pre_cells,
synapses,
inhib_cell,
inhib_synapses,
Vm,
Vmtb,
post_cell,
inhib_cell2,
info,
)
return {
"time": time_list,
"vm": Vm_list,
"pre_cells": pre_cells_data,
"vmtb": Vmtb_list,
}
class SGCTestPSTH(Protocol):
"""
Tests a Single cell with input recieved from the SGC
__init__: almost all parameters can be modified
run(): simply loops over the run_trial() function and stores the results just
show(): constructs the graphs using other functions
"""
def __init__(
self,
temp=34.0,
seed=2918,
nrep=10,
stimulus="tone",
simulator="cochlea",
n_sgc=12,
debug=True,
cell="pyramidal",
):
"""
:param temp: (float) must be at 34 for default pyramidal cells
:param dt: (float) determine hoc resolution
:param seed: (int) contributes to randomization, needs to be changed to see different results (reduce this
number if you keep getting a timeout error
:param nrep: (int) number of presentations !!must be changed in the __name__ function if not calling from cmd line!!
:param stimulus: (str) must be 'tone'
:param simulator: (str) currently using cochlea instead of matlab
:param n_sgc:(int) This is the number of SGC fibers that connect to the post synaptic cell
:param debug: (bool) controls most of the terminal printouts is on by default
:param cell: (str) cell type !!must be changed in the __name__ function if not calling from cmd line!!
"""
super().__init__()
assert stimulus == "tone"
assert cell in [
"bushy",
"tstellate",
"octopus",
"dstellate",
"tuberculoventral",
"pyramidal",
]
self.debug = debug
self.nrep = nrep
self.stimulus = stimulus
self.run_duration = 0.30 # in seconds
self.pip_duration = 0.05 # in seconds
self.pip_start = [0.1] # in seconds
self.Fs = 100e3 # in Hz
self.f0 = 13000.0 # stimulus in Hz
self.cf = 13000.0 # SGCs in Hz
self.fMod = 100.0 # mod freq, Hz
self.dMod = 0.0 # % mod depth, Hz
self.dbspl = 40.0
self.simulator = simulator
self.sr = 2 # set SR group
self.seed = seed
self.temp = temp
self.dt = 0.025
self.cell = cell
self.synapse_type = "multisite"
if self.stimulus == "tone":
self.stim = sound.TonePip(
rate=self.Fs,
duration=self.run_duration,
f0=self.f0,
dbspl=self.dbspl,
ramp_duration=5e-3,
pip_duration=self.pip_duration,
pip_start=self.pip_start,
)
if not n_sgc:
n_sgc = data.get(
"convergence", species="mouse", post_type=self.cell, pre_type="sgc"
)[0]
self.n_sgc = int(np.round(n_sgc))
# convert nS to uS for NEURON
self.vms = [None for n in range(self.nrep)]
self.vmtbs = [None for n in range(self.nrep)]
self.synapses = [None for n in range(self.nrep)]
self.pre_cells = [None for n in range(self.nrep)]
self.time = [None for n in range(self.nrep)]
# debug function reports a print out of various information about the run
if self.debug:
print("SGCInputTest Created")
print()
print("Test parameters")
print("#" * 70)
print(f"Running test of {cell} cell synapse with Simulated SGC fibers")
print()
print(f"Run Conditions: Run Time: {self.run_duration}s,")
print(f" Run Temp: {self.temp} ")
print(f" Sgc Connections {n_sgc}")
print(f" Number of Presentations: {nrep}")
print()
print(f"Stimulus Conditions: Type: {stimulus}")
print(f" Stim Duration: {self.pip_duration}s")
print(f" Characteristic F: {self.cf}hz")
print(f" Stim Start:{str(self.pip_start)}s")
def run(self):
super().run()
info = {
"n_sgc": self.n_sgc,
"stim": self.stim,
"simulator": self.simulator,
"cf": self.cf,
"sr": self.sr,
"seed": self.seed,
"run_duration": self.run_duration,
"synapse_type": self.synapse_type,
"temp": self.temp,
"dt": self.dt,
"init": custom_init,
}
for nr in trange(self.nrep):
info["seed"] = self.seed + self.n_sgc + (nr * (48 + 16 + 20))
res = run_trial(self.cell, info)
# res contains: {'time': time, 'vm': list(Vm), 'pre_cells': pre_cells._spiketrain,'vmtb': list(Vmtb)}
self.pre_cells[nr] = res["pre_cells"]
self.time[nr] = res["time"]
self.vms[nr] = res["vm"]
self.vmtbs[nr] = res["vmtb"]
def show(self):
"""
Creates a single page graph that contains all of the graphs based on the graphical functions in the class
"""
self.win = pg.GraphicsWindow()
self.win.setBackground("w")
p1 = self.stimulus_graph()
p2 = self.an_spike_graph()
p3 = self.pyram_spike_graph()
p4 = self.voltage_graph()
p5 = self.tb_cell_spike_graph()
p6 = (
self.an_psth_graph()
) # requires that an_spikes_graph() has been called before
p7 = (
self.cell_psth_graph()
) # requires that cell_spikes_graph() has been called before
# links x axis
p1.setXLink(p1)
p2.setXLink(p1)
p3.setXLink(p1)
p4.setXLink(p1)
p5.setXLink(p1)
p6.setXLink(p1)
p7.setXLink(p1)
self.win.show()
if self.debug:
print("finished")
############# Graph options to be included in the show() method ###################
def stimulus_graph(self):
p1 = self.win.addPlot(
title="Stimulus", row=0, col=0, labels={"bottom": "T (ms)", "left": "V"}
)
p1.plot(self.stim.time * 1000, self.stim.sound, pen=pg.mkPen("k", width=0.75))
return p1
def an_spike_graph(self):
p2 = self.win.addPlot(
title="AN spikes",
row=1,
col=0,
labels={"bottom": "T (ms)", "left": "AN spikes (first trial)"},
)
self.all_xan = []
for nr in range(self.nrep):
xan = []
yan = []
for k in range(len(self.pre_cells[nr])):
r = self.pre_cells[nr][k]
xan.extend(r)
self.all_xan.extend(r)
yr = k + np.zeros_like(r) + 0.2
yan.extend(yr)
c = pg.PlotCurveItem()
xp = np.repeat(np.array(xan), 2)
yp = np.repeat(np.array(yan), 2)
yp[1::2] = yp[::2] + 0.6
c.setData(
xp.flatten(),
yp.flatten(),
connect="pairs",
width=1.0,
pen=pg.mkPen("k", width=1.5),
)
p2.addItem(c)
return p2
def pyram_spike_graph(self):
p3 = self.win.addPlot(
title="Pyramidal Spikes",
row=2,
col=0,
labels={"bottom": "T (ms)", "left": "Trial #"},
)
xcn = []
ycn = []
for k in range(self.nrep):
bspk = PU.findspikes(self.time[k], self.vms[k], -35.0)
xcn.extend(bspk)
yr = k + np.zeros_like(bspk) + 0.2
ycn.extend(yr)
d = pg.PlotCurveItem()
xp = np.repeat(np.array(xcn), 2)
yp = np.repeat(np.array(ycn), 2)
yp[1::2] = yp[::2] + 0.6
d.setData(
xp.flatten(), yp.flatten(), connect="pairs", pen=pg.mkPen("k", width=1.5)
)
self.xcn = xcn
self.ycn = ycn
p3.addItem(d)
return p3
def voltage_graph(self):
p4 = self.win.addPlot(
title="%s Vm" % self.cell,
row=0,
col=1,
labels={"bottom": "T (ms)", "left": "Vm (mV)"},
)
if self.nrep > 3:
display = 3
else:
display = self.nrep
for nr in range(display):
p4.plot(
self.time[nr],
self.vms[nr],
pen=pg.mkPen(pg.intColor(nr, self.nrep), hues=self.nrep, width=1.0),
)
return p4
def tb_cell_spike_graph(self):
p5 = self.win.addPlot(
title="Tuberculoventral Spikes",
row=3,
col=0,
labels={"bottom": "T (ms)", "left": "Trial #"},
)
xtcn = []
ytcn = []
for k in range(self.nrep):
bspk = PU.findspikes(self.time[k], self.vmtbs[k], -35.0)
xtcn.extend(bspk)
yr = k + np.zeros_like(bspk) + 0.2
ytcn.extend(yr)
d = pg.PlotCurveItem()
xp = np.repeat(np.array(xtcn), 2)
yp = np.repeat(np.array(ytcn), 2)
yp[1::2] = yp[::2] + 0.6
d.setData(
xp.flatten(), yp.flatten(), connect="pairs", pen=pg.mkPen("k", width=1.5)
)
p5.addItem(d)
return p5
def an_psth_graph(self):
p6 = self.win.addPlot(
title="AN PSTH",
row=1,
col=1,
labels={"bottom": "T (ms)", "left": "Sp/ms/trial"},
)
bins = np.arange(50, 200, 1)
(hist, binedges) = np.histogram(self.all_xan, bins)
curve6 = p6.plot(
binedges,
hist,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
return p6
def cell_psth_graph(self):
p7 = self.win.addPlot(
title="Pyramidal PSTH",
row=2,
col=1,
labels={"bottom": "T (ms)", "left": "Sp/ms/trial"},
)
bins = np.arange(50, 200, 1)
(hist, binedges) = np.histogram(self.xcn, bins)
curve7 = p7.plot(
binedges,
hist,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
return p7
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Compute AN only PSTH in postsynaptic cell"
)
parser.add_argument(
"-n",
"--nrep",
type=int,
dest="nrep",
default=10,
help="Set number of repetitions",
)
args = parser.parse_args()
nrep = args.nrep
prot = SGCTestPSTH(nrep=50)
prot.run()
prot.show()
import sys
if sys.flags.interactive == 0:
pg.QtGui.QApplication.exec_()

View File

@@ -0,0 +1,412 @@
"""
Layout:
if __name__==__main__ handles cmd args, instantiates test, runs it, displays results
run_trial(): defines a model and then runs the test using preset params in hoc and return the info to the class
SGCInputTest:
__init__ : defines many static variables
run(): calls delivers information to the run_trial() function and the recieved information of a single run
back and stores it as an exstensible list in the class
show(): displays graphs depending on the graph options selected below it and displayed in a printout
"""
import argparse
import numpy as np
import pyqtgraph as pg
from neuron import h
from cnmodel.protocols import Protocol
from cnmodel import cells
from cnmodel.util import sound
from cnmodel.util import custom_init
import cnmodel.util.pynrnutilities as PU
from cnmodel import data
try:
from tqdm import trange
except ImportError as err:
raise ImportError("Please 'pip install tqdm' to allow for progress bar")
species = "rat" # tables for other species do not yet exist
def run_trial(cell, info):
"""
info is a dict
"""
if cell == "bushy":
post_cell = cells.Bushy.create(species=species)
elif cell == "tstellate":
post_cell = cells.TStellate.create(species=species)
elif cell == "octopus":
post_cell = cells.Octopus.create(species=species)
elif cell == "dstellate":
post_cell = cells.DStellate.create(species=species)
elif cell == "tuberculoventral":
post_cell = cells.DStellate.create(species=species)
elif cell == "pyramidal":
post_cell = cells.Pyramidal.create(species=species)
else:
raise ValueError("cell %s is not yet implemented for PSTH testing" % cell)
pre_cells = []
synapses = []
for nsgc, sgc in enumerate(range(info["n_sgc"])):
pre_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(pre_cells[-1].connect(post_cell, type=info["synapse_type"]))
synapses[
-1
].terminal.relsite.Dep_Flag = False # no depression in these simulations
pre_cells[-1].set_sound_stim(
info["stim"], seed=info["seed"] + nsgc, simulator=info["simulator"]
)
# stim = insert_current_clamp(post_cell.soma)
Vm = h.Vector()
Vm.record(post_cell.soma(0.5)._ref_v)
rtime = h.Vector()
rtime.record(h._ref_t)
h.tstop = 1e3 * info["run_duration"] # duration of a run
h.celsius = info["temp"]
h.dt = info["dt"]
post_cell.cell_initialize()
info["init"](v_init=-60)
h.t = 0.0
h.run()
pre_cells_data = [x._spiketrain for x in pre_cells]
return {"time": np.array(rtime), "vm": list(Vm), "pre_cells": pre_cells_data}
# stim = insert_current_clamp(post_cell.soma)
def insert_current_clamp(sec):
"""
:param sec: to attach too
dur: ms
amp: nA
delay: ms
:return: stim needs to be put in a variable to stay alive
"""
stim = h.IClamp(0.5, sec=sec)
stim.dur = 90
stim.amp = -0.2
stim.delay = 2
return stim
class SGCTestPSTH(Protocol):
"""
Tests a Single cell with input recieved from the SGC
__init__: almost all parameters can be modified
run(): simply loops over the run_trial() function and stores the results just
show(): constructs the graphs using other functions
"""
def __init__(
self,
temp=34.0,
seed=5908035,
nrep=10,
stimulus="tone",
simulator="cochlea",
n_sgc=12,
debug=True,
cell="bushy",
):
"""
:param temp: (float) must be at 34 for default pyramidal cells
:param dt: (float) determine hoc resolution
:param seed: (int) contributes to randomization, needs to be changed to see different results (reduce this
number if you keep getting a timeout error
:param nrep: (int) number of presentations !!must be changed in the __name__ function if not calling from cmd line!!
:param stimulus: (str) must be 'tone'
:param simulator: (str) currently using cochlea instead of matlab
:param n_sgc:(int) This is the number of SGC fibers that connect to the post synaptic cell
:param debug: (bool) controls most of the terminal printouts is on by default
:param cell: (str) cell type !!must be changed in the __name__ function if not calling from cmd line!!
"""
super().__init__()
assert stimulus == "tone"
assert cell in [
"bushy",
"tstellate",
"octopus",
"dstellate",
"tuberculoventral",
"pyramidal",
]
self.debug = debug
self.nrep = nrep
self.stimulus = stimulus
self.run_duration = 0.30 # in seconds
self.pip_duration = 0.05 # in seconds
self.pip_start = [0.1] # in seconds
self.Fs = 100e3 # in Hz
self.f0 = 13000.0 # stimulus in Hz
self.cf = 13000.0 # SGCs in Hz
self.fMod = 100.0 # mod freq, Hz
self.dMod = 0.0 # % mod depth, Hz
self.dbspl = 55.0
self.simulator = simulator
self.sr = 2 # set SR group
self.seed = seed
self.temp = temp
self.dt = 0.025
self.cell = cell
self.synapse_type = "multisite"
if self.stimulus == "tone":
self.stim = sound.TonePip(
rate=self.Fs,
duration=self.run_duration,
f0=self.f0,
dbspl=self.dbspl,
ramp_duration=2.5e-3,
pip_duration=self.pip_duration,
pip_start=self.pip_start,
)
if not n_sgc:
n_sgc = data.get(
"convergence", species="mouse", post_type=self.cell, pre_type="sgc"
)[0]
self.n_sgc = int(np.round(n_sgc))
# convert nS to uS for NEURON
self.vms = [None for n in range(self.nrep)]
self.synapses = [None for n in range(self.nrep)]
self.pre_cells = [None for n in range(self.nrep)]
self.time = [None for n in range(self.nrep)]
# debug function reports a print out of various information about the run
if self.debug:
print("SGCInputTest Created")
print()
print("Test parameters")
print("#" * 70)
print(f"Running test of {cell} cell synapse with Simulated SGC fibers")
print()
print(f"Run Conditions: Run Time: {self.run_duration}s,")
print(f" Run Temp: {self.temp} ")
print(f" Sgc Connections {n_sgc}")
print(f" Number of Presentations: {nrep}")
print()
print(f"Stimulus Conditions: Type: {stimulus}")
print(f" Stim Duration: {self.pip_duration}s")
print(f" Characteristic F: {self.cf}hz")
print(f" Stim Start:{str(self.pip_start)}s")
def run(self):
super().run()
info = {
"n_sgc": self.n_sgc,
"stim": self.stim,
"simulator": self.simulator,
"cf": self.cf,
"sr": self.sr,
"seed": self.seed,
"run_duration": self.run_duration,
"synapse_type": self.synapse_type,
"temp": self.temp,
"dt": self.dt,
"init": custom_init,
}
for nr in trange(self.nrep):
info["seed"] = self.seed + self.n_sgc + nr + 3
res = run_trial(self.cell, info)
# res contains: {'time': time, 'vm': list(Vm), 'pre_cells': pre_cells._spiketrain,}
self.pre_cells[nr] = res["pre_cells"]
self.time[nr] = res["time"]
self.vms[nr] = res["vm"]
def show(self):
"""
Creates a single page graph that contains all of the graphs based on the graphical functions in the class
"""
self.win = pg.GraphicsWindow()
self.win.setBackground("w")
p1 = self.stimulus_graph()
p2 = self.an_spikes_graph()
p3 = self.cell_spikes_graph()
p4 = self.voltage_graph()
p6 = (
self.an_psth_graph()
) # requires that an_spikes_graph() has been called before
p7 = (
self.cell_psth_graph()
) # requires that cell_spikes_graph() has been called before
# links x axis
p1.setXLink(p1)
p2.setXLink(p1)
p3.setXLink(p1)
p4.setXLink(p1)
self.win.show()
if self.debug:
print("finished")
############# Graph options to be included in the show() method ###################
def stimulus_graph(self):
p1 = self.win.addPlot(
title="Single Tone Stimulus", row=0, col=0, labels={"bottom": "T (ms)"}
)
p1.plot(self.stim.time * 1000, self.stim.sound, pen=pg.mkPen("k", width=0.75))
return p1
def an_spikes_graph(self):
p2 = self.win.addPlot(
title="AN spikes",
row=1,
col=0,
labels={"bottom": "T (ms)", "left": "AN spikes (first trial)"},
)
self.all_xan = []
for nr in range(self.nrep):
xan = []
yan = []
for k in range(len(self.pre_cells[nr])):
r = self.pre_cells[nr][k]
xan.extend(r)
self.all_xan.extend(r)
yr = k + np.zeros_like(r) + 0.2
yan.extend(yr)
c = pg.PlotCurveItem()
xp = np.repeat(np.array(xan), 2)
yp = np.repeat(np.array(yan), 2)
yp[1::2] = yp[::2] + 0.6
c.setData(
xp.flatten(),
yp.flatten(),
connect="pairs",
width=1.0,
pen=pg.mkPen("k", width=1.5),
)
p2.addItem(c)
return p2
def cell_spikes_graph(self):
p3 = self.win.addPlot(
title="Pyramidal Cell Spikes",
row=2,
col=0,
labels={"bottom": "T (ms)", "left": "Trial #"},
)
xcn = []
ycn = []
for k in range(self.nrep):
bspk = PU.findspikes(self.time[k], self.vms[k], -35.0)
xcn.extend(bspk)
yr = k + np.zeros_like(bspk) + 0.2
ycn.extend(yr)
d = pg.PlotCurveItem()
xp = np.repeat(np.array(xcn), 2)
yp = np.repeat(np.array(ycn), 2)
yp[1::2] = yp[::2] + 0.6
d.setData(
xp.flatten(), yp.flatten(), connect="pairs", pen=pg.mkPen("k", width=1.5)
)
self.xcn = xcn
self.ycn = ycn
p3.addItem(d)
return p3
def voltage_graph(self):
p4 = self.win.addPlot(
title="Pyramidal Vm",
row=0,
col=1,
labels={"bottom": "T (ms)", "left": "Vm (mV)"},
)
if self.nrep > 5:
display = 3
else:
display = self.nrep
for nr in range(display):
p4.plot(
self.time[nr],
self.vms[nr],
pen=pg.mkPen(pg.intColor(nr, self.nrep), hues=self.nrep, width=1.0),
)
return p4
def an_psth_graph(self):
p6 = self.win.addPlot(
title="AN PSTH",
row=1,
col=1,
labels={"bottom": "T (ms)", "left": "# of Spikes(0.75ms"},
)
bins = np.arange(60, 200, 0.5)
(hist, binedges) = np.histogram(self.all_xan, bins)
curve6 = p6.plot(
binedges,
hist,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
return p6
def cell_psth_graph(self):
p7 = self.win.addPlot(
title="Pyramidal PSTH",
row=2,
col=1,
labels={"bottom": "T (ms)", "left": "# of Spikes(0.75ms)"},
)
bins = np.arange(60, 200, 0.5)
(hist, binedges) = np.histogram(self.xcn, bins)
curve7 = p7.plot(
binedges,
hist,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
return p7
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Compute AN only PSTH in postsynaptic cell"
)
parser.add_argument(
type=str,
dest="cell",
default="pyramidal",
choices=[
"bushy",
"tstellate",
"dstellate",
"octopus",
"tuberculoventral",
"pyramidal",
],
help="Select target cell",
)
parser.add_argument(
"-n",
"--nrep",
type=int,
dest="nrep",
default=1,
help="Set number of repetitions",
)
args = parser.parse_args()
cell = args.cell
nrep = args.nrep
prot = SGCTestPSTH(nrep=100, cell=cell)
prot.run()
prot.show()
import sys
if sys.flags.interactive == 0:
pg.QtGui.QApplication.exec_()

View File

@@ -0,0 +1,397 @@
"""
The Assumptions of this cell are modified to the test_sgc_input_PSTH.py but should be identical in function
synapse type = simple
synapse type = single
species = mouse
sgc = dummy SGC lacks cell body
cell connection = pyramidal
"""
import sys
import numpy as np
import pyqtgraph as pg
from neuron import h
from cnmodel.protocols import Protocol
from cnmodel import cells
from cnmodel.util import sound
from cnmodel.util import custom_init
import cnmodel.util.pynrnutilities as PU
from cnmodel import data
synapseType = "simple" # no other options exist
species = "mouse" # tables for other species do not yet exist
def main():
prot = SGCInputTestPSTH(seed=1233451898)
prot.run()
prot.show()
if sys.flags.interactive == 0:
pg.QtGui.QApplication.exec_()
class SGCInputTestPSTH(Protocol):
def __init__(self, temp=34.0, dt=0.025, seed=575982035):
"""
:param temp: Celcius
:param dt: resolution in ms
:param seed: seed should be generated randomly
Pre-determined variables that can be changed by editing the value next to them
AMPA_gmax and n_sgc = loaded from data that is kept in cnmodel/data dir
Defines a single tone parameters with which to test the neuron complex
"""
# super only defines reset function
super(SGCInputTestPSTH, self).__init__()
#
self.temp = temp
self.dt = dt
self.seed = seed
self.simulator = "cochlea"
# predetermined variables
self.cell = "pyramidal"
self.nrep = 50 # number of repetitions
self.stimulus = "tone"
self.Fs = 100e3 # in Hz
self.f0 = 4000.0 # stimulus in Hz
self.cf = 4000.0 # SGCs in Hz
self.fMod = 100.0 # mod freq, Hz
self.dMod = 0.0 # % mod depth, Hz
self.dbspl = 50.0
self.sr = 2 # set SR group
# variables loaded from data
AMPA_gmax, n_sgc = self.load_variables_from_data()
self.n_sgc = int(np.round(n_sgc))
# value needed for simple synapses
self.AMPA_gmax = AMPA_gmax
# the stimulation delivered is a Tone
self.run_duration = 0.20 # in seconds
self.pip_duration = 0.05 # in seconds
self.pip_start = [0.1] # in seconds
self.f0 = 4000.0
self.cf = 4000.0
self.stim = sound.TonePip(
rate=self.Fs,
duration=self.run_duration,
f0=self.f0,
dbspl=self.dbspl,
ramp_duration=2.5e-3,
pip_duration=self.pip_duration,
pip_start=self.pip_start,
)
# creates empty lists that will contain the results of each rep
self.vms = [None for n in range(self.nrep)]
self.synapses = [None for n in range(self.nrep)]
self.xmtrs = [None for n in range(self.nrep)]
self.pre_cells = [None for n in range(self.nrep)]
self.time = [None for n in range(self.nrep)]
def load_variables_from_data(self):
AMPA_gmax = (
data.get(
"sgc_synapse", species=species, post_type=self.cell, field="AMPA_gmax"
)[0]
/ 1e3
)
n_sgc = data.get(
"convergence", species=species, post_type=self.cell, pre_type="sgc"
)[0]
print(n_sgc)
return AMPA_gmax, n_sgc
def check_assertations(self):
assert self.cell in [
"bushy",
"tstellate",
"octopus",
"dstellate",
"tuberculoventral",
"pyramidal",
]
assert self.stimulus == "tone" # cases available
assert synapseType == "simple"
def run(self):
self.check_assertations()
# info based on the parameters set in the __init__ statement
info = {
"n_sgc": self.n_sgc,
"gmax": self.AMPA_gmax,
"stim": self.stim,
"simulator": self.simulator,
"cf": self.cf,
"sr": self.sr,
"seed": self.seed,
"run_duration": self.run_duration,
"temp": self.temp,
"dt": self.dt,
"init": custom_init,
}
# run number of trials based on nrep defined in __init__ statement
for nr in range(self.nrep):
info["seed"] = self.seed + 3 * self.n_sgc * nr
res = run_trial(info)
# res contains: {'time': time, 'vm': Vm, 'xmtr': xmtr, 'pre_cells': pre_cells, 'post_cell': post_cell}
# unpacks the res dict returned from the run_trial() into refrenceable variables
self.pre_cells[nr] = res["pre_cells"]
self.time[nr] = res["time"]
self.xmtr = {k: v.to_python() for k, v in res["xmtr"].items()}
self.vms[nr] = res["vm"]
self.synapses[nr] = res["synapses"]
self.xmtrs[nr] = self.xmtr
def show(self):
"""
Creates a single page graph that contains all of the graphs based on the graphical functions in the class
"""
self.win = pg.GraphicsWindow()
self.win.setBackground("w")
p1 = self.stimulus_graph()
p2 = self.an_spikes_graph()
p3 = self.cell_spikes_graph()
p4 = self.voltage_graph()
p5 = self.xmtr_graph()
p6 = (
self.an_psth_graph()
) # requires that an_spikes_graph() has been called before
p7 = (
self.cell_psth_graph()
) # requires that cell_spikes_graph() has been called before
# links x axis
p1.setXLink(p1)
p2.setXLink(p1)
p3.setXLink(p1)
p4.setXLink(p1)
p5.setXLink(p1)
self.win.show()
############# Graph options to be included in the show() method ###################
def stimulus_graph(self):
p1 = self.win.addPlot(
title="Stimulus", row=0, col=0, labels={"bottom": "T (ms)", "left": "V"}
)
p1.plot(
self.stim.time * 1000, self.stim.sound, pen=pg.mkPen("k", width=0.75)
)
return p1
def an_spikes_graph(self):
p2 = self.win.addPlot(
title="AN spikes",
row=1,
col=0,
labels={"bottom": "T (ms)", "left": "AN spikes (first trial)"},
)
for nr in range(self.nrep):
xan = []
yan = []
for k in range(len(self.pre_cells[nr])):
r = self.pre_cells[nr][k]._spiketrain
xan.extend(r)
yr = k + np.zeros_like(r) + 0.2
yan.extend(yr)
c = pg.PlotCurveItem()
xp = np.repeat(np.array(xan), 2)
yp = np.repeat(np.array(yan), 2)
yp[1::2] = yp[::2] + 0.6
c.setData(
xp.flatten(),
yp.flatten(),
connect="pairs",
pen=pg.mkPen(pg.intColor(nr, self.nrep), hues=self.nrep, width=1.0),
)
self.xan = xan
self.yan = yan
p2.addItem(c)
return p2
def cell_spikes_graph(self):
p3 = self.win.addPlot(
title="%s Spikes" % self.cell,
row=2,
col=0,
labels={"bottom": "T (ms)", "left": "Trial #"},
)
xcn = []
ycn = []
xspks = []
for k in range(self.nrep):
bspk = PU.findspikes(self.time[k], self.vms[k], -35.0)
xcn.extend(bspk)
yr = k + np.zeros_like(bspk) + 0.2
ycn.extend(yr)
d = pg.PlotCurveItem()
xp = np.repeat(np.array(xcn), 2)
yp = np.repeat(np.array(ycn), 2)
yp[1::2] = yp[::2] + 0.6
d.setData(
xp.flatten(),
yp.flatten(),
connect="pairs",
pen=pg.mkPen("k", width=1.5),
)
self.xcn = xcn
self.ycn = ycn
p3.addItem(d)
return p3
def voltage_graph(self):
p4 = self.win.addPlot(
title="%s Vm" % self.cell,
row=3,
col=0,
labels={"bottom": "T (ms)", "left": "Vm (mV)"},
)
for nr in range(self.nrep):
p4.plot(
self.time[nr],
self.vms[nr],
pen=pg.mkPen(pg.intColor(nr, self.nrep), hues=self.nrep, width=1.0),
)
return p4
def xmtr_graph(self):
p5 = self.win.addPlot(
title="xmtr", row=0, col=1, labels={"bottom": "T (ms)", "left": "gSyn"}
)
if synapseType == "multisite":
for nr in [0]:
syn = self.synapses[nr]
j = 0
for k in range(self.n_sgc):
synapse = syn[k]
for i in range(synapse.terminal.n_rzones):
p5.plot(
self.time[nr],
self.xmtrs[nr]["xmtr%04d" % j],
pen=pg.mkPen(
pg.intColor(nr, self.nrep),
hues=self.nrep,
width=1.0,
),
)
j = j + 1
return p5
def an_psth_graph(self):
p6 = self.win.addPlot(
title="AN PSTH",
row=1,
col=1,
labels={"bottom": "T (ms)", "left": "Sp/ms/trial"},
)
bins = np.arange(0, 200, 1)
(hist, binedges) = np.histogram(self.xan, bins)
curve6 = p6.plot(
binedges,
hist,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
return p6
def cell_psth_graph(self):
p7 = self.win.addPlot(
title="%s PSTH" % self.cell,
row=2,
col=1,
labels={"bottom": "T (ms)", "left": "Sp/ms/trial"},
)
bins = np.arange(0, 200, 1)
(hist, binedges) = np.histogram(self.xcn, bins)
curve7 = p7.plot(
binedges,
hist,
stepMode=True,
fillBrush=(0, 0, 0, 255),
brush=pg.mkBrush("k"),
fillLevel=0,
)
return p7
def run_trial(info):
"""
This function is really the bread
and butter of the run and determines the layout
of the model and the stimulus is
created and delivered by the SGC.
Runs a single trial and returns it
into another dictionary that is stored
before the next trial is run.
:param info: dict containing :'n_sgc': self.n_sgc,
'gmax': self.AMPA_gmax,
'stim': self.stim,
'simulator': self.simulator,
'cf': self.cf, 'sr': self.sr,
'seed': self.seed,
'run_duration': self.run_duration,
'temp': self.temp,
'dt': self.dt,
'init': custom_init
post cell allowed to use defaults in the case of things like pyramidal cells are guinea pigs instead of a mouse
"""
# for the model to change the post_cell needs to be changed here otherwise the model will not be changed.
# special consideration needs to be taken because not all cell parameters are universal
# ex: Pyramidal does not have a species='mouse', nothing just assumes a default and not all defaults are the same
post_cell = cells.Pyramidal.create()
pre_cells = []
synapses = []
xmtr = {}
# connects all of the SGC fibers to the post_cell using simple synapses and then generates a sound stim based on a
# seed the number of repetitions desired
for nsgc, sgc in enumerate(range(info["n_sgc"])):
pre_cells.append(cells.DummySGC(cf=info["cf"], sr=info["sr"]))
synapses.append(pre_cells[-1].connect(post_cell, type="simple"))
synapses[-1].terminal.netcon.weight[0] = info["gmax"]
# sets sounds stim for each of the SGC fibers independently
pre_cells[-1].set_sound_stim(
info["stim"], seed=info["seed"] + nsgc, simulator=info["simulator"]
)
# Recording each trial and returning it as a dictionary
Vm = h.Vector()
Vm.record(post_cell.soma(0.5)._ref_v)
rtime = h.Vector()
rtime.record(h._ref_t)
h.tstop = 1e3 * info["run_duration"] # duration of a run
h.celsius = info["temp"]
h.dt = info["dt"]
post_cell.cell_initialize()
info["init"]()
h.t = 0.0
h.run()
return {
"time": np.array(rtime),
"vm": Vm.to_python(),
"xmtr": xmtr,
"pre_cells": pre_cells,
"post_cell": post_cell,
"synapses": synapses,
}
if __name__ == "__main__":
main()

0
project/util/__init__.py Normal file
View File

35
project/util/tools.py Normal file
View File

@@ -0,0 +1,35 @@
import functools
import time
class Clock(object):
"""
This is a decorator for the purpose of timing
functions and classes, it can be added to any function
and during runtime will spit out a formatted str
that displays function(arguments) and results with
a time delta. Uses pref_counter() not time()
"""
def __init__(self, func):
self.func = func
functools.update_wrapper(self, func)
def __call__(self, *args, **kwargs):
t0 = time.perf_counter()
result = self.func(*args, **kwargs)
elapsed = time.perf_counter() - t0
name = self.func.__name__
arg_lst = []
if args:
arg_lst.extend(repr(arg) for arg in args)
if kwargs:
arg_lst.extend("{}={}".format(k, w) for k, w in kwargs.items())
arg_str = ", ".join(arg_lst)
print(
"TIME TRIAL: {:s}({:.30s}~) -> {!r:.30}~ dt=[{:.8}]".format(
name, arg_str, result, elapsed
)
)
print()
return result