Construct annotations from boolean mask of the data.
(times, mask, annot_name, orig_time=None)
| 405 | |
| 406 | |
| 407 | def _annotations_from_mask(times, mask, annot_name, orig_time=None): |
| 408 | """Construct annotations from boolean mask of the data.""" |
| 409 | mask_tf = distance_transform_edt(mask) |
| 410 | # Overcome the shortcoming of find_peaks |
| 411 | # in finding a marginal peak, by |
| 412 | # inserting 0s at the front and the |
| 413 | # rear, then subtracting in index |
| 414 | ins_mask_tf = np.concatenate((np.zeros(1), mask_tf, np.zeros(1))) |
| 415 | left_midpt_index = find_peaks(ins_mask_tf)[0] - 1 |
| 416 | right_midpt_index = ( |
| 417 | np.flip(len(ins_mask_tf) - 1 - find_peaks(ins_mask_tf[::-1])[0]) - 1 |
| 418 | ) |
| 419 | onsets_index = left_midpt_index - mask_tf[left_midpt_index].astype(int) + 1 |
| 420 | ends_index = right_midpt_index + mask_tf[right_midpt_index].astype(int) |
| 421 | # Ensure onsets_index >= 0, |
| 422 | # otherwise the duration starts from the beginning |
| 423 | onsets_index[onsets_index < 0] = 0 |
| 424 | # Ensure ends_index < len(times), |
| 425 | # otherwise the duration is to the end of times |
| 426 | if len(times) == len(mask): |
| 427 | ends_index[ends_index >= len(times)] = len(times) - 1 |
| 428 | # To be consistent with the original code, |
| 429 | # possibly a bug in tests code |
| 430 | else: |
| 431 | ends_index[ends_index >= len(mask)] = len(mask) |
| 432 | onsets = times[onsets_index] |
| 433 | ends = times[ends_index] |
| 434 | durations = ends - onsets |
| 435 | desc = [annot_name] * len(durations) |
| 436 | return Annotations(onsets, durations, desc, orig_time=orig_time) |
| 437 | |
| 438 | |
| 439 | @verbose |
no test coverage detected