[中文](../star.md) | [Back to README](../../../README.en.md)
> Full examples in this manual run from the repository root.
The library ships a catalog of 9100 stars (BSC / HR numbers `1-9110`, apparent magnitudes `-1.46` to `7.96`) and propagates proper motion automatically. The catalog stores **J2000** right ascension and declination (`InnerStarData.Ra`/`Dec`); to get the position at a given instant you must apply proper motion, precession and nutation through `StarData.RaDecByDate(date)`. Rise/set, topocentric quantities and constellation lookup all expect the corrected coordinates.
`star/catalog` is independent of the embedded 9100-star database and does not automatically download or load large catalogs. `Entry.Coordinate` is a `basic.StarCoordinate` with epoch, frame and proper motion; pass it directly to `moon.FindStarOccultations` or `phenomena.StarApproaches`.
| Entry point | Input and purpose |
| --- | --- |
| `ReadCSV` | Header-based CSV / TSV; `ColumnMap` sets columns, epoch and frame; zero `Delimiter` enables detection |
| `ReadHipparcos2007` / `ReadBSC5` | Corresponding fixed-width catalog text |
| `ReadStellariumStars` / `ReadStellariumDir` | One binary shard or an `fs.FS` directory; directory options load names/cross-IDs and filter by `MaxMagnitude` |
| `Lookup` / `Entries` / `Len` | ID or alias lookup, copied records and count |
| `Near` / `Band` | Cone / declination-band searches at catalog epochs, without propagation to the observing date |
| `Merge` / `WithNames` | Return new catalogs; right-hand records win for the same primary ID and component; names use `id\|name` lines |
-`RA` and `Dec` default to degrees; `AnglesInRadians` selects radians. Proper motions are mas/year, parallax mas and radial velocity km/s.
- Set `PMRAIncludesCosDec: true` if PMRA already represents `dRA*cos(Dec)`; otherwise the reader multiplies by the cosine.
- Supply `Epoch` or `EpochColumn` (Julian year) and the correct `Frame`; a zero epoch is not an unknown-epoch placeholder.
Reading behavior:
- With `ReadOptions.Strict`, invalid records return an error; otherwise they are skipped and counted by `Skipped()`. Structural errors such as missing required headers always fail.
-`Filter` controls admission without counting rejected records as bad.
- Missing magnitudes are `NaN`; do not use `BandV`, `BandG` and `BandHp` interchangeably for a V-band visibility threshold.
-`Near` searches at each record's own epoch: normalize mixed epochs/frames first and apply proper-motion propagation for exact observing-date selection.
Catalog coordinates have epoch J2000. `RaDecByDate` applies proper motion, precession and nutation before date-specific rise/set, altitude or constellation calculations.
Proper motion is propagated in **Julian years** (365.25 days), and `RaDecByDate` converts the civil instant to TT before taking the epoch difference. Whenever a record carries a distance (`Pc > 0`), `RaDecByJde` advances a full **three-dimensional space motion**: proper motion supplies the tangential velocity and `RadVel` the line-of-sight component, the position vector is extrapolated linearly and its direction is taken. Records without a distance fall back to two dimensions, advancing only the two angular components, which is equivalent to treating the star as infinitely distant. The two differ only in second-order terms: three-dimensional propagation also changes the star's distance, so the apparent place is slightly smaller than in the two-dimensional case; even the fastest bright star moves less than about 0.09 arcseconds from it within 26 years.
| Group | Entry points | Purpose | Units and convention |
| --- | --- | --- | --- |
| Constellation | `Constellation` / `ConstellationEN` / `ConstellationCode` | Chinese name / English name / IAU three-letter code | Corrected RA/Dec in degrees plus the instant |
| Star catalog | `InitStarDatabase` / `StarDataByHR` / `StarDataByName` / `StarDataByNameAll` / `StarDataByNameIn` / `TopBrightStars` | Initialise the embedded catalog; look up by HR number, Chinese name/alias or English common name; disambiguate duplicates with `All` or `In`; fetch the bright-star sample | HR `1-9110`; `Mag` is apparent magnitude |
| Name disambiguation | `StarDataByNameAll` / `StarDataByNameIn` | All candidates sharing a name / the unique star matching `ChineseRegion` | For example `StarDataByNameIn("杵增一", "危宿")` |
| Error checks | `ErrStarNotFound` / `ErrStarNameAmbiguous` | Distinguish "not found" from "ambiguous name" with `errors.Is` | Exported by the `star` package |
| Coordinate correction | `StarData.RaDecByDate` (`RaDecByJde` on the `basic` side) | Correct a J2000 position to the given instant | Returns RA/Dec in degrees |
| Rise, set, culmination | `RiseTime` / `SetTime` / `CulminationTime` (`DownTime` is a deprecated alias of `SetTime`) | Rise, set and culmination instants | Civil instants; polar cases return sentinel errors |
| Rise/set with weather | `RiseTimeWithAtmosphere` / `SetTimeWithAtmosphere` | Rise and set with measured pressure (hPa) and temperature (°C) | Refraction always applied |
The `star` package has no `...N` entry points; the `n`-parameterised evaluation functions live on the matching functions of `sun`, `moon`, the planets and `coord`, with the semantics described in those manuals (`n < 0` uses the full series; under the semianalytic model every `n >= 0` uses the fast table, and Legacy truncates by `n`).
All three share one boundary table and differ only in output convention. The lookup uses the **apparent position of the day**, so pass the result of `RaDecByDate`, never the J2000 coordinates from the catalog.
The catalog loads on first lookup; `InitStarDatabase()` only warms it up. It is idempotent and surfaces the load error explicitly, and skipping it still works because the first lookup loads the catalog automatically.
| `ChineseRegion` | Mansion/enclosure qualifier the name belongs to, for example `危宿` or `太微垣`; empty when not annotated, used to disambiguate shared names |
| `CommonName` / `CommonAliasName` | Common English name and alias; `CommonName` is searchable with `StarDataByName` |
Lookup by name matches the catalog's Chinese names, Chinese aliases and English common names (`天狼`, `织女一`, `Sirius`); English names are case-insensitive and ignore leading/trailing whitespace. Use `StarDataByHR` to look up by number.
Chinese names can repeat across mansions or enclosures; for example, `杵增一` appears in both `箕宿` and `危宿`. `StarDataByName` returns an ambiguity error when more than one star matches. Use `StarDataByNameIn(name, region)` with `ChineseRegion` to select one, or `StarDataByNameAll` to list all candidates. The `名[宿]` form (for example `"杵增一[危宿]"`) is also accepted, but structured arguments are preferred.
**Breaking change**: the old implementation silently returned one of the matching stars; it now returns `ErrStarNameAmbiguous`. Check it with `errors.Is(err, star.ErrStarNameAmbiguous)`, then disambiguate with `StarDataByNameAll` or `StarDataByNameIn`. An empty region in `StarDataByNameIn` is equivalent to `StarDataByName` and still reports ambiguity for duplicate names. Error text also changed from `no such star` to `star not found: ...`; use `errors.Is` instead of matching strings.
English common names use the same `StarDataByName` entry point, case-insensitively and ignoring leading/trailing whitespace, for example `"sirius"`, `"Vega"` or `"Polaris"`. It covers the built-in `CommonName` field only (about 218 entries), not full Bayer designations such as `Alpha Canis Majoris`; Bayer/Flamsteed designations remain in `Name`. English names can also be duplicated (for example, `Gienah` refers to two stars); that returns `ErrStarNameAmbiguous`, and `StarDataByNameAll` lists the candidates.
With `aero` true the rise/set solution uses the horizon corrected by refraction and apparent radius; false uses the geometric horizon. `CulminationTime` needs only right ascension and longitude.
Under a polar night or midnight sun, `RiseTime`/`SetTime` return sentinel errors instead of an instant, see below.
`ApparentAltitude`/`ApparentZenith` take two extra arguments, pressure (hPa) and temperature (C), for the refraction correction. `ParallacticAngle` is the usual input for rotating a camera or a spectrograph slit.
天狼 Sirius -1.46 // first bright-star entry: Chinese name, common name, magnitude
```
The printed constellation name is the Chinese one because `Constellation` is the Chinese-name entry point; use `ConstellationEN` for `Canis Major` and `ConstellationCode` for `CMA`.
The catalog loads once on first access and is then a read-only cache, so share it across calls and goroutine-free request paths instead of caching it yourself. Unknown numbers or names return an error; in bulk code it is enough to skip on `err != nil` without classifying the error.
`aero = true` solves rise/set against the horizon corrected for refraction and apparent radius, which sits closer to the visual "just above the horizon" moment; `false` uses the geometric horizon, and the two differ on the order of 2-3 minutes.
Use the apparent altitude to decide whether the star is visible now, with `1010 hPa / 10 C` as the usual default weather values. `height` is **ellipsoidal height** in metres; when you only have orthometric height, add the geoid undulation first, see [Observer height conventions](coord.md#observer-height) in the README.
The catalog stores J2000 positions, so skipping `RaDecByDate` puts rise/set and constellation lookups off by degrees. Sidereal time, horizontal transforms, precession and nutation are covered in [Coordinate tools](coord.md); every time argument is a civil instant (a UTC label, equal to UT1 before 1972-01-01), see [Time Scale Declaration](map-geojson.md#time-scale-declaration).
### Constellation lookup and the bright-star catalog
All three constellation entry points share one boundary table and differ only in output: `Constellation` gives the Chinese name, `ConstellationEN` the English name and `ConstellationCode` the IAU three-letter code; the lookup uses the apparent position of the day. Catalog fields (`HR`/`HD`/`HIP`, J2000 RA/Dec, magnitude, proper motion, parallax distance and the naming fields) are listed as a table under [API Reference](#star-catalog).
- **Polar sentinel errors**: `RiseTime` returns `star.ERR_STAR_NEVER_RISE` during a polar night (below the horizon all day) and `SetTime` returns `star.ERR_STAR_NEVER_SET` during a midnight sun (above it all day); branch with `errors.Is`.
`ERR_STAR_NEVER_DOWN` is a deprecated alias of `ERR_STAR_NEVER_SET`, and `DownTime` is a deprecated alias of `SetTime`.
- **Refraction range**: the Saemundsson approximation only applies for true altitudes inside `(-5, 90)` degrees and contributes zero outside, so well below the horizon the apparent altitude equals the geometric one.
- **Catalog conventions**: BSC / HR `1-9110`, apparent magnitudes `-1.46` to `7.96`; Name lookup matches built-in Chinese names, aliases and English common names (`天狼`, `织女一`, `Sirius`); duplicate names require `StarDataByNameIn` or `StarDataByNameAll`.
- **Cross-checking against external catalogs**: positions here are J2000 mean places with proper motion plus precession and nutation; when comparing term by term, bring both sides to the same instant with `RaDecByDate` first.
## Parameter and result conventions
- **Units**: right ascension, declination, altitude, zenith distance, azimuth, hour angle, parallactic angle are in **degrees**; sidereal time is in **hours**; `tools.Format` renders them as degrees-minutes-seconds or hours-minutes-seconds.
In the catalog `PmRA`/`PmDec` are arcseconds per year, `RadVel`/`RotVel` are km/s and `Pc` is parsecs.
- **Time scale**: every public time argument and return value is a civil instant (a UTC label, equal to UT1 before 1972-01-01); see [Time Scale Declaration](map-geojson.md#time-scale-declaration).
- **Coordinate convention**: the catalog is J2000; `RaDecByDate` adds proper motion, precession and nutation. Skipping it puts rise/set and constellation lookups off by a large margin (a century of precession is a degree-level shift).
- **Observer height**: `height` is ellipsoidal height in metres; when you only have orthometric height, add the geoid undulation first, as described under "Observer Height Convention" in the README.
- **Refraction range**: the Saemundsson approximation behind `ApparentAltitude`/`ApparentZenith` only applies for true altitudes inside `(-5, 90)` degrees and contributes zero outside that range, so well below the horizon the apparent altitude equals the geometric one (the `alt=-30.180` above is the same value `Altitude` returns).
Pressure must be positive and temperature above absolute zero, otherwise the result is `NaN`.
- **`aero` semantics**: a true value solves rise/set against the horizon corrected by standard refraction, a false value uses the geometric horizon; the difference is about 2-3 minutes at low latitudes and grows noticeably at high latitudes.
- **Catalog range**: HR `1-9110`, apparent magnitudes `-1.46` to `7.96`; name lookup matches built-in Chinese names, Chinese aliases and English common names (case-insensitive); duplicate names require `StarDataByNameIn` or `StarDataByNameAll`.