# Tile-activity classification


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L70"
target="_blank" style="float:right; font-size:smaller">source</a>

### ClassifyConfig

``` python

def ClassifyConfig(
    delta_bic:float=10.0, min_tiles:int=20, frac_zero_high:float=0.85, frac_zero_low:float=0.15, random_state:int=42,
    global_threshold:float | None=None
)->None:

```

*Decision thresholds for the per-obsid classifier.*

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L62"
target="_blank" style="float:right; font-size:smaller">source</a>

### Pattern

``` python

def Pattern(
    args:VAR_POSITIONAL, kwds:VAR_KEYWORD
):

```

*Classification of an obsid’s tile-count distribution.*

## Data loading

Defaults to the public v3.1 fan/blotch parquets via `p4tools.io`. The
per-tile coverage CSV is external and supplied as an explicit path.

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L110"
target="_blank" style="float:right; font-size:smaller">source</a>

### load_v3p1_data

``` python

def load_v3p1_data(
    coverage_csv:str | pathlib.Path, # Path to a CSV with columns ``[obsid, tile_id, Coverage]``
(e.g. ``FnotchCoverage_Full_v3.1.csv``).
    version:str='v3.1', # Catalog version forwarded to ``p4tools.io.get_*_catalog``.
    fan:pandas.DataFrame | None=None, blotch:pandas.DataFrame | None=None
)->P4Data:

```

*Load the v3.1 fan, blotch, and per-tile coverage frames.*

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L103"
target="_blank" style="float:right; font-size:smaller">source</a>

### P4Data

``` python

def P4Data(
    fan:DataFrame, blotch:DataFrame, coverage:DataFrame
)->None:

```

*Container for the three v3.1 dataframes used by this module.*

## Per-tile marking counts

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L153"
target="_blank" style="float:right; font-size:smaller">source</a>

### count_markings_per_tile

``` python

def count_markings_per_tile(
    data:P4Data
)->DataFrame:

```

*One row per (obsid, tile_id) with total marking counts.*

Tiles present in `data.coverage` but absent from the catalogs appear
with `n_markings = 0`. Returned columns:
`[obsid, tile_id, n_fans, n_blotches, n_markings, Coverage]`.

## Per-obsid classification

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L218"
target="_blank" style="float:right; font-size:smaller">source</a>

### classify_obsid

``` python

def classify_obsid(
    counts:ndarray, obsid:str='',
    config:ClassifyConfig=ClassifyConfig(delta_bic=10.0, min_tiles=20, frac_zero_high=0.85, frac_zero_low=0.15, random_state=42, global_threshold=None),
    global_threshold:float | None=None
)->ObsidClassification:

```

*Classify one obsid’s tile-count distribution.*

`global_threshold` overrides `config.global_threshold` for the
forced-unimodal small-obsid path.

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L172"
target="_blank" style="float:right; font-size:smaller">source</a>

### ObsidClassification

``` python

def ObsidClassification(
    obsid:str, pattern:Pattern, n_tiles:int, frac_zero:float, mean_count:float, bic1:float, bic2:float,
    cluster_means:tuple[float, float] | None, busy_mask:ndarray
)->None:

```

*Result of classifying a single HiRISE observation’s tile distribution.*

## All-obsid classification

First pass: classify every obsid; gather bimodal split-points to learn
the global threshold T. Second pass: only the small-obsid
forced-unimodal entries are re-classified with T.

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L290"
target="_blank" style="float:right; font-size:smaller">source</a>

### classify_all

``` python

def classify_all(
    tile_counts:DataFrame,
    config:ClassifyConfig=ClassifyConfig(delta_bic=10.0, min_tiles=20, frac_zero_high=0.85, frac_zero_low=0.15, random_state=42, global_threshold=None)
)->tuple: # ``[obsid, tile_id, n_fans, n_blotches, n_markings, Coverage,
pattern, busy]``.

```

*Classify every obsid and label every tile.*

## Coverage on busy tiles

Vectorised aggregation across the cap (no Python-level loop over
obsids).

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L388"
target="_blank" style="float:right; font-size:smaller">source</a>

### summary

``` python

def summary(
    labeled:DataFrame, params:dict
)->dict:

```

*Cap-wide one-line summary suitable for printing or logging.*

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L357"
target="_blank" style="float:right; font-size:smaller">source</a>

### coverage_on_busy

``` python

def coverage_on_busy(
    labeled:DataFrame
)->DataFrame:

```

*Per-obsid coverage statistics, split by busy/quiet.*

## CLI

End-to-end pipeline writing per-tile labels and per-obsid summary CSVs.

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L430"
target="_blank" style="float:right; font-size:smaller">source</a>

### main

``` python

def main(
    
)->None: # pragma: no cover

```

*CLI entry; prints the cap-wide summary.*

------------------------------------------------------------------------

<a
href="https://github.com/michaelaye/p4tools/blob/main/p4tools/classify_by_activity.py#L407"
target="_blank" style="float:right; font-size:smaller">source</a>

### run_pipeline

``` python

def run_pipeline(
    coverage_csv:str | pathlib.Path, out_dir:str | pathlib.Path='outputs',
    config:ClassifyConfig=ClassifyConfig(delta_bic=10.0, min_tiles=20, frac_zero_high=0.85, frac_zero_low=0.15, random_state=42, global_threshold=None),
    version:str='v3.1'
)->dict:

```

*Run the full classification pipeline and write CSVs to `out_dir`.*

------------------------------------------------------------------------

Manual entry point so
`python -m p4tools.classify_by_activity --coverage-csv ...` works:
