creates a labeled spike data structure

                time_label_array is list of lists (or matrix), containing a timestamp in the 
                first column (or first element of each element) and indizes that are to be 
                applied to the data in the remaining columns / elements.

            This function will not add or remove spikes, but only shift spikes according to the 
            adjecent time signals.

            If you want to get spikes relative to a time signal with fixed limits, use `label_peri_signals`,
            which will leave out and duplicate spikes, but can manage overlapping time signals.

def label_by_time(self,time_signals,label_names=[],copy=False, **kwargs):
        """
            creates a labeled spike data structure

                time_label_array is list of lists (or matrix), containing a timestamp in the 
                first column (or first element of each element) and indizes that are to be 
                applied to the data in the remaining columns / elements.

            This function will not add or remove spikes, but only shift spikes according to the 
            adjecent time signals.

            If you want to get spikes relative to a time signal with fixed limits, use `label_peri_signals`,
            which will leave out and duplicate spikes, but can manage overlapping time signals.


        """
        new_containers = []
        for sc in self.spike_containers:
            new_sc = sc.label_by_time(time_signals=time_signals,copy=True, label_names=label_names, **kwargs)
            new_containers.append(new_sc)
        return SpikeContainerCollection(new_containers,
                        units=self.units,
                        min_t=self.min_t,
                        max_t=self.max_t, 
                        copy_from=self, 
                        label_names = label_names, 
                        index_dimensions = np.max(time_signals[1:,:],1)+1)