def test_NeuronCalibration(self):

        with TemporaryDirectory() as tmp_dir:

            backend = loadXMLBackend(tmp_dir)

            nc0 = cal.NeuronCollection()
            nc0.setSpeedup(int(1e4))
            nc0.setStartingCycle(42)
            tmp = cal.NeuronCalibration()
            tmp.setDefaults()
            nc0.insert(0, tmp)

            self.assertLess(0, tmp.at(pyhalbe.HICANN.neuron_parameter.E_l).apply(0.5))

            backend.store("fisch", cal.MetaData(), nc0)

            nc1 = cal.NeuronCollection()
            md = cal.MetaData()
            backend.load("fisch", md, nc1)
            self.assertEqual(int(1e4), nc1.getSpeedup())
            self.assertEqual(42, nc0.getStartingCycle())

            bio = cell.EIF_cond_exp_isfa_ista()

            hwparam0 = nc0.applyNeuronCalibration(
                bio, 0, cal.NeuronCalibrationParameters())
            hwparam1 = nc1.applyNeuronCalibration(
                bio, 0, cal.NeuronCalibrationParameters())

            for idx in range(cal.HWNeuronParameter.size()):
                self.assertEqual(hwparam0.getParam(idx), hwparam1.getParam(idx),
                                 "HWNeuronParameter[{}]: {} != {}".format(
                                 idx, hwparam0.getParam(idx), hwparam1.getParam(idx)))
def extract_bio_weight_range(src, speedup, cm_bio, bigcap, neuron_size):
    """
    extract the biological range of synaptic weights in the hardware.
    First, the hardware range of a single synapse is extracted from
    the calibration of a synapse row, then these ranges are scaled back
    to the biological domain considering the relevant settings (see below).

    params:
      src     - calibdata for one synapse row of type
                pycalibtic.SynapseRowCalibration
      speedup - speedup factor of hardware emulation vs biological realtime
      cm_bio  - biological membrane capacitance in nF
      bigcap  - choose big (small) capacitance in hardware neuron if True (False)
      neuron_size - number of hardware neurons forming one compound neuron

    returns:
      tuple(min weight, max weight) in microSiemens (PyNN unit for weights)
    """
    hw_range = extract_hw_weight_range(src)
    nc = cal.NeuronCalibration()
    cm_hw = nc.big_cap if bigcap else nc.small_cap
    cm_hw *= neuron_size
    bio_range = []
    nS_to_S = 1.e-9
    nS_to_uS = 1.e-3
    for val in hw_range:
        bio_range.append(
            nc.reverseScaleConductance(val * nS_to_S, speedup, cm_bio, cm_hw) *
            nS_to_uS)
    return bio_range
    def test_ideal_calibration(self):

        nc = cal.NeuronCalibration()
        nc.setDefaults()

        for dac in range(1024):
            ideal_volt = float(dac)/nc.max_fg_value*nc.max_techn_volt
            self.assertEqual(nc.ideal_volt_to_dac(ideal_volt), dac)

        params = cal.NeuronCalibrationParameters()
        params.alphaV = 10
        params.shiftV = 1.2

        pcp = cell.IF_cond_exp()
        pcp.v_thresh = -50
        pcp.v_rest = -60
        pcp.e_rev_E = -70
        pcp.e_rev_I = -80
        pcp.tau_refrac = 10
        pcp.tau_syn_E = 2
        pcp.tau_syn_I = 2

        hw_params = nc.applyNeuronCalibration(pcp, 10000, params)

        # compare with scaling + ideal volt-to-dac or best-guess transformation
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["V_t"]), 398)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["E_l"]), 341)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["E_synx"]), 291)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["E_syni"]), 227)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["I_pl"]), 17)

        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["V_convoffi"]), 1023)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["V_convoffx"]), 1023)

        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["I_convi"]), 1023)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["I_convx"]), 1023)

        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["I_intbbi"]), 511)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["I_intbbx"]), 511)

        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["V_syni"]), 511)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["V_synx"]), 511)

        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["I_spikeamp"]), 1023)

        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["V_syntci"]), 481)
        self.assertEqual(hw_params.getParam(pyhalbe.HICANN.neuron_parameter.names["V_syntcx"]), 481)
    def test_RegressionUpcast(self):

        with TemporaryDirectory() as tmp_dir:

            backend = loadXMLBackend(tmp_dir)

            nc0 = cal.NeuronCollection()
            tmp = cal.NeuronCalibration()
            tmp.setDefaults()
            nc0.insert(0, tmp)

            backend.store("fisch", cal.MetaData(), nc0)

            nc1 = cal.NeuronCollection()
            md = cal.MetaData()
            backend.load("fisch", md, nc1)

            self.assertEqual(nc0.at(0).size(), nc1.at(0).size())
