Source code for src.openCHA.tasks.affect.sleep_analysis
import json
from io import StringIO
from typing import Any
from typing import List
import pandas as pd
from openCHA.tasks.affect import Affect
[docs]
class SleepAnalysis(Affect):
"""
**Description:**
This tasks performs average, sum, or trend analysis on the provided raw sleep affect data for specific patient.
"""
name: str = "affect_sleep_analysis"
chat_name: str = "AffectSleepAnalysis"
description: str = (
"When a request for analysis of sleep data is received (such as calculating averages, sums, or identifying trends), "
"call this analysis tool. This tool is specifically designed to handle complex data computations on sleep data records, "
"ensuring precise and reliable results. Example: If the data spans a year and the user seeks an average sleep data, "
"this tool will calculate the yearly average. If monthly data is needed, this task should be called multiple times for each month."
)
dependencies: List[str] = ["affect_sleep_get"]
inputs: List[str] = [
"You should provide the data source, which is in form of datapipe:datapipe_key "
"the datapipe_key should be extracted from the result of previous actions.",
"the analysis type which is one of **average** or **trend**.",
]
outputs: List[str] = [
"returns an array of json objects which contains the following keys:"
"\n**date (in milliseconds)**: epoch format"
"\n**total_sleep_time (in minutes)**: is Total amount of sleep (a.k.a. sleep duration) registered during the sleep period."
"\n**awake_duration (in minutes)**: is the total amount of awake time registered during the sleep period."
"\n**light_sleep_duration (in minutes)**: is the total amount of light (N1 or N2) sleep registered during the sleep period."
"\n**rem_sleep_duration (in minutes)**: is the total amount of REM sleep registered during the sleep period."
"\n**deep_sleep_duration (in minutes)**: is the total amount of deep (N3) sleep registered during the sleep period."
"\n**sleep_onset_latency (in minutes)**: is detected latency from bedtime_start to the beginning of the first"
"five minutes of persistent sleep."
"\n**midpoint_time_of_sleep (in minutes)**: is the time from the start of sleep to the midpoint of sleep. The midpoint ignores awake periods."
"\n**sleep_efficiency**: is the percentage of the sleep period spent asleep (100% * sleep duration / time in bed)."
"\n**average_heart_rate**: is the average heart rate registered during the sleep period."
"\n**minimum_heart_rate**: is the lowest heart rate (5 minutes sliding average) registered during the sleep period."
"\n**rmssd is the average**: Root Mean Square of Successive Differences (RMSSD) registered during the sleep period."
"\n**average_breathing_rate**: is the average breathing rate registered during the sleep period."
"\n**temperature_variation**: is the skin temperature deviation from the long-term temperature average."
]
# False if the output should directly passed back to the planner.
# True if it should be stored in datapipe
output_type: bool = True
[docs]
def _execute(
self,
inputs: List[Any],
) -> str:
try:
df = pd.read_json(
StringIO(inputs[0]["data"].strip()), orient="records"
)
except Exception as e:
print(f"An error occurred: {e}")
return json.loads(
'{"Data": "No data for the selected date(s)!"}'
)
if df.empty:
return json.loads(
'{"Data": "No data for the selected date(s)!"}'
)
analysis_type = inputs[1].strip()
if analysis_type == "average":
df = df.drop("date", axis=1) # No average for date!
df = df.mean().to_frame().T
elif analysis_type == "trend":
df = self._calculate_slope(df)
else:
raise ValueError(
"The input analysis type has not been defined!"
)
df = df.round(2)
json_out = df.to_json(orient="records")
return json_out