Exemplo n.º 1
0
def save_to_file(title, result):
    """Save results to either h5 file (if DataFrame), otherwise to npy file."""
    from src.utils.file_io import create_dir
    create_dir("results", timestamp=False)
    path = os.path.join('results', title)
    if type(result) is list:
        np.save(path + '.npy', result)
    elif type(result) is pd.DataFrame:
        result.to_hdf(path, 'table')
    else:
        raise RuntimeError(f"saving failed for {result}")
    logger.info("saved")
def run_NEURON(exc_weight=1, inh_weight=1, timestamp=False, **kwargs):
    """ Run NEURON simulations where the number of inhibitory and excitatory synapses are varied independently.

    Note that results are added to a txt file, so repeated calls will only run values not present in the file
    already. To force a re-rerun, set timestamp=True

    :param exc_weight: The weighting of the synapses. If `None`, `check_synapse_strengths` is called
    :type exc_weight: int or None
    :param inh_weight: The weighting of the synapses. If `None`, `check_synapse_strengths` is called
    :type inh_weight: int or None
    :param timestamp: Include a timestamp in output file (forces re-run).
    :type timestamp: bool
    :param kwargs: Further keyword arguments to be passed to the sub-method `check_num_synapses`
        - exc_weight, inh_weight
        - exc_syn_list, inh_syn_list
        - exc_freq, inh_freq
        - exc_noise, inh_noise
        - num_runs=5
        - max_num_runs=15
        - upper_bound=15
        - break_bound=True
    :return: List of full-path file names for analysis.
    :rtype: list[str]
    """
    from neuron import h
    date = datetime.strftime(datetime.now(), '%Y-%m-%d_%Hh%M')
    # get output from NEURON (save to file for quicker re-analysis)
    if settings.NEURON_GUI:
        h.showV()
        h.showRunControl()
    create_dir(FOLDER_NAME, timestamp=False)
    try:
        h.hoc_stdout(os.path.join(FOLDER_NAME, f"hoc_stdout_{date}.txt"))
    except RuntimeError:
        pass
    files = []
    for synapse_type in ["distal_KCC2", "proximal_KCC2"]:
        if timestamp:
            f_name = os.path.join(FOLDER_NAME, f"{synapse_type}_{date}.txt")
        else:
            f_name = os.path.join(FOLDER_NAME, f"{synapse_type}.txt")
            if not os.path.exists(f_name):
                with open(f_name, 'w') as _f:
                    _f.write(date)
        logger.info("="*20 + f_name + "="*20)
        with open(f_name, 'r+') as f:
            if exc_weight is None:
                exc_weight, inh_weight = check_synapse_strengths(f)
            logger.info(f"best weights = E:{exc_weight}, I:{inh_weight}")
            check_num_synapses(f, synapse_type, exc_weight, inh_weight, **kwargs)
        files.append(f_name)
    return files
Exemplo n.º 3
0
import os
import time
from matplotlib import pyplot as plt

from src.utils.file_io import create_dir

shared.INIT_NEURON()

# fix python only using one core
# (https://stackoverflow.com/questions/15639779/why-does-multiprocessing-use-only-a-single-core-after-i-import-numpy)
os.system("taskset -p 0xff %d" % os.getpid())
fig_time = time.strftime('%Y_%m_%d_%Hh%Mm')
is_menu = 0
save_location = "results_plots/"
create_dir(save_location)


# noinspection PyArgumentEqualDefault
def iotime(
        file_name="distal",
        ifr_windowsize=0.02,
        time_points=None,
        synapse_type=1,  # 1 for persistent
        synapse_numbers=(100, 100),
        exc_input=None,
        inh_input=None,
        diam=None,
        trials=5,
        save=True):
    from src.iocurves.sim import show_menu
