Speed calculation
Races

Speed calculation

MyPigeons computes the speed of every arrival from the same building blocks: distance, flight duration, clock deviations, dead time, and a critical-low-speed switch that flips the ordering to arrival time when birds slow down. This page walks through every input, the order in which they are applied, and the edge cases that bite multi-day races.

Good to know before you start

  • Speed is reported in m/min by default, or y/min for imperial countries. Precision is controlled globally by the speed decimals setting.
  • Dead time can be configured countrywide or overridden on a single race. The per-race override always wins.
  • A pigeon flying slower than the critical low speed (default 750 m/min) is ranked by arrival time instead of speed when the race opts in.

The basic speed formula

Every speed in the system uses the same formula:

speed = distance × 60 / flight duration, where distance is expressed in metres (or yards for imperial countries) and flight duration is in seconds.

Distance unit conversion

The speed unit system setting drives the unit. Metric countries store distance in kilometres and convert to metres (× 1000). Imperial countries store distance in miles and convert to yards (× 1760). Bangladesh is a deliberate hybrid: kilometres are stored in the database but speeds are reported in y/min, so distance is multiplied by 1093.6133.

Precision and sanity checks

The final speed is rounded to the configured number of decimal places. Two safeguards run last: a flight duration of zero or less collapses the speed to 0, and any speed above 10 000 also collapses to 0 (typically caused by a clock deviation pointing the wrong way or an arrival entered before the liberation).

Flight duration in detail

Flight duration is not simply arrival - liberation. It is the result of four steps applied in this order:

  1. Compute the absolute arrival timestamp

    The arrival timestamp is computed as elapsed seconds from the liberation moment: liberation + (arrival day - 1) × 86400 + h × 3600 + m × 60 + s. This avoids issues with daylight-saving transitions across countries - by counting elapsed seconds from the liberation moment instead of reconstructing a calendar date, the result stays correct even when liberation and arrival fall on different sides of a DST change.

  2. Subtract clock or relative deviation

    When relative deviation is enabled, the relative deviation is used; otherwise the raw clock deviation is used. Sign handling depends on two switches. Use positive deviation always inverts the sign - useful in countries where a positive deviation is the unfavourable direction. Use negative deviation only applies the deviation when it is negative; positive deviations are zeroed out, which is the default behaviour for most federations. The full mechanics of the relative deviation are covered in their own section below.

  3. Subtract bicycle time

    If the fancier records a bicycle time - the time spent transporting the clock from the loft to the club for read-out - it is subtracted from the flight duration so that ringing time wins, not transport time.

  4. Subtract dead time

    The dead-time deduction is the most involved step and has its own section below.

Relative deviation in detail

Some federations distribute the clock deviation proportionally over the clock's running window instead of applying the full deviation to every arrival. This is what relative deviation does. When enabled, the calculator uses the relative deviation in place of the raw clock deviation when computing the flight duration.

The clock-running window: open and close times

When the import file is processed, the system stores two timestamps per race that bracket the clock's running window:

  • Open time - when the clock was set and started at the club, before basketing.
  • Close time - when the clock was stopped and read out after the race.

Both timestamps live in the same table and are stored at two levels.

Club-level record

One record per club and race, holding the open and close that apply by default to every member of that club. This is the most common shape - the whole club basketed and read out together, so a single open/close pair covers all the members.

Per-fancier override

Some federations also import fancier-level open and (optionally) close timestamps. These records override the club values for that one fancier. The override is partial: a fancier-only open replaces just the open and inherits the club's close, while a fancier record that also fills out close replaces both.

When a fancier record exists, the running window starts at the fancier's open. The end of the window comes from the fancier record if it carries a close timestamp; otherwise it falls back to the club's close.

How the relative deviation is computed

The formula has three pieces:

  • running_time = open - close - the total span of seconds during which the clock was running.
  • running_time_at_arrival = arrival - close - where the arrival sits within that window.
  • relative_deviation = (running_time_at_arrival / running_time) × clock_deviation - the share of the clock deviation that applies to this arrival, proportional to how much of the running window had elapsed at arrival time.

