Beispiel #1
0
    def locate_pads_on_nerve(self):
        """ Find the locations in the nerve corresponding 
		to the pads """

        # Iterate over the ring's pads
        self.contact_points = []

        for i_pad in range(self.npads):
            # The pad's angular position determines which cable cell(s)
            # is (are) stimulated

            # Select which of the targets is in contact
            # with a pad 'i_pad' according to its angular position
            angdiff = np.abs(ws.contour_angles - self.thts[i_pad])
            which_cables = np.where(angdiff == angdiff.min())[0]

            # Iterate over possible cables
            ncables_here = len(which_cables)
            for i_cable in which_cables:
                # For cable_cell i, see where this is
                try:
                    i_sec, zpos = anatomy.locate(ws.seclens[i_cable], self.z)
                except TypeError:
                    msg = 'ERROR: A ring of an electrode could not be placed on the nerve'
                    ws.log(msg)
                    ws.terminate()
                # Add the point
                point = {'cable': i_cable, 'section': i_sec, 'z': zpos}
                try:
                    self.contact_points[i_pad].append(point)
                except IndexError:
                    self.contact_points.append([point])
Beispiel #2
0
    def __init__(self, name):

        self.name = name
        settings = ws.electrodes_settings[name]
        self.type = settings['type']
        self.role = settings['role']
        self.z = settings['z-position']
        self.nrings = settings['number of rings']
        self.rng_sp = settings['inter-ring distance']
        self.nppr = settings['pads per ring']
        self.length = settings['length']
        self.thickness = settings['thickness']
        self.rho = settings['insulator resistivity']
        self.center = ws.nvt.circumcenter
        self.d_in = ws.nvt.circumdiameter
        self.d_out = self.d_in + 2. * self.thickness
        if self.role == 'stimulation':
            self.stimulation_protocol = \
             settings['stimulation protocol']

        # Necessary by-products

        # Ends of the cuff
        z = self.z
        l = self.length
        nrings = self.nrings
        left_end = z - 0.5 * l
        rght_end = z + 0.5 * l

        # Positions of the rings
        rings_halfspan = 0.5 * (nrings - 1) * self.rng_sp
        z_ring_left = z - rings_halfspan
        z_ring_rght = z + rings_halfspan
        self.rings_poss = np.linspace(z_ring_left, z_ring_rght, nrings)

        # Angular positions of the pads on the rings
        self.thts = settings['angular positions']
        # Consistency check
        if len(self.thts) != self.nppr:
            msg = 'ERROR: Different number of pads and angles for them'
            ws.log(msg)
            ws.terminate()

        # Warning if size mismatch
        if z_ring_left < left_end or z_ring_rght > rght_end:
            msg = 'ERROR: Cuff electrode rings outside the cuff.'
            ws.log(msg)
            ws.terminate()

        # Store variables into attributes
        self.left_end = left_end
        self.rght_end = rght_end
        self.z_ring_left = z_ring_left
        self.z_ring_rght = z_ring_rght

        # Create rings
        self.create_rings()
Beispiel #3
0
def parameter_regressions(filename):
    """ Open and read a file with parameters over which to make 
	regressions and obtain new expressions and values """
    # Read data
    with open(filename, 'r') as f:
        frl = list(csv.reader(f))
        keys = frl[0]
        data = np.array(frl[1:], dtype=np.float64)

    n_fields = len(keys)
    n_entries = len(data)
    data_dict = OrderedDict()
    for i in range(n_fields):
        data_dict[keys[i]] = data[:, i]

    # Independent variable
    indepvar = keys[0]

    # Dictionary containing the regressions
    regressions = OrderedDict()
    # Of course, indicate which one is the independent variable
    regressions['independent variable'] = indepvar

    for i, (k, v) in enumerate(list(data_dict.items())[1:]):

        x = data_dict[indepvar]

        # Linear regression
        slope, intercept, r_value, p_value, std_err = linregress(x, v)
        # Check if it's valid
        if intercept < 0:
            # Negative values, unacceptable. Use a polynomial fit
            # Quadratic fit
            parabolic_coeffs = np.polyfit(x, v, 2)
            if parabolic_coeffs[-1] < 0:
                # Not even a quadratic fit worked
                msg = 'ERROR: Could not obtain positive values for ' + k + ' for small ' + indepvar
                ws.log(msg)
                ws.terminate()
            # Give it a x-array that covers the whole domain
            x_ = np.linspace(0, x.max(), 100)
            ypol = polynomial(x_, parabolic_coeffs)
            # return polynomial regression
            a, b, c = parabolic_coeffs
            regressions[k] = lambda x: a * x**2 + b * x + c
        else:
            # Plot linear regression
            # Create straight line object and draw it
            sl = geo.StraightLine((0, intercept), slope)
            regressions[k] = sl.equation
    return regressions
