Safely find sample boundaries.
(
times, tmin=None, tmax=None, sfreq=None, raise_error=True, include_tmax=True
)
| 449 | |
| 450 | |
| 451 | def _time_mask( |
| 452 | times, tmin=None, tmax=None, sfreq=None, raise_error=True, include_tmax=True |
| 453 | ): |
| 454 | """Safely find sample boundaries.""" |
| 455 | orig_tmin = tmin |
| 456 | orig_tmax = tmax |
| 457 | tmin = -np.inf if tmin is None else tmin |
| 458 | tmax = np.inf if tmax is None else tmax |
| 459 | if not np.isfinite(tmin): |
| 460 | tmin = times[0] |
| 461 | if not np.isfinite(tmax): |
| 462 | tmax = times[-1] |
| 463 | include_tmax = True # ignore this param when tmax is infinite |
| 464 | if sfreq is not None: |
| 465 | # Push to a bit past the nearest sample boundary first |
| 466 | sfreq = float(sfreq) |
| 467 | tmin = int(round(tmin * sfreq)) / sfreq - 0.5 / sfreq |
| 468 | tmax = int(round(tmax * sfreq)) / sfreq |
| 469 | tmax += (0.5 if include_tmax else -0.5) / sfreq |
| 470 | else: |
| 471 | assert include_tmax # can only be used when sfreq is known |
| 472 | if raise_error and tmin > tmax: |
| 473 | raise ValueError( |
| 474 | f"tmin ({orig_tmin}) must be less than or equal to tmax ({orig_tmax})" |
| 475 | ) |
| 476 | mask = times >= tmin |
| 477 | mask &= times <= tmax |
| 478 | if raise_error and not mask.any(): |
| 479 | extra = "" if include_tmax else "when include_tmax=False " |
| 480 | raise ValueError( |
| 481 | f"No samples remain when using tmin={orig_tmin} and tmax={orig_tmax} " |
| 482 | f"{extra}(original time bounds are [{times[0]}, {times[-1]}] containing " |
| 483 | f"{len(times)} sample{_pl(times)})" |
| 484 | ) |
| 485 | return mask |
| 486 | |
| 487 | |
| 488 | def _freq_mask(freqs, sfreq, fmin=None, fmax=None, raise_error=True): |