# FlyFace FlyFace presents human face images to an experimental simulation of the male fruit-fly connectome and reports the resulting neural responses. ![Robust orientation response matrix](docs/assets/robust-orientation-heatmap.png) The current prototype has a reproducible image-to-neural-response pipeline. Its playful A/B output is called a preference, while the structured results retain each neural measurement and explicitly mark the DNa02 orientation readout as unvalidated. Current experiments show image-specific responses, with no global human-like or inverse attractiveness ranking. ## Install FlyFace requires Python 3.11+, a C++17 compiler, several GB of free disk space, and about 16 GB of RAM for the full model. ```bash python3.12 -m venv .venv source .venv/bin/activate pip install -e '.[neural,datasets,test]' python -m flyface prepare python -m flyface dataset prepare ``` `prepare` downloads about 1.1 GB of checksum-verified MaleCNS v1.0 source data, builds the retained graph, and verifies the compiled arrays. The dataset command downloads the 172 MB SCUT-FBP5500 research dataset and creates a balanced 100-face starter sample. Its 5,500 frontal faces include mean attractiveness ratings from 60 human volunteers on a 1–5 scale, giving us a direct reference for the later FlyFace-versus-human comparison. The dataset is restricted to non-commercial research use. ## Run ```bash python -m flyface score face.jpg python -m flyface compare face_a.jpg face_b.jpg python -m flyface compare face_a.jpg face_b.jpg --json python -m flyface compare face_a.jpg face_b.jpg --output runs/comparison.json python -m flyface batch datasets/scut-fbp5500/sample.csv --output runs/scut-100.csv python -m flyface robust-batch datasets/scut-fbp5500/sample.csv --output runs/scut-20-robust.csv python -m flyface pair-batch datasets/scut-fbp5500/sample.csv --output runs/scut-low-vs-high.csv python -m flyface orientation-tournament datasets/scut-fbp5500/sample.csv --output runs/scut-orientation-100.csv python -m flyface orientation-aggregate runs/scut-*-orientation-900ms.csv --output runs/scut-orientation-100-900ms.csv python -m flyface robust-orientation datasets/scut-fbp5500/sample.csv --output runs/scut-20-robust-orientation.csv python -m flyface feature-analysis datasets/scut-fbp5500/sample.csv runs/scut-orientation-100-900ms-face-scores.csv --output runs/scut-face-features.csv python -m flyface batch-compare runs/scut-100-standardized.csv runs/scut-100-standardized-900ms.csv --output runs/scut-300-vs-900ms.json python -m flyface calibrate-orientation --output runs/orientation-calibration.json python -m flyface screen-orientation --output runs/orientation-population-screen.json ``` Every trial starts by resetting the full neural state, warming up on a neutral screen, measuring a neutral baseline, and then showing the stimulus. Plasticity is frozen. A comparison runs four independent trials: A alone, B alone, A-left/B-right, and B-left/A-right. `Preference: A/B` is the FlyFace decision. It uses counterbalanced DNa02 right-minus-left orientation activity when available, then PAM11, visual (KC), and whole-network response as successive tie-breakers. The JSON records which signal decided the result and keeps the visual, PAM11, aversive, motor, and left/right measurements separate, along with stimulus hashes, spike hashes, parameters, and model provenance. `batch` is resumable: it saves each completed face to CSV immediately. Its summary JSON reports Pearson and Spearman correlation with the human ratings for every neural measurement, globally and for each SCUT demographic subset. `robust-batch` selects a sample balanced across the four SCUT groups and five human-rating quintiles. It scores each face in color, mirrored, grayscale, left-positioned, and right-positioned conditions, then reports cross-variant rank stability and the aggregate response. `pair-batch` constructs 20 within-group duels between the lowest and highest human-rating quintiles. Every duel is counterbalanced left/right and reports whether the FlyFace preference agrees with or opposes the human ratings. `orientation-tournament` runs all 100 within-group low×high combinations but reads only counterbalanced DNa02 orientation. It reports no choice when that circuit is silent; no visual, PAM11, or whole-network fallback is used. `orientation-aggregate` combines compatible tournament CSVs, averages the five duels involving each face, and runs a deterministic within-group permutation test against the human ratings. The default 900 ms exposure was selected after a 300/900 ms pilot increased informative DNa02 responses from 6/100 to 65/100. ### Current SCUT pilot With standardized images and a 900 ms exposure, DNa02 chose the higher-rated human face in 36 of 65 informative duels (55.4%, two-sided binomial p=0.457); 35 duels were silent. Per-face preference and human rating were essentially uncorrelated (Spearman rho=-0.038, within-group permutation p=0.820). The current model therefore shows image-specific preferences, but neither a human-like nor an inverse attractiveness ranking. The five-variant matched-pair assay is exactly balanced: 33 higher-rated versus 32 lower-rated variant votes, 7 versus 8 pair consensuses, and 3 versus 3 stable consensuses. Simple image features do not predict the per-face score after multiple-testing correction. Static and moving controls do not validate DNa02 as an orientation-toward-image readout: none of four static patterns responds correctly in both positions, the moving bar is silent, and no alternative among 473 bilateral descending types passes all four controls. FlyFace still calls its internal A/B decision a preference, but the structured output records that the orientation component is unvalidated. See [EXPERIMENTS.md](EXPERIMENTS.md) for the complete record. `robust-orientation` takes the 20 matched low/high pairs and repeats each duel in color, mirrored, grayscale, and eight-pixel left/right shifted conditions. It reports variant votes, consensus direction, and a conservative stable consensus when at least three variants agree and no more than one disagrees. The summary also separates demographic groups, mean-evidence direction, and pairwise agreement between transformations, and writes a PNG heatmap of every pair-by-variant response plus a contact sheet of the conservative stable pairs. `feature-analysis` extracts edge energy, high-frequency detail, symmetry error, chroma, colorfulness, luminance entropy, center/border luminance, left/right luminance, and red/blue balance. It tests their Spearman association with the per-face DNa02 score using within-group permutations and Benjamini-Hochberg multiple-testing correction. `batch-compare` measures rank stability, activity counts, and human-rating correlations between two exposure protocols. Its second-protocol significance tests permute ratings within SCUT groups and apply the same multiple-testing correction. `calibrate-orientation` places white, black, striped, and checkerboard controls on each side independently. It verifies the assumed DNa02 right-minus-left sign and reports whether both placements point toward the same synthetic stimulus. It also sweeps a dark bar across the panorama in both directions and reports whether the two motion directions produce opponent DNa02 signs. `screen-orientation` applies the four static controls to every bilateral descending-neuron type and ranks populations by consistent left/right response. It is a calibration aid; it does not silently replace the configured DNa02 readout. Images are normalized deterministically to a 90×160 RGB stimulus using EXIF orientation, a centered 9:16 crop, Lanczos resizing, 1% autocontrast, and fixed global luminance mean and contrast. Use `--normalization autocontrast` to reproduce the original photometry-sensitive condition. ## Architecture ```text CLI → deterministic stimulus → frozen MaleCNS adapter → population readouts → JSON/text ``` The neural dependency is pinned to Stonkfly commit `78ef3e05ab0fa086032098558d893667068944a0`. See [THIRD_PARTY.md](THIRD_PARTY.md).