def print_default_bio_ranges():
    nc = cal.NeuronCalibration()
    nc.setDefaults()
    nc_params = cal.NeuronCalibrationParameters()
    cm_bio = 0.281  # nS, default ADEX membrane capacitance
    #cm_bio = 10. # nS, default IF_cond_exp membrane capacitance
    nc_params.bigcap = True
    nc_params.alphaV = 5.
    speedup = 10000.
    bio_ranges = extract_bio_ranges(nc, nc_params.shiftV, nc_params.alphaV,
                                    speedup, cm_bio, nc_params.bigcap)
    print("Bio ranges for parameters")
    print("speedup:", speedup)
    print("shiftV:", nc_params.shiftV, "V")
    print("alphaV:", nc_params.alphaV)
    print("bigcap:", nc_params.bigcap)
    print("cm_bio:", cm_bio, "nF")
    #pprint.pprint(bio_ranges)
    pprint_ranges_dict(bio_ranges)
    def test_reverse_apply_reverse_domains(self):

        nc = cal.NeuronCalibration()
        nc.setDefaults()

        for c in ["V_t", "E_l", "E_synx", "E_syni", "I_pl",
                  "I_gl_slow0_fast0_bigcap0", "V_syntcx", "V_syntcx"]:

            calib = nc.at(cal.NeuronCalibrationParameters.Calibrations.calib.names[c])
            reverse_domain = calib.getReverseDomainBoundaries()

            at_lower_boundary = calib.reverseApply(reverse_domain.first)
            at_upper_boundary = calib.reverseApply(reverse_domain.second)

            below_boundary = calib.reverseApply(reverse_domain.first-1, cal.Transformation.CLIP)
            above_boundary = calib.reverseApply(reverse_domain.second+1, cal.Transformation.CLIP)

            self.assertEqual(at_lower_boundary, below_boundary)
            self.assertEqual(at_upper_boundary, above_boundary)
def print_default_hw_ranges():
    nc = cal.NeuronCalibration()
    nc.setDefaults()
    hw_ranges = extract_hw_ranges(nc)
    print("DAC ranges:")
    pprint.pprint(hw_ranges)
#!/usr/bin/env python

import pycalibtic
import pycellparameters
from pyhalbe.HICANN import neuron_parameter, shared_parameter

neuron_calib = pycalibtic.NeuronCalibration()
neuron_calib.setDefaults()

neuron_calib_params = pycalibtic.NeuronCalibrationParameters()
neuron_calib_params.alphaV = 10
neuron_calib_params.shiftV = 1.2

bio_params = pycellparameters.EIF_cond_exp_isfa_ista()

bio_params.tau_refrac = 1.00
bio_params.a = 2.5
bio_params.tau_m = 10.0
bio_params.e_rev_E = 0.0
bio_params.cm = 0.24
bio_params.delta_T = 1.2
bio_params.e_rev_I = -80.0
bio_params.v_thresh = -40.0
bio_params.b = 0.05
bio_params.tau_syn_E = 2
bio_params.v_spike = 0.0
bio_params.tau_syn_I = 2
bio_params.tau_w = 30.0
bio_params.v_rest = -60.0

speedup = 10000
"""
script to extract the domain values for the default calibration.
I.e. for each parameter, it extracts the range of biological parameters, that can be mapped to the voltage/current domain of the hardware.
"""
import pycalibtic as cal
import pyhalbe
import numpy as np

nrn_param = pyhalbe.HICANN.neuron_parameter

nc = cal.NeuronCalibration()
nc.setDefaults()
# remove domain!
for param in [
        nrn_param.E_l, nrn_param.E_synx, nrn_param.E_syni, nrn_param.V_exp,
        nrn_param.V_t, nrn_param.I_pl, nrn_param.I_radapt, nrn_param.V_syntcx,
        nrn_param.V_syntci, nrn_param.I_gl, nrn_param.I_gladapt,
        nrn_param.I_fire, nrn_param.I_rexp
]:

    coeffs = nc.at(param).getData()
    nc.reset(param, cal.Polynomial(coeffs))

min_current = 0.
max_current = 2500.

min_voltage = 0.
max_voltage = 1800.

min_current_tau = max_current * 1. / 1023
max_current_tau = max_current