The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Sport::Analytics::NHL::PenaltyAnalyzer - analyze the penalties, generate their actual start and finish time and allow determination of on-ice strength and of PB population at any time.

SYNOPSIS

Analyze the game penalties and derive as much as possible useful information from them. This is a very complicated module that implements the NHL penalty rulebook as well as its changes over the years. It builds the timelines of all penalties during the game which indicates the on-ice strength and penalty box population at any point of time in the game. Often, the analysis contradict the NHL's own records, and that's because NHL's own records are erroneous. When the analysis can be tested by the actual on-ice player record, we do the verification, but prior to that, i.e. before 1999, we consider our implementation to be correct even when they contradict the record strength of a goal.

The generated strengths are then inserted into their own collection which is constructed like a timeline for each game.

use Sport::Analytics::NHL::PenaltyAnalyzer
my $opts = ...
my $game_id = 201820001;
analyze_game_penalties($game_id, $opts->{dry_run});
set_strengths($game_id, $opts->{dry_run});

Two main functions listed in the snippet are exported. All the rest are auxiliary and the author has a limited understand of why and how they work. But they do.

The teams are managed as indices: away is 0, home is 1.

FUNCTIONS

decrease_onice

The global variable two-member arrayref ON_ICE counts the number of players on ice for each team. This function decreases the on-ice count for the given team. The count cannot go below 4. The penalty shot situations are not analyzed here.

Arguments: index of the team (0|1)

Returns: void
increase_onice

This function increases the on-ice count for the given team. The count cannot go above 6.

Arguments: index of the team (0|1)

Returns: void
create_player_cache

Creates a cache of game player ids mapped to their positions. The cache is stored in $CACHE (see Sport::Analytics::NHL::Vars) global variable.

Arguments: the game

Returns: void.
dump_penalty

Debugging function that neatly formats a penalty by its attributes

Arguments: the penalty

Returns: void, prints output.
dump_pbox

Debugging function that produces the output of all penalties of both teams

Arguments: the current penalty box (a 2-vector arrayref)

Returns: void, prints output.
is_major_penalty

Checks if the penalty is a major one by the name, despite not carrying a 5-minute length.

Arguments: the penalty
           the vocabulary of the penalty names
           (see Sport::Analytics::NHL::Config)

Returns: 1 if it is, 0 if it isn't.
check_gross_misconduct

Checks if a gross misconduct has occurred and assigns an extra 5-minute major to it.

Arguments: the penalty
           the gross misconduct vocabulary entry
           the penalties array of the game

Returns: void
stack_penalties

Stacks two penalties that overlap but in fact must occur one after another - in a double minor or in a excessive penalty box population cases.

Arguments: the penalty to be stacked
           the penalty it should be stacked with
           the flag to ignore the already existing stacking link

Returns: void
split_double_minor

Splits the double minor into two stacked minor penalties

Arguments: the double penalty
           the penalties array of the game
           the index of the penalty in the array

Returns: void
check_multiple_penalties_by_player

Checks if the penalized player is already serving a penalty in the box

Arguments: the current penalty
           the penalty box

Returns: the matched penalties if any.
prepare_penalties

Prepares a group of penalties by applying the functions described above to be processed later. Penalties that don't go on the clock are marked as such as well.

Arguments: the penalties vocabulary (q.v.)
           the penalties to be prepared
           the penalty box

Returns: void
expire_penalty

Expires a penalty that ran out its clock.

Arguments: the penalty
           the penalized team's index
           the timestamp of the moment
           the penalty box

Returns: void
expire_penalties

Loops through the penalty box to find the penalties to be expired at a given time.

Arguments: the time point
           the penalty box

Returns: void
get_coincidental_penalties

Finds penalties awarded coincidentally at the same time point and groups them by length: 0, 2, 5, 10

Arguments: the current penalty
           all penalties in the group

Returns: the hash of the coincidental penalties.
assign_0_10

Assigns 0-minute and 10-minute penalties to the penalty box

Arguments: the penalty box
           the hash of the coincidental penalties

Returns: void
apply_captain_decision

Applies a deducted captain's decision on which penalties shall expire sooner.

Arguments: the coincidentals hashref

Returns: 1 if there was a captain's decision
         0 if the order is FIFO.
has_coincidental_bench

Checks if coincidental penalties include a bench penalty

Arguments: the coincidentals hashref

Returns: 1 if there was a bench penalty
         0 otherwise
get_c52_count

Gets the count of coincidental matching 5 vs 2 penalties

Arguments: the coincidentals hashref
           the penalty box
           the length of the penalty (2 or 5)

Returns: the count of the coincidentals 5 vs 2.
adjudicate_substitute

Adjudicates whether the penalty is substituted

