Read the chart inputs
We have finished preparing a file of compact position curves. Calculating a chart begins by reading that file and deciding whether the requested date and location are usable. These checks answer different questions: whether the bytes have a readable structure, whether the location is within the accepted ranges, and whether the date falls inside the published interval.
Before this lesson
Read “Package a reusable dataset” first. We will use byte counts and inequalities; all file sizes and time intervals in the worked examples are invented.
What you will learn
You will be able to calculate coefficient byte bounds and apply the engine’s date and location gates without treating a successful parse as proof of a complete or accurate ephemeris.
Dotted-underlined terms open a definition beside the text. Select one to read more, then close it to continue.
Each step has its own check. Pass every step to complete the lesson. Your answers and checked steps are saved in this browser, so you can continue after leaving or reloading.
1. Read a structure the evaluator can use
Opening a file gives us bytes, but bytes do not explain their own layout. The parser first requires a 64-byte header and the eight-byte marker HDCHEB01. It reads the number of series, which must be between 1 and 256, and compares the declared total length with the actual file length. Each series describes one body and one quantity, such as Sun longitude. Its table entry occupies 48 bytes.
Suppose an invented file contains two series. Their table ends at byte 64 + 2 × 48 = 160. A series with three segments and four coefficients per segment needs twelve coefficients. Each coefficient occupies eight bytes, so its payload takes 96 bytes. If it starts at byte 160, it ends at byte 256; a 256-byte file contains it exactly. The end address is exclusive: the last occupied byte is 255.
table_end = 64 + 48 × series_count; payload_bytes = segments × coefficients_per_segment × 8
For each entry, the parser checks a known body and quantity, 1–64 coefficients, a positive segment count, a finite positive segment length, and a finite start time. The coefficient offset must be at or beyond the table end, and checked addition must put its end within the file. The four header time bounds must be finite; the published lower bound must be strictly below the upper bound.
The parser also recomputes a cyclic redundancy check (CRC-32), a number used to detect changes in bytes, over bytes 12 through the table end. The coefficient CRC field is read but is not recomputed over the coefficient payload. Parsing therefore does not establish that the coefficients are intact or finite, that every required series exists, that entries are unique or non-overlapping, or that fitted support covers the published domain. Those are separate concerns.
A checksum precedent, rather than a new file standard
Peter Deutsch’s 1996 GZIP specification includes sample CRC-32 code. It provides a documented precedent for this checksum calculation; HDCHEB01 is the engine’s own layout, not the GZIP format. No separate historical inventor is asserted for this local parser.
Connect this step to the source
src/cheb/format.rs
parse
Paths refer to the astrology-engine repository. Examples use invented inputs; a successful exercise is not an astronomical-accuracy test.
Sources for this section
Apply this step
Answer every part, then check. You can retry as often as you like.
2. Admit a chart request
A valid file does not make every chart request valid. The chart entry point receives an instant, geographic latitude and longitude, and a house-system choice. Latitude tells us how far north or south the location lies; geographic longitude places it east or west. These geographic angles are inputs for the later horizon calculation, distinct from a planet’s longitude around the chart circle.
The function accepts latitude from −90° to +90° and longitude from −180° to +180°, including both endpoints. A request at latitude 45° and longitude −73° passes. Latitude 91° fails even if the longitude is valid. NaN and infinities also fail the range checks. The function does not wrap an out-of-range longitude back into range.
−90° ≤ latitude ≤ 90°; −180° ≤ geographic longitude ≤ 180°
After location validation, the input instant is expressed in ephemeris seconds using the time library’s to_et_seconds conversion. Recall that these are seconds on the Barycentric Dynamical Time scale from noon January 1, 2000 on that scale. This is not a bare local clock reading. The chart asks the public coverage check for zero lookback, then evaluates bodies. A later evaluation can still fail if a series is missing or lacks the needed samples.
Where these bounds come from
These are the current chart API’s explicit admission rules. We do not attribute this implementation decision to an astronomical discoverer. The exact source is linked below, so a change in the API can be followed without inventing an origin story.
Connect this step to the source
src/chart.rs
calculate_chart
Paths refer to the astrology-engine repository. Examples use invented inputs; a successful exercise is not an astronomical-accuracy test.
Sources for this section
Apply this step
Answer every part, then check. You can retry as often as you like.
3. Use the published interval
Imagine that a file publishes the interval from 0 to 864,000 ephemeris seconds: ten days. A chart at 172,800 seconds, two days after the beginning, is admitted because it lies between the endpoints. Both endpoints are also admitted. The coverage accessor reads this interval from the header; it does not calculate the intersection of the individual series.
Some callers need earlier samples. With a requested lookback L seconds, the check subtracts L from the requested time t and requires that earlier instant to remain at or above the lower bound. It also requires t to remain at or below the upper bound. At t = 172,800 s, a lookback of 259,200 s reaches −86,400 s, so this request fails. A lookback of 172,800 s reaches exactly zero and passes.
t − L ≥ published_lower; t ≤ published_upper
For the chart path L is zero. The fitted curves may extend beyond the published interval: that extra support lets motion evaluation sample half a day before and after an admitted date. A direct longitude evaluation uses its selected series bounds instead of this public gate. Passing either check does not imply passing the other. The builder reserves margins, while the runtime parser does not prove that an arbitrary file has them.
An engine contract with two boundaries
Published admission and fitted support are local API and preparation policies. Their roles are documented in the current source. A historical ephemeris format such as the Jet Propulsion Laboratory’s SPK is context for storing curves, not the authority for these particular margins or checks.
See the teaching TypeScript
const admitted = (t: number, lo: number, hi: number, lookback: number): boolean => t - lookback >= lo && t <= hi;Finite, correctly labeled inputs are assumed. This demonstrates the arithmetic; it does not fetch data or replace the engine.
Connect this step to the source
src/lib.rs
coverage; check_coverage
Paths refer to the astrology-engine repository. Examples use invented inputs; a successful exercise is not an astronomical-accuracy test.
Sources for this section
Apply this step
Answer every part, then check. You can retry as often as you like.
Your lesson checks
0 of 3 steps passed.
Use the feedback beside each check to retry any unfinished step.