Expand description
Power-factor calculator and per-organization rulebook pass/fail (MBA-1372).
Power factor (PF) is bullet weight (grains) * velocity (fps) / 1000 – a shared,
organization-agnostic formula used by essentially every American practical/action
shooting sport to gate ammunition into scoring categories. This module computes from
bullet weight and velocity only; it does not run a trajectory.
§Truncation convention – a real rules detail, not rounding noise
USPSA’s rulebook is explicit: “The final result will ignore all decimal places (e.g. for USPSA purposes, a result of 124.9999 is not 125)” (USPSA Competition Rules, March 2026 edition, Sec. 5.6, Rule 36). IDPA’s rulebook states the same convention in different words: “…divide by 1000, and ignore numbers to the right of the decimal” (2024 IDPA Rulebook, Sec. 8.3.4.7). Both truncate toward zero (floor) – neither rounds.
scored_power_factor reports a single canonical PF as floor(weight_gr * v_fps / 1000), matching those two rulebooks’ own scored value exactly. SASS’s handbook does
not spell out a truncation rule for its own threshold check (its worked examples
happen to land on exact values), so applying the same floor to the SASS row too is a
deliberate, conservative choice: it never reports a marginal load as passing a SASS
minimum that an official chronograph session could truncate below.
§Boundary semantics: >= (“meets or exceeds”), never strict >
Every source rulebook uses “meets or exceeds” / “at least” / “not less than” language, never a strict “greater than”:
- USPSA: rule tables read “Minimum power factor for Major: 165” / “…for Minor: 125”; Rule 37: “…until the competitor meets the minimum power factor…”.
- IDPA, Sec. 8.3.5.1.1: “If two of the three rounds meet or exceed the required power factor, the ammunition is in compliance.”
- SASS Shooter’s Handbook: “not less than a minimum power factor of 60” / “If the average velocity…meets or exceeds the calculated power factor of 60”.
A load landing exactly ON a threshold (PF == 125, velocity == 400, etc.) therefore
passes. Every threshold in PF_THRESHOLDS is evaluated as pf >= minimum and
every velocity cap as v <= maximum / v >= minimum (inclusive on both ends) –
never a strict inequality. evaluate_all’s boundary tests exercise both sides of
every published number in the table.
§Data sources (published rulebook facts – no copyright exposure; cited with revision)
- USPSA: USPSA Competition Rules, March 2026 edition, Sec. 5.6 (per-division rule tables: “Minimum power factor for Major: 165” / “…for Minor: 125”).
- IDPA: 2024 IDPA Rulebook, Sec. 8.3.4 (“Ammunition minimum power factors”): 8.3.4.1 SSP/ESP/CO 125; 8.3.4.2 CDP 165; 8.3.4.3 Stock Revolver/CCP 105; 8.3.4.4 Enhanced Revolver 155; 8.3.4.5 BUG 95; 8.3.4.6 PCC 135.
- SASS: SASS Cowboy Action Shooting Shooter’s Handbook, Version 28, January 2026, “Power Factors” and Glossary entry “Power factor”: minimum PF 60, minimum velocity 400 fps, maximum velocity 1000 fps (revolver/pistol) / 1400 fps (rifle).
Structs§
- PfEvaluation
- One rulebook row’s evaluation against a computed load.
- PfThreshold
- One organization/class row in the power-factor rulebook table.
Constants§
- PF_
THRESHOLDS - Rulebook power-factor/velocity thresholds. A DATA TABLE by design (per the brief) so updating a rulebook figure is a one-line edit here, not a code change elsewhere. See the module docs for citations.
Functions§
- evaluate_
all - Evaluate a load (bullet weight in grains, velocity in fps) against every row in
PF_THRESHOLDS. Boundary semantics:>=/<=throughout (see module docs). - power_
factor - Raw power factor:
weight_gr * velocity_fps / 1000, no rounding/truncation. - scored_
power_ factor - The truncated (floored) PF used for rulebook scoring/threshold comparisons. See the module docs’ “Truncation convention” section for why floor (not round) is correct, and why it is applied uniformly across all three organizations.