Arguments: the length of the penalty
           the coincidentals hashref
           the count of 5 vs 2 (see above)
           the reference to a flag where 2-minute coincidentals
            force a substitution

Returns: 1 if a subsistution was required
         0 otherwise
assign_coincidentals

Properly assigns coincidental penalties, adjusts their begin and end marks and sets them as matching penalties where applicable.

Arguments: the penalty box
           the coincidentals hashref
           the length of coincidentals to work with (5 or 2)
           the reference to a flag where 2-minute coincidentals
            force a substitution

Returns: void
assign_different_coincidentals

Assigns a special case of 5 vs 2 coincidentals in the last minutes or in the OT.

Arguments: the penalty box
           the coincidentals hash

Returns: void
has_same_player1_or_servedby

Checks if two penalties has the same offending player or the same servedby

Arguments: penalty1
           penalty2

Returns: 1 or 0
find_same_player_penalty

Finds penalties by the same player that was assigned another penalty

Arguments: the penalty box
           that another penalty

Returns: 1 or 0
find_stack_penalty

Find the penalty that was stacked to the given penalty for the given team.

Arguments: the penalty box
           the given penalty
           the team index

Returns: the stacked penalty or undef.
assign_remaining

After assigning the coincidental penalties, assign the remaining penalties to the penalty box.

Arguments: the penalty box
           the remaining penalties
           the length of these penalties

Returns: void
process_penalties

Processes a list of penalties assigning them to the penalty box and marking their derived properties.

Arguments: the arrayref of penalties
           the penalty box

Returns: void
get_active_penalties

Gets penalties that are currently on the clock at the time of an event.

Arguments: the penalty box
           the event

Returns: the penalties on the clock.
set_indicator

Sets the on-ice event strength indicator (type from 44 to 66, away team first, strength such as PP2 or SH1 or EV5) based on the penalty tracker.

Arguments: the indicator hashref
           the event
           the penalty box
           the active penalties

Returns: void. Dies if invalid indicator is detected.
mark_scores

Marks the penalties if a goal was scored on them.

Arguments: the goal
           the penalties on the clock, sorted

Returns: void
terminate_penalty

Terminates a penalty that was scored upon and thus ended.

Arguments: the goal
           the penalties on the clock

Returns: void, penalties are modified.
restore_on_ice_player

Restores a player who is out of the box to the ice when the on-ice tracker of the NHL fails to do that.

Arguments: the goal
           the penalty box

Returns: void, the event is updated.
get_real_on_ice

Gets the on ice count as provided by the NHL, or as explicitly marked in our constants at the top of this file.

Arguments: the event

Returns: the "real" ice count

Caveats: bad function name; debugging/testing only.
process_goal

Processes the penalties when a goal has been scored.

Arguments: the goal
           the penalty box

Returns: void
clone_match_penalty

Clone a match penalty based on description when it should've accompanied a major.

Arguments: the major penalty
           the end timestamp of the game

Returns: void
update_penalty

Updates a penalty in the database with all the information gathered.

Arguments: the penalty
           the vocabulary entry for misconduct
           the end timestamp of the game

Returns: void
update_penalties

Loops through the game penalties to update them

Arguments: the penalty box
           the vocabulary of penalties
           the end timestamp of the game

Returns: void
analyze_game_penalties

The main exporting function to prepare, process and update the penalties.

Arguments: the game
[optional] the dry run flag

Returns: void
init_strengths

Initializes the 'str' collection of strengths in the database.

Arguments: none

Returns: the collection 'str'
get_strength_affecting_penalties

Gets the list of on-ice strength affecting penalties from a game

Arguments: the game

Returns: the list of penalties
set_timeline

Sets the timeline array of penalties, with 1 marking the penalty start and 0 marking the finish

Arguments: the game
           the game penalties

Returns: the timeline
update_on_ice_for_ot

Updates the special case of on-ice count during the regular season overtime based on the OT rules of that season.

Arguments: the on-ice count
           the game

Returns: void
update_stack_on_ice_match

Updates either the on-ice count, or the penalty box stack count or the matched penalties count.

Arguments: the penalty entry from the timeline
           the on-ice count
           the stack count
           the matching penalty count reference

Returns: void
push_strengths

Pushes a new entry to the strengths arrayref to be inserted later into the database.

Arguments: the strengths arrayref
           the current timestamp
           the next penalty timestamp
           the game
           the on_ice count

Returns: void
set_strengths

The main exporting function to prepare, process and insert the strengths.

Arguments: the game
[optional] the dry run flag

Returns: void

AUTHOR

More Hockey Stats, <contact at morehockeystats.com>

BUGS

Please report any bugs or feature requests to contact at morehockeystats.com, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Sport::Analytics::NHL::PenaltyAnalyzer. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Sport::Analytics::NHL::PenaltyAnalyzer

You can also look for information at: