analysis.osu.std package

Submodules

analysis.osu.std.map_data module

class analysis.osu.std.map_data.StdMapData

Bases: object

Class used for navigating, extracting, and operating on standard gamemode map data.

Note

This is not to be confused with the map data in the osu.local.beatmap.beatmap.Beatmap class. Data used by this class is in numpy array form. Data in the Beatmap class is based on *.osu file structure and is not in a friendly format to perform analysis on.

IDX_OBJECT = 4
IDX_TIME = 0
IDX_TYPE = 3
IDX_X = 1
IDX_Y = 2
POSX = 1
POSY = 2
TIME = 0
TYPE = 3
TYPE_CIRCLE = 1
TYPE_HOLD = 2
TYPE_PRESS = 1
TYPE_RELEASE = 3
TYPE_SLIDER = 2
TYPE_SPINNER = 3
static all_positions(map_data)

Gets positions data for all hitobjects in the map

Parameters:map_data (numpy.array) – Map data to get position data for
Returns:returns numpy array of scorepoint positions
[
    [ aimpoint_x, aimpoint_y ],
    [ aimpoint_x, aimpoint_y ],
    ...
]
Return type:numpy.array
static all_times(map_data)

Gets time data for all scorepoint in the map

Parameters:map_data (numpy.array) – Map data to get position data for
Returns:Returns numpy array of scorepoint times
[ time, time, time, ... ]
Return type:numpy.array
static end_positions(map_data)

Gets the ending positions of all hitobjects

Note

Hitcircle hitobjects will have the same start and end positions

Parameters:map_data (numpy.array) – Map data to get hitobject ending positions for
Returns:Ending positions of hitobject
[
    [ aimpoint_x, aimpoint_y ],
    [ aimpoint_x, aimpoint_y ],
    ...
]
Return type:numpy.array
static end_times(map_data)

Get gets the end times of all hitobjects

Note

Hitcircle hitobjects will have the same start and end times

Parameters:map_data (numpy.array) – Map data to get hitobject end times for
Returns:End times of hitobjects
[ time, time, time, ... ]
Return type:numpy.array
static get_map_data(std_hitobjects)

Note

This function is intended to be used directly

Warning

Some hitobject indices may not be present. These are hitobjects that are not processed and ommited from map data. It is recommended to use StdMapData.get_next_hitobject_idx to get index that follows

Converts a list of Hitobject types into a numpy array equivalent that can be used by the analysis framework.

Parameters:std_hitobjects (Hitobject) – List of hitobjects to convert
Returns:Map data representing the following format:
                            x      y  type
hitobject time
0         494.0    256.000000  192.0   1.0
          495.0    256.000000  192.0   3.0
1         994.0    256.000000  192.0   1.0
          995.0    256.000000  192.0   3.0
2         1494.0   256.000000  192.0   1.0
...                      ...    ...   ...
48        49494.0  302.027397   32.0   2.0
          49994.0  160.000000   32.0   3.0
49        49494.0  320.000000   32.0   1.0
          49994.0  174.027397   32.0   2.0
          50494.0   32.000000   32.0   3.0

[109 rows x 3 columns]
Return type:numpy.array
static get_next_hitobject_idx(map_data, idx)

Gets the next hitobject index, automatically handling indexes for hitobjects that are not handled in map data.

Parameters:
  • map_data (numpy.array) – Map data to operate on
  • idx (int) – Index to get after this one
Returns:

  • int
  • Hitobject index following idx, or number of hitobject there are, which ever is smaller

static get_note_after(map_data, time)

Get the closest note right after the desired point in time

Parameters:
  • map_data (numpy.array) – Map data to operate on
  • time (int) – Desired point in time
Returns:

note data

            x      y  type
time
1494.0  256.0  192.0   1.0
1495.0  256.0  192.0   3.0

Return type:

numpy.array

static get_note_before(map_data, time)

Get the closest note right before the desired point in time

Parameters:
  • map_data (numpy.array) – Map data to operate on
  • time (int) – Desired point in time
Returns:

note data

            x      y  type
time
1494.0  256.0  192.0   1.0
1495.0  256.0  192.0   3.0

Return type:

numpy.array

static get_num_hitobjects(map_data)

Gets number of hitobjects in the map

Parameters:map_data (numpy.array) – Map data to operate on
Returns:
  • int
  • number of hitobjects in the map
static get_objects(map_data)

Gets list of hitobjects types

Parameters:map_data (numpy.array) – Map data to operate on
Returns:Map data representing the following format:
[
    ... N hitobjects
]
Return type:numpy.array
static get_presses(map_data)

Gets aimpoints associated with the player pressing a key

Parameters:map_data (numpy.array) – Map data to operate on
Returns:Map data representing the following format:
[
    [ aimpoint_x, aimpoint_y, type ],
    [ aimpoint_x, aimpoint_y, type ],
    ... N aimpoints
]
Return type:numpy.array
static get_releases(map_data)

Gets aimpoints associated with the player releasing a key

Parameters:map_data (numpy.array) – Map data to operate on
Returns:Map data representing the following format:
[
    [ aimpoint_x, aimpoint_y, type ],
    [ aimpoint_x, aimpoint_y, type ],
    ... N aimpoints
]
Return type:numpy.array
static get_scorepoint_after(map_data, time)

Get the closest scorepoint right after the desired point in time

Parameters:
  • map_data (numpy.array) – Map data to operate on
  • time (int) – Desired point in time
Returns:

Scorepoint data

x       207.609756
y       192.000000
type      3.000000
Name: (8, 11994.0), dtype: float64

Return type:

numpy.array

static get_scorepoint_before(map_data, time)

Get the closest scorepoint right before the desired point in time

Parameters:
  • map_data (numpy.array) – Map data to operate on
  • time (int) – Desired point in time
Returns:

Scorepoint data

x       207.609756
y       192.000000
type      3.000000
Name: (8, 11994.0), dtype: float64

Return type:

numpy.array

static get_visible_at(map_data, time, ar_ms)

Gets number of hitobjects visible at time time given ar_ms

Parameters:
  • map_data (numpy.array) – Map data to operate on
  • time (int) – Time to determine which hitobject are visible at
  • ar_ms (int) – AR of map in milliseconds
Returns:

  • int
  • number of hitobjects in the map

static start_positions(map_data)

Gets the starting positions of all hitobjects

Parameters:map_data (numpy.array) – Map data to get hitobject starting positions for
Returns:Hitobject starting positions
[
    [ aimpoint_x, aimpoint_y ],
    [ aimpoint_x, aimpoint_y ],
    ...
]
Return type:numpy.array
static start_times(map_data)

Gets the start times of all hitobjects

Parameters:map_data (numpy.array) – Map data to get hitobject start times for
Returns:Hitobject start times
[ time, time, time, ... ]
Return type:numpy.array
static std_hitobject_to_aimpoints(std_hitobject, min_press_duration=1)

Warning

This function is not intended to be used directly

Converts a Hitobject type into a numpy array equivalent that can be used by the analysis framework.

Parameters:std_hitobject (Hitobject) – A hitobject to convert
Returns:A list of scorepoints in the following format:
[
    [ aimpoint_x, aimpoint_y, type ],
    [ aimpoint_x, aimpoint_y, type ],
    ... N aimpoints
]

Hitcircles contain only one scorepoint. Sliders can contain more than one. This format is reflected in the groups of [ time, pos ] in the map data

Return type:generator object
static time_slice(map_data, start_time, end_time, exclusive=True)

Gets a list of hitobjects data that occurs between start_time and end_time

Parameters:
  • map_data (numpy.array) – Map data to get the slice of data for
  • start_time (int) – Starting time for the slice of data
  • end_time (int) – Ending time for the slice of data
Returns:

Hitobject data

