Checkpoint 3
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -15,7 +15,8 @@
|
|||||||
<!-- Lung Analysis -->
|
<!-- Lung Analysis -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
3
|
3
|
||||||
</div>
|
</div>
|
||||||
@@ -35,7 +36,8 @@
|
|||||||
<!-- Cardio Metrics -->
|
<!-- Cardio Metrics -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
4
|
4
|
||||||
</div>
|
</div>
|
||||||
@@ -52,7 +54,8 @@
|
|||||||
<!-- Fuel Utilization -->
|
<!-- Fuel Utilization -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
5
|
5
|
||||||
</div>
|
</div>
|
||||||
@@ -66,7 +69,8 @@
|
|||||||
<!-- Local Muscle Activity -->
|
<!-- Local Muscle Activity -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
9
|
9
|
||||||
</div>
|
</div>
|
||||||
@@ -80,7 +84,8 @@
|
|||||||
<!-- Training Recommendations -->
|
<!-- Training Recommendations -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
10
|
10
|
||||||
</div>
|
</div>
|
||||||
@@ -94,7 +99,8 @@
|
|||||||
<!-- Next Steps -->
|
<!-- Next Steps -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
12
|
12
|
||||||
</div>
|
</div>
|
||||||
@@ -111,7 +117,8 @@
|
|||||||
<!-- Glossary -->
|
<!-- Glossary -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
13
|
13
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
<!-- Nutrition Guidelines -->
|
<!-- Nutrition Guidelines -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
3
|
3
|
||||||
</div>
|
</div>
|
||||||
@@ -35,7 +36,8 @@
|
|||||||
<!-- Nutrition Recommendations -->
|
<!-- Nutrition Recommendations -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
4
|
4
|
||||||
</div>
|
</div>
|
||||||
@@ -49,7 +51,8 @@
|
|||||||
<!-- Next Steps -->
|
<!-- Next Steps -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
5
|
5
|
||||||
</div>
|
</div>
|
||||||
@@ -66,7 +69,8 @@
|
|||||||
<!-- Glossary -->
|
<!-- Glossary -->
|
||||||
<div class="flex items-start bg-gray-200 h-24">
|
<div class="flex items-start bg-gray-200 h-24">
|
||||||
<div
|
<div
|
||||||
class="bg-black text-white text-2xl font-bold w-16 h-full flex items-center justify-center mr-8 flex-shrink-0"
|
class="bg-black text-white text-4xl font-extrabold w-24 h-24 flex items-center justify-center mr-8 flex-shrink-0"
|
||||||
|
style="border-radius: 0;"
|
||||||
>
|
>
|
||||||
6
|
6
|
||||||
</div>
|
</div>
|
||||||
@@ -82,8 +86,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<!-- Indications Box -->
|
<!-- Indications Box -->
|
||||||
<div class="bg-gray-200 rounded-lg p-4 text-center mb-2">
|
<div class="bg-gray-200 rounded-lg p-4 text-center mb-2">
|
||||||
<h3 class="font-semibold text-lg mb-2">Indications</h3>
|
<h3 class="font-semibold text-lg mb-2">Indications</h3>
|
||||||
<p >{{ indication | default('No Respiratory Capacity Limitations')}}</p>
|
<p >{{ indication | default('No Respiratory Capacity Limitation')}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -232,10 +232,15 @@ class ContextGenerator:
|
|||||||
if zone_key in metric_overrides:
|
if zone_key in metric_overrides:
|
||||||
metrics[zone_key] = metric_overrides[zone_key]
|
metrics[zone_key] = metric_overrides[zone_key]
|
||||||
else:
|
else:
|
||||||
fat_max_idx = self.pnoe_df["FAT_smoothed"].idxmax()
|
# Use optimal fat burning zone (highest fat:carb ratio) - same as _calculate_zone_metrics
|
||||||
fat_max_row = self.pnoe_df.loc[fat_max_idx]
|
# This ensures consistency between zone calculations and zone metrics
|
||||||
|
self.pnoe_df["fat_carb_ratio"] = self.pnoe_df["FAT_smoothed"] / (
|
||||||
|
self.pnoe_df["CHO_smoothed"] + 0.00000001
|
||||||
|
)
|
||||||
|
optimal_fat_idx = self.pnoe_df["fat_carb_ratio"].idxmax()
|
||||||
|
optimal_row = self.pnoe_df.loc[optimal_fat_idx]
|
||||||
zones = self._calculate_hr_zones(
|
zones = self._calculate_hr_zones(
|
||||||
metrics["vt1"], metrics["vt2"], fat_max_row
|
metrics["vt1"], metrics["vt2"], optimal_row
|
||||||
)
|
)
|
||||||
metrics.update(zones)
|
metrics.update(zones)
|
||||||
|
|
||||||
@@ -280,29 +285,46 @@ class ContextGenerator:
|
|||||||
return vt1, vt2
|
return vt1, vt2
|
||||||
|
|
||||||
def _calculate_hr_zones(
|
def _calculate_hr_zones(
|
||||||
self, vt1: Optional[Dict], vt2: Optional[Dict], fat_max_row: pd.Series
|
self, vt1: Optional[Dict], vt2: Optional[Dict], optimal_row: pd.Series
|
||||||
) -> Dict:
|
) -> Dict:
|
||||||
"""Calculate heart rate zones based on thresholds"""
|
"""Calculate heart rate zones based on thresholds
|
||||||
|
|
||||||
|
Uses optimal fat burning zone (highest fat:carb ratio) to match _calculate_zone_metrics.
|
||||||
|
This ensures consistency between zone string calculations and zone metrics table.
|
||||||
|
"""
|
||||||
|
import math
|
||||||
|
|
||||||
zones = {}
|
zones = {}
|
||||||
if vt1 and vt2:
|
if vt1 and vt2:
|
||||||
zone_1_start = fat_max_row["HR(bpm)_smoothed"] - 15
|
# Use same zone boundary calculation as _calculate_zone_metrics
|
||||||
zone_2_start = fat_max_row["HR(bpm)_smoothed"]
|
zone_1_start = math.floor(optimal_row["HR(bpm)_smoothed"] - 15)
|
||||||
zone_3_start = vt1["HeartRate"]
|
zone_2_start = math.floor(optimal_row["HR(bpm)_smoothed"])
|
||||||
zone_4_start = vt2["HeartRate"] - 10
|
zone_3_start = math.floor(vt1["HeartRate"])
|
||||||
zone_5_start = vt2["HeartRate"] + 10
|
zone_4_start = math.floor(vt2["HeartRate"] - 10)
|
||||||
|
zone_5_start = math.floor(vt2["HeartRate"])
|
||||||
|
# zone_5_end is calculated for consistency with _calculate_zone_metrics
|
||||||
|
# (not used in string format since zone 5 is open-ended: "+bpm")
|
||||||
|
zone_5_end = math.floor(vt2["HeartRate"] + 10) # noqa: F841
|
||||||
|
|
||||||
zones["zone1_bpm"] = f"{int(zone_1_start)}-{int(zone_2_start)}bpm"
|
# Calculate zone ends to match _calculate_zone_metrics exactly
|
||||||
zones["zone2_bpm"] = f"{int(zone_2_start)}-{int(vt1['HeartRate'])}bpm"
|
zone_1_end = zone_2_start
|
||||||
zones["zone3_bpm"] = f"{int(zone_3_start)}-{int(zone_4_start)}bpm"
|
zone_2_end = math.floor(vt1["HeartRate"])
|
||||||
zones["zone4_bpm"] = f"{int(zone_4_start)}-{int(zone_5_start)}bpm"
|
zone_3_end = zone_4_start
|
||||||
zones["zone5_bpm"] = f"{int(zone_5_start)}+bpm"
|
zone_4_end = zone_5_start
|
||||||
|
|
||||||
|
# Format zones to match _calculate_zone_metrics output
|
||||||
|
zones["zone1_bpm"] = f"{int(zone_1_start)}-{int(zone_1_end)}bpm"
|
||||||
|
zones["zone2_bpm"] = f"{int(zone_2_start)}-{int(zone_2_end)}bpm"
|
||||||
|
zones["zone3_bpm"] = f"{int(zone_3_start)}-{int(zone_3_end)}bpm"
|
||||||
|
zones["zone4_bpm"] = f"{int(zone_4_start)}-{int(zone_4_end)}bpm"
|
||||||
|
zones["zone5_bpm"] = f"{int(zone_5_start)}-{int(zone_5_end)}bpm"
|
||||||
else:
|
else:
|
||||||
max_hr = 220 - self.patient_info["age"]
|
max_hr = 220 - self.patient_info["age"]
|
||||||
zones["zone1_bpm"] = f"{int(max_hr * 0.55)}-{int(max_hr * 0.65)}bpm"
|
zones["zone1_bpm"] = f"{int(max_hr * 0.55)}-{int(max_hr * 0.65)}bpm"
|
||||||
zones["zone2_bpm"] = f"{int(max_hr * 0.65)}-{int(max_hr * 0.75)}bpm"
|
zones["zone2_bpm"] = f"{int(max_hr * 0.65)}-{int(max_hr * 0.75)}bpm"
|
||||||
zones["zone3_bpm"] = f"{int(max_hr * 0.75)}-{int(max_hr * 0.85)}bpm"
|
zones["zone3_bpm"] = f"{int(max_hr * 0.75)}-{int(max_hr * 0.85)}bpm"
|
||||||
zones["zone4_bpm"] = f"{int(max_hr * 0.85)}-{int(max_hr * 0.95)}bpm"
|
zones["zone4_bpm"] = f"{int(max_hr * 0.85)}-{int(max_hr * 0.95)}bpm"
|
||||||
zones["zone5_bpm"] = f"{int(max_hr * 0.95)}+bpm"
|
zones["zone5_bpm"] = f"{int(max_hr * 0.95)}-{int(max_hr * 1.05)}bpm"
|
||||||
return zones
|
return zones
|
||||||
|
|
||||||
def _calculate_vo2_drop_points(self, pnoe_metrics: Dict) -> Dict:
|
def _calculate_vo2_drop_points(self, pnoe_metrics: Dict) -> Dict:
|
||||||
@@ -1180,7 +1202,9 @@ class ContextGenerator:
|
|||||||
"page_number": 4,
|
"page_number": 4,
|
||||||
"fat_percentage": f"{self.patient_info['fat_percentage']:.1f}",
|
"fat_percentage": f"{self.patient_info['fat_percentage']:.1f}",
|
||||||
"body_composition_chart": graphs.get("body_composition", ""),
|
"body_composition_chart": graphs.get("body_composition", ""),
|
||||||
"body_fat_chart": graphs.get("body_fat_percent", ""), # Alias for template
|
"body_fat_chart": graphs.get(
|
||||||
|
"body_fat_percent", ""
|
||||||
|
), # Alias for template
|
||||||
"body_fat_percent_chart": graphs.get(
|
"body_fat_percent_chart": graphs.get(
|
||||||
"body_fat_percent", ""
|
"body_fat_percent", ""
|
||||||
), # Keep for consistency
|
), # Keep for consistency
|
||||||
@@ -1265,12 +1289,16 @@ class ContextGenerator:
|
|||||||
"deficit_carbs": f"{int(rmr_metrics.get('total_calories', 1600) * 0.39 / 4)}g Carbs",
|
"deficit_carbs": f"{int(rmr_metrics.get('total_calories', 1600) * 0.39 / 4)}g Carbs",
|
||||||
"deficit_fat": f"{int(rmr_metrics.get('total_calories', 1600) * 0.39 / 9)}g Fat",
|
"deficit_fat": f"{int(rmr_metrics.get('total_calories', 1600) * 0.39 / 9)}g Fat",
|
||||||
"deficit_fiber": "24g Fibre",
|
"deficit_fiber": "24g Fibre",
|
||||||
"refeed_weekday_calories": int(rmr_metrics.get("total_calories", 1600) * 0.85),
|
"refeed_weekday_calories": int(
|
||||||
|
rmr_metrics.get("total_calories", 1600) * 0.85
|
||||||
|
),
|
||||||
"refeed_weekday_protein": f"{int(rmr_metrics.get('total_calories', 1600) * 0.85 * 0.22 / 4)}g Protein",
|
"refeed_weekday_protein": f"{int(rmr_metrics.get('total_calories', 1600) * 0.85 * 0.22 / 4)}g Protein",
|
||||||
"refeed_weekday_carbs": f"{int(rmr_metrics.get('total_calories', 1600) * 0.85 * 0.39 / 4)}g Carbs",
|
"refeed_weekday_carbs": f"{int(rmr_metrics.get('total_calories', 1600) * 0.85 * 0.39 / 4)}g Carbs",
|
||||||
"refeed_weekday_fat": f"{int(rmr_metrics.get('total_calories', 1600) * 0.85 * 0.39 / 9)}g Fat",
|
"refeed_weekday_fat": f"{int(rmr_metrics.get('total_calories', 1600) * 0.85 * 0.39 / 9)}g Fat",
|
||||||
"refeed_weekday_fiber": "20g Fibre",
|
"refeed_weekday_fiber": "20g Fibre",
|
||||||
"refeed_weekend_calories": int(rmr_metrics.get("total_calories", 1600) * 1.375),
|
"refeed_weekend_calories": int(
|
||||||
|
rmr_metrics.get("total_calories", 1600) * 1.375
|
||||||
|
),
|
||||||
"refeed_weekend_protein": f"{int(rmr_metrics.get('total_calories', 1600) * 1.375 * 0.22 / 4)}g Protein",
|
"refeed_weekend_protein": f"{int(rmr_metrics.get('total_calories', 1600) * 1.375 * 0.22 / 4)}g Protein",
|
||||||
"refeed_weekend_carbs": f"{int(rmr_metrics.get('total_calories', 1600) * 1.375 * 0.39 / 4)}g Carbs",
|
"refeed_weekend_carbs": f"{int(rmr_metrics.get('total_calories', 1600) * 1.375 * 0.39 / 4)}g Carbs",
|
||||||
"refeed_weekend_fat": f"{int(rmr_metrics.get('total_calories', 1600) * 1.375 * 0.39 / 9)}g Fat",
|
"refeed_weekend_fat": f"{int(rmr_metrics.get('total_calories', 1600) * 1.375 * 0.39 / 9)}g Fat",
|
||||||
@@ -1562,7 +1590,11 @@ class ContextGenerator:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# For minimal reports, create combined context for page_19_20_minimal
|
# For minimal reports, create combined context for page_19_20_minimal
|
||||||
if report_type == "minimal" and 19 in pages_to_generate and 20 in pages_to_generate:
|
if (
|
||||||
|
report_type == "minimal"
|
||||||
|
and 19 in pages_to_generate
|
||||||
|
and 20 in pages_to_generate
|
||||||
|
):
|
||||||
contexts["page_19_20_minimal"] = {
|
contexts["page_19_20_minimal"] = {
|
||||||
"patient_name": self.patient_info["name"],
|
"patient_name": self.patient_info["name"],
|
||||||
"body_fat_percentage_chart": graphs.get(
|
"body_fat_percentage_chart": graphs.get(
|
||||||
|
|||||||
+23
-20
@@ -2,7 +2,7 @@
|
|||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 1,
|
||||||
"id": "b18c1027",
|
"id": "b18c1027",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 3,
|
||||||
"id": "56a9d655",
|
"id": "56a9d655",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -104,7 +104,10 @@
|
|||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"import pandas as pd\n",
|
"import pandas as pd\n",
|
||||||
"spirometry_df = pd.read_csv(\"data/spirometry_data.csv\")\n",
|
"import os\n",
|
||||||
|
"\n",
|
||||||
|
"base_dir = os.path.dirname(os.path.abspath('.'))\n",
|
||||||
|
"spirometry_df = pd.read_csv(f\"{base_dir}/data/spirometry_data.csv\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"fvc_best = spirometry_df.loc[spirometry_df['Parameters'] == 'FVC', 'Best'].values[0]\n",
|
"fvc_best = spirometry_df.loc[spirometry_df['Parameters'] == 'FVC', 'Best'].values[0]\n",
|
||||||
"fvc_pred = spirometry_df.loc[spirometry_df['Parameters'] == 'FVC', '%Pred.'].values[0]\n",
|
"fvc_pred = spirometry_df.loc[spirometry_df['Parameters'] == 'FVC', '%Pred.'].values[0]\n",
|
||||||
@@ -122,7 +125,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 4,
|
||||||
"id": "990f4b4f",
|
"id": "990f4b4f",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -136,7 +139,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"df = pd.read_csv('data/Pnoe_20250729_1550-Moran_Keirstyn.csv', delimiter=';')\n",
|
"df = pd.read_csv(f'{base_dir}/data/Pnoe_20250729_1550-Moran_Keirstyn.csv', delimiter=';')\n",
|
||||||
"peak_vt = df['VT(l)'].max()\n",
|
"peak_vt = df['VT(l)'].max()\n",
|
||||||
"max_vt_row = df.loc[df['VT(l)'].idxmax()]\n",
|
"max_vt_row = df.loc[df['VT(l)'].idxmax()]\n",
|
||||||
"print(f\"Peak VT: {peak_vt}\")\n",
|
"print(f\"Peak VT: {peak_vt}\")\n",
|
||||||
@@ -146,7 +149,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 19,
|
||||||
"id": "041cbc3d",
|
"id": "041cbc3d",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -154,21 +157,21 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Peak VT: 2.3770000000000002\n",
|
"Peak VT: 2.3844444444444446\n",
|
||||||
"HR at Peak VT: 171.525\n"
|
"HR at Peak VT: 172.80555555555554\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "stderr",
|
"name": "stderr",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"/tmp/ipykernel_69398/4157056299.py:3: FutureWarning: errors='ignore' is deprecated and will raise in a future version. Use to_numeric without passing `errors` and catch exceptions explicitly instead\n",
|
"/tmp/ipykernel_53922/361246798.py:3: FutureWarning: errors='ignore' is deprecated and will raise in a future version. Use to_numeric without passing `errors` and catch exceptions explicitly instead\n",
|
||||||
" df = df.apply(pd.to_numeric, errors='ignore')\n"
|
" df = df.apply(pd.to_numeric, errors='ignore')\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"df = pd.read_csv('data/Pnoe_20250729_1550-Moran_Keirstyn.csv', delimiter=';')\n",
|
"df = pd.read_csv(f'{base_dir}/data/Pnoe_20250729_1550-Moran_Keirstyn.csv', delimiter=';')\n",
|
||||||
"# Convert all columns to numeric where possible, coercing errors to NaN\n",
|
"# Convert all columns to numeric where possible, coercing errors to NaN\n",
|
||||||
"df = df.apply(pd.to_numeric, errors='ignore')\n",
|
"df = df.apply(pd.to_numeric, errors='ignore')\n",
|
||||||
"df['VO2 Pulse'] = df['VO2(ml/min)'] / df['HR(bpm)'] # VO2 Pulse in mL/beat\n",
|
"df['VO2 Pulse'] = df['VO2(ml/min)'] / df['HR(bpm)'] # VO2 Pulse in mL/beat\n",
|
||||||
@@ -176,7 +179,7 @@
|
|||||||
"df['CHO'] = df['EE(kcal/min)'] * df['CARBS(%)']/100\n",
|
"df['CHO'] = df['EE(kcal/min)'] * df['CARBS(%)']/100\n",
|
||||||
"df['FAT'] = df['EE(kcal/min)'] * df['FAT(%)']/100\n",
|
"df['FAT'] = df['EE(kcal/min)'] * df['FAT(%)']/100\n",
|
||||||
"# Smooth key columns using rolling window\n",
|
"# Smooth key columns using rolling window\n",
|
||||||
"window_size = 10\n",
|
"window_size = 9\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# List of columns to smooth\n",
|
"# List of columns to smooth\n",
|
||||||
"columns_to_smooth = ['VO2(ml/min)', 'VCO2(ml/min)', 'HR(bpm)', 'VT(l)', 'BF(bpm)', 'VE(l/min)', 'VO2 Pulse', 'VO2 Breath', 'CHO', 'FAT']\n",
|
"columns_to_smooth = ['VO2(ml/min)', 'VCO2(ml/min)', 'HR(bpm)', 'VT(l)', 'BF(bpm)', 'VE(l/min)', 'VO2 Pulse', 'VO2 Breath', 'CHO', 'FAT']\n",
|
||||||
@@ -195,7 +198,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 20,
|
||||||
"id": "de7cadd1",
|
"id": "de7cadd1",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -203,7 +206,7 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"Percent FEV: 72.91411042944786\n"
|
"Percent FEV: 73.14246762099523\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -214,7 +217,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 21,
|
||||||
"id": "cb972ed3",
|
"id": "cb972ed3",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -311,13 +314,13 @@
|
|||||||
"[1 rows x 147 columns]"
|
"[1 rows x 147 columns]"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 11,
|
"execution_count": 21,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"personal_df = pd.read_excel('data/SECA body comp for all patients.xlsx')\n",
|
"personal_df = pd.read_excel(f'{base_dir}/data/SECA body comp for all patients.xlsx')\n",
|
||||||
"\n",
|
"\n",
|
||||||
"keirstyn_data = personal_df[personal_df['LastName'].str.contains('Moran', case=False, na=False)]\n",
|
"keirstyn_data = personal_df[personal_df['LastName'].str.contains('Moran', case=False, na=False)]\n",
|
||||||
"keirstyn_data"
|
"keirstyn_data"
|
||||||
@@ -325,7 +328,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": 22,
|
||||||
"id": "98d9295a",
|
"id": "98d9295a",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
@@ -333,7 +336,7 @@
|
|||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
"VO2 Max: 47.906290322580645\n"
|
"VO2 Max: 48.19062126642772\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -823,7 +826,7 @@
|
|||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"kernelspec": {
|
"kernelspec": {
|
||||||
"display_name": "report_generation",
|
"display_name": ".venv",
|
||||||
"language": "python",
|
"language": "python",
|
||||||
"name": "python3"
|
"name": "python3"
|
||||||
},
|
},
|
||||||
@@ -837,7 +840,7 @@
|
|||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.12.3"
|
"version": "3.12.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
|||||||
Reference in New Issue
Block a user