Concretely, an arrival at the very start of the running window contributes a 0 deviation; an arrival at the very end contributes the full clock deviation; an arrival in the middle contributes half. The result is rounded to four decimal places before being passed back to the flight-duration formula.

When relative deviation is skipped

Two cases skip the calculation entirely and return 0. First: when the use relative deviation setting is off in the country's configuration. Second: when neither a club record nor a fancier record exists for the race - typically because the import file did not carry open/close times. In both cases the speed calculator falls back to the raw clock deviation.

Sign handling and the positive/negative switches

A clock deviation is a signed number, but federations disagree on which sign means what. Two country-wide switches decide how MyPigeons interprets it.

Use negative deviation controls the sign at input time. With it on (the default), the deviation is stored exactly as entered. With it off, positive numbers entered by the user are flipped to negative when saved - useful for federations that report deviations as positive numbers but treat them as penalties.

Utilise positive deviation inverts the sign when the deviation is fed into the speed formula. With it off (the default), the stored value goes in as-is; with it on, it is multiplied by -1 first - useful when your federation's interpretation of the sign is the opposite of the MyPigeons default.

Both switches are country-wide settings; once they match your federation's rules they do not need to change per race. They act on whichever deviation type is currently in use - if relative deviation is on, the same sign rules apply to the relative deviation, not to the raw clock value.

Where the open and close times come from

Open and close timestamps are populated from the import file at the moment a race's data is uploaded. Most ETS exports carry both for the club; federations that work with per-fancier overrides also include fancier-level rows. The records can also be edited from the clock times screen if a typo or missing entry has to be corrected manually before recalculation.

Dead time zones

A dead-time zone is a recurring nightly window during which pigeons are not flying. The system removes that window from the flight duration so a multi-day arrival is not penalised for the hours when no pigeon could possibly be in the air.

A dead-time zone has a date range (which weeks of the season it applies to) and a time-of-day range (the nightly window, e.g. 21:00 - 05:00). The duration that gets deducted is one full day plus the difference between the two times - so a 21:00 - 05:00 window is 32 hours per night, accounting for the fact that the window crosses midnight.

Two ways to configure dead time

Dead time can be set in two places. They are read in a fixed order during speed calculation.

Global dead time (countrywide)

Configured under Admin panel → Dead time zones. You can create as many intervals as the season needs - typically a short-night window for summer races (e.g. 22:00 - 04:00) and a longer one for marathon weeks (e.g. 21:00 - 05:30). Each interval has its own season date range, so they can cover different parts of the year without overlap. The form rejects intervals that overlap an existing record.

Per-race override

Configured directly on the race admin tab as a one-off override for a single race. Use this when a particular race has unusual dead-time needs - for example a long-distance flight where the dead-time window has to be extended just for that race. The override stores only the time-of-day range; it implicitly applies to whichever days the race covers.

Which one wins

The speed calculator looks up both, in this order:

  1. Match a global zone

    The global lookup runs against the race liberation moment. Whichever global interval covers the liberation moment is loaded - start time, end time and nightly duration. The match is by date; the time-of-day range is used later to deduct the dead time, not to filter the lookup.

  2. Apply the per-race override

    If a per-race override exists, its values overwrite whatever the global lookup loaded - the override always wins, all three fields (start, end, duration). If no global match was found but an override exists, the override is used on its own.

  3. No match means no deduction

    If neither produces a result, dead time is zero and the flight duration is left untouched.

Multi-day races and overlapping zones

Most of the dead-time complexity surfaces only on arrivals that take more than one day. Two rules drive what happens.

How many nights are deducted

After the matched zone is known, its nightly duration is multiplied by the number of calendar days between liberation and arrival. A pigeon arriving two days later has two full nights of dead time deducted; one arriving on the same day has none. The day count is computed from the calendar date, not from elapsed seconds, so a flight from Friday afternoon to Sunday morning counts as two days regardless of the exact hours.

Arrivals that land inside the dead-time window

If the arrival's time of day falls between the dead-time start and end, the calculator rolls the arrival forward to the end of the window before running the deduction. Two cases are handled symmetrically:

  1. Arrival before midnight, inside the window

    Example: a 21:00 - 05:00 window with the pigeon arriving at 22:30. The arrival is moved forward to 05:00 the next morning - the time from arrival to midnight is added, then the time from midnight to the end of the window.

  2. Arrival after midnight, still inside the window

    Example: same 21:00 - 05:00 window, pigeon arriving at 03:00. The arrival is moved forward to 05:00 of the same day. Both cases land the arrival on the end of the dead time so the deduction stays symmetrical.