def run_protocol(protocol, root=None, run_using_python=True, record_output=True, timestamp=True, **kwargs):
    """
    run a test file or method
    :param protocol: the protocol to run
    :param root: name to give the run (optional)
    :param run_using_python: option for test to be processed using python or command line NEURON (default True)
    :param record_output: option to record output or not (default True)
    :param timestamp: include a timestamp for output directory
    :param kwargs: keyword arguments to be passed to test method if it is a python method
    """
    global switched_output
    # Create dir
    to_path = create_dir(root=root, timestamp=timestamp)
    date = datetime.strftime(datetime.now(), '%Y-%m-%d_%Hh%M')
    hoc_output = 'hoc_output_{}.txt'.format(date)
    print("directory: {} created".format(to_path))
    # Filter files
    included_extenstions = ['hoc', 'mod', 'py', 'm', 'txt', 'dll']
    src = 'src/' if os.path.exists('src') else ''
    file_names = []
    for ext in included_extenstions:
        file_names += glob.glob(f"{src}hoc_files/**/*.{ext}", recursive=True)

    # Copy files
    for file_name in file_names:
        copy_file(file_name, to_path)

    print("files copied")
    # Change directory, stop if error
    with cd(to_path):
        print("changed directory\nusing environment:")
        try:
            if run_using_python:
                print('Python + NEURON')
                print("----------------------------------------------------------------------------------------")
                # load neuron standard run environment (not needed if 'from neuron import gui' used)
                h.load_file('stdrun.hoc')
                if record_output and not switched_output:
                    # to see output, open the file in an editor that can view files as they update (e.g. Sublime Text)
                    h.hoc_stdout(hoc_output)
                    switched_output = True

                if isinstance(protocol, str):
                    # protocol is a hoc file
                    print("running protocol:{}".format(protocol))
                    h.load_file(protocol)
                else:
                    print("running protocol:{}".format(protocol.__name__))
                    result = start(protocol, **kwargs)
                h.hoc_stdout()  # reset output
            else:
                print("running protocol:{}".format(protocol))
                if platform.system() == 'Windows':
                    print('Windows NEURON')
                    cmds = ["c:\\nrn\\bin\\nrniv"]
                else:
                    print('Unix NEURON')
                    cmds = ["nrniv"]
                cmds.append(protocol)
                # Record shell/terminal output (best method for large output)
                if record_output:
                    logging.basicConfig(filename=hoc_output)  # set logging to output to file
                    import tempfile
                    import subprocess
                    # no realtime output
                    # Sub_TODO: fix using http://www.cyberciti.biz/faq/python-run-external-command-and-get-output/
                    with tempfile.TemporaryFile() as tempf:
                        proc = subprocess.Popen(cmds, stdout=tempf, stderr=tempf)
                        proc.wait()
                        tempf.seek(0)
                        logger.info(tempf.read())
                else:
                    os.system(" ".join(cmds))
            print("----------------------------------------------------------------------------------------")
            print("finished running NEURON")
        except Exception as e:
            print("Exception occured: {}".format(e))
        finally:
            # Exclude specific files from being zipped and deleted:
            file_names.remove('config.hoc')
            # Zip files (not data files, log files or dlls)
            #       data (dat) and log (txt) files created AFTER file_names list was generated
            with zipfile.ZipFile('files.zip', 'w', zipfile.ZIP_DEFLATED) as zip_name:
                for file_name in file_names:
                    # exclude files from being zipped
                    if not file_name.endswith('dll'):
                        zip_name.write(file_name)
            print("code files zipped...")
            # Clean up
            for file_name in file_names:
                os.remove(file_name)
            print("and removed")

    print("done with python script")
    return to_path
Exemplo n.º 5
0
ss_port = int(config.get("ServiceServer", "ss_port"))
ss_debug = bool(config.get("ServiceServer", "ss_debug"))

dc_ip = config.get("DataCollectorServer", "dc_ip")
dc_port = config.get("DataCollectorServer", "dc_port")

app = Flask(__name__)

app.config['SECRET_KEY'] = "A0Zr98j/3yX R~XHH!jmN]LWX/,?RT"
app.config["SQLALCHEMY_DATABASE_URI"] = f'mysql+pymysql://{db_id}:{db_pw}@{db_ip}:{db_port}/{db_name}'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True

db = SQLAlchemy(app)

create_dir(stored_notice_board_file_path)
create_dir(stored_free_board_file_path)
create_dir(stored_archive_board_file_path)

