# fantiflex/ulm26 architecture

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

- Interactive diagram: https://gitdiagram.com/fantiflex/ulm26
- Repository: https://github.com/fantiflex/ulm26

## Overview

Minority Estimation combines a reproducible stimulus-preparation pipeline with three browser-based study conditions. The main workflow audits CFD metadata, selects and age-matches face stimuli, extracts face regions and luminance, then generates paired face and grayscale-circle matrices for participant estimation trials. The README documents the study conditions and processing stages; source excerpts show selected pipeline calls and shared utilities. Some matrix-to-experiment wiring is documented but the generated-matrix directory is absent from the supplied tree, so that connection is based on the README.

Main entry points: [`scripts/stimulus_preparation/04_generate_matrices.py`](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/04_generate_matrices.py) (Paired Matrix Generation), [`scripts/stimulus_preparation/03_extract_faces.py`](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/03_extract_faces.py) (Face Extraction), [`scripts/stimulus_preparation/02_build_stimuli.py`](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/02_build_stimuli.py) (Stimulus Selection), [`src/minority_estimation/cfd_manifest.py`](https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/cfd_manifest.py) (Manifest Harmonization)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_curation["Metadata Curation"]
  node_manifest_audit["CFD Audit"]
  node_manifest_lib["Manifest Harmonization<br/>[cfd_manifest.py]"]
  node_stimuli_build["Stimulus Selection"]
  node_stimuli_lib["Image Matching and Filtering<br/>[stimuli.py]"]
  node_validation["Stimulus Validation<br/>[validation.py]"]
  node_age_match["Age Matching"]
  node_qc["Stimulus QC"]
end

subgraph group_stimuli["Stimulus Engineering"]
  node_face_extract["Face Extraction"]
  node_area_calibration["Face Area Calibration"]
  node_luminance_analysis["Luminance Analysis"]
  node_matrix_generation["Paired Matrix Generation"]
end

subgraph group_study["Study Delivery"]
  node_mixed["Mixed Condition<br/>[script.js]"]
  node_social["Social-only Condition<br/>[script.js]"]
  node_nonsocial["Non-social Condition<br/>[script.js]"]
end

subgraph group_shared["Shared Pipeline"]
  node_face_crop["Face Crop Utility"]
  node_config["Study Configuration<br/>[config.py]"]
  node_schemas["Data Schemas<br/>[schemas.py]"]
end

node_researcher(("Study Participant"))

node_manifest_audit -->|"loads and harmonizes"| node_manifest_lib
node_manifest_lib -->|"checks columns"| node_schemas
node_stimuli_build -->|"loads metadata"| node_manifest_lib
node_stimuli_build -->|"builds selection"| node_stimuli_lib
node_stimuli_build -->|"validates stimuli"| node_validation
node_stimuli_lib -->|"requires columns"| node_schemas
node_validation -->|"requires columns"| node_schemas
node_manifest_audit -.->|"produces audit inputs"| node_qc
node_age_match -->|"selects final set"| node_face_extract
node_face_extract -->|"uses crop settings"| node_face_crop
node_face_extract -->|"uses processing settings"| node_config
node_face_extract -.->|"measures face regions"| node_area_calibration
node_face_extract -.->|"records luminance"| node_luminance_analysis
node_matrix_generation -->|"uses crop utility"| node_face_crop
node_matrix_generation -->|"uses matrix settings"| node_config
node_matrix_generation -.->|"uses calibrated size"| node_area_calibration
node_matrix_generation -.->|"uses face luminance"| node_luminance_analysis
node_matrix_generation -->|"supplies shared matrices"| node_mixed
node_matrix_generation -->|"supplies face matrices"| node_social
node_matrix_generation -->|"supplies circle matrices"| node_nonsocial
node_researcher -->|"completes condition"| node_mixed
node_researcher -->|"completes condition"| node_social
node_researcher -->|"completes condition"| node_nonsocial

