def generate_affine_backtransformation(self): """ Generate synthetic examples and test them to determine transformation This is the key method! """ if type(self.example) == FeatureVector: testsample = FeatureVector.replace_data( self.example, numpy.zeros(self.example.shape)) self.offset = numpy.longdouble(self._execute(testsample)) self.trafo = FeatureVector.replace_data( self.example, numpy.zeros(self.example.shape)) for j in range(len(self.example.feature_names)): testsample = FeatureVector.replace_data( self.example, numpy.zeros(self.example.shape)) testsample[0][j] = 1.0 self.trafo[0][j] = \ numpy.longdouble(self._execute(testsample) - self.offset) elif type(self.example) == TimeSeries: testsample = TimeSeries.replace_data( self.example, numpy.zeros(self.example.shape)) self.offset = numpy.longdouble(numpy.squeeze( self._execute(testsample))) self.trafo = TimeSeries.replace_data( self.example, numpy.zeros(self.example.shape)) for i in range(self.example.shape[0]): for j in range(self.example.shape[1]): testsample = TimeSeries.replace_data( self.example, numpy.zeros_like(self.example)) testsample[i][j] = 1.0 self.trafo[i][j] = \ numpy.longdouble(numpy.squeeze(self._execute(testsample)) - self.offset)
def _execute(self, data): """ Apply the windowing to the given data and return the result """ #Create a window of the correct length for the given data if self.num_of_samples is None: self.num_of_samples = data.shape[0] self.create_window_array() data_array=data.view(numpy.ndarray) #Do the actual windowing # TODO: check if windowed_data = (self.window_array.T * data) works also??? windowed_data = (self.window_array * data_array.T).T # Skip trailing zeros if self.window_has_zeros and self.reduce_window: windowed_data = windowed_data[ range(self.window_not_equal_zero[0], self.window_not_equal_zero[-1] + 1), :] result_time_series = TimeSeries.replace_data(data, windowed_data) # Adjust start and end time when chopping was done result_time_series.start_time = data.start_time + \ self.window_not_equal_zero[0] * 1000.0 / data.sampling_frequency result_time_series.end_time = \ data.end_time - (data.shape[0] - self.window_not_equal_zero[-1] - 1) * 1000.0 / data.sampling_frequency else: result_time_series = TimeSeries.replace_data(data, windowed_data) return result_time_series
def generate_affine_backtransformation(self): """ Generate synthetic examples and test them to determine transformation This is the key method! """ if type(self.example) == FeatureVector: testsample = FeatureVector.replace_data( self.example, numpy.zeros(self.example.shape)) self.offset = numpy.longdouble(self._execute(testsample)) self.trafo = FeatureVector.replace_data( self.example, numpy.zeros(self.example.shape)) for j in range(len(self.example.feature_names)): testsample = FeatureVector.replace_data( self.example, numpy.zeros(self.example.shape)) testsample[0][j] = 1.0 self.trafo[0][j] = \ numpy.longdouble(self._execute(testsample) - self.offset) elif type(self.example) == TimeSeries: testsample = TimeSeries.replace_data( self.example, numpy.zeros(self.example.shape)) self.offset = numpy.longdouble( numpy.squeeze(self._execute(testsample))) self.trafo = TimeSeries.replace_data( self.example, numpy.zeros(self.example.shape)) for i in range(self.example.shape[0]): for j in range(self.example.shape[1]): testsample = TimeSeries.replace_data( self.example, numpy.zeros_like(self.example)) testsample[i][j] = 1.0 self.trafo[i][j] = \ numpy.longdouble(numpy.squeeze(self._execute(testsample)) - self.offset)
def _execute(self, data): """ Perform a shift and normalization according (whole_data - mean(specific_samples)) / std(specific_samples) """ if self.devariance: # code copy from LocalStandardizationNode std = numpy.std(data[self.subset],axis=0) std = check_zero_division(self, std, tolerance=10**-15, data_ts=data) return TimeSeries.replace_data(data, (data-numpy.mean(data[self.subset], axis=0)) / std) else: return TimeSeries.replace_data(data, \ data-numpy.mean(data[self.subset], axis=0))
def _execute(self, x): """ Apply high pass filter to data x and return the result """ #Determine the indices of the channels which will be filtered selected_channel_names = self.selected_channels \ if self.selected_channels != None else x.channel_names selected_channel_indices = [x.channel_names.index(channel_name) \ for channel_name in selected_channel_names] if self.b is None: #Compute the FIR window which is required for the high pass filter try: b = scipy.signal.firwin(numtaps = self.taps, cutoff = self.cutoff_frequency * 2.0 / x.sampling_frequency, width = self.width, window = self.window) except TypeError: b = scipy.signal.firwin(N = self.taps-1, cutoff = self.cutoff_frequency * 2.0 / x.sampling_frequency, width = self.width, window = self.window) b = -b b[self.taps/2] = b[self.taps/2]+1 self.set_permanent_attributes(b=b) #Do the actual filtering y=x.view(numpy.ndarray) filtered_data = numpy.zeros(x.shape) for channel_index in selected_channel_indices: filtered_data[:,channel_index] = \ scipy.signal.lfilter(self.b, [1], y[:,channel_index]) result_time_series = TimeSeries.replace_data(x, filtered_data) return result_time_series
def _execute(self, x): """ Compute the energy of the given signal x using the TKEO """ # Determine the indices of the channels which will be filtered # Done only once... if self.selected_channel_indices is None: self.selected_channels = self.selected_channels \ if self.selected_channels != None else x.channel_names self.selected_channel_indices = [x.channel_names.index(channel_name) \ for channel_name in self.selected_channels] self.old_data = numpy.zeros( (2, len(self.selected_channel_indices))) filtered_data = numpy.zeros(x.shape) channel_counter = -1 for channel_index in self.selected_channel_indices: channel_counter += 1 for i in range(len(x)): if i == 0: filtered_data[i][channel_index] = \ math.pow(self.old_data[1][channel_counter],2) - ( self.old_data[0][channel_counter] * x[0][channel_index]) elif i == 1: filtered_data[i][channel_index] = \ math.pow(x[0][channel_index],2) - ( self.old_data[1][channel_counter] * x[1][channel_index]) else: filtered_data[i][channel_index] = \ math.pow(x[i-1][channel_index],2) - ( x[i-2][channel_index] * x[i][channel_index]) self.old_data[0][channel_counter] = x[-2][channel_index] self.old_data[1][channel_counter] = x[-1][channel_index] result_time_series = TimeSeries.replace_data(x, filtered_data) return result_time_series
def _execute(self, data): """ Apply the :func:`scipy.signal.lfilter` function with the DC removal coefficients on the data """ #Determine the indices of the channels which will be filtered if self.selected_channel_indices is None: self.selected_channel_names = self.selected_channels \ if self.selected_channels is not None else data.channel_names self.selected_channel_indices = [ data.channel_names.index(channel_name) for channel_name in self.selected_channel_names] # create initial filter conditions for all channels if self.internal_state is None: self.internal_state = dict() for channel_index in xrange(data.shape[1]): self.internal_state[channel_index] = \ scipy.signal.lfiltic(self.b, self.a, [0, 0]) # do the actual removal cleaned_data = numpy.zeros(data.shape) for channel_index in self.selected_channel_indices: (cleaned_data[:, channel_index], self.internal_state[channel_index]) = \ scipy.signal.lfilter(self.b, self.a, data[:, channel_index], zi=self.internal_state[channel_index]) result_time_series = TimeSeries.replace_data(data, cleaned_data) return result_time_series
def _execute(self, x): """ Apply low pass filter to data x and return the result """ #Determine the indices of the channels which will be filtered selected_channel_names = self.selected_channels \ if self.selected_channels != None else x.channel_names selected_channel_indices = [x.channel_names.index(channel_name) \ for channel_name in selected_channel_names] # Compute the FIR window which is required for the low pass filter # This is quite slow! # filter_order = 2 * x.sampling_frequency / self.cutoff_frequency filter_order = 31 if self.b is None: try: b = \ scipy.signal.firwin(numtaps = filter_order, cutoff = self.cutoff_frequency * 2.0 / x.sampling_frequency, width = self.width, window = self.window) except TypeError: b = \ scipy.signal.firwin(N = filter_order-1, cutoff = self.cutoff_frequency * 2.0 / x.sampling_frequency, width = self.width, window = self.window) self.set_permanent_attributes(b=b) #Do the actual filtering filtered_data = numpy.zeros(x.shape) y=x.view(type=numpy.ndarray) for channel_index in selected_channel_indices: filtered_data[:,channel_index] = scipy.signal.convolve(self.b, \ y[:,channel_index])[len(self.b)/2:-len(self.b)/2+1] result_time_series = TimeSeries.replace_data(x, filtered_data) return result_time_series
def merge_time_series(self, input_collection): """ Merges all timeseries of the input_collection to one big timeseries """ # Retriev the time series from the input_collection input_timeseries = input_collection.get_data(0, 0, 'test') # Get the data from the first timeseries output_data = input_timeseries[0][0].get_data() # Change the endtime of the first timeseries to the one of the last # timeseries inside the input_collection input_timeseries[0][0].end_time = input_timeseries[-1][0].end_time # For all the remaining timeseries for ts in input_timeseries[1:]: # Concatenate the data... output_data = numpy.vstack((output_data, ts[0].get_data())) # ... and add the marker to the first timeseries if (len(ts[0].marker_name) > 0): for k in ts[0].marker_name: if (not input_timeseries[0][0].marker_name.has_key(k)): input_timeseries[0][0].marker_name[k] = [] for time in ts[0].marker_name[k]: input_timeseries[0][0].marker_name[k].append( time + ts[0].start_time + input_timeseries[0][0].start_time) # Use the meta information from the first timeseries e.g. marker start/end_time # and create a new timeseries with the concatenated data merged_time_series = TimeSeries.replace_data(input_timeseries[0][0], output_data) # Change the name of the merged_time_series merged_time_series.name = "%s, length %d ms, %s" % (merged_time_series.name.split(',')[0], \ (len(merged_time_series)*1000.0)/merged_time_series.sampling_frequency,\ merged_time_series.name.split(',')[-1]) return merged_time_series
def _execute(self, x): """ Apply low pass filter to data x and return the result """ #Determine the indices of the channels which will be filtered selected_channel_names = self.selected_channels \ if self.selected_channels != None else x.channel_names selected_channel_indices = [x.channel_names.index(channel_name) \ for channel_name in selected_channel_names] # Compute the FIR window which is required for the low pass filter # This is quite slow! # filter_order = 2 * x.sampling_frequency / self.cutoff_frequency filter_order = 31 if self.b is None: try: b = \ scipy.signal.firwin(numtaps = filter_order, cutoff = self.cutoff_frequency * 2.0 / x.sampling_frequency, width = self.width, window = self.window) except TypeError: b = \ scipy.signal.firwin(N = filter_order-1, cutoff = self.cutoff_frequency * 2.0 / x.sampling_frequency, width = self.width, window = self.window) self.set_permanent_attributes(b=b) #Do the actual filtering filtered_data = numpy.zeros(x.shape) y = x.view(type=numpy.ndarray) for channel_index in selected_channel_indices: filtered_data[:,channel_index] = scipy.signal.convolve(self.b, \ y[:,channel_index])[len(self.b)/2:-len(self.b)/2+1] result_time_series = TimeSeries.replace_data(x, filtered_data) return result_time_series
def merge_time_series(self, input_collection): """ Merges all timeseries of the input_collection to one big timeseries """ # Retriev the time series from the input_collection input_timeseries = input_collection.get_data(0,0,'test') # Get the data from the first timeseries output_data = input_timeseries[0][0] skiped_range = output_data.start_time # Change the endtime of the first timeseries to the one of the last # timeseries inside the input_collection input_timeseries[0][0].end_time = input_timeseries[-1][0].end_time # For all the remaining timeseries for ts in input_timeseries[1:]: # Concatenate the data... output_data = numpy.vstack((output_data,ts[0])) # ... and add the marker to the first timeseries if(len(ts[0].marker_name) > 0): for k in ts[0].marker_name: if(not input_timeseries[0][0].marker_name.has_key(k)): input_timeseries[0][0].marker_name[k] = [] for time in ts[0].marker_name[k]: input_timeseries[0][0].marker_name[k].append(time+ts[0].start_time - skiped_range) # Use the meta information from the first timeseries e.g. marker start/end_time # and create a new timeseries with the concatenated data merged_time_series = TimeSeries.replace_data(input_timeseries[0][0],output_data) # Change the name of the merged_time_series merged_time_series.name = "%s, length %d ms, %s" % (merged_time_series.name.split(',')[0], \ (len(merged_time_series)*1000.0)/merged_time_series.sampling_frequency,\ merged_time_series.name.split(',')[-1]) return merged_time_series
def _execute(self, x): """ Compute the energy of the given signal x using the TKEO """ #Determine the indices of the channels which will be filtered #Done only once... if(self.selected_channel_indices == None): self.selected_channels = self.selected_channels \ if self.selected_channels != None else x.channel_names self.selected_channel_indices = [x.channel_names.index(channel_name) \ for channel_name in self.selected_channels] self.old_data = numpy.zeros((2,len(self.selected_channel_indices))) filtered_data = numpy.zeros(x.shape) channel_counter = -1 for channel_index in self.selected_channel_indices: channel_counter += 1 for i in range(len(x)): if i==0: filtered_data[i][channel_index] = math.pow(self.old_data[1][channel_counter],2) - (self.old_data[0][channel_counter] * x[0][channel_index]) elif i==1: filtered_data[i][channel_index] = math.pow(x[0][channel_index],2) - (self.old_data[1][channel_counter] * x[1][channel_index]) else: filtered_data[i][channel_index] = math.pow(x[i-1][channel_index],2) - (x[i-2][channel_index] * x[i][channel_index]) self.old_data[0][channel_counter] = x[-2][channel_index] self.old_data[1][channel_counter] = x[-1][channel_index] result_time_series = TimeSeries.replace_data(x, filtered_data) return result_time_series
def _execute(self, x): """ f' = (f(x+h)-f(x)) """ if self.datapoints == None: self.datapoints = len(x) #create new channel names new_names = [] for channel in range(len(x.channel_names)): new_names.append("%s'" % (x.channel_names[channel])) #Derive the f' d2 from data x timeSeries = [] for datapoint in range(self.datapoints): temp = [] if((datapoint+1)<self.datapoints): for channel in range(len(x.channel_names)): temp.append(x[datapoint+1][channel]-x[datapoint][channel])#*8*sampling_frequency timeSeries.append(temp) #padding with zero's if the original length of the time series have to remain equal. if self.keep_number_of_samples: temp = [] for i in range(len(x.channel_names)): temp.append(0) timeSeries.append(temp) #Create a new time_series with the new data and channel names result_time_series = TimeSeries.replace_data(x, numpy.array(timeSeries)) result_time_series.channel_names = new_names #if necessary adjust the length of the time series if not self.keep_number_of_samples: result_time_series.end_time -= 1 return result_time_series
def _execute(self, data): """ Apply filter to data and return the result .. todo:: check if other view is needed here please """ #Compute the FIR window which is required for the low pass filter, if it #not exists if self.filter_kernel is None: self.calc_filter_kernel(data) #Determine the indices of the channels which will be filtered self.selected_channel_names = self.selected_channels \ if self.selected_channels != None else data.channel_names self.selected_channel_indices = \ [data.channel_names.index(channel_name) for channel_name in \ self.selected_channel_names] if self.comp_type == 'normal': #normal filtering with scipy filtered_data = numpy.zeros(data.shape) for channel_index in self.selected_channel_indices: filtered_data[:,channel_index] = \ scipy.signal.lfilter(self.filter_kernel[0], self.filter_kernel[1], data[:,channel_index]) result_time_series = TimeSeries.replace_data(data, filtered_data) elif self.comp_type == 'mirror': #filtering with scipy, mirror the data beforehand on the right border data_mirrored = numpy.vstack((data,numpy.flipud(data))) pre_filtered_data = numpy.zeros(data_mirrored.shape) for channel_index in self.selected_channel_indices: pre_filtered_data[:,channel_index] = \ scipy.signal.lfilter(self.filter_kernel[0], self.filter_kernel[1], data_mirrored[:,channel_index]) pre_filtered_data[:,channel_index] = \ scipy.signal.lfilter(self.filter_kernel[0], self.filter_kernel[1], numpy.flipud(pre_filtered_data[:,channel_index])) result_time_series = \ TimeSeries.replace_data(data, pre_filtered_data[:len(data)]) else: raise ValueError("Computation type unknown") return result_time_series
def _execute(self, data): """ Apply filter to data and return the result .. todo:: check if other view is needed here please """ #Compute the FIR window which is required for the low pass filter, if it #not exists if self.filter_kernel is None: self.calc_filter_kernel(data) #Determine the indices of the channels which will be filtered self.selected_channel_names = self.selected_channels \ if self.selected_channels != None else data.channel_names self.selected_channel_indices = \ [data.channel_names.index(channel_name) for channel_name in \ self.selected_channel_names] if self.comp_type == 'normal': #normal filtering with scipy filtered_data = numpy.zeros(data.shape) for channel_index in self.selected_channel_indices: filtered_data[:,channel_index] = \ scipy.signal.lfilter(self.filter_kernel[0], self.filter_kernel[1], data[:,channel_index]) result_time_series = TimeSeries.replace_data(data, filtered_data) elif self.comp_type == 'mirror': #filtering with scipy, mirror the data beforehand on the right border data_mirrored = numpy.vstack((data, numpy.flipud(data))) pre_filtered_data = numpy.zeros(data_mirrored.shape) for channel_index in self.selected_channel_indices: pre_filtered_data[:,channel_index] = \ scipy.signal.lfilter(self.filter_kernel[0], self.filter_kernel[1], data_mirrored[:,channel_index]) pre_filtered_data[:,channel_index] = \ scipy.signal.lfilter(self.filter_kernel[0], self.filter_kernel[1], numpy.flipud(pre_filtered_data[:,channel_index])) result_time_series = \ TimeSeries.replace_data(data, pre_filtered_data[:len(data)]) else: raise ValueError("Computation type unknown") return result_time_series
def _execute(self, data): # Initialize the ringbuffers and variables one for each channel if(self.ringbuffer == None): self.width /= 1000.0 self.width = int(self.width * data.sampling_frequency) self.nChannels = len(data.channel_names) self.ringbuffer = numpy.zeros((self.width,self.nChannels),dtype=numpy.double) self.variables = numpy.zeros((2,self.nChannels),dtype=numpy.double) self.index = numpy.zeros(self.nChannels,'i') # Convert the input data to double x = data.view(numpy.ndarray).astype(numpy.double) # Initialize the result data array filtered_data = numpy.zeros(x.shape) # Lists which are passed to the standadization # TODO: make self processing_filtered_data = None processing_ringbuffer = None processing_variables = None processing_index = None if(self.standardization): for channel_index in range(self.nChannels): # Copy the different data to the processing listst processing_filtered_data = numpy.array(filtered_data[:,channel_index],'d') processing_ringbuffer = numpy.array(self.ringbuffer[:,channel_index],'d') processing_variables = numpy.array(self.variables[:,channel_index],'d') processing_index = int(self.index[channel_index]) if self.var_tools: # Perform the standardization # The module vt (variance_tools) is implemented in c using boost to wrap the code in python # The module is located in trunk/library/variance_tools and have to be compiled self.index[channel_index] = vt.standardization(processing_filtered_data, numpy.array(x[:,channel_index],'d'), processing_ringbuffer, processing_variables, self.width, processing_index) else: self.index[channel_index] = self.standardisation(processing_filtered_data, numpy.array(x[:,channel_index],'d'), processing_ringbuffer, processing_variables, self.width, processing_index) # Copy the processing lists back to the local variables filtered_data[:,channel_index] = processing_filtered_data self.ringbuffer[:,channel_index] = processing_ringbuffer self.variables[:,channel_index] = processing_variables else: for channel_index in range(self.nChannels): # Copy the different data to the processing listst processing_filtered_data = numpy.array(filtered_data[:,channel_index],'d') processing_ringbuffer = numpy.array(self.ringbuffer[:,channel_index],'d') processing_variables = numpy.array(self.variables[:,channel_index],'d') processing_index = int(self.index[channel_index]) if self.var_tools: # Perform the filtering with the variance # The module vt (variance_tools) is implemented in c using boost to wrap the code in python # The module is located in trunk/library/variance_tools and have to be compiled self.index[channel_index] = vt.filter(processing_filtered_data, numpy.array(x[:,channel_index],'d'), processing_ringbuffer, processing_variables, self.width, processing_index) else: self.index[channel_index] = self.variance(processing_filtered_data, numpy.array(x[:,channel_index],'d'), processing_ringbuffer, processing_variables, self.width, processing_index) # Copy the processing lists back to the local variables filtered_data[:,channel_index] = processing_filtered_data self.ringbuffer[:,channel_index] = processing_ringbuffer self.variables[:,channel_index] = processing_variables # Return the result result_time_series = TimeSeries.replace_data(data, filtered_data) return result_time_series
def _execute(self, data): """ Subsample the given data and return a new time series """ if self.new_len == 0 : self.new_len = int(round(self.target_frequency*len(data)/(1.0*data.sampling_frequency))) if not self.mirror: downsampled_time_series = \ TimeSeries.replace_data(data, scipy.signal.resample(data, self.new_len, t=None, axis=0, window=self.window)) else: downsampled_time_series = \ TimeSeries.replace_data(data, scipy.signal.resample(numpy.vstack((data,numpy.flipud(data))), self.new_len*2, t=None, axis=0, window=self.window)[:self.new_len]) downsampled_time_series.sampling_frequency = self.target_frequency return downsampled_time_series
def _execute(self, data): """ Apply the cast """ #Determine the indices of the channels which will be filtered self._log("Cast data") casted_data = data.astype(self.datatype) result_time_series = TimeSeries.replace_data(data, casted_data) return result_time_series
def _execute(self, data): """ Apply the cast """ #Determine the indices of the channels which will be filtered self._log("Cast data") casted_data = data.astype(self.datatype) result_time_series = TimeSeries.replace_data(data, casted_data) return result_time_series
def _execute(self, data): """ Subsample the given data and return a new time series """ if self.new_len == 0 : self.new_len = int(round(self.target_frequency*len(data)/(1.0*data.sampling_frequency))) if not self.mirror: downsampled_time_series = \ TimeSeries.replace_data(data, scipy.signal.resample(data, self.new_len, t=None, axis=0, window=self.window)) else: downsampled_time_series = \ TimeSeries.replace_data(data, scipy.signal.resample(numpy.vstack((data,numpy.flipud(data))), self.new_len*2, t=None, axis=0, window=self.window)[:self.new_len]) downsampled_time_series.sampling_frequency = self.target_frequency return downsampled_time_series
def _execute(self, x): """ Apply z-score transformation to the given data and return a modified time series. """ data = x.view(numpy.ndarray) #Do the z-score transformation std = numpy.std(data-numpy.mean(data, axis=0), axis=0) std = check_zero_division(self, std, tolerance=10**-15, data_ts=x) return TimeSeries.replace_data(x, (data-numpy.mean(data, axis=0)) / std)
def _execute(self, x): data = x.view(numpy.ndarray) mean = numpy.mean(data, axis=0) data -= mean max_values = numpy.abs(numpy.max(data, axis=0)) max_values = check_zero_division(self, max_values, tolerance=10**-15, data_ts=x) return TimeSeries.replace_data(x, data/max_values)
def _execute(self, data): """ Apply the scaling to the given data x and return a new time series. """ x = data.view(numpy.ndarray).astype(numpy.double) x = x * self.factor result_time_series = TimeSeries.replace_data(data, x) return result_time_series
def _execute(self, data): """ Reorder the memory. """ # exchange data of time series object to correctly ordered data buffer = numpy.array(data, order='F') if self.convert_type and numpy.dtype('float64') != buffer.dtype: buffer = buffer.astype(numpy.float) data = TimeSeries.replace_data(data,buffer) return data
def _execute(self, data): """ Apply the scaling to the given data x and return a new time series. """ x = data.view(numpy.ndarray) x.clip(self.min_threshold, self.max_threshold, out = x) result_time_series = TimeSeries.replace_data(data, x) return result_time_series
def _execute(self, data): """ Reorder the memory. """ # exchange data of time series object to correctly ordered data buffer = numpy.array(data, order='F') if self.convert_type and numpy.dtype('float64') != buffer.dtype: buffer = buffer.astype(numpy.float) data = TimeSeries.replace_data(data, buffer) return data
def _execute(self, data): # First check if all channels actually appear in the data # Determine the indices of the channels that are the basis for the # average reference. if not self.inverse: if self.avg_channels == None: self.avg_channels = data.channel_names channel_indices = [ data.channel_names.index(channel_name) for channel_name in self.avg_channels ] else: channel_indices = [ data.channel_names.index(channel_name) for channel_name in data.channel_names if channel_name not in self.avg_channels ] not_found_channels = \ [channel_name for channel_name in self.avg_channels if channel_name not in data.channel_names] if not not_found_channels == []: warnings.warn( "Couldn't find selected channel(s): %s. Ignoring." % not_found_channels, Warning) if self.old_ref is None: self.old_ref = 'avg' # Compute the actual data of the reference channel. This is the sum of all # channels divided by (the number of channels +1). ref_chen = -numpy.sum(data[:, channel_indices], axis=1) / ( data.shape[1] + 1) ref_chen = numpy.atleast_2d(ref_chen).T # Reference all electrodes against average avg_referenced_data = data + ref_chen # Add average as new channel to the signal if enabled if self.keep_average: avg_referenced_data = numpy.hstack((avg_referenced_data, ref_chen)) channel_names = data.channel_names + [self.old_ref] result_time_series = TimeSeries(avg_referenced_data, channel_names, data.sampling_frequency, data.start_time, data.end_time, data.name, data.marker_name) else: result_time_series = TimeSeries.replace_data( data, avg_referenced_data) return result_time_series
def test_repalce_data(self): data = TimeSeries.replace_data( self.x2, [10, 11, 12, 13, 14, 15], channel_names=['m', 'n', 'o', 'p', 'q', 'r'], sampling_frequency=30, start_time=1200.0) self.assertFalse( (data.view(np.ndarray) - [10, 11, 12, 13, 14, 15]).any()) self.assertEqual(data.channel_names, ['m', 'n', 'o', 'p', 'q', 'r']) self.assertEqual(data.sampling_frequency, 30) self.assertEqual(data.start_time, 1200) self.assertEqual(data.end_time, 13004) self.assertEqual(data.name, 'Name_text ending with Standard') self.assertEqual(data.tag, 'Tag of x2')
def _execute(self, x): """ Apply devariancing to the given data and return the modified time series """ #Determine the indices of the channels which will be filtered selected_channel_indices = [x.channel_names.index(channel_name) for channel_name in self.selected_channels] #Do the actual devariancing, i.e. multiply with the scale factor devarianced_data = numpy.zeros(x.shape) for channel in self.selected_channels: channel_index = x.channel_names.index(channel) devarianced_data[:, channel_index] = x[:, channel_index] * \ self.scale_factors[channel] return TimeSeries.replace_data(x, devarianced_data)
def _execute(self, data): # First check if all channels actually appear in the data # Determine the indices of the channels that are the basis for the # average reference. if not self.inverse: if self.avg_channels == None: self.avg_channels = data.channel_names channel_indices = [data.channel_names.index(channel_name) for channel_name in self.avg_channels] else: channel_indices = [data.channel_names.index(channel_name) for channel_name in data.channel_names if channel_name not in self.avg_channels] not_found_channels = \ [channel_name for channel_name in self.avg_channels if channel_name not in data.channel_names] if not not_found_channels == []: warnings.warn("Couldn't find selected channel(s): %s. Ignoring." % not_found_channels, Warning) if self.old_ref is None: self.old_ref = 'avg' # Compute the actual data of the reference channel. This is the sum of all # channels divided by (the number of channels +1). ref_chen = -numpy.sum(data[:, channel_indices], axis=1)/(data.shape[1]+1) ref_chen = numpy.atleast_2d(ref_chen).T # Reference all electrodes against average avg_referenced_data = data + ref_chen # Add average as new channel to the signal if enabled if self.keep_average: avg_referenced_data = numpy.hstack((avg_referenced_data, ref_chen)) channel_names = data.channel_names + [self.old_ref] result_time_series = TimeSeries(avg_referenced_data, channel_names, data.sampling_frequency, data.start_time, data.end_time, data.name, data.marker_name) else: result_time_series = TimeSeries.replace_data(data, avg_referenced_data) return result_time_series
def _execute(self, x): """ Apply memory z-score transformation to the given data and return a new time series. """ data = x.view(numpy.ndarray) # calculate the important measures in an array format mean = numpy.mean(data, axis=0) var = numpy.var(data, axis=0) # initialize the memory when it is first used if self.memory is None: self.memory = dict() self.memory['mean'] = list() self.memory['var'] = list() for i in range(self.order): self.memory['mean'].append(mean) self.memory['var'].append(var) # extend the memory by the new mean and variance if the # std<200 and not zero to exclude big artifacts if (var < 40000).all() and (var > 10**-9).all(): self.memory['var'].append(var) self.memory['mean'].append(mean) # calculate the mean of the current mean and variance # and the latest (order) means and variances in memory # and delete the last, because it is no longer needed var = numpy.mean(self.memory['var'], axis=0) mean = numpy.mean(self.memory['mean'], axis=0) self.memory['var'].pop(0) self.memory['mean'].pop(0) std = numpy.sqrt(var) # # code for easy viszualization # statistic = numpy.vstack((mean,std)) # statistic = TimeSeries.replace_data(data, statistic) # statistic.sampling_frequency = 1 # return statistic #Do the modified z-score transformation std = check_zero_division(self, std, tolerance=10**-15, data_ts=x) return TimeSeries.replace_data(x, (data - numpy.mean(data, axis=0)) / std)
def _execute(self, x): """ Executes the preprocessing on the given data vector x""" #Number of retained channels num_channels = numpy.size(x, 1) if (self.below_threshold == None): # When the node is called for the first time initialize all parameters/variables self.width_AT = int((self.width_AT * x.sampling_frequency) / 1000.) #Convert the time from ms to samples self.time_below_threshold = int( (self.time_below_threshold * x.sampling_frequency) / 1000.) #Create and prefill the array which indicates how long a signal was below the threshold self.below_threshold = numpy.zeros(num_channels) self.below_threshold.fill(self.time_below_threshold + 1) #Create the ringbuffer and the variables list for the adaptive threshold self.ringbuffer_AT = numpy.zeros((self.width_AT, num_channels)) self.variables_AT = numpy.zeros((4, num_channels)) data = x.view(numpy.ndarray) #Create the array for the thresholded data threshold_data = numpy.zeros(data.shape) #For each sample of each retained channel for i in range(num_channels): data_index = 0 for sample in data[:, i]: #calculate the adaptive threshold value = self.adaptive_threshold(sample, i) #if the actual sample exceeds the threshold... if (sample >= value): #and the resting time was observed if (self.below_threshold[i] > self.time_below_threshold): #store a 1 indicating a onset threshold_data[data_index][i] = 1 #reset the resting time counter self.below_threshold[i] = 0 #increase the time the signal was below the signal else: self.below_threshold[i] += 1 data_index += 1 #return the thresholded data result_time_series = TimeSeries.replace_data(x, threshold_data) return result_time_series
def _execute(self, x): """ Apply memory z-score transformation to the given data and return a new time series. """ data = x.view(numpy.ndarray) # calculate the important measures in an array format mean = numpy.mean(data, axis=0) var = numpy.var(data, axis=0) # initialize the memory when it is first used if self.memory is None: self.memory=dict() self.memory['mean'] = list() self.memory['var'] = list() for i in range(self.order): self.memory['mean'].append(mean) self.memory['var'].append(var) # extend the memory by the new mean and variance if the # std<200 and not zero to exclude big artifacts if (var < 40000).all() and (var > 10**-9).all(): self.memory['var'].append(var) self.memory['mean'].append(mean) # calculate the mean of the current mean and variance # and the latest (order) means and variances in memory # and delete the last, because it is no longer needed var = numpy.mean(self.memory['var'],axis=0) mean = numpy.mean(self.memory['mean'],axis=0) self.memory['var'].pop(0) self.memory['mean'].pop(0) std = numpy.sqrt(var) # # code for easy viszualization # statistic = numpy.vstack((mean,std)) # statistic = TimeSeries.replace_data(data, statistic) # statistic.sampling_frequency = 1 # return statistic #Do the modified z-score transformation std = check_zero_division(self, std, tolerance=10**-15, data_ts=x) return TimeSeries.replace_data(x, (data-numpy.mean(data, axis=0))/std)
def _execute(self, x): """ Executes the preprocessing on the given data vector x""" #Number of retained channels num_channels = numpy.size(x,1) if(self.below_threshold == None): # When the node is called for the first time initialize all parameters/variables self.width_AT = int((self.width_AT*x.sampling_frequency)/1000.) #Convert the time from ms to samples self.time_below_threshold = int((self.time_below_threshold*x.sampling_frequency)/1000.) #Create and prefill the array which indicates how long a signal was below the threshold self.below_threshold = numpy.zeros(num_channels) self.below_threshold.fill(self.time_below_threshold+1) #Create the ringbuffer and the variables list for the adaptive threshold self.ringbuffer_AT=numpy.zeros((self.width_AT,num_channels)) self.variables_AT=numpy.zeros((4,num_channels)) data=x.view(numpy.ndarray) #Create the array for the thresholded data threshold_data = numpy.zeros(data.shape) #For each sample of each retained channel for i in range(num_channels): data_index = 0 for sample in data[:,i]: #calculate the adaptive threshold value = self.adaptive_threshold(sample, i) #if the actual sample exceeds the threshold... if(sample >= value): #and the resting time was observed if(self.below_threshold[i] > self.time_below_threshold): #store a 1 indicating a onset threshold_data[data_index][i] = 1 #reset the resting time counter self.below_threshold[i] = 0 #increase the time the signal was below the signal else: self.below_threshold[i] += 1 data_index += 1 #return the thresholded data result_time_series = TimeSeries.replace_data(x, threshold_data) return result_time_series
def _train(self, data): """ Check which channels have constant values. The training data is considered and the invalid channel names are removed. The first data entry is saved and the starting assumption is that all channels have constant values. When a value different from the first data entry for a respective channel is found, that channel is removed from the list of channels that have constant values. """ # copy the first data value if self.data_values is None: # copy the first entry self.data_values = TimeSeries.replace_data(data, data.get_data()[0]) # invalidate all the channels in the beginning self.selected_channel_names = copy.deepcopy(data.channel_names) for channel in self.selected_channel_names: if (data.get_channel(channel) != self.data_values.get_channel(channel)[0]).any(): self.selected_channel_names.remove(channel)
def _execute(self, data): """ Apply the detrending method to the given data x and return a new time series """ #Determine the indices of the channels which will be filtered x = data.view(numpy.ndarray) if self.selected_channel_indices is None: self.selected_channel_names = self.selected_channels \ if not self.selected_channels is None else data.channel_names self.selected_channel_indices = \ [data.channel_names.index(channel_name) for channel_name in self.selected_channel_names] #Do the actual detrending detrended_data = numpy.zeros(x.shape) for channel_index in self.selected_channel_indices: detrended_data[:, channel_index] = \ self.detrend_method(x[:, channel_index]) result_time_series = TimeSeries.replace_data(data, detrended_data) return result_time_series
def _execute(self, x): """ Apply the detrending method to the given data x and return a new time series. """ #Determine the indices of the channels which will be filtered if None == self.selected_channel_indices: self.selected_channel_names = self.selected_channels \ if self.selected_channels != None else x.channel_names self.selected_channel_indices = \ [x.channel_names.index(channel_name) for channel_name in \ self.selected_channel_names] #Do the actual detrending detrended_data = numpy.zeros(x.shape) for channel_index in self.selected_channel_indices: temp = x[:, channel_index] temp = temp*numpy.float64(1)/numpy.linalg.norm(temp) detrended_data[:, channel_index] = temp result_time_series = TimeSeries.replace_data(x, detrended_data) return result_time_series
def _execute(self, data): """ Exchanges the data with some manually generated data. """ if self.generator is None: self.generator = eval(self.generator_expression) self.data_item = \ self.ts_generator.generate_test_data( channels=data.shape[1], time_points=data.shape[0], function=self.generator, sampling_frequency=data.sampling_frequency, channel_order=True, channel_names=data.channel_names, dtype=numpy.float) result_time_series = TimeSeries.replace_data(data, self.data_item) return result_time_series
def _execute(self, data): """ Exchanges the data with some manually generated data. """ if self.generator is None: self.generator = eval(self.generator_expression) self.data_item = \ self.ts_generator.generate_test_data( channels=data.shape[1], time_points=data.shape[0], function=self.generator, sampling_frequency=data.sampling_frequency, channel_order=True, channel_names=data.channel_names, dtype=numpy.float) result_time_series = TimeSeries.replace_data(data, self.data_item) return result_time_series
def _train(self, data): """ Check which channels have constant values. The training data is considered and the invalid channel names are removed. The first data entry is saved and the starting assumption is that all channels have constant values. When a value different from the first data entry for a respective channel is found, that channel is removed from the list of channels that have constant values. """ # copy the first data value if self.data_values is None: # copy the first entry self.data_values = TimeSeries.replace_data(data, data.get_data()[0]) # invalidate all the channels in the beginning self.selected_channel_names = copy.deepcopy(data.channel_names) for channel in self.selected_channel_names: if (data.get_channel(channel) != self.data_values.get_channel(channel)[0]).any(): self.selected_channel_names.remove(channel)
def _execute(self, data): """ Subsample the given data data and return a new time series """ # Compute the downsampling factor source_frequency = int(round(data.sampling_frequency * 100)) target_frequency = int(round(self.target_frequency * 100)) reduce_fraction_factor = gcd(source_frequency, target_frequency) new_downsampling_factor = source_frequency / reduce_fraction_factor upsampling_factor = target_frequency / reduce_fraction_factor if not (upsampling_factor == 1): self._log("Upsampling used but not implemented!" + " Check target frequency and real frequency!", level=logging.WARNING) # reset filter if downsampling factor has changed if new_downsampling_factor != self.downsampling_factor: self.downsampling_factor = new_downsampling_factor if self.downsampling_factor <= 1: self._log("Inapplicable downsampling factor: " + str(self.downsampling_factor) + " Downsampling will be skipped", level=logging.WARNING) # omit downsampling, if inapplicable if self.downsampling_factor <= 1: return data # Downsampling (can be achieved by a simple re-striding) # Note: We have to create a new array since otherwise the off-strided # data remains in memory downsampled_data = numpy.array(data[::self.downsampling_factor, :]) downsampled_time_series = TimeSeries.replace_data( data, downsampled_data) downsampled_time_series.sampling_frequency = self.target_frequency return downsampled_time_series
def _execute(self, x): """ Apply band pass filter to data x and return the result """ #Determine the indices of the channels which will be filtered selected_channel_names = self.selected_channels \ if self.selected_channels != None else x.channel_names selected_channel_indices = [x.channel_names.index(channel_name) \ for channel_name in selected_channel_names] #Do the actual filtering x_data = x.view( numpy.ndarray) # More efficient slicing, without memory copy... filtered_data = numpy.zeros(x.shape) for channel_index in selected_channel_indices: #Fourier transform fourier_transformed = scipy.fftpack.fft(x_data[:, channel_index]) #Compute the pass band indices lower_bound = int(round(float(self.pass_band[0]) / \ x.sampling_frequency * len(fourier_transformed))) upper_bound = int(round(float(self.pass_band[1]) / \ x.sampling_frequency * len(fourier_transformed))) #Setting frequencies outside the pass band to 0 for i in range(0, lower_bound): fourier_transformed[i] = 0 fourier_transformed[-i - 1] = 0 for i in range(upper_bound, len(fourier_transformed) / 2): fourier_transformed[i] = 0 fourier_transformed[-i - 1] = 0 #Inverse Fourier transform and project to real component filtered_data[:, channel_index] = \ scipy.fftpack.ifft(fourier_transformed).real result_time_series = TimeSeries.replace_data(x, filtered_data) return result_time_series
def _execute(self, x): """ Apply band pass filter to data x and return the result """ #Determine the indices of the channels which will be filtered selected_channel_names = self.selected_channels \ if self.selected_channels != None else x.channel_names selected_channel_indices = [x.channel_names.index(channel_name) \ for channel_name in selected_channel_names] #Do the actual filtering x_data=x.view(numpy.ndarray) # More efficient slicing, without memory copy... filtered_data = numpy.zeros(x.shape) for channel_index in selected_channel_indices: #Fourier transform fourier_transformed = scipy.fftpack.fft(x_data[:, channel_index]) #Compute the pass band indices lower_bound = int(round(float(self.pass_band[0]) / \ x.sampling_frequency * len(fourier_transformed))) upper_bound = int(round(float(self.pass_band[1]) / \ x.sampling_frequency * len(fourier_transformed))) #Setting frequencies outside the pass band to 0 for i in range(0, lower_bound): fourier_transformed[i] = 0 fourier_transformed[-i-1] = 0 for i in range(upper_bound,len(fourier_transformed)/2): fourier_transformed[i] = 0 fourier_transformed[-i-1] = 0 #Inverse Fourier transform and project to real component filtered_data[:, channel_index] = \ scipy.fftpack.ifft(fourier_transformed).real result_time_series = TimeSeries.replace_data(x, filtered_data) return result_time_series
def _execute(self, x): """ Apply high pass filter to data x and return the result """ #Determine the indices of the channels which will be filtered selected_channel_names = self.selected_channels \ if self.selected_channels != None else x.channel_names selected_channel_indices = [x.channel_names.index(channel_name) \ for channel_name in selected_channel_names] if self.b is None: #Compute the FIR window which is required for the high pass filter try: b = scipy.signal.firwin(numtaps=self.taps, cutoff=self.cutoff_frequency * 2.0 / x.sampling_frequency, width=self.width, window=self.window) except TypeError: b = scipy.signal.firwin(N=self.taps - 1, cutoff=self.cutoff_frequency * 2.0 / x.sampling_frequency, width=self.width, window=self.window) b = -b b[self.taps / 2] = b[self.taps / 2] + 1 self.set_permanent_attributes(b=b) #Do the actual filtering y = x.view(numpy.ndarray) filtered_data = numpy.zeros(x.shape) for channel_index in selected_channel_indices: filtered_data[:,channel_index] = \ scipy.signal.lfilter(self.b, [1], y[:,channel_index]) result_time_series = TimeSeries.replace_data(x, filtered_data) return result_time_series
def _execute(self, data): """ Subsample the given data data and return a new time series """ # Compute the downsampling factor source_frequency = int(round(data.sampling_frequency * 100)) target_frequency = int(round(self.target_frequency * 100)) reduce_fraction_factor = gcd(source_frequency, target_frequency) new_downsampling_factor = source_frequency /reduce_fraction_factor upsampling_factor = target_frequency / reduce_fraction_factor if not(upsampling_factor == 1): self._log("Upsampling used but not implemented!" +" Check target frequency and real frequency!", level=logging.WARNING) # reset filter if downsampling factor has changed if new_downsampling_factor != self.downsampling_factor: self.downsampling_factor = new_downsampling_factor if self.downsampling_factor <= 1: self._log("Inapplicable downsampling factor: " + str(self.downsampling_factor) +" Downsampling will be skipped", level=logging.WARNING) # omit downsampling, if inapplicable if self.downsampling_factor <= 1: return data # Downsampling (can be achieved by a simple re-striding) # Note: We have to create a new array since otherwise the off-strided # data remains in memory downsampled_data = numpy.array(data[::self.downsampling_factor, :]) downsampled_time_series = TimeSeries.replace_data(data, downsampled_data) downsampled_time_series.sampling_frequency = self.target_frequency return downsampled_time_series
def _execute(self, x): """ Subsample the given data x and return a new time series """ # Compute the upsampling and downsampling factor source_frequency = int(round(x.sampling_frequency * 100)) target_frequency = int(round(self.target_frequency * 100)) reduce_fraction_factor = gcd(source_frequency, target_frequency) upsampling_factor = target_frequency / reduce_fraction_factor downsampling_factor = source_frequency /reduce_fraction_factor # Upsampling if upsampling_factor == 1: upsampled_time_series = x else: # We make a linear interpolation for upsampling as an easy version. # This should be enough because of the following Lowpassfilter. # It is maybe a better version to construction a C^1 spline, # because it prevents artifacts in frequency, but this would # decrease processing speed significantly. # The new Data Array for the upsampled data # The last timepoint does not bring additional points. # This results in the -1+1 calculation. self._log("Using upsampling.", level=logging.WARNING) interpolated_time_series = numpy.zeros((upsampling_factor*(len(x)-1)+1, len(x.channel_names))) # Array that corresponds to the x value of the fictive function # (original data) time = linspace(0, len(x)-1, len(x)) # Array that corresponds to the x value of the fictive function # (upsampled data) newTime = linspace(0, len(x)-1, len(interpolated_time_series)) # Linear interpolation of each channel for channel_name in x.channel_names: channel_index = x.channel_names.index(channel_name) f = interp1d(time, x[:,channel_index]) interpolated_time_series[:,channel_index] = f(newTime) upsampled_time_series = TimeSeries.replace_data(x, interpolated_time_series) # Low Pass filtering: According to Shannon-Nyquist's sampling theorem, # we should only retain frequency components below 1/2*target_frequency # We multiply with 0.45 instead of 0.5 because of the finite window # length lpf_node = filtering.SimpleLowPassFilterNode(cutoff_frequency = self.target_frequency * 0.45) filtered_time_series = lpf_node.execute(upsampled_time_series) # Downsampling (can be achieved by a simple re-striding) # Note: We have to create a new array since otherwise the off-strided # data remains in memory downsampled_data = numpy.array(filtered_time_series[::downsampling_factor, :]) downsampled_time_series = TimeSeries.replace_data(x, downsampled_data) downsampled_time_series.sampling_frequency = self.target_frequency # # Uncomment for graphical analyzation # import pylab # pylab.figure(1) # pylab.plot(pylab.linspace(0.0, 1.0, x.shape[0]), # x[:,x.channel_names.index('Pz')], # label = 'Pz' + "_subsampled") # pylab.figure(2) # pylab.subplot(312) # pylab.specgram(x[:,x.channel_names.index('Pz')], Fs = x.sampling_frequency, # NFFT = 64, noverlap = 63) # pylab.colorbar() # pylab.show() return downsampled_time_series
def _prepare_prediction(self, data): #PredictionVector Data to work with. """ Convert prediction vector to time series object for visualization Using the function *get_previous_transformations* the node history is searched for the respective transformation parametrizations and then the transformations are combined tog et a complete picture of the data processing chain. A special case is, when the :class:`~pySPACE.missions.nodes.meta.flow_node.BacktransformationNode` **Parameters** :data: This is a Prediction Vector, which might contain data in its history component which is used for multiplication with the transformation or which is used as sample for calculating the derivative of the processing chain for the backtransformation. """ if self.current_trafo_TS is None: #needed only once transformation_list = self.get_previous_transformations(data) classifier = transformation_list[-1] if classifier[3] == "generic_backtransformation": current_trafo = classifier[0] if type(current_trafo) == FeatureVector: current_trafo_TS = type_conversion.\ FeatureVector2TimeSeriesNode()._execute(current_trafo) elif type(current_trafo) == TimeSeries: current_trafo_TS = current_trafo if self.covariancing: shape = current_trafo_TS.shape covariance = classifier[1][1] new_TS_array = numpy.dot( covariance, current_trafo_TS.flatten()).reshape(shape) current_trafo_TS = TimeSeries.replace_data( current_trafo_TS, new_TS_array) elif classifier[3] == "linear classifier": classifier_FV = FeatureVector(numpy.atleast_2d(classifier[0]), feature_names=classifier[2]) current_trafo = classifier_FV if self.use_FN: try: FN = transformation_list[-2] assert (FN[3] == "feature normalization") assert ( classifier[2] == FN[2] ), "VisualizationBase:: Feature names do not match!" FN_FV = FeatureVector(numpy.atleast_2d(FN[0]), feature_names=FN[2]) current_trafo = FeatureVector( current_trafo * FN_FV, feature_names=FN_FV.feature_names) except: warnings.warn( "VisualizationBase:: Did not get any feature normalization!" ) pass #raise current_trafo_TS = type_conversion.FeatureVector2TimeSeriesNode( )._execute(current_trafo) if self.use_SF: try: # TODO CHECK fitting of channel names SF = transformation_list[-2] if not SF[3] == "spatial filter": SF = transformation_list[-3] assert (SF[3] == "spatial filter") new_channel_names = SF[2] SF_trafo = SF[0] current_trafo_TS = TimeSeries( numpy.dot(current_trafo_TS, SF_trafo.T), channel_names=new_channel_names, sampling_frequency=current_trafo_TS. sampling_frequency) except: warnings.warn( "VisualizationBase:: Did not get any spatial filter!" ) pass #raise else: warnings.warn("VisualizationBase:: " + "Did not get any classifier transformation!") raise RuntimeError # the reordering should have been done in the type conversion current_trafo_TS.reorder(sorted(current_trafo_TS.channel_names)) self.current_trafo_TS = current_trafo_TS prepared_prediction = self.current_trafo_TS if self.history_index: found_in_history = False if data.has_history(): try: prepared_history = copy.deepcopy( data.history[self.history_index - 1]) if type(prepared_history) == FeatureVector: prepared_history = type_conversion.FeatureVector2TimeSeriesNode( )._execute(prepared_history) found_in_history = True except: pass if found_in_history: prepared_history.reorder(self.current_trafo_TS.channel_names) prepared_prediction = copy.deepcopy( prepared_prediction) * prepared_history else: warnings.warn( "VisualizationBase:: No FeatureVector or TimeSeries found in history. Parameter history_index ignored!" ) return prepared_prediction
def central_difference_with_halfstep_method(self, sample): """ implementation of the central difference method with a half step **Principle** The principle applied by the central difference method with a half step is .. math:: f'(x)=\\frac{f(x-h)-8f(x-\\frac{h}{2})+8f(x+\\frac{h}{2})-f(x-h)}{6h} where :math:`h` is the step of the differentiation that is computed as :math:`h(x)=\sqrt{\\varepsilon} \\cdot x` for :math:`x \\neq 0` and :math:`h(0)=\\sqrt{\\varepsilon}` for :math:`x=0`. **Parameters** :sample: the initial value used for the derivation .. note:: This method is the most accurate differentiation method but also has the greatest overhead. """ if type(sample) == FeatureVector: self.trafo = FeatureVector.replace_data( self.example, numpy.zeros(self.example.shape)) for j in range(len(sample.feature_names)): positive_offset = copy.deepcopy(sample) negative_offset = copy.deepcopy(sample) half_positive_offset = copy.deepcopy(sample) half_negative_offset = copy.deepcopy(sample) if positive_offset[0][j] == 0.: diff = numpy.sqrt(self.eps) else: diff = numpy.sqrt(self.eps)*positive_offset[0][j] positive_offset[0][j] += diff negative_offset[0][j] -= diff half_positive_offset[0][j] += diff/2. half_negative_offset[0][j] -= diff/2. diff = (positive_offset[0][j]-negative_offset[0][j])/2. positive_vector = FeatureVector.replace_data( sample, positive_offset ) negative_vector = FeatureVector.replace_data( sample, negative_offset ) half_positive_vector = FeatureVector.replace_data( sample, half_positive_offset ) half_negative_vector = FeatureVector.replace_data( sample, half_negative_offset ) self.trafo[0][j] = \ numpy.longdouble((self._execute(negative_vector) - 8*self._execute(half_negative_vector) + 8*self._execute(half_positive_vector) - self._execute(positive_vector))/(6.*diff)) elif type(sample) == TimeSeries: self.trafo = TimeSeries.replace_data( self.example, numpy.zeros(self.example.shape)) for i in range(sample.shape[0]): for j in range(sample.shape[1]): positive_offset = copy.deepcopy(sample) negative_offset = copy.deepcopy(sample) half_positive_offset = copy.deepcopy(sample) half_negative_offset = copy.deepcopy(sample) if positive_offset[i][j] == 0.: diff = numpy.sqrt(self.eps) else: diff = numpy.sqrt(self.eps)*positive_offset[i][j] positive_offset[i][j] += diff negative_offset[i][j] -= diff half_positive_offset[i][j] += diff/2. half_negative_offset[i][j] -= diff/2. diff = (positive_offset[i][j]-negative_offset[i][j])/2. positive_series = TimeSeries.replace_data( sample, positive_offset ) negative_series = TimeSeries.replace_data( sample, negative_offset ) half_positive_series = TimeSeries.replace_data( sample, half_positive_offset ) half_negative_series = TimeSeries.replace_data( sample, half_negative_offset ) self.trafo[i][j] = \ numpy.longdouble((self._execute(negative_series) - 8*self._execute(half_negative_series) + 8*self._execute(half_positive_series) - self._execute(positive_series))/(6.*diff))
def _execute(self, data): # Initialize the ringbuffers and variables one for each channel if (self.ringbuffer == None): self.width /= 1000.0 self.width = int(self.width * data.sampling_frequency) self.nChannels = len(data.channel_names) self.ringbuffer = numpy.zeros((self.width, self.nChannels), dtype=numpy.double) self.variables = numpy.zeros((2, self.nChannels), dtype=numpy.double) self.index = numpy.zeros(self.nChannels, 'i') if (self.width <= 1): warnings.warn( "Width have to be greater than 1!\nThe data won't be changed!!!" ) return data if (self.normalize and self.ringbufferNormalize == None): self.ringbufferNormalize = numpy.zeros( (self.lenNormalize, self.nChannels), dtype=numpy.double) # Convert the input data to double x = data.view(numpy.ndarray).astype(numpy.double) # Initialize the result data array filtered_data = numpy.zeros(x.shape) # Lists which are passed to the standadization # TODO: make self processing_filtered_data = None processing_ringbuffer = None processing_variables = None processing_index = None if (self.standardization): for channel_index in range(self.nChannels): # Copy the different data to the processing listst processing_filtered_data = numpy.array( filtered_data[:, channel_index], 'd') processing_ringbuffer = numpy.array( self.ringbuffer[:, channel_index], 'd') processing_variables = numpy.array( self.variables[:, channel_index], 'd') processing_index = int(self.index[channel_index]) if self.var_tools: # Perform the standardization # The module vt (variance_tools) is implemented in c using # boost to wrap the code in Python # The module is located in trunk/library/variance_tools # and have to be compiled self.index[channel_index] = vt.standardization( processing_filtered_data, numpy.array(x[:, channel_index], 'd'), processing_ringbuffer, processing_variables, self.width, processing_index) else: self.index[channel_index] = self.standardisation( processing_filtered_data, numpy.array(x[:, channel_index], 'd'), processing_ringbuffer, processing_variables, self.width, processing_index) # Copy the processing lists back to the local variables filtered_data[:, channel_index] = processing_filtered_data self.ringbuffer[:, channel_index] = processing_ringbuffer self.variables[:, channel_index] = processing_variables else: for channel_index in range(self.nChannels): # Copy the different data to the processing listst processing_filtered_data = numpy.array( filtered_data[:, channel_index], 'd') processing_ringbuffer = numpy.array( self.ringbuffer[:, channel_index], 'd') processing_variables = numpy.array( self.variables[:, channel_index], 'd') processing_index = int(self.index[channel_index]) if self.var_tools: # Perform the filtering with the variance # The module vt (variance_tools) is implemented in c using # boost to wrap the code in Python # The module is located in trunk/library/variance_tools # and have to be compiled self.index[channel_index] = vt.filter( processing_filtered_data, numpy.array(x[:, channel_index], 'd'), processing_ringbuffer, processing_variables, self.width, processing_index) if self.normalize: lenData = len(processing_filtered_data) self.ringbufferNormalize[0:-lenData,channel_index] = \ self.ringbufferNormalize[lenData:,channel_index] self.ringbufferNormalize[-lenData:,channel_index] = \ processing_filtered_data[:] processing_filtered_data /= numpy.max( (50, numpy.max( self.ringbufferNormalize[:, channel_index]))) else: self.index[channel_index] = self.variance( processing_filtered_data, numpy.array(x[:, channel_index], 'd'), processing_ringbuffer, processing_variables, self.width, processing_index) # Copy the processing lists back to the local variables filtered_data[:, channel_index] = processing_filtered_data self.ringbuffer[:, channel_index] = processing_ringbuffer self.variables[:, channel_index] = processing_variables # Return the result result_time_series = TimeSeries.replace_data(data, filtered_data) return result_time_series