class MotorUnitPool(object): ''' Class that implements a motor unit pool. Encompasses a set of motor units that controls a single muscle. ''' def __init__(self, conf, pool): ''' Constructor - Inputs: + **conf**: Configuration object with the simulation parameters. + **pool**: string with Motor unit pool to which the motor unit belongs. ''' ## Indicates that is Motor Unit pool. self.kind = 'MU' ## Configuration object with the simulation parameters. self.conf = conf ## String with Motor unit pool to which the motor unit belongs. self.pool = pool MUnumber_S = int(conf.parameterSet('MUnumber_' + pool + '-S', pool, 0)) MUnumber_FR = int( conf.parameterSet('MUnumber_' + pool + '-FR', pool, 0)) MUnumber_FF = int( conf.parameterSet('MUnumber_' + pool + '-FF', pool, 0)) ## Number of motor units. self.MUnumber = MUnumber_S + MUnumber_FR + MUnumber_FF ## List of MotorUnit objects. self.unit = [] for i in xrange(0, self.MUnumber): if i < MUnumber_S: self.unit.append(MotorUnit(conf, pool, i, 'S')) elif i < MUnumber_S + MUnumber_FR: self.unit.append(MotorUnit(conf, pool, i, 'FR')) else: self.unit.append(MotorUnit(conf, pool, i, 'FF')) ## Vector with the instants of spikes in the soma compartment, in ms. self.poolSomaSpikes = np.array([]) ## Vector with the instants of spikes in the terminal, in ms. self.poolTerminalSpikes = np.array([]) #activation signal self.Activation = MuscularActivation(self.conf, self.pool, self.MUnumber, self.unit) #Force ## String indicating whther a Hill model is used or not. For now, it can be *No*. self.hillModel = conf.parameterSet('hillModel', pool, 0) if self.hillModel == 'No': self.Muscle = MuscleNoHill(self.conf, self.pool, self.MUnumber, MUnumber_S, self.unit) else: self.Muscle = MuscleHill(self.conf, self.pool, self.MUnumber, MUnumber_S, self.unit) ## #print 'Motor Unit Pool ' + pool + ' built' # MP # Spawn de dois processos no codigo cprc.py self.comm = MPI.COMM_SELF.Spawn(sys.executable, args=['cprc.py'], maxprocs=1) # Merge para juntar todos processos em um so grupo self.common_comm = self.comm.Merge(False) # Numero de processos (tamanho do comunicador) self.size = self.common_comm.Get_size() print 'size = ' + str(self.size) # Porcao que cada processo recebe # Processo pai nao participa (por isso - 1) self.procSize = len(self.unit) / (self.size - 1) def atualizeMotorUnitPool(self, t): ''' Update all parts of the Motor Unit pool. It consists to update all motor units, the activation signal and the muscle force. - Inputs: + **t**: current instant, in ms. ''' t = self.common_comm.bcast(t, root=0) for rank in xrange(1, self.size): self.common_comm.send(self.unit[(rank - 1) * self.procSize:rank * self.procSize], dest=rank, tag=rank) for rank in xrange(1, self.size): self.unit[(rank - 1) * self.procSize:rank * self.procSize] = self.common_comm.recv(source=rank, tag=rank) #self.common_comm.Recv(self.unit[(rank - 1) * self.procSize:rank * self.procSize], source=rank,tag=rank) # Forma original #for i in self.unit: i.atualizeMotorUnit(t) self.Activation.atualizeActivationSignal(t, self.unit) self.Muscle.atualizeForce(self.Activation.activation_Sat) def listSpikes(self): ''' List the spikes that occurred in the soma and in the terminal of the different motor units. ''' for i in xrange(0, self.MUnumber): if i == 0: somaSpikeTrain = np.array(self.unit[i].somaSpikeTrain) terminalSpikeTrain = np.array(self.unit[i].terminalSpikeTrain) else: somaSpikeTrain = np.append( somaSpikeTrain, np.array(self.unit[i].somaSpikeTrain)) terminalSpikeTrain = np.append( terminalSpikeTrain, np.array(self.unit[i].terminalSpikeTrain)) self.poolSomaSpikes = somaSpikeTrain self.poolTerminalSpikes = terminalSpikeTrain self.poolSomaSpikes = np.reshape(self.poolSomaSpikes, (-1, 2)) self.poolTerminalSpikes = np.reshape(self.poolTerminalSpikes, (-1, 2))
class MotorUnitPool(object): ''' Class that implements a motor unit pool. Encompasses a set of motor units that controls a single muscle. ''' def __init__(self, conf, pool): ''' Constructor - Inputs: + **conf**: Configuration object with the simulation parameters. + **pool**: string with Motor unit pool to which the motor unit belongs. ''' ## Indicates that is Motor Unit pool. self.kind = 'MU' ## Configuration object with the simulation parameters. self.conf = conf ## String with Motor unit pool to which the motor unit belongs. self.pool = pool MUnumber_S = int(conf.parameterSet('MUnumber_' + pool + '-S', pool, 0)) MUnumber_FR = int( conf.parameterSet('MUnumber_' + pool + '-FR', pool, 0)) MUnumber_FF = int( conf.parameterSet('MUnumber_' + pool + '-FF', pool, 0)) ## Number of motor units. self.MUnumber = MUnumber_S + MUnumber_FR + MUnumber_FF ## List of MotorUnit objects. self.unit = [] for i in xrange(0, self.MUnumber): if i < MUnumber_S: self.unit.append(MotorUnit(conf, pool, i, 'S')) elif i < MUnumber_S + MUnumber_FR: self.unit.append(MotorUnit(conf, pool, i, 'FR')) else: self.unit.append(MotorUnit(conf, pool, i, 'FF')) ## Vector with the instants of spikes in the soma compartment, in ms. self.poolSomaSpikes = np.array([]) ## Vector with the instants of spikes in the terminal, in ms. self.poolTerminalSpikes = np.array([]) #activation signal self.Activation = MuscularActivation(self.conf, self.pool, self.MUnumber, self.unit) #Force ## String indicating whther a Hill model is used or not. For now, it can be *No*. self.hillModel = conf.parameterSet('hillModel', pool, 0) if self.hillModel == 'No': self.Muscle = MuscleNoHill(self.conf, self.pool, self.MUnumber, MUnumber_S, self.unit) else: self.Muscle = MuscleHill(self.conf, self.pool, self.MUnumber, MUnumber_S, self.unit) ## #print 'Motor Unit Pool ' + pool + ' built' # MPI self.comm = MPI.COMM_WORLD self.size = self.comm.Get_size() self.rank = self.comm.Get_rank() self.procSize = self.MUnumber / self.size self.unitSlice = [] print 'size ' + str(self.size) print 'rank ' + str(self.rank) print 'procSize ' + str(self.procSize) def atualizeMotorUnitPool(self, t): ''' Update all parts of the Motor Unit pool. It consists to update all motor units, the activation signal and the muscle force. - Inputs: + **t**: current instant, in ms. ''' #### Primeira tentativa a falhar #self.unitSlice = copy.deepcopy(self.unit[self.rank * self.procSize:(self.rank + 1) * self.procSize]) #for i in self.unitSlice: i.atualizeMotorUnit(t) #self.aux = self.comm.allgather (self.unitSlice) #self.unit = copy.deepcopy(list(itertools.chain.from_iterable(self.aux))) #### #### # Forma original de se atualizar as unidades # Forma original #for i in self.unit: i.atualizeMotorUnit(t) # Forma levemente alterada #for i in xrange(self.rank * self.procSize,(self.rank + 1) * self.procSize): # self.unit[i].atualizeMotorUnit(t) #### #### Alteracoes principais # Cada processo usa um pedaco de self.unit unittest = [] for i in xrange(self.rank * self.procSize, (self.rank + 1) * self.procSize): self.unitSlice.append(self.unit[i]) for i in self.unitSlice: i.atualizeMotorUnit(t) # Fazer atualize MotorUnit normalmente e entao usar allgather reproduz # o erro aux = self.comm.allgather(self.unitSlice) # Flattening, pois allgather retorna lista de listas for i in xrange(len(aux)): for j in xrange(len(aux[i])): unittest.append((aux[i])[j]) # alternativa ao metodo acima #self.unittest=list(itertools.chain.from_iterable(self.aux)) # Para checar se sao iguais #if self.rank==0: # print self.unittest[0]==self.unit[0] # print vars(self.unittest[0]) # print vars(self.unit[0]) # Retornando valores para self.unit self.unit = [] for i in xrange(len(unittest)): #self.unit.append(copy.copy(self.unittest[i])) # alternativa self.unit.append(unittest[i]) # Checando os objetos synapses #if self.rank==0: # print vars(self.unit[0].transmitSpikesThroughSynapses[0]), '1' # print vars(self.unit[0].transmitSpikesThroughSynapses[1]), '2' self.unitSlice = [] ## O valor dessa variavel e sempre zero qnd o erro ocorre #print self.unit[0].iIonic #### self.Activation.atualizeActivationSignal(t, self.unit) self.Muscle.atualizeForce(self.Activation.activation_Sat) def listSpikes(self): ''' List the spikes that occurred in the soma and in the terminal of the different motor units. ''' for i in xrange(0, self.MUnumber): if i == 0: somaSpikeTrain = np.array(self.unit[i].somaSpikeTrain) terminalSpikeTrain = np.array(self.unit[i].terminalSpikeTrain) else: somaSpikeTrain = np.append( somaSpikeTrain, np.array(self.unit[i].somaSpikeTrain)) terminalSpikeTrain = np.append( terminalSpikeTrain, np.array(self.unit[i].terminalSpikeTrain)) self.poolSomaSpikes = somaSpikeTrain self.poolTerminalSpikes = terminalSpikeTrain self.poolSomaSpikes = np.reshape(self.poolSomaSpikes, (-1, 2)) self.poolTerminalSpikes = np.reshape(self.poolTerminalSpikes, (-1, 2))
class MotorUnitPool(object): ''' Class that implements a motor unit pool. Encompasses a set of motor units that controls a single muscle. ''' def __init__(self, conf, pool): ''' Constructor - Inputs: + **conf**: Configuration object with the simulation parameters. + **pool**: string with Motor unit pool to which the motor unit belongs. ''' self.t = 0 ## Indicates that is Motor Unit pool. self.kind = 'MU' ## Configuration object with the simulation parameters. self.conf = conf ## String with Motor unit pool to which the motor unit belongs. self.pool = pool MUnumber_S = int(conf.parameterSet('MUnumber_' + pool + '-S', pool, 0)) MUnumber_FR = int( conf.parameterSet('MUnumber_' + pool + '-FR', pool, 0)) MUnumber_FF = int( conf.parameterSet('MUnumber_' + pool + '-FF', pool, 0)) ## Number of motor units. self.MUnumber = MUnumber_S + MUnumber_FR + MUnumber_FF ## Muscle thickness, in mm. self.muscleThickness_mm = float( self.conf.parameterSet('thickness:' + pool, pool, 0)) ## Dictionary of MotorUnit objects. self.unit = dict() for i in xrange(0, self.MUnumber): if i < MUnumber_S: self.unit[i] = MotorUnit(conf, pool, i, 'S', self.muscleThickness_mm, conf.skinThickness_mm) elif i < MUnumber_S + MUnumber_FR: self.unit[i] = MotorUnit(conf, pool, i, 'FR', self.muscleThickness_mm, conf.skinThickness_mm) else: self.unit[i] = MotorUnit(conf, pool, i, 'FF', self.muscleThickness_mm, conf.skinThickness_mm) # This is used to get values from MotorUnit.py and make computations # in MotorUnitPool.py # TODO create it all here instead? self.totalNumberOfCompartments = 0 for i in xrange(self.MUnumber): self.totalNumberOfCompartments = self.totalNumberOfCompartments \ + self.unit[i].compNumber self.v_mV = np.zeros((self.totalNumberOfCompartments), dtype=np.double) self.G = lil_matrix( (self.totalNumberOfCompartments, self.totalNumberOfCompartments), dtype=float) self.iInjected = np.zeros_like(self.v_mV, dtype='d') self.capacitanceInv = np.zeros_like(self.v_mV, dtype='d') self.iIonic = np.full_like(self.v_mV, 0.0) self.EqCurrent_nA = np.zeros_like(self.v_mV, dtype='d') # Retrieving data from Motorneuron class # Vectors or matrices from Motorneuron compartments are copied, # populating larger vectors or matrices that will be used for computations for i in xrange(self.MUnumber): self.v_mV[i*self.unit[i].compNumber:i*self.unit[i].compNumber \ +self.unit[i].v_mV.shape[0]] = self.unit[i].v_mV # Consists of smaller matrices on its diagonal self.G[i*self.unit[i].compNumber:i*self.unit[i].compNumber \ +self.unit[i].G.shape[0], \ i*self.unit[i].compNumber:i*self.unit[i].compNumber \ +self.unit[i].G.shape[1]] = self.unit[i].G self.capacitanceInv[i*self.unit[i].compNumber: \ i*self.unit[i].compNumber \ +self.unit[i].capacitanceInv.shape[0]] \ = self.unit[i].capacitanceInv self.EqCurrent_nA[i*self.unit[i].compNumber: \ i*self.unit[i].compNumber \ +self.unit[i].EqCurrent_nA.shape[0]] \ = self.unit[i].EqCurrent_nA self.sizeOfBlock = int(self.totalNumberOfCompartments / self.MUnumber) self.G = self.G.tobsr(blocksize=(self.sizeOfBlock, self.sizeOfBlock)) # TODO Conditional GPU use #self.GGPU = pcu.csr_matrix(self.G) #self.GPU = pcu.Sparse(0) #self.m, self.n = self.GGPU.shape #self.nnz = self.GGPU.nnz #self.descr = self.GPU.matdescr() #self.csrVal = self.GGPU.data #self.csrRowPtr = self.GGPU.indptr #self.csrColInd = self.GGPU.indices self.dVdtValue = np.empty(self.totalNumberOfCompartments, dtype=np.double) ## Vector with the instants of spikes in the soma compartment, in ms. self.poolSomaSpikes = np.array([]) ## Vector with the instants of spikes in the last dynamical compartment, in ms. self.poolLastCompSpikes = np.array([]) ## Vector with the instants of spikes in the terminal, in ms. self.poolTerminalSpikes = np.array([]) #activation signal self.Activation = MuscularActivation(self.conf, self.pool, self.MUnumber, self.unit) #Force ## String indicating whther a Hill model is used or not. For now, it can be *No*. self.hillModel = conf.parameterSet('hillModel', pool, 0) if self.hillModel == 'No': self.Muscle = MuscleNoHill(self.conf, self.pool, self.MUnumber, MUnumber_S, self.unit) else: self.Muscle = MuscleHill(self.conf, self.pool, self.MUnumber, MUnumber_S, self.unit) # EMG ## EMG along time, in mV. self.emg = np.zeros( (int(np.rint(conf.simDuration_ms / conf.timeStep_ms)), 1), dtype=float) # Spindle self.spindle = MuscleSpindle(self.conf, self.pool) ## print 'Motor Unit Pool ' + pool + ' built' def atualizeMotorUnitPool(self, t): ''' Update all parts of the Motor Unit pool. It consists to update all motor units, the activation signal and the muscle force. - Inputs: + **t**: current instant, in ms. ''' np.clip( runge_kutta(self.dVdt, t, self.v_mV, self.conf.timeStep_ms, self.conf.timeStepByTwo_ms, self.conf.timeStepBySix_ms), -30.0, 120.0, self.v_mV) for i in xrange(self.MUnumber): self.unit[i].atualizeMotorUnit( t, self.v_mV[i * self.unit[i].compNumber:(i + 1) * self.unit[i].compNumber]) self.Activation.atualizeActivationSignal(t, self.unit) self.Muscle.atualizeForce(self.Activation.activation_Sat) self.spindle.atualizeMuscleSpindle(t, self.Muscle.lengthNorm, self.Muscle.velocityNorm, self.Muscle.accelerationNorm, 31, 33) def dVdt(self, t, V): #k = 0 for i in xrange(self.MUnumber): for j in xrange(self.unit[i].compNumber): self.iIonic.itemset( i * self.unit[0].compNumber + j, self.unit[i].compartment[j].computeCurrent( t, V.item(i * self.unit[0].compNumber + j))) #k += 1 return (self.iIonic + self.G.dot(V) + self.iInjected + self.EqCurrent_nA) * self.capacitanceInv ''' # TODO Conditional GPU use self.GPU.csrmv('N', self.m, self.n, self.nnz, 1.0, self.descr, self.csrVal, self.csrRowPtr, self.csrColInd, V, 0.0, self.dVdtValue) return (self.iIonic + self.dVdtValue + self.iInjected + self.EqCurrent_nA) * self.capacitanceInv return (self.iIonic + SpMV_viaMKL(self.G,V,self.MUnumber, self.sizeOfBlock) + self.iInjected + self.EqCurrent_nA) * self.capacitanceInv ''' def listSpikes(self): ''' List the spikes that occurred in the soma and in the terminal of the different motor units. ''' for i in xrange(0, self.MUnumber): if i == 0: somaSpikeTrain = np.array(self.unit[i].somaSpikeTrain) lastCompSpikeTrain = np.array(self.unit[i].lastCompSpikeTrain) terminalSpikeTrain = np.array(self.unit[i].terminalSpikeTrain) else: somaSpikeTrain = np.append( somaSpikeTrain, np.array(self.unit[i].somaSpikeTrain)) lastCompSpikeTrain = np.append( lastCompSpikeTrain, np.array(self.unit[i].lastCompSpikeTrain)) terminalSpikeTrain = np.append( terminalSpikeTrain, np.array(self.unit[i].terminalSpikeTrain)) self.poolSomaSpikes = np.reshape(somaSpikeTrain, (-1, 2)) self.poolLastCompSpikes = np.reshape(lastCompSpikeTrain, (-1, 2)) self.poolTerminalSpikes = np.reshape(terminalSpikeTrain, (-1, 2)) def getMotorUnitPoolInstantEMG(self, t): ''' ''' emg = 0 for i in xrange(self.MUnumber): emg += self.unit[i].getEMG(t) return emg def getMotorUnitPoolEMG(self): ''' ''' for i in xrange(0, len(self.emg)): self.emg[i] = self.getMotorUnitPoolInstantEMG( i * self.conf.timeStep_ms) def reset(self): ''' ''' self.poolSomaSpikes = np.array([]) self.poolLastCompSpikes = np.array([]) self.poolTerminalSpikes = np.array([]) self.emg = np.zeros((int( np.rint(self.conf.simDuration_ms / self.conf.timeStep_ms)), 1), dtype=float) for i in xrange(self.MUnumber): self.unit[i].reset() self.Activation.reset() self.Muscle.reset()
class MotorUnitPool(object): ''' Class that implements a motor unit pool. Encompasses a set of motor units that controls a single muscle. ''' def __init__(self, conf, pool): ''' Constructor - Inputs: + **conf**: Configuration object with the simulation parameters. + **pool**: string with Motor unit pool to which the motor unit belongs. ''' ## Indicates that is Motor Unit pool. self.kind = 'MU' ## Configuration object with the simulation parameters. self.conf = conf ## String with Motor unit pool to which the motor unit belongs. self.pool = pool MUnumber_S = int(conf.parameterSet('MUnumber_S_' + pool, pool, 0)) MUnumber_FR = int(conf.parameterSet('MUnumber_FR_' + pool, pool, 0)) MUnumber_FF = int(conf.parameterSet('MUnumber_FF_' + pool, pool, 0)) ## Number of motor units. self.MUnumber = MUnumber_S + MUnumber_FR + MUnumber_FF ## List of MotorUnit objects. self.unit = [] for i in xrange(0, self.MUnumber): if i < MUnumber_S: self.unit.append(MotorUnit(conf, pool, i, 'S')) elif i < MUnumber_S + MUnumber_FR: self.unit.append(MotorUnit(conf, pool, i, 'FR')) else: self.unit.append(MotorUnit(conf, pool, i, 'FF')) ## Vector with the instants of spikes in the soma compartment, in ms. self.poolSomaSpikes = np.array([]) ## Vector with the instants of spikes in the terminal, in ms. self.poolTerminalSpikes = np.array([]) #activation signal self.Activation = MuscularActivation(self.conf,self.pool, self.MUnumber,self.unit) #Force ## String indicating whther a Hill model is used or not. For now, it can be *No*. self.hillModel = conf.parameterSet('hillModel',pool, 0) if self.hillModel == 'No': self.Muscle = MuscleNoHill(self.conf, self.pool, self.MUnumber, MUnumber_S, self.unit) else: self.Muscle = MuscleHill(self.conf, self.pool, self.MUnumber, MUnumber_S, self.unit) ## print 'Motor Unit Pool ' + pool + ' built' def atualizeMotorUnitPool(self, t): ''' Update all parts of the Motor Unit pool. It consists to update all motor units, the activation signal and the muscle force. - Inputs: + **t**: current instant, in ms. ''' for i in self.unit: i.atualizeMotorUnit(t) self.Activation.atualizeActivationSignal(t, self.unit) self.Muscle.atualizeForce(self.Activation.activation_Sat) def listSpikes(self): ''' List the spikes that occurred in the soma and in the terminal of the different motor units. ''' for i in xrange(0,self.MUnumber): if i == 0: somaSpikeTrain = np.array(self.unit[i].somaSpikeTrain) terminalSpikeTrain = np.array(self.unit[i].terminalSpikeTrain) else: somaSpikeTrain = np.append(somaSpikeTrain, np.array(self.unit[i].somaSpikeTrain)) terminalSpikeTrain = np.append(terminalSpikeTrain, np.array(self.unit[i].terminalSpikeTrain)) self.poolSomaSpikes = somaSpikeTrain self.poolTerminalSpikes = terminalSpikeTrain self.poolSomaSpikes = np.reshape(self.poolSomaSpikes, (-1, 2)) self.poolTerminalSpikes = np.reshape(self.poolTerminalSpikes, (-1, 2))