many updates
This commit is contained in:
168
FitnessSync/scratch/debug_specific_matches.py
Normal file
168
FitnessSync/scratch/debug_specific_matches.py
Normal file
@@ -0,0 +1,168 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
import statistics
|
||||
import logging
|
||||
sys.path.append('/app/backend')
|
||||
|
||||
from src.services.postgresql_manager import PostgreSQLManager
|
||||
from src.utils.config import config
|
||||
from src.models.activity import Activity
|
||||
from src.models.bike_setup import BikeSetup
|
||||
from src.services.parsers import extract_activity_data
|
||||
from src.services.bike_matching import WHEEL_CIRCUMFERENCE_M
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Re-implement logic to capture samples
|
||||
def analyze_streams_debug(speed_stream, cadence_stream, window_size=10):
|
||||
if not speed_stream or not cadence_stream or len(speed_stream) != len(cadence_stream):
|
||||
print(" - Streams missing or mismatched length")
|
||||
return [], 0.0
|
||||
|
||||
ratios = []
|
||||
samples = []
|
||||
|
||||
rejected_reasons = {'none': 0, 'threshold': 0, 'variance': 0}
|
||||
|
||||
n = len(speed_stream)
|
||||
for i in range(0, n - window_size, 5):
|
||||
window_speeds = speed_stream[i:i+window_size]
|
||||
window_cadences = cadence_stream[i:i+window_size]
|
||||
|
||||
if any(v is None for v in window_speeds) or any(c is None for c in window_cadences):
|
||||
rejected_reasons['none'] += 1
|
||||
continue
|
||||
|
||||
if all(c > 55 for c in window_cadences) and all(v > 2.5 for v in window_speeds):
|
||||
try:
|
||||
cad_std = statistics.stdev(window_cadences)
|
||||
spd_std = statistics.stdev(window_speeds)
|
||||
|
||||
if cad_std < 5 and spd_std < 0.5:
|
||||
avg_speed = statistics.mean(window_speeds)
|
||||
avg_cadence = statistics.mean(window_cadences)
|
||||
|
||||
ratio = (avg_speed * 60) / (avg_cadence * WHEEL_CIRCUMFERENCE_M)
|
||||
ratios.append(ratio)
|
||||
|
||||
if len(samples) < 10:
|
||||
samples.append({
|
||||
'time_idx': i,
|
||||
'avg_spd': avg_speed,
|
||||
'avg_cad': avg_cadence,
|
||||
'ratio': ratio,
|
||||
'cad_std': cad_std
|
||||
})
|
||||
else:
|
||||
rejected_reasons['variance'] += 1
|
||||
except statistics.StatisticsError:
|
||||
pass
|
||||
else:
|
||||
rejected_reasons['threshold'] += 1
|
||||
|
||||
if not ratios:
|
||||
print(f" - No steady segments. Rejections: {rejected_reasons}")
|
||||
return [], 0.0
|
||||
|
||||
return samples, statistics.median(ratios)
|
||||
|
||||
def main():
|
||||
target_ids = ['21072264737', '18469350198', '18349164690']
|
||||
|
||||
db = PostgreSQLManager(config.DATABASE_URL).SessionLocal()
|
||||
|
||||
# Load all setups
|
||||
setups = db.query(BikeSetup).all()
|
||||
print(f"Loaded {len(setups)} bike setups.")
|
||||
for s in setups:
|
||||
if s.rear_cog == 0:
|
||||
print(f" - {s.name or s.frame}: No gears configured (skipped)")
|
||||
continue
|
||||
mech_ratio = s.chainring / s.rear_cog
|
||||
print(f" - {s.name or s.frame}: {s.chainring}/{s.rear_cog} = {mech_ratio:.3f} (Active: {s.purchase_date} to {s.retirement_date})")
|
||||
|
||||
print("\n" + "="*80)
|
||||
|
||||
# Add a control activity to verify script works
|
||||
print("\n" + "="*80)
|
||||
print("CONTROL CHECK: Finding a random activity WITH cadence to verify script logic...")
|
||||
control_activity = db.query(Activity).filter(Activity.avg_cadence > 0, Activity.file_content != None).first()
|
||||
if control_activity:
|
||||
target_ids.append(control_activity.garmin_activity_id)
|
||||
else:
|
||||
print("No control activity found!")
|
||||
|
||||
for gid in target_ids:
|
||||
print(f"\nAnalyzing Activity Garmin ID: {gid}")
|
||||
activity = db.query(Activity).filter(Activity.garmin_activity_id == str(gid)).first()
|
||||
|
||||
if not activity:
|
||||
print(" - Not found in DB")
|
||||
continue
|
||||
|
||||
print(f" - Type: {activity.activity_type}")
|
||||
print(f" - Date: {activity.start_time}")
|
||||
print(f" - Global Avg Speed: {activity.avg_speed:.2f} m/s" if activity.avg_speed else " - Global Avg Speed: None")
|
||||
print(f" - Global Avg Cadence: {activity.avg_cadence:.1f} rpm" if activity.avg_cadence else " - Global Avg Cadence: None")
|
||||
|
||||
if not activity.file_content:
|
||||
print(" - No file content available")
|
||||
continue
|
||||
|
||||
data = extract_activity_data(activity.file_content, activity.file_type)
|
||||
speeds = data.get('speed') or []
|
||||
cadences = data.get('cadence') or []
|
||||
|
||||
# Check if actual data exists
|
||||
valid_speeds = [x for x in speeds if x is not None]
|
||||
valid_cadences = [x for x in cadences if x is not None]
|
||||
|
||||
if len(valid_cadences) < 10:
|
||||
print(" - CRITICAL: No cadence data stream found in file.")
|
||||
print(" - Result: IMPOSSIBLE TO MATCH GEAR RATIO.")
|
||||
continue
|
||||
|
||||
samples, observed_ratio = analyze_streams_debug(speeds, cadences)
|
||||
|
||||
print(f" - Steady Segments Found: {len(samples) if samples else 0}")
|
||||
print(f" - Observed Ratio (Median): {observed_ratio:.3f}")
|
||||
|
||||
if samples:
|
||||
print(" - First 10 Steady Samples:")
|
||||
for s in samples:
|
||||
print(f" - T={s['time_idx']}s | Spd={s['avg_spd']:.1f} | Cad={s['avg_cad']:.1f} | R={s['ratio']:.3f} (std_cad={s['cad_std']:.1f})")
|
||||
|
||||
# ... logic continues ...
|
||||
|
||||
print("\n - Matching Against Setups:")
|
||||
if observed_ratio > 0:
|
||||
for bike in setups:
|
||||
if bike.rear_cog == 0:
|
||||
continue
|
||||
# Date Check
|
||||
active = True
|
||||
if bike.purchase_date and activity.start_time.date() < bike.purchase_date:
|
||||
active = False
|
||||
if bike.retirement_date and activity.start_time.date() > bike.retirement_date:
|
||||
active = False
|
||||
|
||||
status_str = "ACTIVE" if active else "INACTIVE"
|
||||
|
||||
mech_ratio = bike.chainring / bike.rear_cog
|
||||
diff = abs(observed_ratio - mech_ratio)
|
||||
error_pct = diff / mech_ratio
|
||||
confidence = max(0.0, 1.0 - error_pct)
|
||||
|
||||
marker = "<<< BEST MATCH" if confidence > 0.9 else ""
|
||||
if not active: marker = "(Date Mismatch)"
|
||||
|
||||
print(f" - {bike.name or bike.frame} ({bike.chainring}/{bike.rear_cog}): Mech={mech_ratio:.3f} | Diff={diff:.3f} | Conf={confidence:.3f} [{status_str}] {marker}")
|
||||
else:
|
||||
print(" - Could not calculate valid observed ratio from streams.")
|
||||
|
||||
db.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user