docs: def label_by_time(self,time_signals,label_names=[],time_units='ms',time_dimension=0,copy=True,backup_original_spike_times_to=None,**kwargs):
          """
              creates a labeled spike data structure
  
                  `time_signals` 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 
              preceding 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.
  
              To get the absolute spike times back, `.absolute_spike_times_from_labels` can be used
              on the resulting SpikeContainer.
              However, the order and length of the timing signals might not be correct, if eg. 
              the intervals between time signals vary in length.
  
              If `backup_original_spike_times_to` is set to a string, the original spike times will
              be saved as this dimension as the new (relative) spike times replace the old time dimension.
          """
          if self.data_format == 'empty':
              return SpikeContainer(None,units=self.units,copy_from=self)
          spike_times = self.spike_times.get_converted(time_dimension, units=time_units)[1].copy() # this is read only
          time_signals = np.array(time_signals)
          re_zeroed_spike_times = spike_times.copy() # this will be modified
          indizes = np.zeros((len(spike_times),time_signals.shape[0] -1 ))
          maximal_time_gap = np.max(np.diff(time_signals[0]))
          for t in range(len(time_signals[0])):
              if t + 1 < len(time_signals[0]):
                  # we are past the last time signal
                  spike_range = (spike_times > time_signals[0][t]) * (spike_times <= time_signals[0][t+1])
                  indizes[spike_range,:] = [time_signals[_i][t] for _i in range(1,time_signals.shape[0])]
                  re_zeroed_spike_times[spike_range] = (
                          spike_times[spike_range] - time_signals[0][t]
                      )
              else:
                  # we move all spikes in the future back by this time signal
                  # (this will overwrite the spike times multiple times)
                  indizes[spike_times > time_signals[0][t],:] = [time_signals[_i][t] for _i in range(1,time_signals.shape[0])]
                  re_zeroed_spike_times[spike_times > time_signals[0][t]] = (
                          spike_times[spike_times > time_signals[0][t]] - time_signals[0][t]
                      )
          new_spike_times = LabeledMatrix(self.spike_times.matrix,self.spike_times.labels)
          new_spike_times.add_label_dimension(label_names,indizes)
          new_spike_times.labels[0].units = time_units
          new_spike_times.matrix[:,0] = re_zeroed_spike_times
          new_spike_times.labels[0].min = 0
          new_spike_times.labels[0].max = maximal_time_gap
          if kwargs.get('recalculate_time_extent',False):
              new_spike_times.labels[0].min = np.min(re_zeroed_spike_times)
              new_spike_times.labels[0].max = np.max(re_zeroed_spike_times)
          if backup_original_spike_times_to is not None:
              new_spike_times.add_label_dimension(backup_original_spike_times_to,self[time_dimension])
          if copy:
              s = SpikeContainer(new_spike_times, copy_from=self)
              #if backup_original_spike_times_to is not None:
              #    # copying spikes
              #    time_label = self.get_label(time_dimension)
              #    s[backup_original_spike_times_to] = {'data':self[time_dimension],'label': time_label}
              return s
          else:
              #if backup_original_spike_times_to is not None:
              #    # copying spikes
              #    time_label = self.get_label(time_dimension)
              #    self[backup_original_spike_times_to] = {'data':self[time_dimension],'label': time_label}
              self.set_spike_times(new_spike_times)
              return self