[
    [ time, aimpoint_x, aimpoint_y, type ]
    [ time, aimpoint_x, aimpoint_y, type ]
    ...
]

Return type:

numpy.array

analysis.osu.std.map_metrics module

class analysis.osu.std.map_metrics.StdMapMetrics

Bases: object

Class used for calculating pattern attributes and difficulty.

Warning

Undocumented functions in this class are not supported and are experimental.

static calc_acceleration(map_data=[])
static calc_agility_skill(hitobjects)
static calc_angles(map_data=[])

Calculates angle between aimpoints. Aimpoints are hitobject start and end times, and slider ticks.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, angles). times are aimpoint timings. angles are angles between aimpoints. Resultant array size is len(map_data) - 1.
Return type:(numpy.array, numpy.array)
static calc_intensity(map_data=[])
static calc_lin_int(map_data=[])

Calculates linear intensity between aimpoints. Aimpoints are hitobject start and end times, and slider ticks. Linear intensity is how much strongly the path between aimpoints is linear, factoring in average radial velocity of the path as well as overall velocity throughout the path (measured in osu!px*radians/millisconds^2).

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, lin_ints). times are aimpoint timings. lin_ints are linear intensities. Resultant array size is len(map_data) - 2.
Return type:(numpy.array, numpy.array)
static calc_notes_per_sec(map_data=[])

Gets number of notes tapped per second based on immidiate duration between notes.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, nps). times are hitobject timings. nps is notes per second. Resultant array size is len(map_data) - 1.
Return type:(numpy.array, numpy.array)
static calc_path_accel(map_data=[])

Calculates acceleration between aimpoints. Aimpoints are hitobject start and end times, and slider ticks.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, accels). times are aimpoint timings. accels are based on change in velocity between aimpoints. Resultant array size is len(map_data) - 3.
Return type:(numpy.array, numpy.array)
static calc_path_curvature(hitobjects)
static calc_path_dist(map_data=[])

Calculates distance between aimpoints. Aimpoints are hitobject start and end times, and slider ticks.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, dists). times are aimpoint timings. dists are distances between aimpoints. Resultant array size is len(map_data) - 1.
Return type:(numpy.array, numpy.array)
static calc_path_vel(map_data=[])

Calculates velocity between aimpoints. Aimpoints are hitobject start and end times, and slider ticks.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, vels). times are aimpoint timings. vels are based on time and distance between aimpoints. Resultant array size is len(map_data) - 2.
Return type:(numpy.array, numpy.array)
static calc_perp_int(map_data=[])

Calculates perpendicular intensity between aimpoints. Aimpoints are hitobject start and end times, and slider ticks. Perpendicular intensity is how much strongly the path between aimpoints turns 90 deg, factoring in average radial velocity of the path as well as overall velocity throughout the path (measured in osu!px*radians/millisconds^2).

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, perp_ints). times are aimpoint timings. perp_ints are perpendicular intensities. Resultant array size is len(map_data) - 2.
Return type:(numpy.array, numpy.array)
static calc_radial_velocity(map_data=[])

Calculates radial velocity between aimpoints. Aimpoints are hitobject start and end times, and slider ticks. Radial velocity is how fast a path moves in a circle in radians per second. Unlike calc_theta_per_second, which calculates immediate rotation, this calculates average rotation.

The difference between the two implemtations is apparent when considering zig-zag and circular patterns. Zig-zag patterns has no average angular velocity, but have average linear velocity. In a zig-zag pattern one angle would be positive indicating a rotation in a clockwise direction, and another angle would be negative indicating a rotation in a counter-clockwise direction. Ultimately those two cancel out to result in no overall rotation direction. A circular pattern would have either both angles positive or both angles negative, yielding a net negative or a net positive rotation direction.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, avg_rad_vels). times are aimpoint timings. avg_rad_vels are average radial velocities. Resultant array size is len(map_data) - 2.
Return type:(numpy.array, numpy.array)
static calc_rhythmic_complexity(map_data=[])
static calc_speed_response(resolution=1, x_range=(1, 100))
static calc_speed_skill(hitobjects)
static calc_tapping_intervals(map_data=[])