@app.route("/")
def index():
    return "Welcome iPLAT service server"

app.register_blueprint(construct_user_blueprint(db))  # User
app.register_blueprint(construct_device_blueprint(db))  # Device
app.register_blueprint(construct_sensor_blueprint(db))  # Sensor
app.register_blueprint(construct_data_blueprint(db, stored_data_path))  # Data
app.register_blueprint(construct_free_board_blueprint(db, stored_free_board_file_path))  # Free Board
app.register_blueprint(construct_notice_board_blueprint(db, stored_notice_board_file_path))  # Notice Board
app.register_blueprint(construct_archive_blueprint(db, stored_archive_board_file_path))  # Archive
def figure_v_traces(inh_region="distal",
                    KCC2=True,
                    show_cli=False,
                    base=True,
                    synapse_type=0,
                    synapse_numbers=(100, 100),
                    hz=None,
                    mean=False,
                    savefig=False,
                    **kwargs):
    """
    Display voltage traces for an inhibitory input region (e.g. "distal") and (E, I) synapse pairs.

    Optionally include an axis for [Cl-]i.

    :param inh_region: Region for inhibitory synapses. Only those in hoc_files/cells/ are supported.
    :type inh_region: str
    :param KCC2: Open the '_KCC2' version of the hoc file instead if True.
    :type KCC2: bool
    :param show_cli: Include a plot for [Cl-]i. Only applicable when KCC2 is True.
    :type show_cli: bool
    :param base: Find steady-state values for vm and cli (`True`),
        provide the steady-state values (`(<vm value>, <cli value>)`),
        use defaults of -71 mV and 4.25 mM for vm and cli, respectively(`False`).
    :type base: bool or tuple of float
    :param synapse_type: Use frequency-based synapses (`0`) or persistant synapses (`1`).
    :type synapse_type: int
    :param synapse_numbers: Synapses numbers for the neuron in (E, I) format. A list of (E,I) pairs can be provided
        for multiple traces.
    :type synapse_numbers: list of (tuple of (int)) or tuple of int
    :param hz: Frequency of synapses (if `synapse_type` is `0`) or the relative conductance (if `synapse_type` is `1`).
    :type hz: dict
    :param mean: Additionally plot the mean vm and cli values using `plot_v_trace`
    :type mean: bool
    :param savefig: Save the figure to results_plots
    :type savefig: bool
    :param kwargs: Keyword arguments to pass to `get_trace`
    :type kwargs: dict
    :return: Steady-state voltage and [Cl-]i used for this simulation
    :rtype:
    """
    if hz is None:
        hz = {'in': 5, 'ex': 5}
    logger.info(
        f"figure_v_traces(inh_region={inh_region} KCC2={KCC2}, synapse_numbers={synapse_numbers}, hz={hz})"
    )
    cmap_name = "Blues" if inh_region == "distal" else "Greens"
    cmap = sns.color_palette(cmap_name, n_colors=len(synapse_numbers))
    if mean: cmap = None
    filename = inh_region
    if KCC2:
        filename += "_KCC2"
    else:
        show_cli = False
    logger.info("getting base vm cli")
    if base:
        if type(base) is tuple:
            vm, cli = base
        else:
            vm, cli = get_base_vm_cli(f"{inh_region}_KCC2", load=True)
    else:
        vm, cli = -71., 4.25

    if type(synapse_numbers) is tuple:
        synapse_numbers = [synapse_numbers]

    dynamic_data = []
    spikes = []
    for syn_num in synapse_numbers:
        trace_kwargs = dict(synapse_type=synapse_type,
                            synapse_numbers=syn_num,
                            hz=hz,
                            space_plot=False,
                            **kwargs)
        dynamic_data.append(get_trace(filename, vm=vm, cli=cli,
                                      **trace_kwargs))
        spikes.append(h.apc.n)
    logger.info("plotting voltage")
    fig, ax = plot_v_trace(*dynamic_data,
                           show_cli=show_cli,
                           cmap=cmap,
                           mean=mean)
    if not mean:
        for i, (spike_num, syn_num) in enumerate(zip(spikes, synapse_numbers)):
            ax[i, 0].text(ax[i, 0].get_xlim()[1],
                          0,
                          f"{spike_num:.0f}",
                          ha="left")
            ax[i, 0].set_title(str(syn_num).replace("(", "").replace(")", ""),
                               fontsize='small',
                               va='top')
    title = filename + str(hz)
    title = title.replace("{",
                          "\n(").replace("}",
                                         ")").replace("'",
                                                      "").replace(": ", "=")
    if synapse_type == 0:
        title = title.replace(",", " Hz,").replace(")", " Hz)")
    fig.suptitle(title, fontsize='medium')
    fig.align_ylabels(ax[:, 0])
    sns.despine(fig, bottom=True, left=True)
    for _ax in ax[:-1, 0]:
        _ax.xaxis.set_visible(False)
        _ax.yaxis.set_visible(False)
    sns.despine(ax=ax[-1, 0])
    fig.subplots_adjust(left=0.15, bottom=0.15)
    if savefig:
        create_dir("results_plots")
        fig.savefig(f"results_plots/figure_trace_{title}.png",
                    bbox_inches='tight',
                    facecolor='None')
        fig.savefig(f"results_plots/figure_trace_{title}.pdf",
                    bbox_inches='tight',
                    facecolor='None')
    return vm, cli
