def _form_onset_offset_fronts(ons_or_offs, sample_rate_hz, threshold_ms=<NUM_LIT:20>):
threshold_s = threshold_ms / <NUM_LIT:1000><EOL>threshold_samples = sample_rate_hz * threshold_s<EOL>ons_or_offs = np.copy(ons_or_offs)<EOL>claimed = []<EOL>this_id = <NUM_LIT:2><EOL>for frequency_index, row in enumerate(ons_or_offs[:, :]):<EOL><INDENT>ones = np.reshape(np.where(row == <NUM_LIT:1>), (-<NUM_LIT:1>,))<EOL>for top_level_frequency_one_index in ones:<EOL><INDENT>claimed.append((frequency_index, top_level_frequency_one_index))<EOL>found_a_front = False<EOL>for other_frequency_index, other_row in enumerate(ons_or_offs[frequency_index + <NUM_LIT:1>:, :], start=frequency_index + <NUM_LIT:1>):<EOL><INDENT>upper_limit_index = top_level_frequency_one_index + threshold_samples<EOL>lower_limit_index = top_level_frequency_one_index - threshold_samples<EOL>other_ones = np.reshape(np.where(other_row == <NUM_LIT:1>), (-<NUM_LIT:1>,))  <EOL>tmp = np.reshape(np.where((other_ones >= lower_limit_index)  <EOL>& (other_ones <= upper_limit_index)), (-<NUM_LIT:1>,))<EOL>other_ones = other_ones[tmp]  <EOL>if len(other_ones) > <NUM_LIT:0>:<EOL><INDENT>unclaimed_idx = other_ones[<NUM_LIT:0>]  <EOL>claimed.append((other_frequency_index, unclaimed_idx))<EOL><DEDENT>elif len(claimed) < <NUM_LIT:3>:<EOL><INDENT>ons_or_offs[frequency_index, top_level_frequency_one_index] = <NUM_LIT:0><EOL>claimed = []<EOL>break  <EOL><DEDENT>elif len(claimed) >= <NUM_LIT:3>:<EOL><INDENT>found_a_front = True<EOL>claimed_as_indexes = tuple(np.array(claimed).T)<EOL>ons_or_offs[claimed_as_indexes] = this_id<EOL>this_id += <NUM_LIT:1><EOL>claimed = []<EOL>break  <EOL><DEDENT><DEDENT>if len(claimed) >= <NUM_LIT:3>:<EOL><INDENT>claimed_as_indexes = tuple(np.array(claimed).T)<EOL>ons_or_offs[claimed_as_indexes] = this_id<EOL>this_id += <NUM_LIT:1><EOL>claimed = []<EOL><DEDENT>elif found_a_front:<EOL><INDENT>this_id += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>ons_or_offs[frequency_index, top_level_frequency_one_index] = <NUM_LIT:0><EOL>claimed = []<EOL><DEDENT><DEDENT><DEDENT>return ons_or_offs<EOL>
Takes an array of onsets or offsets (shape = [nfrequencies, nsamples], where a 1 corresponds to an on/offset,
and samples are 0 otherwise), and returns a new array of the same shape, where each 1 has been replaced by
either a 0, if the on/offset has been discarded, or a non-zero positive integer, such that
each front within the array has a unique ID - for example, all 2s in the array will be the front for on/offset
front 2, and all the 15s will be the front for on/offset front 15, etc.

Due to implementation details, there will be no 1 IDs.