STiMCON_core.py
# -*- coding: utf-8 -*-
"""
Created on Fri May 1 09:14:09 2020
@author: sanoev
STiMCON: Speech Timing in a Model Constrained Oscillatory Network
This script contains the core code for a single layer of the STiMCON
"""
import numpy as np
import math as math
#%% define class for single layer activation parameters
class modelPara(object):
def __init__(self, parameters):
self.Nnodes = parameters['Nnodes']
self.oscFreq = parameters['OsFreq']
self.oscAmp = parameters['OsAmp']
self.oscOffset = parameters['OsOffset']
self.latAct_thres = parameters['activation_threshold']
self.feedbackInfluence = parameters['feedbackinf']
self.feedbackDecay = parameters['feedbackdecay']
self.feedbackDelay = parameters['feedbackdelay']
self.feedbackMat = parameters['feedbackmat']
self.latLatinhib = parameters['latinhibstrength']
self.latSelexc = parameters['selfexitation']
self.latInhib = parameters['Inhib']
self.fs = parameters['fs']
def runsingle(self, sensory_input):
# define the layers
semantic_node = np.zeros(self.Nnodes)
feedback_conn = np.zeros(self.Nnodes)
feedforward_conn = np.zeros(self.Nnodes)
inhibT = np.zeros(self.Nnodes)+200*self.fs
# main loop
Ntime = np.ma.size(sensory_input,1)
act = np.zeros([self.Nnodes,int(Ntime)]) # activation
sptim = np.zeros([self.Nnodes,int(Ntime)]) # spike times (1: through feedback, 2: through feedforward + feedback)
fbm = np.zeros([self.Nnodes,int(Ntime)]) # feedback input (fbm2 is feedback input including the delay for plotting)
for T in range(0,len(sensory_input[0])):
for nodecnt in range(0,self.Nnodes):
feedforward_conn[nodecnt] = feedforward_conn[nodecnt]-self.feedbackDecay
if feedforward_conn[nodecnt]<0:
feedforward_conn[nodecnt] = 0
inhibT[nodecnt] = inhibT[nodecnt]+1
semantic_node[nodecnt] = semantic_node[nodecnt]*self.latSelexc + self.oscFun(T) + sensory_input[nodecnt,T] + \
fbm[nodecnt,T-self.feedbackDelay] + self.inhibFun(inhibT[nodecnt])
semantic_node = self.latin(semantic_node)
for nodecnt in range(0,self.Nnodes):
if semantic_node[nodecnt] > self.latAct_thres:
if act[nodecnt][T-1] < self.latAct_thres:
inhibT[nodecnt] = 0
sptim[nodecnt,T] = 1
if sensory_input[nodecnt,T] > 0:
feedforward_conn = np.zeros(self.Nnodes);
feedforward_conn[nodecnt] = 1
sptim[nodecnt,T] = 2
act[nodecnt][T] = semantic_node[nodecnt]
feedback_conn = self.feedback(feedforward_conn)
fbm[:,T] = feedback_conn
fbm2 = np.concatenate((np.zeros([self.Nnodes, self.feedbackDelay]), fbm[:,0:-self.feedbackDelay]), 1)
modelOut = {'activation': act,
'spiketimes': sptim,
'feedback': fbm,
'feedbackdel': fbm2};
return modelOut
def oscFun(self,T):
return (math.cos(2.0*math.pi*float(T/self.fs)*self.oscFreq+self.oscOffset)*self.oscAmp)
def inhibFun(self,Ti):
inhib = self.latInhib
if Ti < 0.02*self.fs:
inhib = inhib*-3 # suprathreshold activation
elif Ti < 0.05*self.fs:
inhib = inhib*3
elif Ti < 0.1*self.fs:
inhib = inhib*3
return inhib
def latin(self, semantic_node):
latmat = np.zeros([self.Nnodes,self.Nnodes])+self.latLatinhib
np.fill_diagonal(latmat, 0)
semantic_node.dot(latmat)
semantic_node = semantic_node + semantic_node.dot(latmat)
return semantic_node
def feedback(self,feedforward_conn):
feedbackmat = self.feedbackMat*self.feedbackInfluence
feedback_conn = feedforward_conn.dot(feedbackmat)
return feedback_conn