Gets the timing difference between note starting times.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, intervals). times are hitobject timings. intervals are the timings difference between current and previous note. Resultant array size is len(map_data) - 1.
Return type:(numpy.array, numpy.array)
static calc_tapping_skill(hitobjects)
static calc_targeting_skill(hitobjects)
static calc_theta_per_second(map_data=[])

Calculates immediate path rotation (in radians per second) from previous aimpoint.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, rps). times are aimpoint timings. rps are radians per second between aimpoints. Resultant array size is len(map_data) - 1.
Return type:(numpy.array, numpy.array)
static calc_velocity_start(map_data=[])
static calc_visual_density(hitobjects)
static calc_xy_accel(map_data=[])

Calculates parametric acceleration between aimpoints. Aimpoints are hitobject start and end times, and slider ticks.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, x_accels, y_accels). times are aimpoint timings. x_accels are accelerations between aimpoints in the x-coordinate direction. y_accels are accelerations between aimpoints in the y-coordinate direction. Resultant array size is len(map_data) - 3.
Return type:(numpy.array, numpy.array)
static calc_xy_dist(map_data=[])

Calculates parametric distance between aimpoints. Aimpoints are hitobject start and end times, and slider ticks.

Parameters map_data map_data : numpy.array

Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, x_dists, y_dists). times are aimpoint timings. x_dists are distances between aimpoints in the x-coordinate direction. y_dists are distances between aimpoints in the y-coordinate direction. Resultant array size is len(map_data) - 1.
Return type:(numpy.array, numpy.array)
static calc_xy_jerk(map_data=[])

Calculates parametric jerks between aimpoints. Aimpoints are hitobject start and end times, and slider ticks.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, x_jerks, y_jerks). times are aimpoint timings. x_jerks are jerks between aimpoints in the x-coordinate direction. y_jerks are jerks between aimpoints in the y-coordinate direction. Resultant array size is len(map_data) - 4.
Return type:(numpy.array, numpy.array)
static calc_xy_vel(map_data=[])

Calculates parametric velocity between aimpoints. Aimpoints are hitobject start and end times, and slider ticks.

Parameters:map_data (numpy.array) – Hitobject data from StdMapData.get_aimpoint_data
Returns:Tuple of (times, x_vels, y_vels). times are aimpoint timings. x_vels are velocities between aimpoints in the x-coordinate direction. y_vels are velocities between aimpoints in the y-coordinate direction. Resultant array size is len(map_data) - 2.
Return type:(numpy.array, numpy.array)

analysis.osu.std.replay_data module

class analysis.osu.std.replay_data.StdReplayData

Bases: object

Class used for navigating, extracting, and operating on standard gamemode replay data.

Note

This is not to be confused with the replay data in the osu.local.replay.replay.Replay class. Data used by this class is in numpy array form. Data in the Replay class is based on *.osr file structure and is not in a friendly format to perform analysis on.

FREE = 0
HOLD = 2
PRESS = 1
RELEASE = 3
static get_reduced_replay_data(replay_data, press_block=True, release_block=False)

Filters out replay data where there are no buttons being pressed, except frames where button was pressed before or after the event. Removes smoke key, and merges 4 buttons into one button

Parameters:replay_data (numpy.array) – Action data from StdReplayData.get_replay_data
Returns:
  • numpy.array
  • Reduced replay data
static get_replay_data(replay_events)

Gets replay data

Parameters:replay_events (list) – Replay event data located in Replay.play_data
Returns:List of events with data on time, positions of cursor, and flags on various key presses in the following format:
[
    [ time, x_pos, y_pos, m1, m2, k1, k2, smoke ],
    [ time, x_pos, y_pos, m1, m2, k1, k2, smoke ],
    [ time, x_pos, y_pos, m1, m2, k1, k2, smoke ],
    ...  N events
]
Return type:numpy.array
static press_times(replay_data, btn=['m1', 'm2', 'k1', 'k2'])

