---
title: "Using a manually downloaded CIMIS CSV with TrackTrap"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Using a manually downloaded CIMIS CSV with TrackTrap}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
```

## When to use this

Use `weather_source = "cimis_csv"` to calculate degree-days from a
manually downloaded station report. This pathway works offline.

## 1. Prepare the daily report

Download daily maximum and minimum temperatures in Fahrenheit from
[CIMIS](https://cimis.water.ca.gov).

The CSV must contain columns that `read.csv()` reads as:

- `Date`
- `Max.Air.Temp..F.`
- `Min.Air.Temp..F.`

Provide one weather observation for every day from the first through
the last trap observation, including days without trap sampling.
Missing dates, missing temperatures, duplicate daily dates, and
minimum temperatures exceeding maxima cause an error.

## 2. Locate and inspect the example

The bundled example, `example_cimis_synthetic_daily.csv`, contains
synthetic daily temperatures in CIMIS-compatible format for
April 1–22, 2024. Daily maximum and minimum temperatures are fixed
at 85°F and 55°F, respectively. These values demonstrate the software
and do not represent observed station weather.

The file is stored in
`inst/extdata/example_cimis_synthetic_daily.csv` in the package source.

```{r}
library(TrackTrap)

example_path <- system.file(
  "extdata",
  "example_cimis_synthetic_daily.csv",
  package = "TrackTrap",
  mustWork = TRUE
)

example_weather <- read.csv(example_path)
names(example_weather)

expected_dates <- seq(
  as.Date("2024-04-01"),
  as.Date("2024-04-22"),
  by = "day"
)

weather_dates <- as.Date(example_weather$Date, format = "%m/%d/%Y")

stopifnot(
  !anyNA(weather_dates),
  !anyDuplicated(weather_dates),
  all(expected_dates %in% weather_dates)
)
```

`read.csv()` normally converts a header such as `Max Air Temp (F)`
to `Max.Air.Temp..F.`. Check the actual column names before calculation.

## 3. Date formats

TrackTrap accepts `YYYY-MM-DD`, `M/D/YYYY`, and
`MM/DD/YYYY` character dates. Trap dates can also be R `Date` objects.

Invalid or missing dates cause an error.

## 4. Calculate degree-days

This example uses an illustrative lower threshold of 50°F and
explicitly selects no upper cutoff. These settings demonstrate the
software; they are not a recommended parameter set for any particular pest.

For a biological application, select documented parameters and a
calculation method appropriate to the pest and developmental endpoint.

The bundled weather CSV must cover April 1–22, 2024, inclusive,
for this example to run.

```{r}
trap_df <- data.frame(
  date = as.Date(c(
    "2024-04-01",
    "2024-04-08",
    "2024-04-15",
    "2024-04-22"
  )),
  trap_counts = c(0, 0, 3, 9)
)

result <- calc_pest_phenology(
  trap_data = trap_df,
  pest = NULL,
  weather_source = "cimis_csv",
  cimis_csv_path = example_path,
  custom_lower = 50,
  upper_cutoff = "none",
  custom_pest_label = "Illustrative trap series",
  weather_provenance = list(
    data_type = "Synthetic demonstration data",
    temperature_units = "Fahrenheit",
    description = "Daily Tmax = 85 and Tmin = 55; not station observations."
  )
)
```

Biofix is the first positive trap count: April 15 in this example. Accumulation begins on April 16. Values in cumulative_dd_from_biofix are NA before biofix and zero on the biofix date. The separate cumulative_dd column records accumulation from the first trap observation date. With these synthetic temperatures and a lower threshold of 50°F, daily accumulation is 20°F-days, giving 140°F-days from biofix on April 22.

When using database parameters, supply `pest` with the relevant code.
A missing lower threshold requires `custom_lower`. A missing upper
threshold requires either `custom_upper` or an explicit
`upper_cutoff = "none"` choice.

To apply an upper threshold to the daily mean, use
`upper_cutoff = "horizontal"` with a finite upper threshold greater
than the lower threshold.

## 5. Station information

Station coordinates are not extracted from the CSV. Optional `lat`
and `lon` arguments supplied to `calc_pest_phenology()` are retained
for plot labelling; they do not change calculations using CSV weather.

Coordinates may also be supplied directly to `plot_trap_phenology()`.
Use the actual station or monitoring-location coordinates and clearly
identify which location they represent.

For observed CIMIS data, weather_provenance is optional but recommended. Supply the station identifier, download date, temperature units, and observation-day convention when available. The output also records the CSV filename and checksum. For this example, provenance identifies the temperatures as synthetic..

## 6. Plot the results

Plot trap catches against accumulated degree-days from first capture:

```{r, fig.width = 9, fig.height = 4.5}
plot_trap_phenology(result)
```

No thermal reference markers are displayed unless a thermal requirement
is supplied during calculation or plotting.

The following example adds an illustrative reference of 100°F-days.
This value demonstrates marker placement only; it is not a published
thermal requirement for a particular pest.

```{r, fig.width = 9, fig.height = 4.5}
plot_trap_phenology(
  result,
  custom_thermal_requirement = 100,
  repeat_markers = TRUE
)
```

When a thermal reference is supplied, the plot automatically adds:

- A subtitle showing its value in Fahrenheit degree-days.
- The developmental endpoint when the value matches the database
  reference retained during calculation; otherwise, the subtitle states
  "developmental endpoint not specified."
- A caption explaining the thermal reference.

In this synthetic example, no pest database record was selected, so
the developmental endpoint is unspecified.

Set `repeat_markers = TRUE` to display multiples of the reference value.
The default, `repeat_markers = FALSE`, displays a single reference marker.

Database thermal requirements are not automatically selected as markers.
Markers are positioned relative to first capture and do not independently
establish flight or generation identities. Matching a database value does
not establish that its original model is compatible with the selected
calculation method or first-capture biofix.

## 7. Inspect the daily calculations

The returned rows correspond to trap observation dates. Complete
daily weather and calculations are retained separately as attributes.

```{r}
daily_calculations <- attr(result, "daily_weather")
calculation_metadata <- attr(result, "calculation_metadata")

head(daily_calculations)
calculation_metadata$biofix_date
calculation_metadata$upper_cutoff
calculation_metadata$accumulation_start
calculation_metadata$weather_provenance
```
