def generate_whitenoise_sequence(seq_array_bool, seq_array, scale: int, debug=False, mask=None, **kwargs): """ Generates a sequence for upload to DMD. :param seq_array_bool: boolean ndarray to write the random bits, dimensions (N_pix, H_dmd/scale, W_dmd/scale) :param seq_array: uint8 ndarray for upload with dimensions (N_pix, H_dmd, W_dmd) :param scale: scale for discreet random pixels in DMD space. ie if scale=2, each random pixel will be projected as 2x2 pix on the dmd. :param debug: use numeric debug sequence generator to test synchronization. """ if not debug: random_sequence_generator(seq_array_bool) zoomer(seq_array_bool, scale, seq_array) else: global _DEBUG_COUNTER # a bit messy, but I don't want to spend to much time on the debug cleanliness. # _DEBUG_COUNTER += seq_array_bool.shape[0] number_sequence_generator(_DEBUG_COUNTER, seq_array) seq_array *= 255 _DEBUG_COUNTER += seq_array_bool.shape[0] # print(seq_array.mean()) seq_array[:] *= mask # mask is 1 in areas we want to stimulate and 0 otherwise. This is faster than alternatives.
def sequence_generator(seq_array_bool, seq_array, scale: int, debug=False, mask=None): """ Generates a sequence for upload to DMD. :param seq_array_bool: boolean ndarray to write the random bits, dimensions (N_pix, H_dmd/scale, W_dmd/scale) :param seq_array: uint8 ndarray for upload with dimensions (N_pix, H_dmd, W_dmd) :param scale: scale for discreet random pixels in DMD space. ie if scale=2, each random pixel will be projected as 2x2 pix on the dmd. :param debug: use numeric debug sequence generator to test synchronization. """ if random_threshold is None: raise ValueError('random_threshold kwarg is not set.') unmasked = find_unmasked_px(mask, scale) n_nmasked = unmasked.sum() n_frames, h, w = seq_array_bool.shape total_randnums = n_nmasked * n_frames randnums = np.random.rand(total_randnums) randbool = randnums <= random_threshold reshape(randbool, unmasked, seq_array_bool) zoomer(seq_array_bool, scale, seq_array) seq_array[:] *= mask # mask is 1 in areas we want to stimulate and 0 otherwise. This is faster than alternatives.
def make_patterns(self, boolean_array: np.ndarray, whole_seq_array: np.ndarray, debug): """ Modifies arrays in place with random values (on, off). This makes sparse random patterns drawn from varying probability distributions. :param boolean_array: boolean array that is of shape ( n_frames, h / scale, w / scale) :param whole_seq_array: array of uint8 values of shave (n_frames, h, w) :param debug: not implemented. """ n_frames, h, w = boolean_array.shape total_randnums = n_frames * self.n_unmasked_pix probs = np.zeros(total_randnums) self._frame_count = self._gen_probs(probs, self._frame_count, self.n_unmasked_pix, self.switch_frequency, self.random_probs, self._last_p) self._last_p = probs[ -1] # save this for the next iteration if we're in the middle of a presentation block. a = np.random.binomial(1, probs, total_randnums) utils.reshape(a, self.unmasked, boolean_array) utils.zoomer(boolean_array, self.scale, whole_seq_array) whole_seq_array *= self.mask
def make_patterns(self, boolean_array, whole_seq_array, debug): n_frames, h, w = boolean_array.shape _, h_full, w_full = whole_seq_array.shape assert h_full // h == self.scale # whole_seq_array[:, :, :] = 0 boolean_array[:, :, :] = False for i in range(n_frames): msg = '{:06n}'.format(self._count) # self._make_text_fast(msg, whole_seq_array[i, :, :]) self._make_text_fast(msg, boolean_array[i, :, :], margins=(2, 2, 37, 37)) self._count += 1 utils.zoomer(boolean_array, self.scale, whole_seq_array)
def make_patterns(self, boolean_array: np.ndarray, whole_seq_array: np.ndarray, debug): """ Modifies arrays in place with random values (on, off). :param boolean_array: boolean array that is of shape ( n_frames, h / scale, w / scale) :param whole_seq_array: array of uint8 values of shave (n_frames, h, w) :param debug: not implemented. :return: """ n_frames, h, w = boolean_array.shape total_randnums = n_frames * self.n_unmasked_pix randnums = np.random.rand(total_randnums) randbool = randnums <= self.threshold utils.reshape(randbool, self.unmasked, boolean_array) utils.zoomer(boolean_array, self.scale, whole_seq_array) whole_seq_array *= self.mask