Skip to content

Feature/issue 303/new nonwear sleep interaction#306

Draft
Asanto32 wants to merge 2 commits into
mainfrom
feature/issue-303/new-nonwear-sleep-interaction
Draft

Feature/issue 303/new nonwear sleep interaction#306
Asanto32 wants to merge 2 commits into
mainfrom
feature/issue-303/new-nonwear-sleep-interaction

Conversation

@Asanto32

Copy link
Copy Markdown
Collaborator

Resolves #303

Begin co-pilot summary:

This pull request introduces significant improvements to the sleep cleanup logic in the analytics module, particularly adding adaptive handling of nonwear periods that immediately precede or are embedded within sleep windows. The changes also update the function signatures and return types, and expand the test suite to ensure robust handling of these new behaviors.

Enhancements to sleep cleanup logic:

  • The sleep_cleanup function in analytics.py now supports an adaptive mode that can absorb nonwear periods into sleep if sleep is detected within a configurable buffer after nonwear ends. The function signature and return type have been updated to return both the cleaned sleep and updated nonwear measurements. [1] [2]

API and documentation updates:

  • The docstrings for sleep_cleanup and sleep_bouts_cleanup have been updated to clarify the new behavior, arguments, and return types, reflecting that sleep_cleanup now returns a tuple and supports adaptive cleanup, and that sleep_bouts_cleanup returns a single measurement. [1] [2]

Integration and usage:

  • The orchestrator's _run_file method has been updated to unpack the new tuple return value from sleep_cleanup, ensuring downstream compatibility.

Testing improvements:

  • The test suite in test_analytics.py has been expanded with several new tests to verify the adaptive sleep cleanup logic, including cases where nonwear is adjacent to sleep, embedded within sleep, separated by a gap, or not adjacent at all. Existing tests have been updated to handle the new tuple return type.

Asanto32 added 2 commits June 11, 2026 19:45
Handle changes for nonwear/sleep overlap. Need to cleanup + add to orchestrator.
@codecov

codecov Bot commented Jun 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.68%. Comparing base (5e8de21) to head (db35ff5).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #306      +/-   ##
==========================================
+ Coverage   96.55%   96.68%   +0.13%     
==========================================
  Files          17       17              
  Lines        1132     1147      +15     
==========================================
+ Hits         1093     1109      +16     
+ Misses         39       38       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Asanto32

Copy link
Copy Markdown
Collaborator Author

After meeting with Greg; if we use the adaptive pass, nonwear should be modified accordingly (remove the overlap)

sleep_windows: List[SleepWindow],
nonwear_measurement: models.Measurement,
adaptive: bool = False,
nonwear_sleep_buffer: int = 0,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can this be optional and None is equivalent to adaptive == False?

def sleep_cleanup(
sleep_windows: List[SleepWindow], nonwear_measurement: models.Measurement
) -> models.Measurement:
sleep_windows: List[SleepWindow],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Iterable[SleepWindow]

)

return models.Measurement(time=sleep.time, measurements=cleaned_sleep)
if adaptive:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Flip around to "if not adaptive return"

nw_run_starts = np.where(nonwear_change == 1)[0]
nw_run_ends = np.where(nonwear_change == -1)[0]

for s, e in zip(nw_run_starts, nw_run_ends):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

zip(...., strict=True)



def test_new_sleep_cleanup_nonwear_gap_absorbed_only_with_sufficient_buffer() -> None:
"""Test nonwear + gap is absorbed only when buffer >= gap length."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Contradictory statement to the test; either change docstring or change the test

@reindervdw-cmi reindervdw-cmi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Minor comments, but no need for re-review.

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.

Task: Handle nonwear/sleep edge

2 participants