Gets list of press timings in replay_data for button(s) btn

Parameters:
  • replay_data (numpy.array) – Action data from StdReplayData.get_replay_data
  • btn (str, list) – Button(s) to get timings for Available options are: m1, m2, k1, k2, smoke
Returns:

  • numpy.array
  • Press timings

static release_times(replay_data, btn=['m1', 'm2', 'k1', 'k2'])

Gets list of release timings in replay_data for button(s) btn

Parameters:
  • replay_data (numpy.array) – Action data from StdReplayData.get_replay_data
  • btn (str, list) – Button(s) to get timings for Available options are: m1, m2, k1, k2, smoke
Returns:

  • numpy.array
  • Release timings

analysis.osu.std.replay_metrics module

class analysis.osu.std.replay_metrics.StdReplayMetrics

Bases: object

Class used for analyzing replay data.

static avg_cursor_pos(replay_data_list)

Takes all replays and determines average cursor position throughout all points in time Cursor positions are averaged across a moving average of 16 ms

Parameters:replay_data_list (numpy.array) – List of replay datas
Returns:Averaged cursor position data
[
    ( times, pos_x, pos_y ),
    ( times, pos_x, pos_y ),
    ...
]
Return type:tuple
static cursor_accel_xy(replay_data)

Parametric cursor acceleration

Parameters:replay_data (numpy.array) – Replay data
Returns:A pair of time and parametric cursor acceleration data. Size of resultant data is len(replay_data) - 2
( times, accel_x, accel_y )
Return type:tuple
static cursor_acceleration(replay_data)

Absolute cursor acceleration

Parameters:replay_data (numpy.array) – Replay data
Returns:A pair of time and cursor acceleration data. Size of resultant data is len(replay_data) - 2
( times, accel )
Return type:tuple
static cursor_jerk(replay_data)

Absolute cursor jerk

Parameters:replay_data (numpy.array) – Replay data
Returns:A pair of time and cursor jerk data. Size of resultant data is len(replay_data) - 3
( times, jerk )
Return type:tuple
static cursor_jerk_xy(replay_data)

Parametric cursor jerk

Parameters:replay_data (numpy.array) – Replay data
Returns:A pair of time and parametric cursor jerk data. Size of resultant data is len(replay_data) - 3
( times, jerk_x, jerk_y )
Return type:tuple
static cursor_vel_xy(replay_data)

Parametric cursor velocity

Parameters:replay_data (numpy.array) – Replay data
Returns:A pair of time and parametric cursor velocity data. Size of resultant data is len(replay_data) - 1
( times, vel_x, vel_y )
Return type:tuple
static cursor_velocity(replay_data)

Absolute cursor velocity

Parameters:replay_data (numpy.array) – Replay data
Returns:A pair of time and cursor velocity data. Size of resultant data is len(replay_data) - 1
( times, vel )
Return type:tuple
static press_intervals(replay_data)

List of intermixed press intervals for all keys

Parameters:replay_data (numpy.array) – Replay data
Returns:A pair of time and key press interval data
( times, intervals )
Return type:tuple

analysis.osu.std.score_data module

class analysis.osu.std.score_data.StdScoreData

Bases: object

Class used for analyzing score data pertaining to a specific play.

DATA_MAP_IDX = 2
0 < pos_hit_range < pos_hit_miss_range < inf
0 < neg_hit_range < neg_hit_miss_range < inf
Hit processing occurs:
-neg_hit_range -> pos_hit_range
Miss processing occurs:
-neg_hit_miss_range -> neg_hit_range pos_hit_range -> pos_hit_miss_range
No processing occurs:
-inf -> -neg_hit_miss_range pos_hit_miss_range -> inf
Type:The following must be true
DATA_OFFSET = 0
DATA_TYPE = 1
TYPE_AIMH = 2
TYPE_EMPTY = 4
TYPE_HITP = 0
TYPE_HITR = 1
TYPE_MISS = 3
static aim_offsets(score_data)
static aim_x_offsets(score_data)
static aim_y_offsets(score_data)
blank_miss = False

