code: def create_timing_signals(timings,ranges=[3,8]):
      
      if ranges[-1] == -1:
          ranges[-1] = np.floor(len(timings)/float(np.prod(ranges[:-1]))) + 1
      return np.array([([t]+[cc for cc in c]) for t,c in zip(timings,icartesian([range(int(r)) for r in ranges]))]).transpose()
docs: Creates a linear list/np.array of timestamps and a list of integers, specifying the sequence 
          and number of levels.
  
          The levels are first rotated on the first dimension, then the second and so on. If the 
          last dimension is -1, the number of levels is computed from the timestamps.
  
          returns a 2 dimensional array with len(ranges) + 1 columns
              * the timestamp is in the first column
              * the following columns contain the specific level for this time stamp
  
          Example:
  
              utils.create_timing_signals(range(100),[2,5,-1])
  
          will return a matrix with the first column being the nubmers from 0 to 99, 
          the second alternates between 0 and 1 (eg. whether the number is odd), the third column 
          contains numbers 0 to 4, each bracketing a block of 2*5 = 10 numbers. The last column is
          computed according to the length of the timeseries (in this case 100/(2*5) is 10, ie the 
          column counts blocks of 10 numbers).