# `Astro.Lunar.CrescentVisibility`
[🔗](https://github.com/kipcole9/astro/blob/v2.1.0/lib/astro/lunar/crescent_visibility.ex#L1)

Implements three criteria for predicting the visibility of the new
crescent moon: Yallop (1997), Odeh (2006), and Schaefer (1988/2000).

All three functions accept a normalized location and a moment (midnight
UTC for the date of interest) and return `{:ok, visibility}` where
`visibility` is one of `:A`, `:B`, `:C`, `:D`, or `:E`.

## Yallop (1997)

An empirical single-parameter criterion based on the **geocentric**
arc of vision (ARCV) and crescent width (W). The q-value is the
scaled residual between the observed ARCV and a cubic polynomial
fit to Bruin's (1977) visibility curves:

    ARCV' = 11.8371 − 6.3226·W + 0.7319·W² − 0.1018·W³
    q = (ARCV − ARCV') / 10

## Odeh (2006)

An updated empirical criterion using the same polynomial family as
Yallop but fitted to 737 observations (vs Yallop's 295). Uses
**topocentric** ARCV and a different intercept:

    ARCV' = 7.1651 − 6.3226·W + 0.7319·W² − 0.1018·W³
    V = ARCV − ARCV'

Odeh also enforces a Danjon limit of 6.4° (ARCL < 6.4° → not visible).

## Schaefer (1988/2000)

A physics-based model that computes the contrast between the crescent
moon's brightness and the twilight sky brightness, then compares
against the human contrast detection threshold (Blackwell 1946). The
best observation time is found by scanning from sunset to moonset.

The visibility parameter is:

    Rs = log₁₀(contrast / threshold)

where Rs > 0 means the crescent is detectable. This implementation
uses the V-band sky brightness model from Schaefer (1993) with
default atmospheric parameters suitable for a sea-level site with
clean air.

## Visibility categories

| Code | Meaning                           |
|------|-----------------------------------|
| `:A` | Visible to the naked eye          |
| `:B` | Visible with optical aid          |
| `:C` | May need optical aid              |
| `:D` | Not visible with optical aid      |
| `:E` | Not visible                       |

## References

* Yallop, B. D. (1997). *A Method for Predicting the First Sighting
  of the New Crescent Moon*. NAO Technical Note No. 69.

* Odeh, M. Sh. (2004). *New Criterion for Lunar Crescent Visibility*.
  Experimental Astronomy, 18, 39–64.

* Schaefer, B. E. (1993). *Astronomy and the Limits of Vision*.
  Vistas in Astronomy, 36, 311–361.

* Schaefer, B. E. (2000). *New Methods and Techniques for Historical
  Astronomy and Archaeoastronomy*. Archaeoastronomy, XV, 121–136.

# `visibility`

```elixir
@type visibility() :: :A | :B | :C | :D | :E
```

# `odeh_new_visible_crescent`

```elixir
@spec odeh_new_visible_crescent(Geo.PointZ.t(), Astro.Time.moment()) ::
  {:ok, visibility()} | {:error, atom()}
```

Computes the Odeh (2006) visibility criterion for the new crescent moon.

Uses topocentric ARCV, the same polynomial family as Yallop with an
updated intercept (7.1651), and enforces a Danjon limit of 6.4°.

### Arguments

* `location` is a `t:Geo.PointZ.t/0` struct (already normalized).

* `moment` is a `t:Astro.Time.moment/0` representing the date.

### Returns

* `{:ok, visibility}` where `visibility` is one of `:A`, `:B`, `:C`, `:D`, or `:E`.

* `{:error, :no_sunset}` if sunset cannot be computed.

# `schaefer_new_visible_crescent`

```elixir
@spec schaefer_new_visible_crescent(Geo.PointZ.t(), Astro.Time.moment(), keyword()) ::
  {:ok, visibility()} | {:error, atom()}
```

Computes the Schaefer (1988/2000) visibility criterion for the new
crescent moon.

This physics-based model computes the contrast between the crescent
moon's brightness and the twilight sky brightness, comparing against
the human contrast detection threshold. The best observation time is
found by scanning from sunset to moonset.

### Arguments

* `location` is a `t:Geo.PointZ.t/0` struct (already normalized).

* `moment` is a `t:Astro.Time.moment/0` representing the date.

* `options` is a keyword list of optional atmospheric parameters:

  * `:extinction` — V-band zenith extinction coefficient. Default `0.172`
    (clean sea-level site). Typical values: 0.12 (high mountain),
    0.17 (sea level), 0.25 (hazy).

### Returns

* `{:ok, visibility}` where `visibility` is one of `:A`, `:B`, `:C`, `:D`, or `:E`.

* `{:error, :no_sunset}` if sunset cannot be computed.

# `yallop_new_visible_crescent`

```elixir
@spec yallop_new_visible_crescent(Geo.PointZ.t(), Astro.Time.moment()) ::
  {:ok, visibility()} | {:error, atom()}
```

Computes the Yallop (1997) visibility criterion for the new crescent moon.

Uses geocentric ARCV and the polynomial fit to Bruin's visibility curves.

### Arguments

* `location` is a `t:Geo.PointZ.t/0` struct (already normalized).

* `moment` is a `t:Astro.Time.moment/0` representing the date.

### Returns

* `{:ok, visibility}` where `visibility` is one of `:A`, `:B`, `:C`, `:D`, or `:E`.

* `{:error, :no_sunset}` if sunset cannot be computed.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