def figure_cli_heatmaps(distal,
                        proximal,
                        freqs=(5, 10, 25, 50),
                        n_trials=1,
                        show_fr=False,
                        vmin=0,
                        vmax=None,
                        savefig=False):
    """
    Heatmaps of [Cl-]i for different frequencies and (E,I) synapse pairs and for both proximal and distal.

    :param distal: List (E,I) synapse number pairs for distal input.
    :type distal: list of (tuple of (float))
    :param proximal: List (E,I) synapse number pairs for proximal input.
    :type proximal: list of (tuple of (float))
    :param freqs:
    :type freqs: list of Number or tuple of Number
    :param n_trials: Nomber of repeated runs.
    :type n_trials: int
    :param show_fr: Show the firing rate to the right of the heatmaps when plotting.
        True shows the firing rate as an arrow and text.
        Any value greater than 1 shows the firing rate as a heatmap cell (different colormap)
    :type show_fr: bool or int
    :param vmin: Minimum [Cl-]i for color range.
    :type vmin: float
    :param vmax: Maximum [Cl-]i for color range.
    :type vmax: float
    :param savefig: Whether to save the figure to results_plots
    :type savefig: bool
    """
    logger.info(f"figure_cli_heatmaps(distal={distal}, proximal={proximal}, "
                f"n_trials={n_trials}, show_fr={show_fr})")

    fig, ax2d = plt.subplots(nrows=2,
                             ncols=len(distal) + 1 + int(show_fr > 1),
                             figsize=(8, 5),
                             gridspec_kw={
                                 'width_ratios': [15] * len(distal) + [2] *
                                 (1 + int(show_fr > 1))
                             })
    cmap = sns.cubehelix_palette(16,
                                 start=2.7,
                                 rot=-.2,
                                 light=0.98,
                                 dark=0.40,
                                 as_cmap=True)
    cmap_fr = sns.color_palette("Reds" if show_fr > 1 else "magma",
                                n_colors=200,
                                desat=1)
    vmax_fr = 5
    # h.hoc_stdout("hoc_output_traces.txt")
    for fdx, (filename, synapse_numbers) in enumerate(
            zip(["distal_KCC2", "proximal_KCC2"], [distal, proximal])):
        ax = ax2d[fdx, :]
        cbar_ax = ax[-1 - int(show_fr > 1)]
        vm, cli = get_base_vm_cli(filename, load=True)

        d_cli = {}
        fr = {}
        stddev = {}
        for i, syn_n in enumerate(synapse_numbers):
            kwargs = dict(synapse_type=0,
                          synapse_numbers=syn_n,
                          space_plot=True)
            for hz in freqs:
                n_spikes = []
                sec_means = [0, 0, 0,
                             0]  # 4 sections [ldend, bdend, soma, axon]
                for t in range(n_trials):
                    logger.info(
                        f"filename={filename} syn_n={syn_n} hz={hz} t={t}")
                    _, _, _, data = get_trace(filename,
                                              vm=vm,
                                              cli=cli,
                                              hz={
                                                  'in': hz,
                                                  'ex': hz
                                              },
                                              **kwargs)
                    n_spikes.append(h.apc.n)
                    x, y = space_from_dict(data)
                    # separate x into regions based on known lengths
                    ldend = x <= -50
                    bdend = np.logical_and(-50 <= x, x <= 0)
                    soma = np.logical_and(0 <= x, x <= 15)
                    axon = x >= 15
                    for s, sec in enumerate([ldend, bdend, soma, axon]):
                        sec_means[s] += y[sec].mean()
                sec_means = [m / n_trials for m in sec_means]
                d_cli[(f"{syn_n[0]:>3.0f}:{syn_n[1]:>3.0f}", hz)] = sec_means
                fr[(f"{syn_n[0]:>3.0f}:{syn_n[1]:>3.0f}",
                    hz)] = sum(n_spikes) / n_trials
                stddev[(f"{syn_n[0]:>3.0f}:{syn_n[1]:>3.0f}",
                        hz)] = np.std(n_spikes)

        df = pd.DataFrame.from_dict(
            d_cli,
            orient='index',
            columns=["Distal\nDendrite", "Proximal\nDendrite", "Soma", "Axon"])
        df_fr = pd.DataFrame.from_dict(fr, orient='index', columns=["Output"])
        df = df.reindex(pd.MultiIndex.from_tuples(df.index))
        df_fr = df_fr.reindex(pd.MultiIndex.from_tuples(df_fr.index))
        vmin = vmin or df.values.min()
        vmax = vmax or df.values.max()
        vmin_fr = 0
        vmax_fr = max(
            vmax_fr,
            df_fr.values.max()) * 1.1  # give a 10% buffer for the cmap

        logger.info("plotting cli_heatmaps")
        for i, syn_n in enumerate(df.index.levels[0]):
            df_syn = df.loc[syn_n]
            df_fr_syn = df_fr.loc[syn_n]
            sns.heatmap(
                df_syn,
                ax=ax[i],
                annot=False,
                fmt=".1f",
                square=True,
                annot_kws=dict(fontsize='xx-small'),
                vmin=vmin,
                vmax=vmax,
                cmap=cmap,
                cbar=(i == 0),
                cbar_ax=None if i > 0 else cbar_ax,
            )

            if show_fr > 1:
                new_df = pd.concat([df_syn, df_fr_syn], axis='columns')
                mask = np.ones(df_syn.shape)
                mask = np.append(mask, np.zeros(df_fr_syn.shape), axis=1)
                cbar_fr_ax = ax[-1]
                sns.heatmap(
                    new_df,
                    ax=ax[i],
                    annot=True,
                    fmt=".1f",
                    square=False,
                    annot_kws=dict(fontsize='xx-small'),
                    vmin=vmin_fr,
                    vmax=vmax_fr,
                    cmap=cmap_fr,
                    mask=mask,
                    cbar=(i == 0),
                    cbar_ax=cbar_fr_ax,
                    cbar_kws={'label': "Firing rate (Hz)"},
                )
            elif show_fr:
                for j, _fr in enumerate(df_fr_syn['Output']):
                    idx = (len(cmap_fr) - 1) * (_fr - vmin_fr) // (vmax_fr -
                                                                   vmin_fr)
                    c = cmap_fr[int(idx)]
                    text = ax[i].annotate(f"{_fr:>2.1f}",
                                          xy=(4, j + 0.5),
                                          xytext=(4.6, j + 0.5),
                                          color=c,
                                          alpha=1,
                                          arrowprops={'arrowstyle': '<-'},
                                          fontsize='x-small',
                                          va='center')
                    # path effects can sometimes make text clearer, but it can also make things worse...
                    # text.set_path_effects([path_effects.Stroke(linewidth=0.5, foreground='black', alpha=0.5),
                    #                        path_effects.Normal()])
            ax[i].set_xticklabels(ax[i].get_xticklabels(),
                                  fontsize="small",
                                  rotation=45)
            ax[i].set_title(syn_n, fontsize='small')
            if i == 0:
                ax[i].set(ylabel='Balanced Input (Hz)')
                ax[i].set_yticklabels(df_syn.index, rotation=0)
            else:
                ax[i].set_yticklabels([])
            if i == 0:
                cbar_ax.set_xlabel(f'{settings.CLI} (mM)', ha='center')
                cbar_ax.xaxis.set_label_position('top')
    fig.tight_layout()
    if savefig:
        create_dir("results_plots", timestamp=False)
        fig.savefig(f"results_plots/figure_cli_heatmaps_{int(show_fr)}.png",
                    bbox_inches='tight',
                    facecolor='None')
        fig.savefig(f"results_plots/figure_cli_heatmaps_{int(show_fr)}.pdf",
                    bbox_inches='tight',
                    facecolor='None')
