Skip to content

The working version of the realtime decoder that worked in 2025 (with SC101,SC104 ...)#15

Open
donghoon-shin wants to merge 1 commit into
mainfrom
sharable-version
Open

The working version of the realtime decoder that worked in 2025 (with SC101,SC104 ...)#15
donghoon-shin wants to merge 1 commit into
mainfrom
sharable-version

Conversation

@donghoon-shin

Copy link
Copy Markdown
Collaborator

I made a private repo and was updating there. now we want to have a codebase that is actively updated by multiple people, i made a pr so that we can have a one version that can work across set ups

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to bring back a known-working (2025-era) realtime decoder/stimulation workflow while making it more configurable across different lab setups (e.g., varying position/arm segment mappings and model buffer behavior).

Changes:

  • Updated stimulation record labeling/buffer sizing and replay detection/threshold-update logic, including additional replay event heuristics.
  • Modified encoder model loading/saving and mark buffering behavior, with additional early-save/downsampling logic.
  • Added/adjusted debugging output in ripple processing and other runtime paths.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 10 comments.

File Description
realtime_decoder/stimulation.py Makes stimulation outputs and replay computations more configurable (arm IDs, region/base probability sums) and adjusts replay/threshold behavior.
realtime_decoder/encoder_process.py Changes encoder mark buffering/model loading logic and adds early-save logic intended to keep saved models usable across runs/setups.
realtime_decoder/ripple_process.py Adds additional debug visibility during ripple stats reset / filtering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +68 to 72
arm_ids = config['encoder']['position']['arm_ids']

rls = ['region_box' if arm_id == 0 else f'region_arm{arm_id}' for arm_id in arm_ids]
region_labels = [f'{rl}_{x}' for x in range(num_decoders) for rl in rls]

Comment on lines +818 to +821
ps_arm1 = prob[arm1_detection_start_bin:(arm1_end+1)].sum() #NOTE(DS): originally, 20-25
ps_arm2 = prob[arm2_detection_start_bin:(arm2_end+1)].sum() #NOTE(DS): originally, 36-41
ps_arm1_base = prob[arm1_start:arm1_detection_start_bin].sum()
ps_arm2_base = prob[arm1_start:arm2_detection_start_bin].sum()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@donghoon-shin you might want to double check this one as it may affect your results

Comment on lines +994 to +997
potentially_duplicated_spikes = False
if num_unique == 2:
if np.abs(np.diff(np.unique(trodes_of_spike))) == 1:
potentially_duplicated_spikes = True
Comment on lines 1337 to 1341
# dim 2 is 3 because 3 regions - box, arm1, arm2
# _ps_ - shorthand for probability sum
self._arm_ps_buff = np.zeros((num_decoders, N, 3))
self._arm_ps_buff = np.zeros((num_decoders, N, len(self._config['encoder']['position']['arm_ids'])))
self._region_ps_buff = np.zeros_like(self._arm_ps_buff)
self._region_ps_base_buff = np.zeros_like(self._arm_ps_buff)
Comment on lines +116 to +120
print(f['mark_idx'])
if f['mark_idx'][0] < self._config['encoder']['bufsize']: #NOTE(DS): it seem to be a offset of 1.
self._mark_idx = f['mark_idx'][0]-1
else:
self._mark_idx = self._config['encoder']['bufsize']-1
Comment on lines +171 to +185
if self._mark_idx == self._marks.shape[0]:
# NOTE(DS): This make buf_size meaningless
self._marks = np.vstack((
self._marks,
np.zeros_like(self._marks)
))
self._positions = np.hstack((
self._positions,
np.zeros_like(self._positions)
))

# this is where the mark_size increases over time
self._marks[self._mark_idx] = mark
self._positions[self._mark_idx] = self._position
self._mark_idx += 1
Comment on lines +548 to +549
if len(mark_vec) is not 8:
print(f"******************mark_vec: {len(mark_vec)}*******************")
Comment on lines 718 to 720
num_signals = len(trodes)
print(f"num_signals: {len(trodes)}")
# stats for individual traces
Comment on lines 1054 to 1057
def _update_scm_threshold(self):

#NOTE(DS): This is old version -- for SC92 that I determine the number of events/minutess
desired_number_of_scm = np.ceil(self._num_scm_each_arm_per_minute * self._elapsed_minutes)
Comment on lines +643 to +656
n_spikes_currently_in_buffer = np.min([encoder._mark_idx,encoder._marks.shape[0]-1])
print(f"n_spikes_current_in_buffer in encoder {encoder._trode}: {n_spikes_currently_in_buffer}")
n_spikes_capacity_buffer = self._config['encoder']['bufsize']
if n_spikes_currently_in_buffer > n_spikes_capacity_buffer:
encoder._chosen_indices = np.sort(np.random.choice(n_spikes_currently_in_buffer,n_spikes_currently_in_buffer,replace=False))
self.class_log.info(
f"in encoder {encoder._trode}: choosing {n_spikes_capacity_buffer} from {n_spikes_currently_in_buffer} spikes"
)
encoder._marks = copy.deepcopy(encoder._marks[encoder._chosen_indices])
encoder._positions = copy.deepcopy(encoder._positions[encoder._chosen_indices])

else:
encoder._chosen_indices = np.arange(encoder._mark_idx)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants