def test_moving_time_frame(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame_gpx = reader._read_file(gpx_file, to_df=False) reset_gpx_file = frame_gpx.reset_index() with pytest.raises(AttributeError): _ = reset_gpx_file.moving_time gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame_without_moving = reader._read_file(gpx_file, to_df=False) with pytest.raises(AttributeError): _ = frame_without_moving.moving_time gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame_gpx = reader._read_file(gpx_file, to_df=False) frame_gpx["distpos"] = frame_gpx.compute.distance(correct_distance=False) frame_gpx["speed"] = frame_gpx.compute.speed(from_distances=True) frame_gpx_only_moving = frame_gpx.only_moving() assert frame_gpx_only_moving.moving_time == Timedelta("0 days 01:14:46") tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") frame_tcx = reader._read_file(tcx_file, to_df=False) frame_tcx["distpos"] = frame_tcx.compute.distance(correct_distance=False) frame_tcx["speed"] = frame_tcx.compute.speed(from_distances=True) frame_tcx = frame_tcx.only_moving() assert frame_tcx.moving_time == Timedelta("0 days 00:33:05") fit_file = os.path.join(dirpath, "fit", "garmin-fenix-5-basic.fit") frame_fit = reader._read_file(fit_file, to_df=False) frame_fit_only_moving = frame_fit.only_moving() assert frame_fit_only_moving.moving_time == Timedelta("0 days 00:00:55")
def test_mean_pace_frame(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame = reader._read_file(gpx_file, to_df=False) with pytest.raises(AttributeError): _ = frame.mean_pace() frame_gpx = reader._read_file(gpx_file, to_df=False) frame_gpx["distpos"] = frame_gpx.compute.distance(correct_distance=False) frame_gpx["speed"] = frame_gpx.compute.speed(from_distances=True) frame_gpx_only_moving = frame_gpx.only_moving() # Calculate the mean pace with only moving and smoothing using speed (m/s) assert ( frame_gpx_only_moving.mean_pace(only_moving=True, smoothing=True) ) == Timedelta("0 days 00:00:00.357566") # Calculate the mean pace with only moving and no smoothing (total distance) assert ( frame_gpx_only_moving.mean_pace(only_moving=True, smoothing=False) ) == Timedelta("0 days 00:00:00.357566") # Calculate the mean pace with all data and no smoothing (total distance) assert ( frame_gpx_only_moving.mean_pace(only_moving=False, smoothing=False) ) == Timedelta("0 days 00:00:00.407078") # Calculate the mean pace with all data and smoothing (total distance) assert ( frame_gpx_only_moving.mean_pace(only_moving=False, smoothing=True) ) == Timedelta("0 days 00:00:00.407078")
def test_mean_speed_frame(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame_no_speed = reader._read_file(gpx_file, to_df=False) with pytest.raises(AttributeError): _ = frame_no_speed.mean_speed() frame_gpx = reader._read_file(gpx_file, to_df=False) frame_gpx["distpos"] = frame_gpx.compute.distance(correct_distance=False) frame_gpx["speed"] = frame_gpx.compute.speed(from_distances=True) frame_gpx_only_moving = frame_gpx.only_moving() # Calculate the mean speed with only moving and smoothing using speed (m/s) assert ( frame_gpx_only_moving.mean_speed(only_moving=True, smoothing=True) ) == 2.7966895287728653 # Calculate the mean speed with only moving and no smoothing (total distance) assert ( frame_gpx_only_moving.mean_speed(only_moving=True, smoothing=False) ) == 2.7966895287728653 # Calculate the mean speed with all data and no smoothing (total distance) assert ( frame_gpx_only_moving.mean_speed(only_moving=False, smoothing=False) ) == 2.4565339871605874 # Calculate the mean speed with all data and smoothing (total distance) assert ( frame_gpx_only_moving.mean_speed(only_moving=False, smoothing=True) ) == 2.4565339871605874
def test_only_moving_acessor(dirpath, mocker): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame_gpx = reader._read_file(gpx_file, to_df=False) frame_gpx["distpos"] = frame_gpx.compute.distance(correct_distance=False) frame_gpx["speed"] = frame_gpx.compute.speed(from_distances=True) frame_gpx_only_moving = frame_gpx.only_moving() assert frame_gpx_only_moving[~frame_gpx_only_moving["moving"]].shape[ 0] == 74 assert frame_gpx_only_moving.ellapsed_time == Timedelta("0 days 01:25:27") assert frame_gpx_only_moving.moving_time == Timedelta("0 days 01:14:46") tcx_file = os.path.join(dirpath, "tcx", "stopped_example.tcx") activity_tcx = reader._read_file(tcx_file, to_df=False) frame_tcx_only_moving = activity_tcx.only_moving() assert frame_tcx_only_moving[~frame_gpx_only_moving.moving].shape[0] == 74 assert frame_tcx_only_moving.ellapsed_time == Timedelta("0 days 01:25:27") assert frame_tcx_only_moving.moving_time == Timedelta("0 days 01:23:57") fit_file = os.path.join(dirpath, "fit", "garmin-fenix-5-basic.fit") fit_file = reader._read_file(fit_file, to_df=False) frame_fit_only_moving = fit_file.only_moving() assert frame_fit_only_moving.ellapsed_time == Timedelta("0 days 00:00:57") assert frame_fit_only_moving.moving_time == Timedelta("0 days 00:00:55") tcx_file2 = os.path.join(dirpath, "tcx", "basic.tcx") frame_tcx_basic = reader._read_file(tcx_file2, to_df=False) frame_tcx_basic["distpos"] = frame_tcx_basic.compute.distance( correct_distance=False) frame_tcx_basic["speed"] = frame_tcx_basic.compute.speed( from_distances=True) frame_tcx2_only_moving = frame_tcx_basic.only_moving() assert frame_tcx2_only_moving.ellapsed_time == Timedelta("0 days 00:33:11") assert frame_tcx2_only_moving.moving_time == Timedelta("0 days 00:33:05") activity_json = os.path.join(dirpath, "strava", "activity.json") streams_json = os.path.join(dirpath, "strava", "streams.json") mocker.patch.object(ApiV3, "get", return_value=MockResponse(activity_json).json()) mocker.patch.object( Client, "get_activity_streams", return_value=mock_get_activity_streams(streams_json), ) # we don't use access token here, since we will mock the stravalib json response activity_strava = read_strava( activity_id=4437021783, access_token=None, refresh_token=None, to_df=False, ) assert activity_strava.ellapsed_time == Timedelta("0 days 01:25:45") assert activity_strava.moving_time == Timedelta("0 days 01:19:41")
def test_gradient_validate(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") activity_gpx = reader._read_file(gpx_file, to_df=False) activity_without_required_column = activity_gpx.drop(["alt"], axis=1) assert "alt" not in activity_without_required_column.columns with pytest.raises(RequiredColumnError): activity_without_required_column.compute.gradient() activity_gpx = reader._read_file(gpx_file, to_df=False) activity_gpx["distpos"] = activity_gpx.compute.distance() assert "dist" not in activity_gpx.columns with pytest.raises(RequiredColumnError): activity_gpx.compute.gradient()
def test_mean_cadence_frame(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame = reader._read_file(gpx_file, to_df=False) frame_no_cadence = frame.drop(["cad"], axis=1) with pytest.raises(AttributeError): _ = frame_no_cadence.mean_cadence() frame_gpx = reader._read_file(gpx_file, to_df=False) frame_gpx["distpos"] = frame_gpx.compute.distance(correct_distance=False) frame_gpx["speed"] = frame_gpx.compute.speed(from_distances=True) frame_gpx_only_moving = frame_gpx.only_moving() assert (frame_gpx_only_moving.mean_cadence(only_moving=False)) == 84.99764289923394 assert (frame_gpx_only_moving.mean_cadence(only_moving=True)) == 85.96118299445472
def test_read_file_tcx_basic_activity(dirpath): tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") activity = reader._read_file(tcx_file, to_df=False) assert isinstance(activity, types.Activity) included_data = set(["lat", "lon", "alt", "dist", "hr"]) assert included_data <= set(activity.columns.to_list()) assert activity.size == 1915
def test_vam_validate(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") activity_gpx = reader._read_file(gpx_file, to_df=False) activity_without_required_column = activity_gpx.drop(["alt"], axis=1) assert "alt" not in activity_without_required_column.columns with pytest.raises(RequiredColumnError): activity_without_required_column.compute.vertical_speed()
def test_read_file_fit_basic_dataframe(dirpath): fit_file = os.path.join(dirpath, "fit", "garmin-fenix-5-basic.fit") activity = reader._read_file(fit_file, to_df=True) assert isinstance(activity, DataFrame) assert isinstance(activity.index, TimedeltaIndex) assert activity.size == 462 included_data = set([ "position_lat", "position_long", "distance", "temperature", "altitude", "speed", "heart_rate", "cadence", "speed", "lap", "session", ]) assert included_data <= set(activity.columns.to_list()) assert "lap" in activity.columns assert activity["lap"].max() == 0 # no laps assert "session" in activity.columns assert activity["session"].max() == 0 # no sessions
def test_pace_validate(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") with pytest.raises(RequiredColumnError): activity_gpx = reader._read_file(gpx_file, to_df=False) assert "speed" not in activity_gpx.columns activity_gpx.compute.pace()
def test_full_tcx_2_activity(dirpath): tcx_file = os.path.join(dirpath, "tcx", "run.tcx") frame_tcx = reader._read_file(tcx_file, to_df=False) # testActivityStartTime assert frame_tcx.start == Timestamp("2017-05-27 08:13:01+00:00") # testActivityTotalDistance frame_tcx["distpos"] = frame_tcx.compute.distance() frame_tcx["dist"] = frame_tcx["distpos"].to_distance() assert frame_tcx["dist"].fillna(0).iloc[0] == 0.0 # (NaN number for position 0) assert frame_tcx["dist"].iloc[-1] == pytest.approx(4806.843188885856, 0.01) # test_duration_is_correct (we don't consider fraction time) assert frame_tcx.ellapsed_time.total_seconds() == 1423 # test_speed frame_tcx["speed"] = frame_tcx.compute.speed(from_distances=True) assert frame_tcx.mean_speed() == pytest.approx(3.3779642929626545, 0.01) # test_pace (converted to seconds) "00:04:55" pace_min_km = convert_pace_secmeters2minkms(frame_tcx.mean_pace().total_seconds()) assert pace_min_km == Timedelta("0 days 00:04:56") # test_max_speed assert frame_tcx["speed"].max() == pytest.approx(5.458744217718473, 0.01) # test_ascent_is_correct assert frame_tcx["alt"].ascent.sum() == 50.90000000000001 # test_descent_is_correct assert frame_tcx["alt"].descent.sum() == -50.20000000000001
def test_measured_series_activity(dirpath): tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") activity = reader._read_file(tcx_file, to_df=False) assert isinstance(activity, types.Activity) assert isinstance(activity.hr, types.columns.HeartRate) assert activity.hr.base_unit == "bpm" assert activity.hr.colname == "hr"
def test_pace_min_km(dirpath): tcx_file = os.path.join(dirpath, "tcx", "stopped_example.tcx") activity_tcx = reader._read_file(tcx_file, to_df=False) activity_tcx["speed"] = activity_tcx.compute.speed() activity_tcx["pace"] = activity_tcx.compute.pace() assert (activity_tcx["pace"].min_per_km[-1] ) == pd.Timedelta("0 days 00:07:03.590608")
def test_altitude_ascent_descent(dirpath): tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") activity_tcx = reader._read_file(tcx_file, to_df=False) # test ascent and descent altitudes assert (activity_tcx["alt"].ascent[-5]) == 0.4805908200000033 assert (activity_tcx["alt"].ascent[-1]) == 0.0 assert (activity_tcx["alt"].descent[-1]) == -1.4420166019999954 assert (activity_tcx["alt"].descent[-5]) == 0.0
def test_pace_min_mile(dirpath): tcx_file = os.path.join(dirpath, "tcx", "stopped_example.tcx") activity_tcx = reader._read_file(tcx_file, to_df=False) activity_tcx["speed"] = activity_tcx.compute.speed() activity_tcx["pace"] = activity_tcx.compute.pace() assert (activity_tcx["pace"].min_per_mile[-1].total_seconds() ) == pytest.approx( pd.Timedelta("0 days 00:04:23.099756").total_seconds())
def test_read_file_gpx_basic_activity(dirpath): gpx_file = os.path.join(dirpath, "gpx", "garmin_connect.gpx") activity = reader._read_file(gpx_file, to_df=False) assert isinstance(activity, types.Activity) assert isinstance(activity.index, TimedeltaIndex) assert activity.size == 15 included_data = set(["lat", "lon", "alt", "cad", "hr"]) assert included_data <= set(activity.columns.to_list())
def test_validate_session(multi_frame, dirpath): sessions_dir = os.path.join(dirpath, "samples") activities = [activity for activity in read_dir(sessions_dir)] assert multi_frame.index.levshape[0] == len(activities) assert multi_frame.session.count() == multi_frame.index.levshape[0] # test validation error (get the activity) gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") with pytest.raises(AssertionError): # Activity instance activity_gpx = reader._read_file(gpx_file, to_df=True) activity_gpx.session.count() with pytest.raises(AttributeError): # index errror activity_gpx = reader._read_file(gpx_file, to_df=False) activity_gpx.session.count()
def test_speed_topace(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") activity_gpx = reader._read_file(gpx_file, to_df=False) activity_gpx["distpos"] = activity_gpx.compute.distance( correct_distance=True) activity_gpx["speed"] = activity_gpx.compute.speed(from_distances=True) expected = pd.Timedelta("0 days 00:00:00.392662") assert activity_gpx["speed"].to_pace()[-1].total_seconds( ) == pytest.approx(expected.total_seconds())
def test_distance_km(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") activity_gpx = reader._read_file(gpx_file, to_df=False) activity_gpx["distpos"] = activity_gpx.compute.distance() # test distpos conversion (meters to miles) assert (activity_gpx["distpos"].km[-1]) == 0.005093437453100809 # test distance conversion (meters to miles) distance = activity_gpx["distpos"].to_distance() assert (distance.km[-1]) == 12.594649752172337
def test_distance_miles(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") activity_gpx = reader._read_file(gpx_file, to_df=False) activity_gpx["distpos"] = activity_gpx.compute.distance() # test distpos conversion (meters to miles) assert (activity_gpx["distpos"].miles[-1]) == 0.0031649143236707027 # test distance conversion (meters to miles) distance = activity_gpx["distpos"].to_distance() assert (distance.miles[-1]) == 7.825950111157077
def test_constructor(dirpath): tcx_file = os.path.join(dirpath, "tcx", "stopped_example.tcx") activity_tcx = reader._read_file(tcx_file, to_df=False) activity_tcx["speed"] = activity_tcx.compute.speed() # test custom constructor_expanddim series speed_frame = activity_tcx["speed"].to_frame() assert type(speed_frame) is Activity assert isinstance(speed_frame.speed, columns.Speed) assert list(speed_frame.columns) == ["speed"]
def test_mean_heartrate_frame(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame = reader._read_file(gpx_file, to_df=False) frame_no_hr = frame.drop(["hr"], axis=1) with pytest.raises(AttributeError): _ = frame_no_hr.mean_heart_rate() frame_gpx = reader._read_file(gpx_file, to_df=False) frame_gpx["distpos"] = frame_gpx.compute.distance(correct_distance=False) frame_gpx["speed"] = frame_gpx.compute.speed(from_distances=True) frame_gpx_only_moving = frame_gpx.only_moving() assert ( frame_gpx_only_moving.mean_heart_rate(only_moving=False) ) == 151.22097819681792 assert ( frame_gpx_only_moving.mean_heart_rate(only_moving=True) ) == 151.90203327171903
def test_ellapsed_time_frame(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame_gpx = reader._read_file(gpx_file, to_df=False) reset_gpx_file = frame_gpx.reset_index() with pytest.raises(AttributeError): _ = reset_gpx_file.ellapsed_time gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame_gpx = reader._read_file(gpx_file, to_df=False) assert frame_gpx.ellapsed_time == Timedelta("0 days 01:25:27") tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") frame_tcx = reader._read_file(tcx_file, to_df=False) assert frame_tcx.ellapsed_time == Timedelta("0 days 00:33:11") fit_file = os.path.join(dirpath, "fit", "garmin-fenix-5-basic.fit") frame_fit = reader._read_file(fit_file, to_df=False) assert frame_fit.ellapsed_time == Timedelta("0 days 00:00:57")
def test_metrics_validate(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") activity_gpx = reader._read_file(gpx_file, to_df=True) # copy of dataframe for testing the index error frame_without_index = activity_gpx.copy() frame_without_index = frame_without_index.reset_index() with pytest.raises(AttributeError): frame_without_index.only_moving() # dataframe without speed column with pytest.raises(AttributeError): activity_gpx.only_moving() tcx_file = os.path.join(dirpath, "tcx", "stopped_example.tcx") activity_tcx = reader._read_file(tcx_file, to_df=True) # copy of dataframe for testing the index error frame_without_index = activity_tcx.copy() frame_without_index = frame_without_index.reset_index() with pytest.raises(AttributeError): frame_without_index.only_moving()
def test_distance_frame(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") frame_no_distance = reader._read_file(gpx_file, to_df=False) with pytest.raises(KeyError): _ = frame_no_distance.distance frame_gpx = reader._read_file(gpx_file, to_df=False) frame_gpx["distpos"] = frame_gpx.compute.distance(correct_distance=False) assert round(frame_gpx.distance, 2) == 12594.65 tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") frame_tcx = reader._read_file(tcx_file, to_df=False) assert round(frame_tcx.distance, 2) == 4686.31 fit_file = os.path.join(dirpath, "fit", "garmin-fenix-5-basic.fit") frame_fit = reader._read_file(fit_file, to_df=False) assert round(frame_fit.distance, 2) == 157.56 tcx_file = os.path.join(dirpath, "tcx", "stopped_example.tcx") activity_tcx = reader._read_file(tcx_file, to_df=False) assert round(activity_tcx.distance, 2) == 12007.99
def test_read_file_tcx_basic_dataframe(dirpath): tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") activity = reader._read_file(tcx_file, to_df=True) assert isinstance(activity, DataFrame) included_data = set([ "latitude_degrees", "longitude_degrees", "altitude_meters", "distance_meters", "heart_rate_bpm", ]) assert included_data <= set(activity.columns.to_list()) assert activity.size == 1915
def test_metrics_validate(dirpath): gpx_file = os.path.join(dirpath, "gpx", "stopped_example.gpx") with pytest.raises(AssertionError): activity_gpx = reader._read_file(gpx_file, to_df=True) activity_gpx.compute.speed() activity_gpx = reader._read_file(gpx_file, to_df=False) # copy of dataframe for testing the index error frame_without_index = activity_gpx.copy() frame_without_index = frame_without_index.reset_index() with pytest.raises(AttributeError): frame_without_index.compute.speed() # test the decorator special_column activity_without_required_column = activity_gpx.drop(["lat"], axis=1) with pytest.raises(RequiredColumnError): activity_without_required_column.compute.distance() activity_without_required_column = activity_gpx.drop(["alt"], axis=1) with pytest.raises(RequiredColumnError): activity_without_required_column.compute.distance( correct_distance=True, to_special_column=False)
def test_read_file_fit_basic_activity(dirpath): gpx_file = os.path.join(dirpath, "fit", "garmin-fenix-5-basic.fit") activity = reader._read_file(gpx_file, to_df=False) assert isinstance(activity, types.Activity) assert isinstance(activity.index, TimedeltaIndex) assert activity.size == 462 included_data = set(["lat", "lon", "alt", "cad", "hr", "speed", "temp"]) assert included_data <= set(activity.columns.to_list()) assert "lap" in activity.columns assert activity["lap"].max() == 0 # no laps assert "session" in activity.columns assert activity["session"].max() == 0 # no sessions
def test_activity_summary_missing_moving(dirpath): tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") frame_tcx = reader._read_file(tcx_file, to_df=False) frame_tcx["distpos"] = frame_tcx.compute.distance(correct_distance=False) frame_tcx["speed"] = frame_tcx.compute.speed(from_distances=True) # removing hr to simulate the missing values frame_tcx.drop("hr", axis=1, inplace=True) result = frame_tcx.summary() expected = Series( [ "Running: 26-12-2012 21:29:53", 4686.31, Timedelta("0 days 00:33:11"), np.nan, 8.476556294170631, np.nan, Timedelta("0 days 00:07:04"), np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, ], index=[ "Session", "Total distance (meters)", "Total ellapsed time", "Total moving time", "Average speed (km/h)", "Average moving speed (km/h)", "Average pace (per 1 km)", "Average pace moving (per 1 km)", "Average cadence", "Average moving cadence", "Average heart rate", "Average moving heart rate", "Average temperature", ], ) assert_series_equal(result, expected)
def test_activity_summary_with_missing_values(dirpath): tcx_file = os.path.join(dirpath, "tcx", "basic.tcx") frame_tcx = reader._read_file(tcx_file, to_df=False) result = frame_tcx.summary() expected = Series( [ "Running: 26-12-2012 21:29:53", 4686.31, Timedelta("0 days 00:33:11"), np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, 156.653, np.nan, np.nan, ], index=[ "Session", "Total distance (meters)", "Total ellapsed time", "Total moving time", "Average speed (km/h)", "Average moving speed (km/h)", "Average pace (per 1 km)", "Average pace moving (per 1 km)", "Average cadence", "Average moving cadence", "Average heart rate", "Average moving heart rate", "Average temperature", ], ) assert_series_equal(result, expected)