geeViz.fsInsights.vocab

Cached, searchable vocabularies for the FIA and LCMS APIs.

FIADB-API’s /fullreport takes an estimate attribute, a row grouping, a column grouping, and an evaluation. Live counts, measured against the API:

That is a combinatorial space no one memorizes, and the published docs still say “This page is under construction”. Nothing in the official documentation mentions that the parameter endpoints accept outputFormat=JSON — but they do, and that is what makes discovery possible at all: the entire vocabulary is machine-readable, ~1.4 MB total, and changes per release rather than per query.

So it is cached, and search runs locally. The caching policy mirrors the MCP dataset catalog’s — bundled snapshot, user cache, ~30-day stale-while-revalidate — for the practical reason that one caching idea in a codebase is easier to reason about than two.

Failure is always backward, never forward. A vocabulary lookup falls from user cache, to bundled snapshot, to an empty result — it does not raise, and it does not block on the network. Discovery is what people do before they know what they want; making it fragile makes the whole subpackage feel fragile.

Module Attributes

FIA_CATALOGS

FIA parameter catalogs, by the query-parameter name they populate.

FIA_CATALOG_ALIASES

Aliases onto the three fetched catalogs.

CACHE_TTL_SECONDS

Refresh interval.

Functions

cache_dir()

Directory for refreshed catalogs.

describe_grouping(label)

Prose documentation for a grouping variable, codes included.

find_attributes([query, land_basis, ...])

Search the 752 FIA estimate attributes.

find_evaluations([state, most_recent, ...])

Search the 1,129 FIA evaluations.

find_groupings([query, limit])

Search the 96 FIA grouping variables.

get_attribute(snum)

Full record for one attribute number, or None.

get_evaluation(wc)

Full record for one evaluation group, or None.

load_catalog(name, *[, refresh])

Return one vocabulary, from memory, cache, bundle, or the network.

refresh_all(*[, quiet])

Force-refresh every catalog.

geeViz.fsInsights.vocab.FIA_CATALOGS = ('snum', 'rselected', 'wc')

FIA parameter catalogs, by the query-parameter name they populate. sdenom shares snum’s vocabulary and cselected/pselected share rselected’s, so only the distinct ones are fetched.

geeViz.fsInsights.vocab.FIA_CATALOG_ALIASES = {'cselected': 'rselected', 'pselected': 'rselected', 'sdenom': 'snum'}

Aliases onto the three fetched catalogs.

geeViz.fsInsights.vocab.CACHE_TTL_SECONDS = 2592000

Refresh interval. These change when FIA publishes a new evaluation cycle or LCMS cuts a release — an annual-ish cadence — so 30 days is frequent enough to pick changes up well before anyone notices, and rare enough that the network is essentially never on the hot path.

geeViz.fsInsights.vocab.cache_dir() → Path[source]

Directory for refreshed catalogs.

Sits alongside the workload-tag store under ~/.geeViz so geeViz keeps exactly one place where it writes user state. Overridable with GEEVIZ_FSINSIGHTS_CACHE for tests and for locked-down machines where the home directory is not writable.

geeViz.fsInsights.vocab.load_catalog(name: str, *, refresh: bool = False) → List[dict][source]

Return one vocabulary, from memory, cache, bundle, or the network.

Parameters:
  • name – A catalog or alias — any of snum, sdenom, rselected, cselected, pselected, wc.

  • refresh – Force a network fetch, ignoring TTL. Still falls back to cached data if the fetch fails.

Returns:

List of records. Empty only when every source failed, which means discovery degrades rather than breaking.

geeViz.fsInsights.vocab.refresh_all(*, quiet: bool = False) → Dict[str, int][source]

Force-refresh every catalog. Returns {name: record_count}.

The escape hatch for “a new release just dropped and I do not want to wait out the TTL”. Normal use should never need it.

geeViz.fsInsights.vocab.find_attributes(query: str = '', *, land_basis: str = '', eval_typ: str = '', limit: int = 25) → Any[source]

Search the 752 FIA estimate attributes.

Parameters:
  • query – Free text matched against description and group, e.g. "carbon", "net growth volume", "mortality".

  • land_basis – Restrict to "Forest land" or "Timberland".

  • eval_typ – Restrict to an evaluation type — EXPCURR, EXPVOL, EXPGROW, EXPMORT, EXPREMV, EXPCHNG, EXPDWM.

  • limit – Maximum rows returned.

Returns:

A pandas.DataFrame with the columns that matter for choosing an attribute — number, description, units, and the evaluation type it requires. The full record is available via get_attribute().

Note

FIA’s own catalog contains duplicate descriptions — 7 of the 752 appear more than once. snum 209 and 956, for instance, are identical across description, estimate group, evaluation type, estimation basis and tree portion. Both are returned rather than silently de-duplicated, because they are distinct attribute numbers upstream and collapsing them would hide a real property of the catalog. Where descriptions match on every field, either number should produce the same estimate.

geeViz.fsInsights.vocab.get_attribute(snum: int) → dict | None[source]

Full record for one attribute number, or None.

geeViz.fsInsights.vocab.find_groupings(query: str = '', *, limit: int = 25) → Any[source]

Search the 96 FIA grouping variables.

These are what rselected / cselected / pselected accept, and they are passed as display strings — so the exact label in this result is what the query needs, character for character.

geeViz.fsInsights.vocab.describe_grouping(label: str) → str[source]

Prose documentation for a grouping variable, codes included.

FIA ships this as PRC_METADATA — an HTML fragment that usually enumerates what each code value means. It is the difference between a column of integers and a column you can interpret, so it is worth surfacing rather than leaving buried in the catalog.

geeViz.fsInsights.vocab.find_evaluations(state: str = '', *, most_recent: bool = True, growth_only: bool = False, limit: int = 25) → Any[source]

Search the 1,129 FIA evaluations.

Parameters:
  • state – State name, matched case-insensitively on a prefix.

  • most_recent – Keep only each state’s current evaluation. Almost always what you want; set False to see the back catalog.

  • growth_only – Keep only evaluations with growth accounting (GROWTH_ACCT == 'Y'), which is a prerequisite for every growth, removals, and mortality attribute.

  • limit – Maximum rows returned.

geeViz.fsInsights.vocab.get_evaluation(wc: int) → dict | None[source]

Full record for one evaluation group, or None.