If True, holds have to be times in distance range of HOLD scorepoint prior to completing it If False, the player can complete the slider with cursor being anywhere so long as the key is held down

static cursor_pos_offset_mean(score_data)

Average of cursor position offsets at moments the player tapped notes

Parameters:score_data (numpy.array) – Score data
Returns:
Return type:float
static cursor_pos_offset_stdev(score_data)

Standard deviation of cursor position offsets at moments the player tapped notes

Parameters:score_data (numpy.array) – Score data
Returns:
Return type:float
static cursor_pos_offset_var(score_data)

Variance of cursor position offsets at moments the player tapped notes

Parameters:score_data (numpy.array) – Score data
Returns:
Return type:float
dist_miss_range = 50
dynamic_window = False

Enables missing in blank space. If True, the Nothing window behaves like the miss window, but the iterator does not go to the next note. Also allows missing when clicked in empty space.

follow_radius = 100
static get_score_data(replay_data, map_data, ar=8, cs=4)
hitobject_radius = 36.5
hold_range_miss = False

If True, sliders can be released and then pressed again so long as player holds key down when an aimpoint is passed. If false, then upon release all aimpoints that follow are dropped and note’s release timing is processed

hold_range_window = False

If True, holds have to be times in distance range of HOLD scorepoint prior to completing it or it will miss If False, the scorepoint won’t be completed until the cursor is in distance range of scorepoint

hold_range_window must be True for this to take effect

neg_hit_miss_range = 450
neg_hit_range = 300
neg_hld_range = 50
neg_rel_miss_range = 1000
neg_rel_range = 500
notelock = True

Overrides the miss and hit windows to correspond to spacing between notes. If True then all the ranges are are overridden to be split up in 1/4th sections relative to the distance between current and next notes

TODO: implement

static odds_all_conditions_within(score_data, tap_offset, cursor_offset)

Creates gaussian distribution models using tap offsets and cursor offsets for hits. That is used to calculate the odds of the player consistently tapping and aiming within those boundaries for the entire play. Be weary of survivorship bias.

Parameters:
  • score_data (numpy.array) – Score data
  • tap_offset (float) – Tap offset (ms) to determine odds for
  • cursor_offset (float) – Cursor offset (ms) to determine odds for
Returns:

Return type:

float

static odds_all_cursor_within(score_data, offset)

Creates a 2D gaussian distribution model using avg and var of cursor 2D position offsets and uses it to calculates the odds that all cursor positions are within the specified distance from the center of all hitobject

Parameters:
  • score_data (numpy.array) – Score data
  • offset (float) – Tap offset (ms) to determine odds for
Returns:

Probability all random values {[X, Y], ...} are between (-offset, -offset) <= (X, Y) <= (offset, offset) In simpler terms, look at all the cursor positions for score; What are the odds all of them are between an area of (-offset, -offset) and (offset, offset)?

Return type:

float

static odds_all_tap_within(score_data, offset)

Creates a gaussian distribution model using avg and var of tap offsets and calculates the odds that all hits are within the specified offset

Parameters:
  • score_data (numpy.array) – Score data
  • offset (float) – Tap offset (ms) to determine odds for
Returns:

Probability all random values [X] are between -offset <= X <= offset. In simpler terms, look at all the hits for scores; What are the odds all of them are between -offset and offset?

Return type:

float

static odds_some_cursor_within(score_data, offset)

Creates a 2D gaussian distribution model using avg and var of cursor 2D position offsets and uses it to calculates the odds that some cursor position is within the specified distance from the center of any hitobject

Parameters:
  • score_data (numpy.array) – Score data
  • offset (float) – Tap offset (ms) to determine odds for
Returns:

