import sys import os import logging from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # Setup environment sys.path.append(os.path.dirname(os.path.abspath(__file__))) from src.models.base import Base from src.models.activity import Activity from src.models.segment import Segment from src.models.segment_effort import SegmentEffort from src.services.postgresql_manager import PostgreSQLManager from src.services.segment_matcher import SegmentMatcher from src.services.power_estimator import PowerEstimatorService from src.utils.config import config # Configure logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def verify_segment_power(): db_url = config.DATABASE_URL if not db_url: print("DATABASE_URL not set") return manager = PostgreSQLManager(db_url) with manager.get_db_session() as session: # 1. Get our test activity (ID 256) activity = session.query(Activity).filter(Activity.id == 256).first() if not activity: print("Activity 256 not found") return print(f"Activity {activity.id}: is_estimated_power={activity.is_estimated_power}, avg_power={activity.avg_power}") if not activity.is_estimated_power: print("Activity does not have estimated power enabled. Please run verify_filters.py or backfill/estimate job first.") return # 2. Ensure we have at least one segment that matches this activity # We'll check if any segments exist, if not create a dummy one for the activity bounds # Or better, just check if any exist. segments_count = session.query(Segment).count() print(f"Found {segments_count} segments in DB.") # 3. Clear existing efforts for this activity to test fresh matching existing_efforts = session.query(SegmentEffort).filter(SegmentEffort.activity_id == activity.id).all() print(f"Deleting {len(existing_efforts)} existing efforts.") for e in existing_efforts: session.delete(e) session.commit() # 4. Trigger Matching matcher = SegmentMatcher(session) # We need points. Accessing parsers... from src.services.parsers import extract_activity_data data = extract_activity_data(activity.file_content, activity.file_type) if not data: print("Could not extract data.") return print(f"Extracted data keys: {data.keys()}") if 'position_lat' in data: print(f"Lat points: {len(data['position_lat'])}") if 'points' in data: points = data['points'] # Ensure format is [lon, lat] # print(f"Sample point: {points[0] if points else 'None'}") else: lats = data.get('position_lat') longs = data.get('position_long') if lats and longs: for i in range(len(lats)): if lats[i] is not None and longs[i] is not None: points.append([longs[i], lats[i]]) print(f"Matching with {len(points)} points...") efforts = matcher.match_activity(activity, points) if len(efforts) == 0 and len(points) > 100: print("No segments matched. Creating a dummy segment to verify logic...") # Create a simple segment from the middle of the activity mid = len(points) // 2 seg_points = points[mid:mid+50] # 50 points # Bounds from src.utils.geo import calculate_bounds import json bounds = calculate_bounds(seg_points) dummy_segment = Segment( name="Temp Verify Segment", activity_type=activity.activity_type, distance=1000.0, # Approximate points=json.dumps(seg_points), bounds=json.dumps(bounds) ) session.add(dummy_segment) session.commit() print(f"Created dummy segment {dummy_segment.id}") # Retry Match efforts = matcher.match_activity(activity, points) print(f"Retried Match: {len(efforts)} segments.") # 5. Verify Power for effort in efforts: print(f"Effort ID: {effort.id}, Segment ID: {effort.segment_id}") print(f" Avg Power: {effort.avg_power}") print(f" Avg HR: {effort.avg_hr}") print(f" Elapsed: {effort.elapsed_time}s") if effort.avg_power and effort.avg_power > 0: print("SUCCESS: Segment Effort has power!") else: print("FAILURE: Segment Effort missing power.") if __name__ == "__main__": verify_segment_power()