click node_manifest_audit "https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/01_audit_cfd_manifest.py"
click node_manifest_lib "https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/cfd_manifest.py"
click node_stimuli_build "https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/02_build_stimuli.py"
click node_stimuli_lib "https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/stimuli.py"
click node_validation "https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/validation.py"
click node_age_match "https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/02b_age_match_stimuli.py"
click node_face_extract "https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/03_extract_faces.py"
click node_face_crop "https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/image_processing.py"
click node_area_calibration "https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/03b_analyze_face_area.py"
click node_luminance_analysis "https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/03c_analyze_mean_luminance.py"
click node_matrix_generation "https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/04_generate_matrices.py"
click node_config "https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/config.py"
click node_schemas "https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/schemas.py"
click node_qc "https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/02c_plot_stimulus_qc.py"
click node_mixed "https://github.com/fantiflex/ulm26/blob/main/experiment/mixed/script.js"
click node_social "https://github.com/fantiflex/ulm26/blob/main/experiment/social_only/script.js"
click node_nonsocial "https://github.com/fantiflex/ulm26/blob/main/experiment/nonsocial_only/script.js"

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_manifest_audit,node_manifest_lib,node_stimuli_build,node_stimuli_lib,node_validation,node_age_match,node_qc toneBlue
class node_face_extract,node_area_calibration,node_luminance_analysis,node_matrix_generation toneAmber
class node_mixed,node_social,node_nonsocial toneMint
class node_face_crop,node_config,node_schemas toneRose
class node_researcher toneIndigo
```

## Components

### Metadata Curation

- [CFD Audit](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/01_audit_cfd_manifest.py): `scripts/stimulus_preparation/01_audit_cfd_manifest.py`
- [Manifest Harmonization](https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/cfd_manifest.py): `src/minority_estimation/cfd_manifest.py`
- [Stimulus Selection](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/02_build_stimuli.py): `scripts/stimulus_preparation/02_build_stimuli.py`
- [Image Matching and Filtering](https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/stimuli.py): `src/minority_estimation/stimuli.py`
- [Stimulus Validation](https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/validation.py): `src/minority_estimation/validation.py`
- [Age Matching](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/02b_age_match_stimuli.py): `scripts/stimulus_preparation/02b_age_match_stimuli.py`
- [Stimulus QC](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/02c_plot_stimulus_qc.py): `scripts/stimulus_preparation/02c_plot_stimulus_qc.py`

### Stimulus Engineering

- [Face Extraction](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/03_extract_faces.py): `scripts/stimulus_preparation/03_extract_faces.py`
- [Face Area Calibration](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/03b_analyze_face_area.py): `scripts/stimulus_preparation/03b_analyze_face_area.py`
- [Luminance Analysis](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/03c_analyze_mean_luminance.py): `scripts/stimulus_preparation/03c_analyze_mean_luminance.py`
- [Paired Matrix Generation](https://github.com/fantiflex/ulm26/blob/main/scripts/stimulus_preparation/04_generate_matrices.py): `scripts/stimulus_preparation/04_generate_matrices.py`

### Study Delivery

- [Mixed Condition](https://github.com/fantiflex/ulm26/blob/main/experiment/mixed/script.js): `experiment/mixed/script.js`
- [Social-only Condition](https://github.com/fantiflex/ulm26/blob/main/experiment/social_only/script.js): `experiment/social_only/script.js`
- [Non-social Condition](https://github.com/fantiflex/ulm26/blob/main/experiment/nonsocial_only/script.js): `experiment/nonsocial_only/script.js`

### Shared Pipeline

- [Face Crop Utility](https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/image_processing.py): `src/minority_estimation/image_processing.py`
- [Study Configuration](https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/config.py): `src/minority_estimation/config.py`
- [Data Schemas](https://github.com/fantiflex/ulm26/blob/main/src/minority_estimation/schemas.py): `src/minority_estimation/schemas.py`

### Other components

- **Study Participant**

## Connections

- CFD Audit → Manifest Harmonization: loads and harmonizes (evidence: `scripts/stimulus_preparation/01_audit_cfd_manifest.py`)
- Manifest Harmonization → Data Schemas: checks columns (evidence: `src/minority_estimation/cfd_manifest.py`)
- Stimulus Selection → Manifest Harmonization: loads metadata (evidence: `scripts/stimulus_preparation/02_build_stimuli.py`)
- Stimulus Selection → Image Matching and Filtering: builds selection (evidence: `scripts/stimulus_preparation/02_build_stimuli.py`)
- Stimulus Selection → Stimulus Validation: validates stimuli (evidence: `scripts/stimulus_preparation/02_build_stimuli.py`)
- Image Matching and Filtering → Data Schemas: requires columns (evidence: `src/minority_estimation/stimuli.py`)
- Stimulus Validation → Data Schemas: requires columns (evidence: `src/minority_estimation/validation.py`)
- CFD Audit → Stimulus QC: produces audit inputs
- Age Matching → Face Extraction: selects final set (evidence: `README.md`)
- Face Extraction → Face Crop Utility: uses crop settings (evidence: `scripts/stimulus_preparation/03_extract_faces.py`)
- Face Extraction → Study Configuration: uses processing settings (evidence: `scripts/stimulus_preparation/03_extract_faces.py`)
- Face Extraction → Face Area Calibration: measures face regions
- Face Extraction → Luminance Analysis: records luminance
- Paired Matrix Generation → Face Crop Utility: uses crop utility (evidence: `scripts/stimulus_preparation/04_generate_matrices.py`)
- Paired Matrix Generation → Study Configuration: uses matrix settings (evidence: `scripts/stimulus_preparation/04_generate_matrices.py`)
- Paired Matrix Generation → Face Area Calibration: uses calibrated size (evidence: `README.md`)
- Paired Matrix Generation → Luminance Analysis: uses face luminance (evidence: `README.md`)
- Paired Matrix Generation → Mixed Condition: supplies shared matrices (evidence: `README.md`)
- Paired Matrix Generation → Social-only Condition: supplies face matrices (evidence: `README.md`)
- Paired Matrix Generation → Non-social Condition: supplies circle matrices (evidence: `README.md`)
- Study Participant → Mixed Condition: completes condition (evidence: `README.md`)
- Study Participant → Social-only Condition: completes condition (evidence: `README.md`)
- Study Participant → Non-social Condition: completes condition (evidence: `README.md`)