def figure_cli_distribution(
        syn_n_dist=(250, 300), syn_n_prox=(330, 90), savefig=False):
    """
    Plot the distribution of [Cl-]i along a neuron for distal and proximal inhibitory input.

    :param syn_n_dist: Number of (E, I) synapses for the distal input simulation.
    :type syn_n_dist: tuple
    :param syn_n_prox: Number of (E, I) synapses for the proximal input simulation.
    :type syn_n_prox: tuple
    :param savefig: Whether to save the figure to results_plots.
    :type savefig: bool
    """
    txt = f"figure_cli_distribution(syn_n_dist={syn_n_dist}, syn_n_prox={syn_n_prox})"
    logger.info(txt)
    fig, ax = plt.subplots(nrows=2,
                           ncols=1,
                           figsize=(8, 3.5),
                           sharey=True,
                           sharex=True)
    fig.subplots_adjust(hspace=0.5)

    for filename, syn_n, _ax in zip(['distal_KCC2', 'proximal_KCC2'],
                                    [syn_n_dist, syn_n_prox], ax):
        # steady state vm and [Cl-]i
        vm, cli = get_base_vm_cli(filename, load=True)
        trace_kwargs = dict(
            synapse_type=0,  # frequency-based
            synapse_numbers=syn_n,  # (E,I)
            space_plot=True)  # compute spatial component for cli

        # run simulations for different frequencies
        _, _, _, inh = get_trace(filename,
                                 vm=vm,
                                 cli=cli,
                                 hz={
                                     'in': 5,
                                     'ex': 0
                                 },
                                 **trace_kwargs)
        _, _, _, exc = get_trace(filename,
                                 vm=vm,
                                 cli=cli,
                                 hz={
                                     'in': 0,
                                     'ex': 5
                                 },
                                 **trace_kwargs)
        _, _, _, equal = get_trace(filename,
                                   vm=vm,
                                   cli=cli,
                                   hz={
                                       'in': 5,
                                       'ex': 5
                                   },
                                   **trace_kwargs)

        logger.info(f"space plot {filename}")
        space_plot(exc, ax=_ax, color=COLOR.E, label='5 : 0')
        space_plot(inh, ax=_ax, color=COLOR.I, label='0 : 5')
        space_plot(equal, ax=_ax, color=COLOR.E_I, label='5 : 5')
        # display some info on figure
        name = filename.split("_")[0].capitalize()
        _ax.set_title(
            f"{name} input (E: I) (# of synapses)\n"
            f"{syn_n[0]}:{syn_n[1]:>3.0f}",
            va='top',
            fontsize='medium')
    # light adjustments
    ax[0].set_xlabel("")
    # ax[0].set_xticklabels([])
    ax[0].set_xlim(-550, 500)  # 0 is soma(0)
    ax[-1].legend(title='Input (E : I) (Hz)', loc='upper right', frameon=False)
    if savefig:
        create_dir("results_plots", timestamp=False)
        fig.savefig(f"results_plots/{txt}.png",
                    bbox_inches='tight',
                    frameon=False)
        fig.savefig(f"results_plots/{txt}.pdf",
                    bbox_inches='tight',
                    frameon=False)