Skip to content

Commit cee2e1a

Browse files
Merge pull request #265 from AurelienJaquier/sbo-template
h5 morphology loadable hoc template/export
2 parents 8450371 + 2b72be3 commit cee2e1a

File tree

2 files changed

+275
-1
lines changed

2 files changed

+275
-1
lines changed

bluepymm/prepare_combos/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def prepare_emodels(conf_dict, continu, scores_db_path, n_processes):
5353
base_dir = os.path.abspath(os.path.dirname(__file__))
5454
template_dir = os.path.join(base_dir, '../templates')
5555
hoc_template = os.path.join(
56-
template_dir, 'cell_template_neurodamus.jinja2')
56+
template_dir, 'cell_template_neurodamus_sbo.jinja2')
5757
hoc_template = os.path.abspath(hoc_template)
5858
print('Preparing emodels in %s' % emodels_dir)
5959
emodels_hoc_dir = os.path.abspath(conf_dict['emodels_hoc_dir'])
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
/*
2+
{%- if banner %}
3+
{{banner}}
4+
{%- endif %}
5+
*/
6+
{load_file("stdrun.hoc")}
7+
{load_file("import3d.hoc")}
8+
9+
{%- if global_params %}
10+
/*
11+
* Check that global parameters are the same as with the optimization
12+
*/
13+
proc check_parameter(/* name, expected_value, value */){
14+
strdef error
15+
if($2 != $3){
16+
sprint(error, "Parameter %s has different value %f != %f", $s1, $2, $3)
17+
execerror(error)
18+
}
19+
}
20+
proc check_simulator() {
21+
{%- for param, value in global_params.items() %}
22+
check_parameter("{{param}}", {{value}}, {{param}})
23+
{%- endfor %}
24+
}
25+
{%- endif %}
26+
{%- if ignored_global_params %}
27+
/* The following global parameters were set in BluePyOpt
28+
{%- for param, value in ignored_global_params.items() %}
29+
* {{param}} = {{value}}
30+
{%- endfor %}
31+
*/
32+
{%- endif %}
33+
34+
begintemplate {{template_name}}
35+
public init, morphology, geom_nseg_fixed, geom_nsec, getCell, getCCell, setCCell, gid, getCell
36+
public channel_seed, channel_seed_set
37+
public connect2target, clear, ASCIIrpt
38+
public soma, dend, apic, axon, myelin, getThreshold
39+
create soma[1], dend[1], apic[1], axon[1], myelin[1]
40+
public nSecAll, nSecSoma, nSecApical, nSecBasal, nSecMyelinated, nSecAxonalOrig, nSecAxonal
41+
public CellRef, synHelperList, synlist
42+
objref this, CellRef, segCounts, ASCIIrpt, synHelperList, synlist
43+
44+
public all, somatic, apical, axonal, basal, myelinated, APC
45+
objref all, somatic, apical, axonal, basal, myelinated, APC
46+
47+
48+
obfunc getCell(){
49+
return this
50+
}
51+
52+
obfunc getCCell(){
53+
return CellRef
54+
}
55+
proc setCCell(){
56+
CellRef = $o1
57+
}
58+
59+
//-----------------------------------------------------------------------------------------------
60+
61+
/*!
62+
* When clearing the model, the circular reference between Cells and CCells must be broken so the
63+
* entity watching reference counts can work.
64+
*/
65+
proc clear() { localobj nil
66+
CellRef = nil
67+
}
68+
69+
70+
71+
/*!
72+
* @param $o1 NetCon source (can be nil)
73+
* @param $o2 Variable where generated NetCon will be placed
74+
*/
75+
proc connect2target() { //$o1 target point process, $o2 returned NetCon
76+
soma $o2 = new NetCon(&v(1), $o1)
77+
$o2.threshold = -30
78+
}
79+
80+
81+
proc init(/* args: morphology_dir, morphology_name */) {
82+
all = new SectionList()
83+
apical = new SectionList()
84+
axonal = new SectionList()
85+
basal = new SectionList()
86+
somatic = new SectionList()
87+
myelinated = new SectionList()
88+
89+
synHelperList = new List()
90+
synlist = new List()
91+
92+
//For compatibility with BBP CCells
93+
CellRef = this
94+
95+
forall delete_section()
96+
97+
gid = $1
98+
99+
if(numarg() >= 3) {
100+
load_morphology($s2, $s3)
101+
} else {
102+
{%- if morphology %}
103+
load_morphology($s2, "{{morphology}}")
104+
{%- else %}
105+
execerror("Template {{template_name}} requires morphology name to instantiate")
106+
{%- endif %}
107+
}
108+
109+
geom_nseg()
110+
indexSections()
111+
{%- if replace_axon %}
112+
replace_axon()
113+
{%- endif %}
114+
insertChannel()
115+
biophys()
116+
117+
// Initialize channel_seed_set to avoid accidents
118+
channel_seed_set = 0
119+
// Initialize random number generators
120+
re_init_rng()
121+
}
122+
123+
/*!
124+
* Assign section indices to the section voltage value. This will be useful later for serializing
125+
* the sections into an array. Note, that once the simulation begins, the voltage values will revert to actual data again.
126+
*
127+
* @param $o1 Import3d_GUI object
128+
*/
129+
proc indexSections() { local index
130+
index = 0
131+
forsec all {
132+
v(0.0001) = index
133+
index = index +1
134+
}
135+
}
136+
137+
func getThreshold() { return 0.0 }
138+
139+
proc load_morphology(/* morphology_dir, morphology_name */) {localobj morph, import, sf, extension, commands, pyobj
140+
strdef morph_path
141+
sprint(morph_path, "%s/%s", $s1, $s2) sf = new StringFunctions()
142+
extension = new String() sscanf(morph_path, "%s", extension.s)
143+
144+
// TODO fix the `-3` here.
145+
sf.right(extension.s, sf.len(extension.s)-3)
146+
147+
if( strcmp(extension.s, ".asc") == 0 ) {
148+
morph = new Import3d_Neurolucida3()
149+
} else if( strcmp(extension.s, ".swc" ) == 0) {
150+
morph = new Import3d_SWC_read()
151+
} else if( strcmp(extension.s, ".h5") == 0 ) {
152+
if(nrnpython ("from morphio_wrapper import MorphIOWrapper") == 1) {
153+
pyobj = new PythonObject()
154+
commands = pyobj.MorphIOWrapper(morph_path).morph_as_hoc()
155+
for i = 0, pyobj.len(commands) - 1 {
156+
execute(commands._[i], this)
157+
}
158+
indexSections()
159+
geom_nsec()
160+
} else {
161+
printf( ".h5 morphlogy used but cannot load 'morphio_wrapper'." )
162+
quit()
163+
}
164+
} else {
165+
printf(extension.s)
166+
printf("Unsupported file format: Morphology file has to end with .asc, .swc or .h5" )
167+
quit()
168+
}
169+
}
170+
171+
/*
172+
* Assignment of mechanism values based on distance from the soma
173+
* Matches the BluePyOpt method
174+
*/
175+
proc distribute_distance(){local x localobj sl
176+
strdef stmp, distfunc, mech
177+
178+
sl = $o1
179+
mech = $s2
180+
distfunc = $s3
181+
this.soma[0] distance(0, 0.5)
182+
sprint(distfunc, "%%s %s(%%f) = %s", mech, distfunc)
183+
forsec sl for(x, 0) {
184+
sprint(stmp, distfunc, secname(), x, distance(x))
185+
execute(stmp)
186+
}
187+
}
188+
189+
proc geom_nseg() {
190+
this.geom_nsec() //To count all sections
191+
//TODO: geom_nseg_fixed depends on segCounts which is calculated by
192+
// geom_nsec. Can this be collapsed?
193+
this.geom_nseg_fixed(40)
194+
this.geom_nsec() //To count all sections
195+
}
196+
197+
proc insertChannel() {
198+
{%- for location, names in channels.items() %}
199+
forsec this.{{location}} {
200+
{%- for channel in names %}
201+
insert {{channel}}
202+
{%- endfor %}
203+
}
204+
{%- endfor %}
205+
}
206+
207+
proc biophys() {
208+
{% for loc, parameters in section_params %}
209+
forsec CellRef.{{ loc }} {
210+
{%- for param in parameters %}
211+
{{ param.name }} = {{ param.value }}
212+
{%- endfor %}
213+
}
214+
{% endfor %}
215+
{%- for location, param_name, value in range_params %}
216+
distribute_distance(CellRef.{{location}}, "{{param_name}}", "{{value}}")
217+
{%- endfor %}
218+
}
219+
220+
func sec_count(/* SectionList */) { local nSec
221+
nSec = 0
222+
forsec $o1 {
223+
nSec += 1
224+
}
225+
return nSec
226+
}
227+
228+
/*
229+
* Iterate over the section and compute how many segments should be allocate to
230+
* each.
231+
*/
232+
proc geom_nseg_fixed(/* chunkSize */) { local secIndex, chunkSize
233+
chunkSize = $1
234+
soma area(.5) // make sure diam reflects 3d points
235+
secIndex = 0
236+
forsec all {
237+
nseg = 1 + 2*int(L/chunkSize)
238+
segCounts.x[secIndex] = nseg
239+
secIndex += 1
240+
}
241+
}
242+
243+
/*
244+
* Count up the number of sections
245+
*/
246+
proc geom_nsec() { local nSec
247+
nSecAll = sec_count(all)
248+
nSecSoma = sec_count(somatic)
249+
nSecApical = sec_count(apical)
250+
nSecBasal = sec_count(basal)
251+
nSecMyelinated = sec_count(myelinated)
252+
nSecAxonalOrig = nSecAxonal = sec_count(axonal)
253+
254+
segCounts = new Vector()
255+
segCounts.resize(nSecAll)
256+
nSec = 0
257+
forsec all {
258+
segCounts.x[nSec] = nseg
259+
nSec += 1
260+
}
261+
}
262+
263+
/*
264+
* Replace the axon built from the original morphology file with a stub axon
265+
*/
266+
{%- if replace_axon %}
267+
{{replace_axon}}
268+
{%- endif %}
269+
270+
271+
{{re_init_rng}}
272+
273+
endtemplate {{template_name}}
274+

0 commit comments

Comments
 (0)