"""Creates .hoc from cell."""
# Copyright 2020-2022 Blue Brain Project / EPFL
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import os
import shutil
from emodelrunner.load import (
load_config,
get_release_params,
get_rin_exp_voltage_base,
)
from emodelrunner.create_cells import create_cell_using_config
from emodelrunner.create_hoc_tools import (
create_synapse_hoc,
create_simul_hoc,
create_run_hoc,
create_main_protocol_hoc,
)
from emodelrunner.parsing_utilities import get_parser_args, set_verbosity
[docs]
def write_hoc(hoc_dir, hoc_file_name, hoc):
"""Write hoc file.
Args:
hoc_dir (str): directory to write the file in
hoc_file_name (str): name to give to the file
hoc (str): content of the file
"""
hoc_path = os.path.join(hoc_dir, hoc_file_name)
with open(hoc_path, "w", encoding="utf-8") as hoc_file:
hoc_file.write(hoc)
[docs]
def write_hocs(
hoc_paths, cell_hoc, simul_hoc, run_hoc, syn_hoc=None, main_protocol_hoc=None
):
"""Write hoc files.
Args:
hoc_paths (HocPaths): contains paths of the hoc files to be created
cell_hoc (str): content of the cell hoc file
simul_hoc (str): content of the 'create simulation' hoc file
run_hoc (str): content of the hoc file meant to run the simulation
syn_hoc (str): content of the synapses hoc file
main_protocol_hoc (str): content of the main protocol hoc file
"""
# cell hoc
write_hoc(hoc_paths.hoc_dir, hoc_paths.cell_hoc_filename, cell_hoc)
# createsimulation.hoc
write_hoc(hoc_paths.hoc_dir, hoc_paths.simul_hoc_filename, simul_hoc)
# run.hoc
write_hoc(hoc_paths.hoc_dir, hoc_paths.run_hoc_filename, run_hoc)
# synapses hoc
if syn_hoc is not None:
write_hoc(hoc_paths.syn_dir, hoc_paths.syn_hoc_filename, syn_hoc)
# main protocol hoc
if main_protocol_hoc is not None:
write_hoc(
hoc_paths.hoc_dir, hoc_paths.main_protocol_filename, main_protocol_hoc
)
[docs]
def get_hoc(config):
"""Return the hoc scripts as strings.
Args:
config (configparser.ConfigParser): configuration
Raises:
KeyError: If no voltage_base feature is found for Rin in feature file
Returns:
(str, str, str, str): cell_hoc, syn_hoc, simul_hoc, run_hoc
the hoc scripts for the cell, the synapses, the simulation and the run_launcher.
syn_hoc is None if the synapses were not added
"""
# pylint: disable=too-many-locals
# get directories and filenames from config
cell_template_path = config.get("Paths", "cell_template_path")
run_hoc_template_path = config.get("Paths", "run_hoc_template_path")
createsimulation_template_path = config.get(
"Paths", "createsimulation_template_path"
)
synapses_template_path = config.get("Paths", "synapses_template_path")
main_protocol_template_path = config.get("Paths", "main_protocol_template_path")
add_synapses = config.getboolean("Synapses", "add_synapses")
syn_temp_name = config.get("Synapses", "hoc_synapse_template_name")
hoc_paths = config.hoc_paths_args()
apical_point_isec = config.get("Protocol", "apical_point_isec")
constants_args = {
"emodel": config.get("Cell", "emodel"),
"morph_path": config.get("Paths", "morph_path"),
"gid": config.getint("Cell", "gid"),
"dt": config.getfloat("Sim", "dt"),
"celsius": config.getfloat("Cell", "celsius"),
"v_init": config.getfloat("Cell", "v_init"),
"mtype": config.get("Morphology", "mtype"),
}
# get the protocols definitions
protocols_filename = config.get("Paths", "prot_path")
with open(protocols_filename, "r", encoding="utf-8") as protocol_file:
protocol_definitions = json.load(protocol_file)
if "__comment" in protocol_definitions:
del protocol_definitions["__comment"]
# handle MainProtocol case
if "Main" in protocol_definitions.keys():
main_protocol = True
new_prot_defs = {}
for prot in protocol_definitions["Main"]["pre_protocols"]:
new_prot_defs[prot] = protocol_definitions[prot]
for prot in protocol_definitions["Main"]["other_protocols"]:
new_prot_defs[prot] = protocol_definitions[prot]
else:
main_protocol = False
new_prot_defs = protocol_definitions
# get cell
cell = create_cell_using_config(config)
release_params = get_release_params(config)
# get cell hoc
cell_hoc = cell.create_custom_hoc(
release_params,
template_path=cell_template_path,
syn_dir=hoc_paths.syn_dir_for_hoc,
syn_hoc_filename=hoc_paths.syn_hoc_filename,
syn_temp_name=syn_temp_name,
)
simul_hoc = create_simul_hoc(
template_path=createsimulation_template_path,
add_synapses=add_synapses,
hoc_paths=hoc_paths,
constants_args=constants_args,
protocol_definitions=new_prot_defs,
apical_point_isec=apical_point_isec,
)
run_hoc = create_run_hoc(
template_path=run_hoc_template_path,
main_protocol=main_protocol,
)
if main_protocol:
rin_exp_voltage_base = get_rin_exp_voltage_base(
config.get("Paths", "features_path")
)
main_protocol_hoc = create_main_protocol_hoc(
template_path=main_protocol_template_path,
protocol_definitions=protocol_definitions,
rin_exp_voltage_base=rin_exp_voltage_base,
mtype=constants_args["mtype"],
)
else:
main_protocol_hoc = None
# get synapse hoc
if cell.add_synapses:
# load synapse config data
syn_mech_args = config.syn_mech_args()
# get synapse hoc
syn_hoc = create_synapse_hoc(
syn_mech_args=syn_mech_args,
syn_hoc_dir=hoc_paths.syn_dir_for_hoc,
template_path=synapses_template_path,
gid=cell.gid,
dt=constants_args["dt"],
synapses_template_name=syn_temp_name,
)
else:
syn_hoc = None
return cell_hoc, syn_hoc, simul_hoc, run_hoc, main_protocol_hoc
[docs]
def copy_features_hoc(config):
"""Copy features hoc file into cell directory."""
features_original_path = config.get("Paths", "features_hoc_template_path")
features_new_path = os.path.join(
config.get("Paths", "memodel_dir"), config.get("Paths", "features_hoc_file")
)
shutil.copy(features_original_path, features_new_path)
if __name__ == "__main__":
args = get_parser_args()
set_verbosity(args.verbosity)
config_ = load_config(config_path=args.config_path)
cell_hoc_, syn_hoc_, simul_hoc_, run_hoc_, main_protocol_hoc_ = get_hoc(
config=config_
)
hoc_paths_ = config_.hoc_paths_args()
if main_protocol_hoc_:
copy_features_hoc(config_)
write_hocs(
hoc_paths_,
cell_hoc_,
simul_hoc_,
run_hoc_,
syn_hoc_,
main_protocol_hoc_,
)