Beispiel #4
0
def list_to_number(l):
    """ Given a list or a list of lists with ONLY ONE NUMBER INSIDE, 
	retrieve that number.
	If there's more than one number, yield an error and quit """

    # Check if it's a list or a number
    try:
        ll = len(l)
    except TypeError:
        # It's probably a number, so just return it as it is
        return float(l)

    l = np.array(l).flatten()
    if len(l) != 1:
        msg = 'ERROR: tools.list_to_number got a list with more than one number'
        ws.log(msg)
        ws.terminate()

    return float(l[0])
Beispiel #5
0
    def __init__(self, name, index=0):

        PointElectrode.__init__(self, name, 0)
        settings = self.settings

        try:
            self.z = settings['z-position']
        except KeyError:
            self.axon = settings['axon']
            try:
                self.node = settings['node of Ranvier']
            except KeyError:
                self.node = settings['internode']
                self.position = settings['position']
            else:
                # For a node of Ranvier, inject current in the middle
                self.position = 0.5
        else:
            # Warning if position mismatch
            if self.z < 0. or self.z > ws.length:
                ws.log('ERROR: Electrode is outside the limits of the nerve.')
                ws.terminate()
        # Note: the warnings or errors for targetting a non-existing
        # node will be automatically raised by NEURON

        # Setting up this point is necessary to set up stimulation and
        # recording
        # Besides, it gives the process uniformity across
        # different types of electrodes
        cable_i = ws.nNAELC + self.axon
        k = 0
        if "node of Ranvier" in settings.keys():
            for j, sec in enumerate(ws.sections[cable_i]):
                secname = sec.name()
                if "NODE" in secname or "node" in secname:
                    if k == self.node:
                        break
                    k += 1

        self.point = {'cable': cable_i, 'section': j, 'z': self.position}

        self.set_stim_info()
Beispiel #6
0
    def __new__(cls, verts, *args, **kwargs):

        lv = len(verts)

        # Validation
        if lv == 0:
            msg = 'ERROR: Point list or array is empty.'
            try:
                ws.log(msg)
            except AttributeError:
                print(msg)
            else:
                ws.terminate()

        elif lv == 1:
            msg = 'WARNING: Defined polygon with only 1 point:\n%s. Returing point' % str(
                verts)
            try:
                ws.log(msg)
            except AttributeError:
                print(msg)
            return Point(*verts[0])

        elif lv == 2:
            msg = 'WARNING: Defined polygon with only 2 points:\n%s. Returing Segment' % str(
                verts)
            try:
                ws.log(msg)
            except AttributeError:
                print(msg)
            return Segment(verts)

            # elif lv == 3:
            # This is a triangle
            # return super(Triangle, cls).__new__(cls)
            # return super(Triangle, cls).__new__(cls)
            # I didn't get this to work...
            pass

        elif lv >= 3:
            # Now, this is a proper polygon. So, proceed.
            return super(Polygon, cls).__new__(cls)
Beispiel #7
0
def sanity_checks():
    """ Perform some checks to make sure that everything is defined 
	correctly and do whatever is necessary if not """

    # Using the Resistor Network model implies...
    if ws.settings["nerve model"] == "resistor network":

        # that there is ephaptic coupling
        if not ws.EC["presence"]:
            msg = "WARNING: Using the Resistor Network Model implies "\
              + "the presence of ephaptic coupling\nEphaptic "\
              + "coupling was activated"
            ws.log(msg)
            ws.EC["presence"] = True
            ws.EC["use"] = "resistor network"

        # that the stimulation forcing can't be "pre-computed"
        if ws.settings["stimulation"]["method"] == "pre-computed":
            msg = "ERROR: Using the Resistor Network Model implies "\
              + "that the stimulation method can't be pre-computed\n"\
              + "Please check your settings"
            ws.log(msg)
            ws.terminate()