code: def decluster(peaks, index, trig_int):
      
      utilslib = _load_cdll('libutils')
  
      length = np.int32(len(peaks))
      utilslib.find_peaks.argtypes = [
          np.ctypeslib.ndpointer(dtype=np.float32, shape=(length,),
                                 flags=native_str('C_CONTIGUOUS')),
          np.ctypeslib.ndpointer(dtype=np.float32, shape=(length,),
                                 flags=native_str('C_CONTIGUOUS')),
          ctypes.c_int, ctypes.c_float, ctypes.c_float,
          np.ctypeslib.ndpointer(dtype=np.uint32, shape=(length,),
                                 flags=native_str('C_CONTIGUOUS'))]
      utilslib.find_peaks.restype = ctypes.c_int
      peaks_sort = sorted(zip(peaks, index),
                          key=lambda amplitude: abs(amplitude[0]),
                          reverse=True)
      arr, inds = zip(*peaks_sort)
      arr = np.ascontiguousarray(arr, dtype=np.float32)
      inds = np.array(inds, dtype=np.float32) / trig_int
      inds = np.ascontiguousarray(inds, dtype=np.float32)
      out = np.zeros(len(arr), dtype=np.uint32)
      ret = utilslib.find_peaks(
          arr, inds, length, 0, np.float32(1), out)
      if ret != 0:
          raise MemoryError("Issue with c-routine, returned %i" % ret)
      peaks_out = list(compress(peaks_sort, out))
      return peaks_out
docs: Decluster peaks based on an enforced minimum separation.
      :type peaks: np.array
      :param peaks: array of peak values
      :type index: np.ndarray
      :param index: locations of peaks
      :type trig_int: int
      :param trig_int: Minimum trigger interval in samples
  
      :return: list of tuples of (value, sample)