def __init__(self, conf, pool, index, kind, muscleThickness, skinThickness): ''' Constructor - Inputs: + **conf**: Configuration object with the simulation parameters. + **pool**: string with Motor unit pool to which the motor unit belongs. + **index**: integer corresponding to the motor unit order in the pool, according to the Henneman's principle (size principle). + **kind**: string with the type of the motor unit. It can be *S* (slow), *FR* (fast and resistant), and *FF* (fast and fatigable). ''' ## Configuration object with the simulation parameters. self.conf = conf ## String with the type of the motor unit. It can be ## *S* (slow), *FR* (fast and resistant) and ## *FF** (fast and fatigable). self.kind = kind self.pool = pool # Neural compartments ## The instant of the last spike of the Motor unit ## at the Soma compartment. self.tSomaSpike = float("-inf") NumberOfAxonNodes = int( conf.parameterSet('NumberAxonNodes', pool, index)) compartmentsList = ['dendrite', 'soma'] for i in xrange(0, NumberOfAxonNodes): compartmentsList.append('internode') compartmentsList.append('node') ## Integer corresponding to the motor unit order in the pool, according to the Henneman's principle (size principle). self.index = int(index) ## Dictionary of Compartment of the Motor Unit. self.compartment = dict() ## Value of the membrane potential, in mV, that is considered a spike. self.threshold_mV = conf.parameterSet('threshold', pool, index) ## Anatomical position of the neuron, in mm. self.position_mm = conf.parameterSet('position', pool, index) # EMG data self.MUSpatialDistribution = conf.parameterSet('MUSpatialDistribution', pool, 0) if self.MUSpatialDistribution == 'random': radius = (muscleThickness / 2) * np.random.uniform(0.0, 1.0) angle = 2.0 * math.pi * np.random.uniform(0.0, 1.0) x = radius * math.sin(angle) y = radius * math.cos(angle) ## Anatomical coordinate of the muscle unit in a muscle section, in (mm,mm). self.muSectionPosition_mm = [x, y] ## Distance of the MU to the EMG elctrode, in mm. self.distance_mm = math.sqrt((x + muscleThickness / 2.0 + skinThickness)**2 + y**2) ## Attenuation of the MUAP amplitude, as measured in the electrode. self.attenuationToSkin = math.exp(-self.distance_mm / conf.EMGAttenuation_mm1) ## Widening of the MUAP duration, as measured in the electrode. self.timeWidening = 1 + conf.EMGWidening_mm1 * self.distance_mm ## Type of the Hermitez-Rodiguez curve. It can be 1 or 2. self.hrType = np.random.random_integers(1, 2) ## MUAP amplitude in mV. self.ampEMG_mV = conf.parameterSet('EMGAmplitude', pool, index) self.ampEMG_mV = self.ampEMG_mV * self.attenuationToSkin ## MUAP time constant, in ms. self.timeCteEMG_ms = conf.parameterSet('EMGDuration', pool, index) self.timeCteEMG_ms = self.timeCteEMG_ms * self.timeWidening for i in xrange(len(compartmentsList)): self.compartment[i] = Compartment(compartmentsList[i], conf, pool, index, self.kind) ## Number of compartments. self.compNumber = len(self.compartment) ## Vector with membrane potential,in mV, of all compartments. self.v_mV = np.zeros((self.compNumber), dtype=np.float64) ## Vector with the last instant of spike of all compartments. self.tSpikes = np.zeros((self.compNumber), dtype=np.float64) gCoupling_muS = np.zeros_like(self.v_mV, dtype='d') for i in xrange(len(self.compartment) - 1): gCoupling_muS[i] = calcGCoupling( float(conf.parameterSet('cytR', pool, index)), self.compartment[i].length_mum, self.compartment[i + 1].length_mum, self.compartment[i].diameter_mum, self.compartment[i + 1].diameter_mum) gLeak = np.zeros_like(self.v_mV, dtype='d') capacitance_nF = np.zeros_like(self.v_mV, dtype='d') EqPot = np.zeros_like(self.v_mV, dtype='d') IPump = np.zeros_like(self.v_mV, dtype='d') compLength = np.zeros_like(self.v_mV, dtype='d') for i in xrange(len(self.compartment)): capacitance_nF[i] = self.compartment[i].capacitance_nF gLeak[i] = self.compartment[i].gLeak_muS EqPot[i] = self.compartment[i].EqPot_mV IPump[i] = self.compartment[i].IPump_nA compLength[i] = self.compartment[i].length_mum self.v_mV[i] = self.compartment[i].EqPot_mV ## Vector with the inverse of the capacitance of all compartments. self.capacitanceInv = 1.0 / capacitance_nF ## Vector with current, in nA, of each compartment coming from other elements of the model. For example ## from ionic channels and synapses. self.iIonic = np.full_like(self.v_mV, 0.0) ## Vector with the current, in nA, injected in each compartment. self.iInjected = np.zeros_like(self.v_mV, dtype='d') #self.iInjected = np.array([0, 10.0]) GC = compGCouplingMatrix(gCoupling_muS) GL = -np.diag(gLeak) ## Matrix of the conductance of the motoneuron. Multiplied by the vector self.v_mV, ## results in the passive currents of each compartment. self.G = np.float64(GC + GL) self.EqCurrent_nA = np.dot(-GL, EqPot) + IPump ## index of the soma compartment. self.somaIndex = compartmentsList.index('soma') ## index of the last compartment. self.lastCompIndex = self.compNumber - 1 ## Refractory period, in ms, of the motoneuron. self.MNRefPer_ms = float(conf.parameterSet('MNSomaRefPer', pool, index)) # delay ## String with type of the nerve. It can be PTN (posterior tibial nerve) or CPN ## (common peroneal nerve). if pool == 'SOL' or pool == 'MG' or pool == 'LG': self.nerve = 'PTN' elif pool == 'TA': self.nerve = 'CPN' ## Distance, in m, of the stimulus position to the terminal. self.stimulusPositiontoTerminal = float( conf.parameterSet('stimDistToTerm_' + self.nerve, pool, index)) ## AxonDelay object of the motor unit. if NumberOfAxonNodes == 0: dynamicNerveLength = 0 else: dynamicNerveLength = np.sum(compLength[2:-1]) * 1e-6 self.nerveLength = float( conf.parameterSet('nerveLength_' + self.nerve, pool, index)) delayLength = self.nerveLength - dynamicNerveLength if self.stimulusPositiontoTerminal < delayLength: self.Delay = AxonDelay(conf, self.nerve, pool, delayLength, self.stimulusPositiontoTerminal, index) self.stimulusCompartment = 'delay' else: self.Delay = AxonDelay(conf, self.nerve, pool, delayLength, -1, index) self.stimulusCompartment = -1 # Nerve stimulus function self.stimulusMeanFrequency_Hz = float( conf.parameterSet('stimFrequency_' + self.nerve, pool, 0)) self.stimulusPulseDuration_ms = float( conf.parameterSet('stimPulseDuration_' + self.nerve, pool, 0)) self.stimulusIntensity_mA = float( conf.parameterSet('stimIntensity_' + self.nerve, pool, 0)) self.stimulusStart_ms = float( conf.parameterSet('stimStart_' + self.nerve, pool, 0)) self.stimulusStop_ms = float( conf.parameterSet('stimStop_' + self.nerve, pool, 0)) self.stimulusModulationStart_ms = float( conf.parameterSet('stimModulationStart_' + self.nerve, pool, 0)) self.stimulusModulationStop_ms = float( conf.parameterSet('stimModulationStop_' + self.nerve, pool, 0)) exec 'def axonStimModulation(t): return ' + conf.parameterSet( 'stimModulation_' + self.nerve, pool, 0) startStep = int(np.rint(self.stimulusStart_ms / self.conf.timeStep_ms)) self.axonStimModulation = axonStimModulation ## Vector with the nerve stimulus, in mA. self.nerveStimulus_mA = np.zeros( (int(np.rint(conf.simDuration_ms / conf.timeStep_ms)), 1), dtype=float) for i in xrange(len(self.nerveStimulus_mA)): if (i * self.conf.timeStep_ms >= self.stimulusStart_ms and i * self.conf.timeStep_ms <= self.stimulusStop_ms): if (i * self.conf.timeStep_ms > self.stimulusModulationStart_ms and i * self.conf.timeStep_ms < self.stimulusModulationStop_ms): stimulusFrequency_Hz = self.stimulusMeanFrequency_Hz + axonStimModulation( i * self.conf.timeStep_ms) else: stimulusFrequency_Hz = self.stimulusMeanFrequency_Hz if stimulusFrequency_Hz > 0: stimulusPeriod_ms = 1000.0 / stimulusFrequency_Hz numberOfSteps = int( np.rint(stimulusPeriod_ms / self.conf.timeStep_ms)) if ((i - startStep) % numberOfSteps == 0): self.nerveStimulus_mA[i:int( np.rint(i + self.stimulusPulseDuration_ms / self.conf.timeStep_ms) )] = self.stimulusIntensity_mA # ## Vector with the instants of spikes at the soma. self.somaSpikeTrain = [] ## Vector with the instants of spikes at the last compartment. self.lastCompSpikeTrain = [] ## Vector with the instants of spikes at the terminal. self.terminalSpikeTrain = [] # contraction DataMUnumber_S = int(conf.parameterSet('MUnumber_S_' + pool, pool, 0)) activationModel = conf.parameterSet('activationModel', pool, 0) ## Contraction time of the twitch muscle unit, in ms. self.TwitchTc_ms = conf.parameterSet('twitchTimePeak', pool, index) ## Amplitude of the muscle unit twitch, in N. self.TwitchAmp_N = conf.parameterSet('twitchPeak', pool, index) ## Parameter of the saturation. self.bSat = conf.parameterSet('bSat' + activationModel, pool, index) ## Twitch- tetanus relationship self.twTet = conf.parameterSet('twTet' + activationModel, pool, index) ## EMG data ## Build synapses self.SynapsesOut = [] self.transmitSpikesThroughSynapses = [] self.indicesOfSynapsesOnTarget = []
def __init__(self, conf, pool, muscle, index): ''' Constructor - Inputs: + **conf**: Configuration object with the simulation parameters. + **pool**: string with Motor unit pool to which the motor unit belongs. + **muscle**: + **index**: integer corresponding to the motor unit order in the pool, according to the Henneman's principle (size principle). ''' ## Configuration object with the simulation parameters. self.conf = conf self.timeStep_ms = self.conf.timeStep_ms self.timeStepByTwo_ms = self.conf.timeStepByTwo_ms self.timeStepBySix_ms = self.conf.timeStepBySix_ms self.kind = muscle self.muscle = muscle # Neural compartments self.pool = pool NumberOfAxonNodes = int(conf.parameterSet('NumberAxonNodes', pool, index)) compartmentsList = [] for i in xrange(0, NumberOfAxonNodes): compartmentsList.append('internode') compartmentsList.append('node') ## Integer corresponding to the motor unit order in the pool, according to the Henneman's principle (size principle). self.index = int(index) ## Dictionary of Compartment of the Motor Unit. self.compartment = dict() for i in xrange(len(compartmentsList)): self.compartment[i] = Compartment(compartmentsList[i], conf, pool, index, self.kind) ## Number of compartments. self.compNumber = len(self.compartment) ## Value of the membrane potential, in mV, that is considered a spike. if self.compNumber: self.threshold_mV = conf.parameterSet('threshold', pool + '-' + muscle, index) else: self.threshold_mV = 0 ## Vector with membrane potential,in mV, of all compartments. self.v_mV = np.zeros((self.compNumber), dtype = np.float64) ## Vector with the last instant of spike of all compartments. self.tSpikes = np.zeros((self.compNumber), dtype = np.float64) gCoupling_muS = np.zeros_like(self.v_mV, dtype = 'd') for i in xrange(len(self.compartment)-1): gCoupling_muS[i] = calcGCoupling(float(conf.parameterSet('cytR',pool, index)), self.compartment[i].length_mum, self.compartment[i + 1].length_mum, self.compartment[i].diameter_mum, self.compartment[i + 1].diameter_mum) gLeak = np.zeros_like(self.v_mV, dtype = 'd') capacitance_nF = np.zeros_like(self.v_mV, dtype = 'd') EqPot = np.zeros_like(self.v_mV, dtype = 'd') IPump = np.zeros_like(self.v_mV, dtype = 'd') compLength = np.zeros_like(self.v_mV, dtype = 'd') for i in xrange(len(self.compartment)): capacitance_nF[i] = self.compartment[i].capacitance_nF gLeak[i] = self.compartment[i].gLeak_muS EqPot[i] = self.compartment[i].EqPot_mV IPump[i] = self.compartment[i].IPump_nA compLength[i] = self.compartment[i].length_mum self.v_mV[i] = self.compartment[i].EqPot_mV ## Vector with the inverse of the capacitance of all compartments. self.capacitanceInv = 1.0 / capacitance_nF ## Vector with current, in nA, of each compartment coming from other elements of the model. For example ## from ionic channels and synapses. self.iIonic = np.full_like(self.v_mV, 0.0) ## Vector with the current, in nA, injected in each compartment. self.iInjected = np.zeros_like(self.v_mV, dtype = 'd') #self.iInjected = np.array([0, 10.0]) GC = compGCouplingMatrix(gCoupling_muS) GL = -np.diag(gLeak) ## Matrix of the conductance of the motoneuron. Multiplied by the vector self.v_mV, ## results in the passive currents of each compartment. self.G = np.float64(GC + GL) self.EqCurrent_nA = np.dot(-GL, EqPot) + IPump ## index of the last compartment. self.lastCompIndex = self.compNumber - 1 ## Refractory period, in ms, of the motoneuron. self.AFRefPer_ms = float(conf.parameterSet('AFRefPer', pool, index)) # delay ## String with type of the nerve. It can be PTN (posterior tibial nerve) or CPN ## (common peroneal nerve). if self.muscle == 'SOL' or self.muscle == 'MG' or self.muscle == 'LG': self.nerve = 'PTN' elif self.muscle == 'TA': self.nerve = 'CPN' ## AxonDelay object of the motor unit. if NumberOfAxonNodes == 0: dynamicNerveLength = 0 else: dynamicNerveLength = np.sum(compLength[2:-1]) * 1e-6 self.nerveLength = float(conf.parameterSet('nerveLength_' + self.nerve, pool, index)) ## Distance, in m, of the stimulus position to the terminal. self.stimulusPositiontoTerminal = self.nerveLength - float(conf.parameterSet('stimDistToTerm_' + self.nerve, pool, index)) ##Frequency threshold of the afferent to th proprioceptor input self.frequencyThreshold_Hz = float(conf.parameterSet('frequencyThreshold', pool + '-' + muscle, index)) delayLength = self.nerveLength - dynamicNerveLength if self.stimulusPositiontoTerminal < delayLength: self.Delay = AxonDelay(conf, self.nerve, pool + '-' + self.muscle, delayLength, self.stimulusPositiontoTerminal, index) self.stimulusCompartment = 'delay' else: self.Delay = AxonDelay(conf, self.nerve, pool + '-' + self.muscle, delayLength, -1, index) self.stimulusCompartment = -1 # Nerve stimulus function self.stimulusMeanFrequency_Hz = float(conf.parameterSet('stimFrequency_' + self.nerve, pool, 0)) self.stimulusPulseDuration_ms = float(conf.parameterSet('stimPulseDuration_' + self.nerve, pool, 0)) self.stimulusIntensity_mA = float(conf.parameterSet('stimIntensity_' + self.nerve, pool, 0)) self.stimulusStart_ms = float(conf.parameterSet('stimStart_' + self.nerve, pool, 0)) self.stimulusStop_ms = float(conf.parameterSet('stimStop_' + self.nerve, pool, 0)) self.stimulusModulationStart_ms = float(conf.parameterSet('stimModulationStart_' + self.nerve, pool, 0)) self.stimulusModulationStop_ms = float(conf.parameterSet('stimModulationStop_' + self.nerve, pool, 0)) exec 'def axonStimModulation(t): return ' + conf.parameterSet('stimModulation_' + self.nerve, pool, 0) self.axonStimModulation = axonStimModulation ## Vector with the nerve stimulus, in mA. self.nerveStimulus_mA = np.zeros((int(np.rint(conf.simDuration_ms/conf.timeStep_ms)), 1), dtype = float) self.createStimulus() # ## Vector with the instants of spikes at the last compartment. self.lastCompSpikeTrain = [] ## Vector with the instants of spikes at the terminal. self.terminalSpikeTrain = [] self.GammaOrder = int(conf.parameterSet('GammaOrder_' + self.pool + '-' + self.muscle, pool, 0)) ## A PointProcessGenerator object, corresponding the generator of ## spikes of the neural tract unit. self.spikesGenerator = PointProcessGenerator(index) self.proprioceptorSpikeTrain = self.spikesGenerator.points ## Build synapses self.SynapsesOut = [] self.transmitSpikesThroughSynapses = [] self.indicesOfSynapsesOnTarget = []