Important caveat: only the liberation-day zone is used

The global lookup runs only once, against the race liberation moment. If your country defines different dead-time intervals for different parts of the season and a single race's flight spans two of them, the liberation-day interval is reused for every subsequent night - the system does not splice configurations across days. Plan countrywide intervals so that any single race fits inside one interval.

For a one-off race that legitimately needs a different dead time than the global setup (for example a marathon flight where the standard nightly window is too short), set a per-race override on the race admin tab. The override replaces all three values (start, end, duration) for that race only and is the cleanest way to handle this case.

Critical low speed (default 750 m/min)

When pigeons stop on the way - extreme heat, headwinds, a flock landing overnight - speeds drop below the level at which the loft-to-loft distance still produces a meaningful ranking. Treating those pigeons by speed alone unfairly favours short-distance lofts, because shorter distances always yield higher speeds at the same flight time. The critical-low-speed switch addresses this.

How the threshold is configured

Two settings drive it. The critical low speed sets the threshold itself - default 750, in m/min for metric systems and y/min for imperial. The use critical low speed master toggle exposes the feature in the race UI.

How a race opts in

Each race has two flags on the race details modal:

Order by arrival time when below threshold

When this flag is on, pigeons whose speed falls below the threshold are written into the temporary results with their adjusted arrival timestamp instead of their speed - the standings then sort by who arrived first, not by who flew faster on a shorter distance. Pigeons above the threshold are not affected; the regular speed sort stays in charge for them. The two ranking systems coexist on the same race.

Apply average-distance adjustment

This flag applies an Austrian-style correction: each loft's arrival time is shifted by 8 seconds for every 100 m of difference from the race's average distance. Lofts further from the release point get a positive shift (their arrival is treated as earlier), lofts closer in get a negative shift. This compensates for distance differences without abandoning the time-based ranking.

Where the average distance comes from

The race's average distance is computed from distinct fanciers' loft distances, not from per-pigeon distances. Each fancier contributes their loft once, regardless of how many pigeons they basketed - so a single large loft cannot skew the average.

When speeds are recomputed

A speed is computed whenever any input that feeds the formula changes. The most common entry points are:

  • New arrival - imported from an ETS file or entered manually triggers a single-arrival speed calculation.
  • Mass edits on a race (clock deviation, distance, dead time) recompute every arrival in the race.
  • Race-level recalculation walks every arrival on the race - the official arrivals, the in-progress temporary results, and the publicly reported arrivals. When relative deviation is enabled, the per-fancier relative deviation is also re-derived from the clock-time records before recomputing the speed.
  • BENZING Live arrivals - both private trainings and shared club trainings recompute the speed every time the live device reports a new arrival.
  • Forwarding API - third-party tools that push arrivals through the public API run through the same calculation path.
  • Training mode uses a separate, simpler formula that ignores deviations, dead time and bicycle time entirely. It is used for personal training records that are never combined with race results.

Edge cases worth knowing

Daylight saving transitions

Arrival timestamps are computed as elapsed seconds from the liberation moment, not from a reconstructed calendar date. This makes the calculation immune to DST changes that fall between liberation and arrival, even when a race spans more than one country.

Organisation timezone

When the timezone setting is enabled and the race's organisation has its own timezone configured, that timezone is used for all dead-time time-of-day comparisons. A federation with offices in two countries therefore gets consistent results - the dead-time window is interpreted in the organisation's local time.

Imperial and Bangladesh units

Imperial races store distance in miles and convert to yards (× 1760) before computing the speed; the unit suffix becomes y/min. Bangladesh runs metric distance (km) but reports y/min, which is why distance is multiplied by 1093.6133 instead of 1000 when both the metric system and the y/min sign are configured.

Sanity ceiling

Any computed speed above 10 000 collapses to 0. This is a defensive guard against bad data - typically a clock deviation pointing the wrong way, or an arrival entered before the liberation.