I defined a custom closed-loop stimulus class in a previous version of TVB (1.5.3, I think). However, since getting a new computer, I have switched to a newer version of TVB (1.5.8), and it seems that the custom stimulus class no longer works. I included my code and the error that I received below.
If the average activity of a particular state variable at each node exceeds a value, the code defines a waveform and iteratively inputs a point of that waveform to the stimulator at each following time point. After a certain period of stimuli, a pause period is defined that prevents stimulation for a certain number of time points.
# Create Stimulation Class
class Stim(patterns.StimuliRegion):
def __init__(self, *args, **kwargs):
super(Stim, self).__init__(*args, **kwargs)
self.threshold1 = -.8 # threshold for mean activity of state variable 0
self.threshold2 = -.5 # threshold for mean activity of state variable 1
self.T1 = 100
self.T = self.T1 #int(self.T1*(1/int_time_step))
self.stim_initiated = 0; #has stimulation been initiated?; controls whether import first stim value/start stim or output later stim values
self.timeleft2stim = self.T-1; #length of stim period minus one; a decreasing indicator of whether stimulation should occur
self.stim_idx = 0; #index of stimulus to output
self.pause = 0; #this is used to create a pause to let the amplitude of the model return to interictal after stimulation
def __call__(self, time, space=None):#nodes):
n_node = self.state.shape[1]
self.stimulus = np.zeros(n_node)
if self.pause == 0: # if it is possible to stimulate at this time (i.e. the pause indicator is not active)
if self.stim_initiated == 0: # if stimulation is not ongoing
if time > 2e3 and mean(self.state[0, epileptogenic_area_indices, 0]) > self.threshold1 and mean(self.state[1, epileptogenic_area_indices, 0]) > self.threshold2:
self.freq = 10 # number of stimuli per 100 time points (T)
self.amp = 9 # amplitude of stimulation
self.t = np.linspace(0,1,self.T,endpoint = False) # define time indices
self.sig = ((sc.signal.square(2*np.pi*self.freq*self.t)+1)/2)*self.amp # define waveform that you can iterate over
self.stimulus[epileptogenic_area_indices] = self.sig[self.stim_idx] # feed value from waveform into stimulus variable
self.stim_initiated = 1 # signal that stimulation has been turned on
self.timeleft2stim -= 1 # decrease the remaining length of stimulation time by 1 point
elif self.stim_initiated == 1: # if stimulation is ongoing
self.stim_idx +=1 # advance the index of the stimulation waveform that will be passed to the stimulator
self.timeleft2stim -=1
if self.timeleft2stim > 0: # if the amount of time left to stim is greater than 0
self.stimulus[epileptogenic_area_indices] = self.sig[self.stim_idx] # pass the next index of the signal to the stimulus
else:
self.stim_initiated = 0
self.timeleft2stim = self.T-1 #reset stim length value
self.stim_idx = 0 # reset stimulus index
self.pause = 400 # set pause to 100 time points (i.e. no stimulus will occur for 400 time points)
self.stimulus[epileptogenic_area_indices] = 0 # turn the stimulus value to 0
else: # if stimulation is on pause
self.pause -= 1 # reduce the remaining pause duration
self.stimulus[epileptogenic_area_indices] = 0 # make sure the stimulus value is set to 0
return self.stimulus # maybe try self.eqn_t
def set_state(self, state):
self.state = state
def configure_time(self, t):
pass
---------------------------------------------------------------------------
TraitAttributeError Traceback (most recent call last)
<ipython-input-9-5a00b4aa5ed7> in <module>
2
3 stim = Stim()
----> 4 stim.configure()
5
6 hiss = noise.Additive(nsig = numpy.array([0.003, 0.003, 0., 0.003, 0.003, 0.]))
~\anaconda3\envs\TVB_env\lib\site-packages\tvb\basic\neotraits\_core.py in configure(self, *args, **kwargs)
222 Override to compute uninitialized state of the class.
223 """
--> 224 self.validate()
225
226
~\anaconda3\envs\TVB_env\lib\site-packages\tvb\basic\neotraits\_core.py in validate(self)
214 # read all declarative attributes. This will trigger errors if they are
215 # in an invalid state, like beeing required but not set
--> 216 getattr(self, k)
217
218
~\anaconda3\envs\TVB_env\lib\site-packages\tvb\basic\neotraits\_attr.py in __get__(self, instance, owner)
168 if self.required and value is None:
169 raise TraitAttributeError('required attribute referenced before assignment. '
--> 170 'Use a default or assign a value before reading it', attr=self)
171 return value
172
TraitAttributeError: required attribute referenced before assignment. Use a default or assign a value before reading it
attribute tvb.datatypes.patterns.StimuliRegion.connectivity = Attr(field_type=<class 'tvb.datatypes.connectivity.Connectivity'>, default=None, required=True)