# ljiro/soilscan architecture

> Architecture diagram of the GitHub repository ljiro/soilscan, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-10-03). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ljiro/soilscan
- Repository: https://github.com/ljiro/soilscan

## Overview

SoilScan combines a mobile soil-analysis app with a Python NPK model-training and analysis pipeline. The user-facing flow is photo capture or upload, model inference, then a soil classification and fertilizer guidance; the README describes the inference backend as Hugging Face Spaces, while this tree contains only selected app screens, not that backend or the classifier screen implementation. The training flow covers configured data preparation, model fitting, evaluation, and embedding-similarity analysis. Edges involving unsampled app behavior rely on README statements; code-level links use the shown source excerpts or SOURCE INDEX.

Main entry points: [`train/config.py`](https://github.com/ljiro/soilscan/blob/main/train/config.py) (Experiment config), [`train/dataset.py`](https://github.com/ljiro/soilscan/blob/main/train/dataset.py) (Dataset preparation), [`train/model.py`](https://github.com/ljiro/soilscan/blob/main/train/model.py) (Model architectures), [`train/train.py`](https://github.com/ljiro/soilscan/blob/main/train/train.py) (Model training)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_mobile["Mobile app"]
  node_scan["Soil scanner"]
  node_fertilizer["Fertilizer guidance"]
  node_guide["Soil guide<br/>[GuideScreen.js]"]
end

subgraph group_training["Training pipeline"]
  node_datamaps[("UUID label maps")]
  node_dataset["Dataset preparation<br/>[dataset.py]"]
  node_model["Model architectures<br/>[model.py]"]
  node_trainer["Model training<br/>[train.py]"]
  node_metrics["Training metrics<br/>[metrics.py]"]
end

subgraph group_analysis["Model analysis"]
  node_inference["Batch inference<br/>[inference.py]"]
  node_evaluation["Checkpoint evaluation<br/>[evaluate.py]"]
  node_similarity["Embedding similarity"]
  node_combo["NPK combo similarity"]
end

subgraph group_settings["Experiment setup"]
  node_config["Experiment config<br/>[config.py]"]
  node_experiments["Experiment presets"]
end

node_farmer(("SoilScan user"))
node_backend{{"Inference backend"}}

node_farmer -->|"submits soil photo"| node_scan
node_scan -->|"requests inference"| node_backend
node_backend -->|"returns classification"| node_scan
node_scan -.->|"opens guidance"| node_fertilizer
node_farmer -->|"enters field values"| node_fertilizer
node_farmer -.->|"views guidance"| node_guide
node_datamaps -.->|"provides labels"| node_dataset
node_config -->|"configures loading"| node_dataset
node_config -->|"configures model"| node_model
node_dataset -->|"builds loaders"| node_trainer
node_model -->|"builds network"| node_trainer
node_trainer -->|"computes metrics"| node_metrics
node_config -->|"sets run parameters"| node_trainer
node_config -->|"configures prediction"| node_inference
node_dataset -->|"supplies transforms"| node_inference
node_model -->|"builds predictor"| node_inference
node_config -->|"configures evaluation"| node_evaluation
node_dataset -->|"builds test loader"| node_evaluation
node_model -->|"builds evaluation model"| node_evaluation
node_trainer -.->|"provides checkpoint"| node_evaluation
node_metrics -->|"scores predictions"| node_evaluation
node_config -->|"configures analysis"| node_similarity
node_dataset -->|"supplies samples"| node_similarity
node_model -->|"extracts embeddings"| node_similarity
node_config -->|"configures analysis"| node_combo
node_dataset -->|"supplies samples"| node_combo
node_model -->|"extracts embeddings"| node_combo
node_experiments -.->|"provides presets"| node_config

click node_scan "https://github.com/ljiro/soilscan/tree/main/SoilScan/screens"
click node_fertilizer "https://github.com/ljiro/soilscan/blob/main/SoilScan/screens/FertilizerRecommendationScreen.js"
click node_guide "https://github.com/ljiro/soilscan/blob/main/SoilScan/screens/GuideScreen.js"
click node_datamaps "https://github.com/ljiro/soilscan/tree/main/datamaps"
click node_dataset "https://github.com/ljiro/soilscan/blob/main/train/dataset.py"
click node_model "https://github.com/ljiro/soilscan/blob/main/train/model.py"
click node_trainer "https://github.com/ljiro/soilscan/blob/main/train/train.py"
click node_metrics "https://github.com/ljiro/soilscan/blob/main/train/metrics.py"
click node_inference "https://github.com/ljiro/soilscan/blob/main/train/inference.py"
click node_evaluation "https://github.com/ljiro/soilscan/blob/main/train/evaluate.py"
click node_similarity "https://github.com/ljiro/soilscan/blob/main/train/similarity_matrix.py"
click node_combo "https://github.com/ljiro/soilscan/blob/main/train/combo_similarity.py"
click node_config "https://github.com/ljiro/soilscan/blob/main/train/config.py"
click node_experiments "https://github.com/ljiro/soilscan/tree/main/experiments"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_scan,node_fertilizer,node_guide,node_farmer toneBlue
class node_datamaps,node_dataset,node_model,node_trainer,node_metrics toneAmber
class node_inference,node_evaluation,node_similarity,node_combo toneMint
class node_config,node_experiments toneRose
class node_backend toneIndigo
```

## Components

### Mobile app

- [Soil scanner](https://github.com/ljiro/soilscan/tree/main/SoilScan/screens): `SoilScan/screens`
- [Fertilizer guidance](https://github.com/ljiro/soilscan/blob/main/SoilScan/screens/FertilizerRecommendationScreen.js): `SoilScan/screens/FertilizerRecommendationScreen.js`
- [Soil guide](https://github.com/ljiro/soilscan/blob/main/SoilScan/screens/GuideScreen.js): `SoilScan/screens/GuideScreen.js`

### Training pipeline

- [UUID label maps](https://github.com/ljiro/soilscan/tree/main/datamaps): `datamaps`
- [Dataset preparation](https://github.com/ljiro/soilscan/blob/main/train/dataset.py): `train/dataset.py`
- [Model architectures](https://github.com/ljiro/soilscan/blob/main/train/model.py): `train/model.py`
- [Model training](https://github.com/ljiro/soilscan/blob/main/train/train.py): `train/train.py`
- [Training metrics](https://github.com/ljiro/soilscan/blob/main/train/metrics.py): `train/metrics.py`

### Model analysis

- [Batch inference](https://github.com/ljiro/soilscan/blob/main/train/inference.py): `train/inference.py`
- [Checkpoint evaluation](https://github.com/ljiro/soilscan/blob/main/train/evaluate.py): `train/evaluate.py`
- [Embedding similarity](https://github.com/ljiro/soilscan/blob/main/train/similarity_matrix.py): `train/similarity_matrix.py`
- [NPK combo similarity](https://github.com/ljiro/soilscan/blob/main/train/combo_similarity.py): `train/combo_similarity.py`

### Experiment setup

- [Experiment config](https://github.com/ljiro/soilscan/blob/main/train/config.py): `train/config.py`
- [Experiment presets](https://github.com/ljiro/soilscan/tree/main/experiments): `experiments`

### Other components

- **SoilScan user**
- **Inference backend**

## Connections

- SoilScan user → Soil scanner: submits soil photo (evidence: `README.md`)
- Soil scanner → Inference backend: requests inference (evidence: `README.md`)
- Inference backend → Soil scanner: returns classification (evidence: `README.md`)
- Soil scanner → Fertilizer guidance: opens guidance
- SoilScan user → Fertilizer guidance: enters field values (evidence: `README.md`)
- SoilScan user → Soil guide: views guidance
- UUID label maps → Dataset preparation: provides labels
- Experiment config → Dataset preparation: configures loading (evidence: `train/dataset.py`)
- Experiment config → Model architectures: configures model (evidence: `train/model.py`)
- Dataset preparation → Model training: builds loaders (evidence: `train/train.py`)
- Model architectures → Model training: builds network (evidence: `train/train.py`)
- Model training → Training metrics: computes metrics (evidence: `train/train.py`)
- Experiment config → Model training: sets run parameters (evidence: `train/train.py`)
- Experiment config → Batch inference: configures prediction (evidence: `train/inference.py`)
- Dataset preparation → Batch inference: supplies transforms (evidence: `train/inference.py`)
- Model architectures → Batch inference: builds predictor (evidence: `train/inference.py`)
- Experiment config → Checkpoint evaluation: configures evaluation (evidence: `train/evaluate.py`)
- Dataset preparation → Checkpoint evaluation: builds test loader (evidence: `train/evaluate.py`)
- Model architectures → Checkpoint evaluation: builds evaluation model (evidence: `train/evaluate.py`)
- Model training → Checkpoint evaluation: provides checkpoint (evidence: `train/evaluate.py`)
- Training metrics → Checkpoint evaluation: scores predictions (evidence: `train/evaluate.py`)
- Experiment config → Embedding similarity: configures analysis (evidence: `train/similarity_matrix.py`)
- Dataset preparation → Embedding similarity: supplies samples (evidence: `train/similarity_matrix.py`)
- Model architectures → Embedding similarity: extracts embeddings (evidence: `train/similarity_matrix.py`)
- Experiment config → NPK combo similarity: configures analysis (evidence: `train/combo_similarity.py`)
- Dataset preparation → NPK combo similarity: supplies samples (evidence: `train/combo_similarity.py`)
- Model architectures → NPK combo similarity: extracts embeddings (evidence: `train/combo_similarity.py`)
- Experiment presets → Experiment config: provides presets