Probability one random value [X, Y] is between (-offset, -offset) <= (X, Y) <= (offset, offset). In simpler terms, look at all the cursor positions for score; What are the odds of you picking a random hit that has a cursor position between an area of (-offset, -offset) and (offset, offset)?

Return type:

float

static odds_some_tap_within(score_data, offset)

Creates a gaussian distribution model using avg and var of tap offsets and calculates the odds that some hit is within the specified offset

Parameters:
  • score_data (numpy.array) – Score data
  • offset (float) – Tap offset (ms) to determine odds for
Returns:

Probability one random value [X] is between -offset <= X <= offset. In simpler terms, look at all the hits for scores; What are the odds of you picking a random hit that is between -offset and offset?

Return type:

float

overlap_hit_handling = False

If true then presses while holding another key will not register

overlap_miss_handling = False

There are cases for which parts of the hitwindow of multiple notes may overlap. If True, all overlapped non miss hitwindow parts are all processed simultaniously for one key event. If False, each overlapped hit part is processed for each individual key event.

pos_hit_miss_range = 450
pos_hit_range = 300
pos_hld_range = 1000
pos_rel_miss_range = 1000
pos_rel_range = 500
press_block = False

If true then releases while holding another key will not register

static press_interval_mean(score_data)
recoverable_missaim = True

There are cases for which parts of the hitwindow of multiple notes may overlap. If True, all overlapped miss hitwindow sections are all processed simultaniously for one key event. If False, each overlapped miss part is processed for each individual key event.

recoverable_release = True

If True, release have to be in range of RELEASE scorepoint to count

release_block = False
release_miss = True

If True, then there is a release window. Otherwise, a release can be counted whenever key is released, basically treating them as single notes. Also if True, release_miss does nothing

release_radius = 100

Disables hit processing if hit on a note is too early. If False, the neg_miss_range of the current note is overridden to extend to the previous note’s pos_hit_range boundary.

TODO: implement

release_range = False

If True, release miss range is processed. Otherwise, it’s impossible to miss a release

release_window = True

If True, the cursor can wander off slider and come back so long as the cursor is there when it’s time for the aimpoint to be processed. If False, then slider release timing is triggered as soon as the cursor is out of range

static tap_offset_mean(score_data)

Average of tap offsets

Parameters:score_data (numpy.array) – Score data
Returns:
Return type:float
static tap_offset_stdev(score_data)

Standard deviation of tap offsets

Parameters:score_data (numpy.array) – Score data
Returns:
Return type:float
static tap_offset_var(score_data)

Variance of tap offsets

Parameters:score_data (numpy.array) – Score data
Returns:
Return type:float
static tap_press_offsets(score_data)
static tap_release_offsets(score_data)
class analysis.osu.std.score_data.StdScoreDataEnums

Bases: enum.Enum

An enumeration.

HITOBJECT_IDX = 4
HIT_OFFSET = 2
POS = 1
POS_OFFSET = 3
TIME = 0

analysis.osu.std.score_metrics module

class analysis.osu.std.score_metrics.StdScoreMetrics

Bases: object

Class used for analyzing mass score data and player statistics.

static get_per_hitobject_score_data(score_data_array)

Takes arrays of score data pertaining to various players and transposes it to be an array of per-hitobject score data by various players. In other words, it stacks all score data per-notes instead of standalone per-player. It allows to easier calculate data based how players do on specific notes or pattens. If a0 corresponds to player a and note 0, then the data

[
    [
a0      [ time, (cursor_pos_x, cursor_pos_y), hit_offset, (pos_offset_x, pos_offset_y), hitobject_idx ],
a1      [ time, (cursor_pos_x, cursor_pos_y), hit_offset, (pos_offset_x, pos_offset_y), hitobject_idx ],
aN      ...  N events
    ],
    [
b0      [ time, (cursor_pos_x, cursor_pos_y), hit_offset, (pos_offset_x, pos_offset_y), hitobject_idx ],
b1      [ time, (cursor_pos_x, cursor_pos_y), hit_offset, (pos_offset_x, pos_offset_y), hitobject_idx ],
bN      ...  N events
    ],
    ...
]

