# Evaluation

Use `test` to compute configured losses and metrics, `infer` to visualize predictions, and `annotate` to turn predictions into a
LuxonisDataset.

The examples use a LuxonisTrain checkpoint containing its configuration and dataset metadata. To supply configuration separately,
add `--config config.yaml` in the CLI or pass `"config.yaml"` as the first argument to `LuxonisModel`. Pass checkpoint weights to
the Python constructor so their metadata is available when the model is built.

## Testing

Testing evaluates the losses and metrics attached to the model's nodes. Select `train`, `val`, or `test` with `--view`; the
default is `test`. These names refer to the views configured in `loader`, so the corresponding dataset must be available.

### CLI

```bash
luxonis_train test --weights path/to/checkpoint.ckpt --view val
```

### Python API

```python
from luxonis_train import LuxonisModel

model = LuxonisModel(weights="path/to/checkpoint.ckpt")
metrics = model.test(view="val")
print(metrics)
```

The synchronous Python call returns a mapping of logged values. Metric keys use the `test/` prefix for every selected view.
Results are sent to the configured [tracking
backends](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/training.md).

`test()` finalizes the tracked run by default. If you continue that run with another operation, pass `finalize_tracker=False` and
call `model.finalize_run()` when finished.

`TestOnTrainEnd` evaluates a checkpoint after training. It selects the best main-metric checkpoint, falling back to the checkpoint
with the lowest validation loss. Automatic configuration adds this callback unless an entry with that name is already configured.

## Inference

`infer` runs the model and renders predictions through its attached visualizers. Without `save_dir`, it opens visualization
windows; press a key to advance, or `q` or `Esc` to stop. Set `--save-dir` to write results to disk, including when running
without a graphical display.

### Dataset View

```bash
luxonis_train infer \
  --weights path/to/checkpoint.ckpt \
  --view val \
  --save-dir predictions
```

The default inference view is `val`. Dataset inference requires a working loader for the selected view.

### Images and Videos

Use `--source-path` for a single image, a directory of images, or a video file:

```bash
luxonis_train infer \
  --weights path/to/checkpoint.ckpt \
  --source-path path/to/images \
  --save-dir predictions
```

Replace `path/to/images` with an image such as `path/to/image.jpg` or a video such as `path/to/video.mp4`. A directory contributes
image files directly inside it; subdirectories are not traversed. Visualizations are saved as PNG images or MP4 videos.

Image and directory inference can use checkpoint metadata without the original dataset. Video inference requires a working
validation loader because it uses that loader's image preprocessing.

### Python API

```python
from luxonis_train import LuxonisModel

model = LuxonisModel(
    weights="path/to/checkpoint.ckpt",
    allow_empty_dataset=True,
)
model.infer(source_path="path/to/images", save_dir="predictions")
```

`allow_empty_dataset=True` lets a dummy loader stand in when the dataset cannot be loaded. It is suitable for this image-directory
example; it does not supply real samples for dataset inference or the preprocessing needed for video inference.

## Annotation

`annotate` predicts labels for images directly inside a directory and writes them to a named LuxonisDataset. The output heads must
support annotation for their tasks.

### CLI

```bash
luxonis_train annotate \
  --weights path/to/checkpoint.ckpt \
  --dir-path path/to/images \
  --dataset-name annotated_dataset
```

### Python API

```python
from luxonis_train import LuxonisModel

model = LuxonisModel(
    weights="path/to/checkpoint.ckpt",
    allow_empty_dataset=True,
)
dataset = model.annotate(
    dir_path="path/to/images",
    dataset_name="annotated_dataset",
)
```

The method returns a `LuxonisDataset`. A non-empty result receives train, validation, and test splits in an 80/10/10 ratio. Review
the generated labels before using them for training. Annotation supports `bucket_storage="local"` or `"gcs"`.

> **Note**
> Annotation deletes an existing dataset with the target name by default, including its remote copy. Use a new dataset name, or set both `delete_local=False` and `delete_remote=False` in Python to preserve an existing dataset and add records. The CLI equivalents are `--no-delete-local --no-delete-remote`.

Image-directory inference and annotation also use the temporary local dataset name `infer_from_directory`. They replace any
existing local dataset of that name and remove the temporary dataset afterwards; reserve that name for these operations.