gets turned into

[
    [
a0      [ time, (cursor_pos_x, cursor_pos_y), hit_offset, (pos_offset_x, pos_offset_y), hitobject_idx ],
b0      [ time, (cursor_pos_x, cursor_pos_y), hit_offset, (pos_offset_x, pos_offset_y), hitobject_idx ],
N0      ...  N events
    ],
    [
a1      [ time, (cursor_pos_x, cursor_pos_y), hit_offset, (pos_offset_x, pos_offset_y), hitobject_idx ],
b1      [ time, (cursor_pos_x, cursor_pos_y), hit_offset, (pos_offset_x, pos_offset_y), hitobject_idx ],
N1      ...  N events
    ],
    ...
]
Parameters:score_data_array (numpy.array) – List of score_data numpy arrays
Returns:
Return type:numpy.array
static get_percent_below_offset_one(per_hitobject_score_data, hitobject_idx, offset)

Gives the % of players that tapped within offset for the hitobject at hitobject_idx.

Parameters:
  • per_hitobject_score_data (numpy.array) – Per-hitobject score data across various plays
  • hitobject_idx (int) – The index of the note to solve for
  • offset (float) – Offset serves as a threshold for the percent calculation
Returns:

% of players able to hit better than offset based on given mass score data in per_hitobject_score_data.

Return type:

float

static percent_players_taps_all(per_hitobject_score_data, offset)

Gives the % of players that tapped within offset for each hitobject.

Parameters:
  • per_hitobject_score_data (numpy.array) – Per-hitobject score data across various plays
  • offset (float) – Offset serves as a threshold for the percent calculation
Returns:

A tuple (times, percents). Percents correspond to how much % of players tapped within offset for a list of hitobject. Times correspond to the timing of the respective hitobjects.

Return type:

(float, numpy.array)

static solve_for_hit_offset_all(per_hitobject_score_data)

Takes all of the players’ results to solve for the tapping offset 50% of players are able to hit better than for each note. This is useful for determining the difficulty response of patterns in the map relative to other patterns in the same map.

Parameters:per_hitobject_score_data (numpy.array) – Per-hitobject score data across various plays
Returns:A tuple (times, offsets). Offsets correspond to each hitobject where 50% of players are able to hit better than. Times correspond to the timing of the respective hitobjects.
Return type:(float, numpy.array)
static solve_for_hit_offset_one(per_hitobject_score_data, hitobject_idx, target_percent)

Solves for the tapping offset for a given note such that a certain percentage, target_percent, of players are able to hit better than.

Parameters:
  • per_hitobject_score_data (numpy.array) – Per-hitobject score data across various plays
  • hitobject_idx (int) – The index of the note to solve for
  • target_percent (float) – Target percentage of players
Returns:

The tap offset from 0ms that would satisfy target_percent % of players being able to hit better than.

Return type:

float

analysis.osu.std.std_layers module

class analysis.osu.std.std_layers.StdLayers

Bases: object

Class used for time dependent visualization in central display. Sample use case: add_std_layer('layer group', 'layer name', replay_data, StdLayers.StdReplayCursorLayer)

static StdReplayCursorLayer(painter, ratio_x, ratio_y, time, replay_data)

Displays player’s cursor movement in replays

static StdReplayCursorVel(painter, ratio_x, ratio_y, time, replay_data)

Displays cursor vel for replay in top left corner

static StdReplayHoldLayer(painter, ratio_x, ratio_y, time, replay_data)

Displays held keys in replay

static StdReplayScatterLayer(painter, ratio_x, ratio_y, time, replay_data, color=[0, 0, 0, 255])

Displays held keys in replay

static StdScoreDebugLayer(painter, ratio_x, ratio_y, time, score_data)

Displays tap offset and position offset for each tapped note in replay.

Module contents