A neuroevolution-driven agent-based model of coral larvae settlement.
The 31 matches · 1 of them tie a paragraph to a whole file, not to given lines: a weak match, whose lines are not tinted
- [1] § 3. Methods › 3.2. Experiments › 3.2.2. Computational experiments – replications. ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/Agent/LarvaAgent.h, lines 43–100 · score 0.92 · competency onset, inner neuron, forward strength, Trained controllers, genome length, volume
- [2] § 3. Methods › 3.2. Experiments › 3.2.2. Computational experiments – replications. ↔ coral-larvae-abm/Source/coral_larvae_abm/Private/SimulationManager.cpp, lines 147–220 · score 0.91 · rest selection rate, descent speed, inner neuron, selection strategy, mutation rate, genome length
- [3] § 4. Results › 4.2. Controller analysis and robustness ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/Agent/LarvaAgent.h, lines 43–100 · score 0.85 · Simpler controller baselines, gradient taxis, fixed reactive rule, directional cue, evolved controller, threshold
- [4] § 4. Results › 4.2. Controller analysis and robustness ↔ Plotting/09_nn_cue_ablation.py, lines 76–107 · score 0.83 · step sensor traces, realized cue influence, controller intrinsic, variance weighted, synthetic, complemented
- [5] § 4. Results › 4.2. Controller analysis and robustness ↔ Plotting/18_weight_distribution.py, lines 1–19 · score 0.78 · sensory channel classes, Weight distribution, connection weights, evolved controllers, elite, pruning
- [6] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/EvolutionManager.h, lines 46–93 · score 0.77 · parent genomes, mutation rate, genome length, offspring, Truncation, Elitism
- [7] § 3. Methods › 3.2. Experiments › 3.2.2. Computational experiments – replications. ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/Experiments/ResultAnalysisFunctions.h, lines 18–51 · score 0.75 · generalized linear model, substrate area, Clarke, Evans, binomial, GLM
- [8] § 3. Methods › 3.2. Experiments › 3.2.2. Computational experiments – replications. ↔ coral-larvae-abm/Source/coral_larvae_abm/Private/Experiments/ResultAnalysisFunctions.cpp, lines 142–211 · score 0.74 · generalized linear model, substrate area, standard errors, binomial, slope, settlement
- [9] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Private/DataGrid/DataGridPreprocessor.cpp, lines 153–218 · score 0.74 · particle motion, seawater, flow, density, calibrated, speed
- [10] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Private/Agent/LarvaAgent.cpp, lines 377–385 · score 0.72 · constant downward behavioral, competency age, geotaxis, bias, swim, gated
- [11] § 4. Results ↔ Plotting/10_convergence_reliability.py, lines 57–116 · score 0.72 · E1 biological metric, genetic diversity, reliability, premature, collapse, median
- [12] § 4. Results ↔ Plotting/19_manuscript_distribution_figures.py, lines 78–85 · score 0.69 · E2 vertical distribution, bottom row, tube bottom, depth zones, descend, rounds
- [13] § 4. Results ↔ Plotting/08_analyze_validation_e3.R, lines 140–195 · score 0.67 · source zone, E3 horizontal, E3 vertical, height zones, farthest, nearest
- [14] § 4. Results ↔ Plotting/13_e1_patchsize_figure.py, the whole file · a weak match · score 0.67 · fixed CCA cover, maximum tile area, Correct settlement, genome seeds, patch, RNG
- [15] § 4. Results › 4.1. Robustness to environmental perturbations ↔ Plotting/20_sensitivity_figures.py, lines 1–27 · score 0.67 · 1–20 kHz, 0.1–1, frequency band, source distance, zone, larvae
- [16] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/SimulationManager.h, lines 24–71 · score 0.66 · mutation rate, fitness functions, operators, Elitism, Stochastic, crossover
- [17] § 3. Methods › 3.2. Experiments › 3.2.2. Computational experiments – replications. ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/SimulationManager.h, lines 24–71 · score 0.66 · CCA covered limestone, light cycle, overrides, vertical, tiles, trained
- [18] § 4. Results › 4.1. Robustness to environmental perturbations ↔ Plotting/20_sensitivity_figures.py, lines 1–27 · score 0.65 · frequency band, light attenuation, 160 dB, 153 dB, sweep, zone
- [19] § 3. Methods › 3.1. Model overview ↔ Plotting/09_nn_cue_ablation.py, lines 109–128 · score 0.65 · acoustic particle motion, internal state, channels, field, setup, weight
- [20] § 3. Methods › 3.2. Experiments › 3.2.2. Computational experiments – replications. ↔ Plotting/08_analyze_validation_e3.R, lines 238–287 · score 0.62 · way ANOVA, height zones, distance zones, horizontal, vertical, uniform
- [21] § 4. Results ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/SimulationManager.h, lines 194–276 · score 0.61 · sound control, RNG seeds, genome seeds, sound source, V3E, V3C
- [22] § 4. Results › 4.2. Controller analysis and robustness ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/Sensors/LarvalSensorBaseComponent.h, lines 22–39 · score 0.59 · Adding Gaussian noise, Sensory noise robustness, validation
- [23] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Private/DataGrid/DataGridPreprocessor.cpp, lines 153–218 · score 0.59 · light intensity, particle motion, wavelength, salinity, pressure, temperature
- [24] § 4. Results ↔ Plotting/06_analyze_validation_e1_e2.R, lines 354–392 · score 0.58 · correct settlement rate, E1 settlement, E2 depth, metric, position
- [25] § 4. Results ↔ Plotting/08_analyze_validation_e3.R, lines 82–120 · score 0.54 · sound control, V3F, sound source, V3E, V3C, V3B
- [26] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Private/DataGrid/DataGridPreprocessor.cpp, lines 220–277 · score 0.53 · Gaussian decay, CCA concentration, reef cells, positioned, larvae
- [27] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Private/Agent/AgentBrainComponent.cpp, lines 167–188 · score 0.53 · target node, source nodes, neurons, connection, mapping, sensors
- [28] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Private/Agent/LarvaAgent.cpp, lines 103–132 · score 0.53 · rotation angles, forward strength, settlement, larva
- [29] § 4. Results ↔ Plotting/10_convergence_reliability.py, lines 57–116 · score 0.53 · biological outcome, E1 correct, metric, tracking, population, depth
- [30] § 3. Methods › 3.1. Model overview ↔ coral-larvae-abm/Source/coral_larvae_abm/Public/GenomeAnalysisFunctions.h, lines 46–70 · score 0.52 · light intensity, particle motion, wavelength, pressure, temperature, CCA
- [31] § 3. Methods › 3.2. Experiments › 3.2.2. Computational experiments – replications. ↔ Plotting/09_nn_cue_ablation.py, lines 130–139 · score 0.52 · diel, shallow, manipulations, cycle, geometry, temperature
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Python · 659 lines · 28 KB · MIT · 3 matches
- #!/usr/bin/env python3
- """
- NN cue-dominance / ablation analysis for the coral-larvae NE-ABM.
- Answers reviewer R1's "open the black box" request functionally, not just
- structurally: for each evolved controller we measure how much each sensed cue
- (sensor input) changes the controller's action outputs (cue-on vs cue-off),
- then aggregate across the successful controllers of each experiment.
- This is a faithful offline re-implementation of the C++ runtime:
- - gene bit layout .......... GenomeFunctions.h (FGene)
- - index renumbering ........ AgentBrainComponent::MakeRenumberedConnectionList
- - unused-neuron pruning .... AgentBrainComponent::RemoveUnusedNeurons / CanReachAction
- - recurrent forward pass ... NeuralNetFunctions::FeedForward (tanh, prev-step neuron state)
- - action activation ........ NeuralNetFunctions::ActivateActions (tanh per action)
- - active sensors ........... LarvaAgent adds exactly the sensors wired in the net
- (GetSensorClasses), so a genome's wired sensors ARE
- its active sensors -> controller-only sensitivity.
- It only reads the saved training genome files, so it is independent of the
- validation seed issue and does not touch the Unreal simulator (safe to run
- while E3 training is in progress).
- Outputs (under Plotting/output/):
- tables/nn_cue_influence_<exp>.csv per-sensor mean action influence + per-action
- tables/nn_cue_influence_ranked.csv combined ranked cue dominance across experiments
- tables/nn_structure_summary_<exp>.csv per-controller structural stats (final controllers)
- plots/nn_cue_influence_<exp>.png ranked cue-influence bar chart
- """
- import os
- import glob
- import math
- import numpy as np
- # ----------------------------------------------------------------------------
- # Constants mirrored from the C++ source
- # ----------------------------------------------------------------------------
- NUM_SENSORS = 16 # ESensorType::NUM_SENSORS (active sensors before it)
- NUM_ACTIONS = 5 # EActionType::NUM_ACTIONS
- NUM_NEURONS = 12 # MaxInnerNeurons used in all final training runs
- GENOME_LEN = 50
- GSENSOR = 1 # bSourceType==1 -> sensor ; ==0 -> neuron (GNeuron)
- GACTION = 1 # bTargetType==1 -> action ; ==0 -> neuron
- GNEURON = 0
- INITIAL_NEURON_OUTPUT = 0.5
- WEIGHT_SCALE = 8192.0
- SENSOR_NAMES = [
- "OSCILLATION", "AGE", "ENERGY", "ALTEROMONAS_BIOFILM", "CCA",
- "CCA_FORWARD_BACK", "CCA_UP_DOWN", "CCA_LEFT_RIGHT", "TEMPERATURE",
- "PRESSURE", "LIGHT_INTENSITY", "LIGHT_WAVELENGTH",
- "PARTICLE_MOTION_FORWARD_BACK", "PARTICLE_MOTION_UP_DOWN",
- "PARTICLE_MOTION_LEFT_RIGHT", "PARTICLE_MOTION",
- ]
- ACTION_NAMES = ["FORWARD", "ROTATE_YAW", "ROTATE_PITCH", "SET_OSC", "SETTLE"]
- # ----------------------------------------------------------------------------
- # Analysis configuration
- # ----------------------------------------------------------------------------
- REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- EXPERIMENTS = {
- # exp -> directory of the FINAL controller set actually used for validation
- # (reselected 2026-07-09/10 from the fresh UE5.8 rerun; SUS wins all three).
- "E1": os.path.join(REPO, "Training", "e1", "SUS"),
- "E2": os.path.join(REPO, "Training", "e2", "SUS"),
- "E3": os.path.join(REPO, "Training", "e3", "SUS_H3"),
- }
- # Final-config genome length per experiment (E3 winner uses the reduced genome = 25).
- GENOME_LENS = {"E1": 50, "E2": 50, "E3": 25}
- # ----------------------------------------------------------------------------
- # AP1 trajectory-based cue analysis (gold standard).
- #
- # When Content/Evolution/validation_trajectory_<exp>_<scenario>.csv files exist
- # (bLogPerStepTrajectory on during the validation rerun; see docs/findings.md
- # "Validation rerun infrastructure"), we can measure REALIZED cue influence
- # from real per-step sensor traces instead of synthetic on/off sweeps: for
- # each wired sensor, how much of the variance in each action output is
- # explained by that sensor's actual observed values during validation runs.
- # This complements (does not replace) the synthetic-sweep analysis above,
- # which measures a controller's structural sensitivity regardless of whether
- # that sensor's field is ever actually varying in a given experiment's
- # geometry.
- #
- # CSV schema (SimulationManager::FlushPerStepTrajectoryLog):
- # timestamp,experiment,scenario,validation_genome_seed,random_seed,
- # agent_index,sim_step,pos_x,pos_y,pos_z,
- # sensor_<ShortName> x NUM_SENSORS (enum order == SENSOR_NAMES order),
- # action_<ShortName> x NUM_ACTIONS (enum order == ACTION_NAMES order)
- # Decimals are DOT-separated (FString::SanitizeFloat), comma-separated columns.
- # ----------------------------------------------------------------------------
- _EVO = os.path.join(REPO, "coral-larvae-abm", "Content", "Evolution")
- TRAJECTORY_GLOB = {
- # Realized (variance-weighted) cue influence from real per-step sensor traces of the FINAL
- # controller sets only. E2: the winner's (SUS_H2) baseline + perturbation runs (excludes the
- # calibration probes SW_*/G5_*/RT_*/CAL and the 1-agent Pop-bug junk file). E1/E3 have no clean
- # stride-sampled trajectory yet (would need a dedicated -Traj V1A/V3A run); realized analysis is
- # skipped for them and the controller-intrinsic (synthetic-sweep) analysis stands alone.
- "E1": os.path.join(_EVO, "validation_trajectory_e1_V1Atraj.csv"),
- "E2": os.path.join(_EVO, "validation_trajectory_e2_E2Hb_SUS_H4b.csv"),
- "E3": os.path.join(_EVO, "validation_trajectory_e3_V3Atraj.csv"),
- }
- # ----------------------------------------------------------------------------
- # Per-experiment cue classification (AP2).
- #
- # This is a FACTUAL classification of which sensory channels carry a non-trivial
- # environmental field in each experiment's setup, NOT a fabricated variance. A
- # sensor whose field does not exist by design (e.g. acoustic particle motion in
- # the CCA-only E1 bowl, or light in the dark E3 tubes) is definitionally
- # uninformative and is excluded from the cue-dominance ranking. Internal-state
- # inputs (oscillator, age, energy) are not environmental cues and are reported
- # separately. Realized (variance-weighted) influence from real per-step sensor
- # traces is deferred to the trajectory-based analysis on the validation rerun
- # (see validation-rerun-plan.md, "AP1").
- # ----------------------------------------------------------------------------
- INTERNAL_SENSORS = {"OSCILLATION", "AGE", "ENERGY"}
- CCA_CUES = {"CCA", "CCA_FORWARD_BACK", "CCA_UP_DOWN", "CCA_LEFT_RIGHT",
- "ALTEROMONAS_BIOFILM"}
- PM_CUES = {"PARTICLE_MOTION", "PARTICLE_MOTION_FORWARD_BACK",
- "PARTICLE_MOTION_UP_DOWN", "PARTICLE_MOTION_LEFT_RIGHT"}
- LIGHT_CUES = {"LIGHT_INTENSITY", "LIGHT_WAVELENGTH"}
- # primary = strong manipulated/spatially varying field; weak = field defined but
- # near-constant in that geometry (kept, but flagged).
- EXP_FIELDS = {
- "E1": {"primary": set(CCA_CUES),
- "weak": {"TEMPERATURE", "PRESSURE"}}, # shallow bowl -> flat T/P
- "E2": {"primary": set(CCA_CUES) | set(LIGHT_CUES) | {"TEMPERATURE", "PRESSURE"},
- "weak": set()}, # 2.2 m tube + diel cycle
- "E3": {"primary": set(PM_CUES),
- "weak": {"TEMPERATURE", "PRESSURE"}},
- }
- def sensor_role(exp, sensor_name):
- if sensor_name in INTERNAL_SENSORS:
- return "internal"
- fields = EXP_FIELDS.get(exp, {"primary": set(), "weak": set()})
- if sensor_name in fields["primary"]:
- return "environmental_primary"
- if sensor_name in fields.get("weak", set()):
- return "environmental_weak"
- return "inactive_no_field"
- TOP_N_PER_SEED = 10 # analyse the top-N (elite / "successful") genomes per seed
- T_STEPS = 80 # recurrent steps to reach steady controller state
- MC_SAMPLES = 48 # random background input vectors per controller
- SEED_RANGE = range(1, 31)
- RNG = np.random.default_rng(20260706) # fixed for reproducibility (no Date/rand)
- OUT_TABLES = os.path.join(REPO, "Plotting", "output", "tables")
- OUT_PLOTS = os.path.join(REPO, "Plotting", "output", "plots")
- os.makedirs(OUT_TABLES, exist_ok=True)
- os.makedirs(OUT_PLOTS, exist_ok=True)
- # ----------------------------------------------------------------------------
- # Genome decoding + wiring (faithful to the C++ pipeline)
- # ----------------------------------------------------------------------------
- def decode_gene(hexstr):
- n = int(hexstr, 16) & 0xFFFFFFFF
- bf = n & 0xFFFF
- w_raw = (n >> 16) & 0xFFFF
- weight = (w_raw - 0x10000) if w_raw >= 0x8000 else w_raw
- b_src = bf & 0x1
- s_idx = (bf >> 1) & 0x7F
- b_tgt = (bf >> 8) & 0x1
- t_idx = (bf >> 9) & 0x7F
- return {
- "b_src": b_src, "s_idx": s_idx,
- "b_tgt": b_tgt, "t_idx": t_idx,
- "w": weight / WEIGHT_SCALE,
- }
- def renumber(genes):
- """MakeRenumberedConnectionList: mod indices by their node-type counts."""
- conns = []
- for g in genes:
- s_idx = g["s_idx"] % (NUM_NEURONS if g["b_src"] == GNEURON else NUM_SENSORS)
- t_idx = g["t_idx"] % (NUM_ACTIONS if g["b_tgt"] == GACTION else NUM_NEURONS)
- conns.append({"b_src": g["b_src"], "s_idx": s_idx,
- "b_tgt": g["b_tgt"], "t_idx": t_idx, "w": g["w"]})
- return conns
- def can_reach_action(neuron_idx, conns):
- """DFS over neuron->neuron/action edges (CanReachAction)."""
- stack = [neuron_idx]
- visited = set()
- while stack:
- cur = stack.pop()
- if cur in visited:
- continue
- visited.add(cur)
- for c in conns:
- if c["b_src"] == GNEURON and c["s_idx"] == cur:
- if c["b_tgt"] == GACTION:
- return True
- if c["b_tgt"] == GNEURON:
- stack.append(c["t_idx"])
- return False
- def prune(conns):
- """RemoveUnusedNeurons: drop neurons that cannot reach an action, and the
- connections feeding them; repeat until stable."""
- conns = list(conns)
- while True:
- neurons = set()
- for c in conns:
- if c["b_tgt"] == GNEURON:
- neurons.add(c["t_idx"])
- if c["b_src"] == GNEURON:
- neurons.add(c["s_idx"])
- dead = {n for n in neurons if not can_reach_action(n, conns)}
- if not dead:
- break
- # remove connections whose TARGET is a dead neuron (RemoveConnectionsToNeuron)
- conns = [c for c in conns
- if not (c["b_tgt"] == GNEURON and c["t_idx"] in dead)]
- return conns
- def build_net(genes):
- """CreateWiringForGenome -> compact recurrent net.
- Returns (connections, n_neurons, driven_mask, wired_sensors).
- Connections use remapped 0..k-1 neuron ids.
- """
- conns = prune(renumber(genes))
- # surviving neurons = neuron ids still present as a source-neuron or target-neuron
- surviving = []
- seen = set()
- for c in conns:
- if c["b_src"] == GNEURON and c["s_idx"] not in seen:
- seen.add(c["s_idx"]); surviving.append(c["s_idx"])
- if c["b_tgt"] == GNEURON and c["t_idx"] not in seen:
- seen.add(c["t_idx"]); surviving.append(c["t_idx"])
- remap = {old: new for new, old in enumerate(surviving)}
- k = len(surviving)
- net = []
- for c in conns:
- s_idx = remap[c["s_idx"]] if c["b_src"] == GNEURON else c["s_idx"]
- t_idx = remap[c["t_idx"]] if c["b_tgt"] == GNEURON else c["t_idx"]
- net.append((c["b_src"], s_idx, c["b_tgt"], t_idx, c["w"]))
- # bDriven: neuron has >=1 non-self input (from sensor or other neuron)
- driven = np.zeros(k, dtype=bool)
- for (b_src, s_idx, b_tgt, t_idx, w) in net:
- if b_tgt == GNEURON:
- is_self = (b_src == GNEURON and s_idx == t_idx)
- if not is_self:
- driven[t_idx] = True
- wired_sensors = sorted({s_idx for (b_src, s_idx, _, _, _) in net
- if b_src == GSENSOR})
- return net, k, driven, wired_sensors
- # ----------------------------------------------------------------------------
- # Vectorised recurrent forward pass (batch over MC samples)
- # ----------------------------------------------------------------------------
- def forward_batch(net, k, driven, sensor_in):
- """sensor_in: (B, NUM_SENSORS). Returns actions (B, NUM_ACTIONS) after tanh.
- Runs T_STEPS recurrent updates with constant inputs, then one action pass
- from the steady neuron state. Mirrors FeedForward + ActivateActions.
- """
- B = sensor_in.shape[0]
- neuron_out = np.full((B, k), INITIAL_NEURON_OUTPUT, dtype=np.float64)
- for _ in range(T_STEPS):
- neuron_acc = np.zeros((B, k), dtype=np.float64)
- for (b_src, s_idx, b_tgt, t_idx, w) in net:
- if b_tgt != GNEURON:
- continue # action targets don't affect neuron state
- src = sensor_in[:, s_idx] if b_src == GSENSOR else neuron_out[:, s_idx]
- neuron_acc[:, t_idx] += src * w
- upd = np.tanh(neuron_acc)
- if k:
- neuron_out[:, driven] = upd[:, driven]
- action_lvl = np.zeros((B, NUM_ACTIONS), dtype=np.float64)
- for (b_src, s_idx, b_tgt, t_idx, w) in net:
- if b_tgt != GACTION:
- continue
- src = sensor_in[:, s_idx] if b_src == GSENSOR else neuron_out[:, s_idx]
- action_lvl[:, t_idx] += src * w
- return np.tanh(action_lvl)
- def cue_influence(net, k, driven, wired_sensors):
- """For each wired sensor: mean |action(on) - action(off)| over MC random
- backgrounds. Returns (n_wired,) x (NUM_ACTIONS) influence matrix keyed by sensor idx."""
- infl = {} # sensor_idx -> (NUM_ACTIONS,) mean abs delta
- if not wired_sensors:
- return infl
- # random background: wired sensors ~ U[0,1], others 0
- base = np.zeros((MC_SAMPLES, NUM_SENSORS), dtype=np.float64)
- base[:, wired_sensors] = RNG.random((MC_SAMPLES, len(wired_sensors)))
- for s in wired_sensors:
- on = base.copy(); on[:, s] = 1.0
- off = base.copy(); off[:, s] = 0.0
- a_on = forward_batch(net, k, driven, on)
- a_off = forward_batch(net, k, driven, off)
- infl[s] = np.abs(a_on - a_off).mean(axis=0) # (NUM_ACTIONS,)
- return infl
- # ----------------------------------------------------------------------------
- # Genome file parsing
- # ----------------------------------------------------------------------------
- def load_genomes(path, genome_len=GENOME_LEN):
- """Returns list of (genes, fitness), genes = list of decoded genes."""
- out = []
- with open(path, "r") as fh:
- lines = [ln.strip() for ln in fh if ln.strip()]
- i = 0
- while i < len(lines):
- gene_line = lines[i]
- fit = math.nan
- if i + 1 < len(lines) and lines[i + 1].startswith(";"):
- parts = lines[i + 1].split()
- if len(parts) >= 2:
- try:
- fit = float(parts[1])
- except ValueError:
- fit = math.nan
- i += 2
- else:
- i += 1
- toks = gene_line.split()
- if len(toks) < genome_len:
- continue
- genes = [decode_gene(t) for t in toks]
- out.append((genes, fit))
- return out
- # ----------------------------------------------------------------------------
- # Structural summary (reproduce nn-structure-summary on final controllers)
- # ----------------------------------------------------------------------------
- def structural_stats(net, k):
- n_conn = len(net)
- if n_conn == 0:
- return dict(active_neurons=0, eff_connections=0, mean_abs_weight=0.0,
- s2n=0, s2a=0, n2n=0, n2a=0)
- s2n = s2a = n2n = n2a = 0
- wsum = 0.0
- for (b_src, s_idx, b_tgt, t_idx, w) in net:
- wsum += abs(w)
- if b_src == GSENSOR and b_tgt == GNEURON: s2n += 1
- elif b_src == GSENSOR and b_tgt == GACTION: s2a += 1
- elif b_src == GNEURON and b_tgt == GNEURON: n2n += 1
- elif b_src == GNEURON and b_tgt == GACTION: n2a += 1
- return dict(active_neurons=k, eff_connections=n_conn,
- mean_abs_weight=wsum / n_conn,
- s2n=s2n, s2a=s2a, n2n=n2n, n2a=n2a)
- # ----------------------------------------------------------------------------
- # Main analysis per experiment
- # ----------------------------------------------------------------------------
- def analyse_experiment(exp, directory):
- print(f"\n=== {exp} ({directory}) ===")
- influence_rows = [] # per (genome) -> per sensor
- struct_rows = []
- n_controllers = 0
- # accumulator: sensor_idx -> list of total influence (summed over actions)
- per_sensor_total = {s: [] for s in range(NUM_SENSORS)}
- per_sensor_byaction = {s: [] for s in range(NUM_SENSORS)} # list of (NUM_ACTIONS,)
- wired_count = {s: 0 for s in range(NUM_SENSORS)}
- for seed in SEED_RANGE:
- matches = glob.glob(os.path.join(
- directory, f"best_genomes_*seed_{seed:02d}.txt"))
- if not matches:
- print(f" seed {seed:02d}: MISSING")
- continue
- genomes = load_genomes(matches[0], GENOME_LENS.get(exp, GENOME_LEN))
- genomes.sort(key=lambda gf: (-gf[1] if not math.isnan(gf[1]) else 0.0))
- elite = genomes[:TOP_N_PER_SEED]
- for genes, fit in elite:
- net, k, driven, wired = build_net(genes)
- n_controllers += 1
- st = structural_stats(net, k)
- st.update(experiment=exp, seed=seed, fitness=fit)
- struct_rows.append(st)
- infl = cue_influence(net, k, driven, wired)
- for s in wired:
- wired_count[s] += 1
- for s, vec in infl.items():
- per_sensor_total[s].append(float(vec.sum()))
- per_sensor_byaction[s].append(vec)
- # aggregate cue influence
- infl_rows = []
- for s in range(NUM_SENSORS):
- vals = per_sensor_total[s]
- if not vals:
- continue
- arr = np.array(vals)
- by = np.array(per_sensor_byaction[s]) # (n, NUM_ACTIONS)
- row = dict(
- experiment=exp,
- sensor=SENSOR_NAMES[s],
- role=sensor_role(exp, SENSOR_NAMES[s]),
- n_controllers_wiring=len(vals),
- frac_controllers=len(vals) / max(1, n_controllers),
- mean_total_influence=float(arr.mean()),
- se_total_influence=float(arr.std(ddof=1) / math.sqrt(len(arr))) if len(arr) > 1 else 0.0,
- )
- for ai, an in enumerate(ACTION_NAMES):
- row[f"infl_{an}"] = float(by[:, ai].mean())
- infl_rows.append(row)
- infl_rows.sort(key=lambda r: -r["mean_total_influence"])
- env_rows = [r for r in infl_rows
- if r["role"] in ("environmental_primary", "environmental_weak")]
- internal_rows = [r for r in infl_rows if r["role"] == "internal"]
- # write tables (full table keeps every wired sensor + role; environmental
- # table is the headline cue-dominance ranking used for interpretation)
- import csv
- infl_path = os.path.join(OUT_TABLES, f"nn_cue_influence_{exp}.csv")
- if infl_rows:
- with open(infl_path, "w", newline="") as fh:
- w = csv.DictWriter(fh, fieldnames=list(infl_rows[0].keys()))
- w.writeheader(); w.writerows(infl_rows)
- env_path = os.path.join(OUT_TABLES, f"nn_cue_influence_{exp}_environmental.csv")
- if env_rows:
- with open(env_path, "w", newline="") as fh:
- w = csv.DictWriter(fh, fieldnames=list(env_rows[0].keys()))
- w.writeheader(); w.writerows(env_rows)
- struct_path = os.path.join(OUT_TABLES, f"nn_structure_summary_{exp}.csv")
- if struct_rows:
- with open(struct_path, "w", newline="") as fh:
- w = csv.DictWriter(fh, fieldnames=list(struct_rows[0].keys()))
- w.writeheader(); w.writerows(struct_rows)
- # console ranking (headline = environmental cues only)
- print(f" controllers analysed: {n_controllers}")
- print(f" ENVIRONMENTAL CUE DOMINANCE (informative fields only):")
- print(f" {'sensor':<28}{'role':<24}{'mean_infl':>10}{'frac':>7} top action")
- for r in env_rows:
- top_act = max(ACTION_NAMES, key=lambda a: r[f"infl_{a}"])
- print(f" {r['sensor']:<28}{r['role']:<24}{r['mean_total_influence']:>10.4f}"
- f"{r['frac_controllers']:>7.2f} {top_act}")
- if internal_rows:
- print(f" internal-state inputs (not environmental cues):")
- for r in internal_rows:
- print(f" {r['sensor']:<26}{r['mean_total_influence']:>10.4f}")
- # plot
- try:
- import matplotlib
- matplotlib.use("Agg")
- import matplotlib.pyplot as plt
- if env_rows:
- names = [r["sensor"] for r in env_rows]
- vals = [r["mean_total_influence"] for r in env_rows]
- ses = [r["se_total_influence"] for r in env_rows]
- colors = ["#3b7a9e" if r["role"] == "environmental_primary" else "#b0b0b0"
- for r in env_rows]
- fig, ax = plt.subplots(figsize=(7, 0.4 * len(names) + 1.6))
- ax.barh(range(len(names)), vals, xerr=ses, color=colors)
- ax.set_yticks(range(len(names))); ax.set_yticklabels(names, fontsize=8)
- ax.invert_yaxis()
- ax.set_xlabel("Mean |action change| (cue on vs off), summed over actions")
- ax.set_title(f"{exp}: environmental cue influence on evolved controllers\n"
- f"(top {TOP_N_PER_SEED}/seed, n={n_controllers})")
- from matplotlib.patches import Patch
- ax.legend(handles=[Patch(color="#3b7a9e", label="primary field"),
- Patch(color="#b0b0b0", label="weak field")],
- loc="lower right", fontsize=8)
- fig.tight_layout()
- fig.savefig(os.path.join(OUT_PLOTS, f"nn_cue_influence_{exp}.png"), dpi=150)
- plt.close(fig)
- except Exception as e:
- print(f" (plot skipped: {e})")
- return env_rows
- # ----------------------------------------------------------------------------
- # Trajectory-based (gold-standard) cue analysis using real per-step sensor
- # and action traces from the AP1 validation-rerun logging.
- # ----------------------------------------------------------------------------
- def load_trajectory_csv(path):
- """Parse one validation_trajectory_<exp>_<scenario>.csv (comma-separated,
- dot decimals). Returns dict of column name -> list, or None if the file
- is empty/malformed."""
- import csv as csv_mod
- rows = []
- with open(path, "r", newline="") as fh:
- reader = csv_mod.DictReader(fh)
- for row in reader:
- rows.append(row)
- if not rows:
- return None
- # Header uses mnemonic short names, not positional indices; recover the
- # sensor/action column order directly from the header instead (enum
- # order is preserved by the C++ writer, but don't assume the names).
- fieldnames = reader.fieldnames or []
- sensor_cols = [c for c in fieldnames if c.startswith("sensor_")]
- action_cols = [c for c in fieldnames if c.startswith("action_")]
- if len(sensor_cols) != NUM_SENSORS or len(action_cols) != NUM_ACTIONS:
- print(f" WARNING: {os.path.basename(path)} has {len(sensor_cols)} sensor "
- f"cols / {len(action_cols)} action cols, expected {NUM_SENSORS}/{NUM_ACTIONS} "
- f"-> skipping")
- return None
- def to_f(x):
- try:
- return float(x)
- except (TypeError, ValueError):
- return math.nan
- sensors = np.array([[to_f(r[c]) for c in sensor_cols] for r in rows])
- actions = np.array([[to_f(r[c]) for c in action_cols] for r in rows])
- return {
- "sensor_cols": sensor_cols,
- "action_cols": action_cols,
- "sensors": sensors, # (n_steps, NUM_SENSORS), header order
- "actions": actions, # (n_steps, NUM_ACTIONS), header order
- "scenario": rows[0].get("scenario", ""),
- "agent_index": [r.get("agent_index") for r in rows],
- }
- def realized_cue_influence(exp, glob_pattern):
- """For each sensor column actually present in the trajectory logs: realized
- influence = |corr(sensor, action)| averaged over actions, weighted by the
- number of steps contributing (i.e. pooled across all matching files),
- using the ACTUAL observed sensor variance (not a synthetic sweep). This
- directly answers "does this cue's real variation in the validation run
- move the controller's outputs", complementing the structural on/off sweep.
- """
- files = sorted(glob.glob(glob_pattern))
- if not files:
- print(f" no trajectory files found for {exp}: {glob_pattern}")
- return []
- print(f" found {len(files)} trajectory file(s) for {exp}")
- pooled_sensors = []
- pooled_actions = []
- sensor_cols = action_cols = None
- for f in files:
- parsed = load_trajectory_csv(f)
- if parsed is None:
- continue
- if sensor_cols is None:
- sensor_cols, action_cols = parsed["sensor_cols"], parsed["action_cols"]
- elif parsed["sensor_cols"] != sensor_cols or parsed["action_cols"] != action_cols:
- print(f" WARNING: column order mismatch in {f}, skipping")
- continue
- pooled_sensors.append(parsed["sensors"])
- pooled_actions.append(parsed["actions"])
- if not pooled_sensors:
- return []
- sensors = np.concatenate(pooled_sensors, axis=0)
- actions = np.concatenate(pooled_actions, axis=0)
- n_steps = sensors.shape[0]
- # Map header short names back to SENSOR_NAMES/ACTION_NAMES via the enum
- # order the C++ writer uses (SensorShortName/ActionShortName iterate
- # ESensorType/EActionType in declaration order == SENSOR_NAMES/ACTION_NAMES).
- if len(sensor_cols) != len(SENSOR_NAMES) or len(action_cols) != len(ACTION_NAMES):
- print(" WARNING: trajectory column count does not match SENSOR_NAMES/ACTION_NAMES")
- rows = []
- for s_idx, s_name in enumerate(SENSOR_NAMES):
- if s_idx >= sensors.shape[1]:
- continue
- s_vals = sensors[:, s_idx]
- if np.all(np.isnan(s_vals)) or np.nanstd(s_vals) == 0:
- continue # constant/missing sensor -> no realized influence, not an error
- corrs = []
- for a_idx in range(actions.shape[1]):
- a_vals = actions[:, a_idx]
- mask = ~np.isnan(s_vals) & ~np.isnan(a_vals)
- if mask.sum() < 2 or np.nanstd(a_vals[mask]) == 0:
- corrs.append(0.0)
- continue
- c = np.corrcoef(s_vals[mask], a_vals[mask])[0, 1]
- corrs.append(0.0 if np.isnan(c) else abs(c))
- row = dict(
- experiment=exp,
- sensor=s_name,
- role=sensor_role(exp, s_name),
- n_steps=int(n_steps),
- observed_sd=float(np.nanstd(s_vals)),
- mean_abs_corr=float(np.mean(corrs)),
- )
- for ai, an in enumerate(ACTION_NAMES):
- row[f"abs_corr_{an}"] = corrs[ai] if ai < len(corrs) else float("nan")
- rows.append(row)
- rows.sort(key=lambda r: -r["mean_abs_corr"])
- return rows
- def analyse_trajectory(exp, glob_pattern):
- print(f"\n=== {exp} trajectory-based (gold-standard) cue analysis ===")
- rows = realized_cue_influence(exp, glob_pattern)
- if not rows:
- return []
- import csv as csv_mod
- out_path = os.path.join(OUT_TABLES, f"nn_cue_influence_trajectory_{exp}.csv")
- with open(out_path, "w", newline="") as fh:
- w = csv_mod.DictWriter(fh, fieldnames=list(rows[0].keys()))
- w.writeheader(); w.writerows(rows)
- print(f" wrote {out_path}")
- env_rows = [r for r in rows if r["role"] in ("environmental_primary", "environmental_weak")]
- print(f" REALIZED ENVIRONMENTAL CUE INFLUENCE (from actual validation-run sensor traces):")
- print(f" {'sensor':<28}{'role':<24}{'mean|corr|':>10}{'observed_sd':>13}")
- for r in env_rows:
- print(f" {r['sensor']:<28}{r['role']:<24}{r['mean_abs_corr']:>10.4f}{r['observed_sd']:>13.4f}")
- return rows
- def main():
- all_rows = []
- for exp, directory in EXPERIMENTS.items():
- if not os.path.isdir(directory):
- print(f"skip {exp}: {directory} not found")
- continue
- all_rows.extend(analyse_experiment(exp, directory))
- if all_rows:
- import csv
- combined = os.path.join(OUT_TABLES, "nn_cue_influence_ranked.csv")
- with open(combined, "w", newline="") as fh:
- w = csv.DictWriter(fh, fieldnames=list(all_rows[0].keys()))
- w.writeheader(); w.writerows(all_rows)
- print(f"\nwrote {combined}")
- # Gold-standard trajectory-based analysis, where AP1 logs are available.
- # Additive: does not affect the synthetic-sweep tables/plots above.
- for exp, glob_pattern in TRAJECTORY_GLOB.items():
- analyse_trajectory(exp, glob_pattern)
- if __name__ == "__main__":
- main()
09_nn_cue_ablation.py at commit 2b78a1f, under MIT · at the source
Overview
- Department of Computer Science, Julius-Maximilians University, Würzburg, Germany
- Department of Biology, University of Konstanz, Konstanz, Germany
Abstract
Coral reefs face significant threats due to climate change and human activities, which require innovative approaches to study and protect these ecosystems. Successful settlement is the bottleneck linking a reef’s free-swimming larvae to the benthic community, ultimately determining the next generation of corals and the long-term resilience of the entire ecosystem. This work introduces an agent-based model (ABM) driven by neuroevolution (NE) to simulate coral larval settlement behavior under various environmental conditions. Inspired by biological processes, the model combines sensory input with a neural network (NN) to guide larval actions, optimizing settlement success through evolutionary algorithms. The model replicates three experimental setups from previous studies, validating it against key metrics such as settlement success, vertical distribution, and orientation to environmental cues. The evolved controllers capture the characteristic cue responses of each experiment: crustose coralline algae (CCA)-driven settlement, the bimodal vertical distribution, and orientation towards reef sound, while also exposing the limits of the simplified environment, as its reduced hydrodynamics. Sensitivity analyses further indicate that these behaviors are driven by different mechanisms across the experiments, illustrating how the model yields interpretable, testable outcomes. This approach provides a basis for integrating adaptive behaviors into coral larval simulations, and future work will focus on refining the model to enhance biological realism and scalability.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repository
Its files are read in the Code ↔ Paper reader above, with 31 matches between paragraphs and lines of code.
sarahkcw/coral-larvae-abm
2b78a1f134a205493caf1611aa5953c3ad0b54be, 6 August 2026Availability: 1 check, the latest on 28 September 2026: the link answers
- 28 September 2026: the link answers
229 files
- Plotting/
01_import_training_data. , R, 215 linesR - Plotting/
02_analyze_training_sele , R, 319 linesction.R - Plotting/
03_import_hyperparameter , R, 220 lines_data.R - Plotting/
04_analyze_hyperparamete , R, 191 linesr_sensitivity.R - Plotting/
05_import_validation_dat , R, 200 linesa.R - Plotting/
06_analyze_validation_e1 , R, 396 lines, 1 match_e2.R - Plotting/
07_import_validation_e3. , R, 177 linesR - Plotting/
08_analyze_validation_e3 , R, 288 lines, 3 matches.R - Plotting/
09_nn_cue_ablation.py , Python, 659 lines, 3 matches - Plotting/
10_convergence_reliabili , Python, 116 lines, 2 matchesty.py - Plotting/
11_sim_vs_lab_gof.py , Python, 92 lines - Plotting/
11b_gof_e1_e3.py , Python, 73 lines - Plotting/
12_baselines_noise.py , Python, 141 lines - Plotting/
13_e1_patchsize_figure.p , Python, 48 lines, 1 matchy - Plotting/
17_effect_sizes.py , Python, 19 lines - Plotting/
18_weight_distribution.p , Python, 207 lines, 1 matchy - Plotting/
19_manuscript_distributi , Python, 103 lines, 1 matchon_figures.py - Plotting/
20_sensitivity_figures.p , Python, 104 lines, 2 matchesy - Plotting/
_plotstyle.py , Python, 55 lines - Plotting/
_valdata.py , Python, 28 lines - coral-larvae-abm/
Plotting/ , R, 59 linesV2dis.R - coral-larvae-abm/
Plotting/ , R, 116 linesV3dis.R - coral-larvae-abm/
Plotting/ , R, 55 linesbioparam.R - coral-larvae-abm/
Plotting/ , R, 22 lineschi.R - coral-larvae-abm/
Plotting/ , R, 33 linesdispersal.R - coral-larvae-abm/
Plotting/ , R, 28 linesexp1training.R - coral-larvae-abm/
Plotting/ , R, 65 linesexp2-v2.R - coral-larvae-abm/
Plotting/ , R, 68 linesexp2_New.R - coral-larvae-abm/
Plotting/ , R, 61 linesexp2_sens_new.R - coral-larvae-abm/
Plotting/ , R, 70 linesexp3_combined.R - coral-larvae-abm/
Plotting/ , R, 99 linesexp3_v2.R - coral-larvae-abm/
Plotting/ , R, 33 linesmodeltypes.R - coral-larvae-abm/
Plotting/ , R, 26 linessearchresults.R - coral-larvae-abm/
Plotting/ , R, 37 linessens2.R - coral-larvae-abm/
Plotting/ , R, 57 linessens2_v2.R - coral-larvae-abm/
Plotting/ , R, 37 linessens3.R - coral-larvae-abm/
Plotting/ , R, 42 linessens3_v2.R - coral-larvae-abm/
Plotting/ , R, 28 linessensexp1.R - coral-larvae-abm/
Plotting/ , R, 36 linesspatial.R - coral-larvae-abm/
Plotting/ , R, 44 linesspider.R - coral-larvae-abm/
Plotting/ , R, 26 linestraining_new.R - coral-larvae-abm/
Source/ , C/C++, 688 linesThirdParty/ Eigen/ Eigen/ src/ Cholesky/ LDLT.h - coral-larvae-abm/
Source/ , C/C++, 558 linesThirdParty/ Eigen/ Eigen/ src/ Cholesky/ LLT.h - coral-larvae-abm/
Source/ , C/C++, 99 linesThirdParty/ Eigen/ Eigen/ src/ Cholesky/ LLT_LAPACKE.h - coral-larvae-abm/
Source/ , C/C++, 682 linesThirdParty/ Eigen/ Eigen/ src/ CholmodSupport/ CholmodSupport.h - coral-larvae-abm/
Source/ , C/C++, 346 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ ComplexEigenSolver.h - coral-larvae-abm/
Source/ , C/C++, 462 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ ComplexSchur.h - coral-larvae-abm/
Source/ , C/C++, 91 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ ComplexSchur_LAPACKE.h - coral-larvae-abm/
Source/ , C/C++, 622 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ EigenSolver.h - coral-larvae-abm/
Source/ , C/C++, 418 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ GeneralizedEigenSolver.h - coral-larvae-abm/
Source/ , C/C++, 226 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ GeneralizedSelfAdjointEi genSolver.h - coral-larvae-abm/
Source/ , C/C++, 374 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ HessenbergDecomposition. h - coral-larvae-abm/
Source/ , C/C++, 158 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ MatrixBaseEigenvalues.h - coral-larvae-abm/
Source/ , C/C++, 657 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ RealQZ.h - coral-larvae-abm/
Source/ , C/C++, 558 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ RealSchur.h - coral-larvae-abm/
Source/ , C/C++, 77 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ RealSchur_LAPACKE.h - coral-larvae-abm/
Source/ , C/C++, 904 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ SelfAdjointEigenSolver.h - coral-larvae-abm/
Source/ , C/C++, 87 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ SelfAdjointEigenSolver_L APACKE.h - coral-larvae-abm/
Source/ , C/C++, 561 linesThirdParty/ Eigen/ Eigen/ src/ Eigenvalues/ Tridiagonalization.h - coral-larvae-abm/
Source/ , C/C++, 486 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ AlignedBox.h - coral-larvae-abm/
Source/ , C/C++, 247 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ AngleAxis.h - coral-larvae-abm/
Source/ , C/C++, 114 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ EulerAngles.h - coral-larvae-abm/
Source/ , C/C++, 501 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ Homogeneous.h - coral-larvae-abm/
Source/ , C/C++, 282 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ Hyperplane.h - coral-larvae-abm/
Source/ , C/C++, 235 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ OrthoMethods.h - coral-larvae-abm/
Source/ , C/C++, 232 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ ParametrizedLine.h - coral-larvae-abm/
Source/ , C/C++, 870 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ Quaternion.h - coral-larvae-abm/
Source/ , C/C++, 199 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ Rotation2D.h - coral-larvae-abm/
Source/ , C/C++, 206 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ RotationBase.h - coral-larvae-abm/
Source/ , C/C++, 188 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ Scaling.h - coral-larvae-abm/
Source/ , C/C++, 1,563 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ Transform.h - coral-larvae-abm/
Source/ , C/C++, 202 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ Translation.h - coral-larvae-abm/
Source/ , C/C++, 166 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ Umeyama.h - coral-larvae-abm/
Source/ , C/C++, 168 linesThirdParty/ Eigen/ Eigen/ src/ Geometry/ arch/ Geometry_SIMD.h - coral-larvae-abm/
Source/ , C/C++, 110 linesThirdParty/ Eigen/ Eigen/ src/ Householder/ BlockHouseholder.h - coral-larvae-abm/
Source/ , C/C++, 176 linesThirdParty/ Eigen/ Eigen/ src/ Householder/ Householder.h - coral-larvae-abm/
Source/ , C/C++, 545 linesThirdParty/ Eigen/ Eigen/ src/ Householder/ HouseholderSequence.h - coral-larvae-abm/
Source/ , C/C++, 226 linesThirdParty/ Eigen/ Eigen/ src/ IterativeLinearSolvers/ BasicPreconditioners.h - coral-larvae-abm/
Source/ , C/C++, 212 linesThirdParty/ Eigen/ Eigen/ src/ IterativeLinearSolvers/ BiCGSTAB.h - coral-larvae-abm/
Source/ , C/C++, 229 linesThirdParty/ Eigen/ Eigen/ src/ IterativeLinearSolvers/ ConjugateGradient.h - coral-larvae-abm/
Source/ , C/C++, 394 linesThirdParty/ Eigen/ Eigen/ src/ IterativeLinearSolvers/ IncompleteCholesky.h - coral-larvae-abm/
Source/ , C/C++, 453 linesThirdParty/ Eigen/ Eigen/ src/ IterativeLinearSolvers/ IncompleteLUT.h - coral-larvae-abm/
Source/ , C/C++, 444 linesThirdParty/ Eigen/ Eigen/ src/ IterativeLinearSolvers/ IterativeSolverBase.h - coral-larvae-abm/
Source/ , C/C++, 198 linesThirdParty/ Eigen/ Eigen/ src/ IterativeLinearSolvers/ LeastSquareConjugateGrad ient.h - coral-larvae-abm/
Source/ , C/C++, 117 linesThirdParty/ Eigen/ Eigen/ src/ IterativeLinearSolvers/ SolveWithGuess.h - coral-larvae-abm/
Source/ , C/C++, 483 linesThirdParty/ Eigen/ Eigen/ src/ Jacobi/ Jacobi.h - coral-larvae-abm/
Source/ , C/C++, 358 linesThirdParty/ Eigen/ Eigen/ src/ KLUSupport/ KLUSupport.h - coral-larvae-abm/
Source/ , C/C++, 117 linesThirdParty/ Eigen/ Eigen/ src/ LU/ Determinant.h - coral-larvae-abm/
Source/ , C/C++, 877 linesThirdParty/ Eigen/ Eigen/ src/ LU/ FullPivLU.h - coral-larvae-abm/
Source/ , C/C++, 432 linesThirdParty/ Eigen/ Eigen/ src/ LU/ InverseImpl.h - coral-larvae-abm/
Source/ , C/C++, 624 linesThirdParty/ Eigen/ Eigen/ src/ LU/ PartialPivLU.h - coral-larvae-abm/
Source/ , C/C++, 83 linesThirdParty/ Eigen/ Eigen/ src/ LU/ PartialPivLU_LAPACKE.h - coral-larvae-abm/
Source/ , C/C++, 351 linesThirdParty/ Eigen/ Eigen/ src/ LU/ arch/ InverseSize4.h - coral-larvae-abm/
Source/ , C/C++, 137 linesThirdParty/ Eigen/ Eigen/ src/ MetisSupport/ MetisSupport.h - coral-larvae-abm/
Source/ , C/C++, 435 linesThirdParty/ Eigen/ Eigen/ src/ OrderingMethods/ Amd.h - coral-larvae-abm/
Source/ , C/C++, 1,863 linesThirdParty/ Eigen/ Eigen/ src/ OrderingMethods/ Eigen_Colamd.h - coral-larvae-abm/
Source/ , C/C++, 153 linesThirdParty/ Eigen/ Eigen/ src/ OrderingMethods/ Ordering.h - coral-larvae-abm/
Source/ , C/C++, 678 linesThirdParty/ Eigen/ Eigen/ src/ PaStiXSupport/ PaStiXSupport.h - coral-larvae-abm/
Source/ , C/C++, 545 linesThirdParty/ Eigen/ Eigen/ src/ PardisoSupport/ PardisoSupport.h - coral-larvae-abm/
Source/ , C/C++, 674 linesThirdParty/ Eigen/ Eigen/ src/ QR/ ColPivHouseholderQR.h - coral-larvae-abm/
Source/ , C/C++, 97 linesThirdParty/ Eigen/ Eigen/ src/ QR/ ColPivHouseholderQR_LAPA CKE.h - coral-larvae-abm/
Source/ , C/C++, 635 linesThirdParty/ Eigen/ Eigen/ src/ QR/ CompleteOrthogonalDecomp osition.h - coral-larvae-abm/
Source/ , C/C++, 713 linesThirdParty/ Eigen/ Eigen/ src/ QR/ FullPivHouseholderQR.h - coral-larvae-abm/
Source/ , C/C++, 434 linesThirdParty/ Eigen/ Eigen/ src/ QR/ HouseholderQR.h - coral-larvae-abm/
Source/ , C/C++, 68 linesThirdParty/ Eigen/ Eigen/ src/ QR/ HouseholderQR_LAPACKE.h - coral-larvae-abm/
Source/ , C/C++, 335 linesThirdParty/ Eigen/ Eigen/ src/ SPQRSupport/ SuiteSparseQRSupport.h - coral-larvae-abm/
Source/ , C/C++, 1,366 linesThirdParty/ Eigen/ Eigen/ src/ SVD/ BDCSVD.h - coral-larvae-abm/
Source/ , C/C++, 812 linesThirdParty/ Eigen/ Eigen/ src/ SVD/ JacobiSVD.h - coral-larvae-abm/
Source/ , C/C++, 91 linesThirdParty/ Eigen/ Eigen/ src/ SVD/ JacobiSVD_LAPACKE.h - coral-larvae-abm/
Source/ , C/C++, 376 linesThirdParty/ Eigen/ Eigen/ src/ SVD/ SVDBase.h - coral-larvae-abm/
Source/ , C/C++, 414 linesThirdParty/ Eigen/ Eigen/ src/ SVD/ UpperBidiagonalization.h - coral-larvae-abm/
Source/ , C/C++, 697 linesThirdParty/ Eigen/ Eigen/ src/ SparseCholesky/ SimplicialCholesky.h - coral-larvae-abm/
Source/ , C/C++, 174 linesThirdParty/ Eigen/ Eigen/ src/ SparseCholesky/ SimplicialCholesky_impl. h - coral-larvae-abm/
Source/ , C/C++, 378 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ AmbiVector.h - coral-larvae-abm/
Source/ , C/C++, 274 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ CompressedStorage.h - coral-larvae-abm/
Source/ , C/C++, 352 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ ConservativeSparseSparse Product.h - coral-larvae-abm/
Source/ , C/C++, 67 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ MappedSparseMatrix.h - coral-larvae-abm/
Source/ , C/C++, 270 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseAssign.h - coral-larvae-abm/
Source/ , C/C++, 571 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseBlock.h - coral-larvae-abm/
Source/ , C/C++, 206 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseColEtree.h - coral-larvae-abm/
Source/ , C/C++, 370 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseCompressedBase.h - coral-larvae-abm/
Source/ , C/C++, 722 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseCwiseBinaryOp.h - coral-larvae-abm/
Source/ , C/C++, 150 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseCwiseUnaryOp.h - coral-larvae-abm/
Source/ , C/C++, 342 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseDenseProduct.h - coral-larvae-abm/
Source/ , C/C++, 138 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseDiagonalProduct.h - coral-larvae-abm/
Source/ , C/C++, 98 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseDot.h - coral-larvae-abm/
Source/ , C/C++, 29 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseFuzzy.h - coral-larvae-abm/
Source/ , C/C++, 305 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseMap.h - coral-larvae-abm/
Source/ , C/C++, 1,518 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseMatrix.h - coral-larvae-abm/
Source/ , C/C++, 398 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseMatrixBase.h - coral-larvae-abm/
Source/ , C/C++, 178 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparsePermutation.h - coral-larvae-abm/
Source/ , C/C++, 181 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseProduct.h - coral-larvae-abm/
Source/ , C/C++, 49 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseRedux.h - coral-larvae-abm/
Source/ , C/C++, 397 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseRef.h - coral-larvae-abm/
Source/ , C/C++, 659 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseSelfAdjointView.h - coral-larvae-abm/
Source/ , C/C++, 124 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseSolverBase.h - coral-larvae-abm/
Source/ , C/C++, 198 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseSparseProductWithP runing.h - coral-larvae-abm/
Source/ , C/C++, 92 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseTranspose.h - coral-larvae-abm/
Source/ , C/C++, 189 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseTriangularView.h - coral-larvae-abm/
Source/ , C/C++, 186 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseUtil.h - coral-larvae-abm/
Source/ , C/C++, 478 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseVector.h - coral-larvae-abm/
Source/ , C/C++, 254 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ SparseView.h - coral-larvae-abm/
Source/ , C/C++, 315 linesThirdParty/ Eigen/ Eigen/ src/ SparseCore/ TriangularSolver.h - coral-larvae-abm/
Source/ , C/C++, 923 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU.h - coral-larvae-abm/
Source/ , C/C++, 66 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLUImpl.h - coral-larvae-abm/
Source/ , C/C++, 226 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_Memory.h - coral-larvae-abm/
Source/ , C/C++, 110 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_Structs.h - coral-larvae-abm/
Source/ , C/C++, 375 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_SupernodalMatri x.h - coral-larvae-abm/
Source/ , C/C++, 80 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_Utils.h - coral-larvae-abm/
Source/ , C/C++, 181 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_column_bmod.h - coral-larvae-abm/
Source/ , C/C++, 179 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_column_dfs.h - coral-larvae-abm/
Source/ , C/C++, 107 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_copy_to_ucol.h - coral-larvae-abm/
Source/ , C/C++, 280 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_gemm_kernel.h - coral-larvae-abm/
Source/ , C/C++, 126 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_heap_relax_snod e.h - coral-larvae-abm/
Source/ , C/C++, 130 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_kernel_bmod.h - coral-larvae-abm/
Source/ , C/C++, 223 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_panel_bmod.h - coral-larvae-abm/
Source/ , C/C++, 258 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_panel_dfs.h - coral-larvae-abm/
Source/ , C/C++, 137 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_pivotL.h - coral-larvae-abm/
Source/ , C/C++, 136 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_pruneL.h - coral-larvae-abm/
Source/ , C/C++, 83 linesThirdParty/ Eigen/ Eigen/ src/ SparseLU/ SparseLU_relax_snode.h - coral-larvae-abm/
Source/ , C/C++, 758 linesThirdParty/ Eigen/ Eigen/ src/ SparseQR/ SparseQR.h - coral-larvae-abm/
Source/ , C/C++, 116 linesThirdParty/ Eigen/ Eigen/ src/ StlSupport/ StdDeque.h - coral-larvae-abm/
Source/ , C/C++, 106 linesThirdParty/ Eigen/ Eigen/ src/ StlSupport/ StdList.h - coral-larvae-abm/
Source/ , C/C++, 131 linesThirdParty/ Eigen/ Eigen/ src/ StlSupport/ StdVector.h - coral-larvae-abm/
Source/ , C/C++, 84 linesThirdParty/ Eigen/ Eigen/ src/ StlSupport/ details.h - coral-larvae-abm/
Source/ , C/C++, 1,025 linesThirdParty/ Eigen/ Eigen/ src/ SuperLUSupport/ SuperLUSupport.h - coral-larvae-abm/
Source/ , C/C++, 642 linesThirdParty/ Eigen/ Eigen/ src/ UmfPackSupport/ UmfPackSupport.h - coral-larvae-abm/
Source/ , C/C++, 82 linesThirdParty/ Eigen/ Eigen/ src/ misc/ Image.h - coral-larvae-abm/
Source/ , C/C++, 79 linesThirdParty/ Eigen/ Eigen/ src/ misc/ Kernel.h - coral-larvae-abm/
Source/ , C/C++, 55 linesThirdParty/ Eigen/ Eigen/ src/ misc/ RealSvd2x2.h - coral-larvae-abm/
Source/ , C/C++, 440 linesThirdParty/ Eigen/ Eigen/ src/ misc/ blas.h - coral-larvae-abm/
Source/ , C/C++, 152 linesThirdParty/ Eigen/ Eigen/ src/ misc/ lapack.h - coral-larvae-abm/
Source/ , C/C++, 3,202 linesThirdParty/ Eigen/ Eigen/ src/ misc/ lapacke.h - coral-larvae-abm/
Source/ , C/C++, 17 linesThirdParty/ Eigen/ Eigen/ src/ misc/ lapacke_mangling.h - coral-larvae-abm/
Source/ , C/C++, 358 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ ArrayCwiseBinaryOps.h - coral-larvae-abm/
Source/ , C/C++, 696 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ ArrayCwiseUnaryOps.h - coral-larvae-abm/
Source/ , C/C++, 1,442 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ BlockMethods.h - coral-larvae-abm/
Source/ , C/C++, 115 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ CommonCwiseBinaryOps.h - coral-larvae-abm/
Source/ , C/C++, 177 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ CommonCwiseUnaryOps.h - coral-larvae-abm/
Source/ , C/C++, 262 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ IndexedViewMethods.h - coral-larvae-abm/
Source/ , C/C++, 152 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ MatrixCwiseBinaryOps.h - coral-larvae-abm/
Source/ , C/C++, 95 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ MatrixCwiseUnaryOps.h - coral-larvae-abm/
Source/ , C/C++, 149 linesThirdParty/ Eigen/ Eigen/ src/ plugins/ ReshapedMethods.h - coral-larvae-abm/
Source/ , C++, 266 lines, 1 matchcoral_larvae_abm/ Private/ Agent/ AgentBrainComponent.cpp - coral-larvae-abm/
Source/ , C++, 209 linescoral_larvae_abm/ Private/ Agent/ GenomeFunctions.cpp - coral-larvae-abm/
Source/ , C++, 655 lines, 2 matchescoral_larvae_abm/ Private/ Agent/ LarvaAgent.cpp - coral-larvae-abm/
Source/ , C++, 125 linescoral_larvae_abm/ Private/ Agent/ NeuralNetFunctions.cpp - coral-larvae-abm/
Source/ , C++, 114 linescoral_larvae_abm/ Private/ Agent/ Threading/ AgentSimTask.cpp - coral-larvae-abm/
Source/ , C++, 2 linescoral_larvae_abm/ Private/ BpFunctions.cpp - coral-larvae-abm/
Source/ , C++, 236 linescoral_larvae_abm/ Private/ DataGrid/ DataGrid.cpp - coral-larvae-abm/
Source/ , C++, 75 linescoral_larvae_abm/ Private/ DataGrid/ DataGridOrganizer.cpp - coral-larvae-abm/
Source/ , C++, 416 lines, 3 matchescoral_larvae_abm/ Private/ DataGrid/ DataGridPreprocessor.cpp - coral-larvae-abm/
Source/ , C++, 129 linescoral_larvae_abm/ Private/ DataGrid/ DataGridUtils.cpp - coral-larvae-abm/
Source/ , C++, 197 linescoral_larvae_abm/ Private/ DataGrid/ DataGridVisualizer.cpp - coral-larvae-abm/
Source/ , C++, 32 linescoral_larvae_abm/ Private/ DataGrid/ DebugControlSphere.cpp - coral-larvae-abm/
Source/ , C++, 406 linescoral_larvae_abm/ Private/ EvolutionManager.cpp - coral-larvae-abm/
Source/ , C++, 759 lines, 1 matchcoral_larvae_abm/ Private/ Experiments/ ResultAnalysisFunctions. cpp - coral-larvae-abm/
Source/ , C++, 1,787 lines, 1 matchcoral_larvae_abm/ Private/ SimulationManager.cpp - coral-larvae-abm/
Source/ , C/C++, 84 linescoral_larvae_abm/ Public/ Actions/ Actions.h - coral-larvae-abm/
Source/ , C/C++, 113 linescoral_larvae_abm/ Public/ Actions/ BaseActionComponent.h - coral-larvae-abm/
Source/ , C/C++, 29 linescoral_larvae_abm/ Public/ Agent/ AgentBrainComponent.h - coral-larvae-abm/
Source/ , C/C++, 100 linescoral_larvae_abm/ Public/ Agent/ GenomeFunctions.h - coral-larvae-abm/
Source/ , C/C++, 257 lines, 2 matchescoral_larvae_abm/ Public/ Agent/ LarvaAgent.h - coral-larvae-abm/
Source/ , C/C++, 29 linescoral_larvae_abm/ Public/ Agent/ NeuralNetFunctions.h - coral-larvae-abm/
Source/ , C/C++, 52 linescoral_larvae_abm/ Public/ Agent/ Threading/ AgentSimTask.h - coral-larvae-abm/
Source/ , C/C++, 122 linescoral_larvae_abm/ Public/ BpFunctions.h - coral-larvae-abm/
Source/ , C/C++, 36 linescoral_larvae_abm/ Public/ DataGrid/ DataGrid.h - coral-larvae-abm/
Source/ , C/C++, 74 linescoral_larvae_abm/ Public/ DataGrid/ DataGridOrganizer.h - coral-larvae-abm/
Source/ , C/C++, 64 linescoral_larvae_abm/ Public/ DataGrid/ DataGridPreprocessor.h - coral-larvae-abm/
Source/ , C/C++, 130 linescoral_larvae_abm/ Public/ DataGrid/ DataGridStructs.h - coral-larvae-abm/
Source/ , C/C++, 28 linescoral_larvae_abm/ Public/ DataGrid/ DataGridUtils.h - coral-larvae-abm/
Source/ , C/C++, 70 linescoral_larvae_abm/ Public/ DataGrid/ DataGridVisualizer.h - coral-larvae-abm/
Source/ , C/C++, 32 linescoral_larvae_abm/ Public/ DataGrid/ DebugControlSphere.h - coral-larvae-abm/
Source/ , C/C++, 93 lines, 1 matchcoral_larvae_abm/ Public/ EvolutionManager.h - coral-larvae-abm/
Source/ , C/C++, 52 lines, 1 matchcoral_larvae_abm/ Public/ Experiments/ ResultAnalysisFunctions. h - coral-larvae-abm/
Source/ , C/C++, 102 lines, 1 matchcoral_larvae_abm/ Public/ GenomeAnalysisFunctions. h - coral-larvae-abm/
Source/ , C/C++, 94 linescoral_larvae_abm/ Public/ SensorActionMapping.h - coral-larvae-abm/
Source/ , C/C++, 162 linescoral_larvae_abm/ Public/ Sensors/ ChemicalSensors.h - coral-larvae-abm/
Source/ , C/C++, 54 linescoral_larvae_abm/ Public/ Sensors/ HydromechanicalSensors.h - coral-larvae-abm/
Source/ , C/C++, 76 lines, 1 matchcoral_larvae_abm/ Public/ Sensors/ LarvalSensorBaseComponen t.h - coral-larvae-abm/
Source/ , C/C++, 42 linescoral_larvae_abm/ Public/ Sensors/ LightSensors.h - coral-larvae-abm/
Source/ , C/C++, 124 linescoral_larvae_abm/ Public/ Sensors/ SensorFunctions.h - coral-larvae-abm/
Source/ , C/C++, 56 linescoral_larvae_abm/ Public/ Sensors/ Sensors.h - coral-larvae-abm/
Source/ , C/C++, 90 linescoral_larvae_abm/ Public/ Sensors/ SoundSensors.h - coral-larvae-abm/
Source/ , C/C++, 279 lines, 3 matchescoral_larvae_abm/ Public/ SimulationManager.h - coral-larvae-abm/
Source/ , C++, 6 linescoral_larvae_abm/ coral_larvae_abm.cpp - coral-larvae-abm/
Source/ , C/C++, 6 linescoral_larvae_abm/ coral_larvae_abm.h - LICENSE, License, 21 lines
- README.md, Text, 44 lines
The paper's code and data availability statement is in the Data section.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 227 scripts, each with its path and the digest of its content;
- 31 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data Availability
Yes - all data are fully available without restriction; All datasets generated and analysed in this study are openly available. The per-run and per-agent training and validation exports, together with the evolved genomes, are archived on Zenodo (doi.org/
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 28 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 3 authors, 8 MeSH terms, 27 references.
Cite
This paper
Wolpold, S., Voolstra, C. R., & von Mammen, S. (2026). A neuroevolution-driven agent-based model of coral larvae settlement. PloS one, 21(9), e0359316. https://
BibTeX
@article{wolpold2026neur
author = {Wolpold, Sarah and Voolstra, Christian R. and von Mammen, Sebastian},
title = {{A neuroevolution-driven agent-based model of coral larvae settlement}},
journal = {PloS one},
year = {2026},
month = sep,
volume = {21},
number = {9},
pages = {e0359316},
publisher = {PLOS},
issn = {1932-6203},
doi = {10.1371/
url = {https://
pmid = {42789678},
pmcid = {PMC13614647}
}
RIS
TY - JOUR
AU - Wolpold, Sarah
AU - Voolstra, Christian R.
AU - von Mammen, Sebastian
TI - A neuroevolution-driven agent-based model of coral larvae settlement
T2 - PloS one
J2 - PLoS One
PY - 2026
DA - 2026/
VL - 21
IS - 9
SP - e0359316
SN - 1932-6203
PB - PLOS
DO - 10.1371/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1371/
"type": "article-journal",
"title": "A neuroevolution-driven agent-based model of coral larvae settlement",
"container-title": "PloS one",
"author": [
{
"family": "Wolpold",
"given": "Sarah"
},
{
"family": "Voolstra",
"given": "Christian R."
},
{
"family": "von Mammen",
"given": "Sebastian"
}
],
"container-title-short":
"volume": "21",
"issue": "9",
"page": "e0359316",
"DOI": "10.1371/
"PMID": "42789678",
"PMCID": "PMC13614647",
"ISSN": "1932-6203",
"publisher": "PLOS",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
9,
25
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1038/s41592-026-03211-w [code]
- Spatial isoform sequencing at single-cell resolution reveals cell-type-specific spatial isoform variability in multiple brain cell types.Journal: Nature methodsIn common: cowplot, reshape2, ggplot2, 4 other tools
- [2] doi:10.1038/s41592-026-03194-8 [code]
- Beyond benchmarking: an expert-guided consensus approach to spatially aware clustering.Journal: Nature methodsIn common: cowplot, reshape2, ggplot2, 4 other tools
- [3] doi:10.1038/s41467-026-76939-w [code]
- HIPPIE: a generative model for electrophysiological analysis across species, technologies, and modalities.Journal: Nature communicationsIn common: cowplot, reshape2, ggplot2, 4 other tools
- [4] doi:10.1002/imt2.70163 [code]
- Spatial multi-omics unveils sphingolipid metabolic reprogramming within the retinal pathological niche.Journal: iMetaIn common: cowplot, reshape2, ggplot2, 4 other tools
- [5] doi:10.1038/s41467-026-76675-1 [code]
- Long-read proteogenomic atlas of human neuronal differentiation reveals isoform diversity informing neurodevelopmental risk mechanisms.Journal: Nature communicationsIn common: cowplot, reshape2, ggplot2, 4 other tools
- [6] doi:10.1126/sciadv.aeg3223 [code]
- The extreme diversity of retinal amacrine cells has deep evolutionary roots.Journal: Science advancesIn common: cowplot, reshape2, ggplot2, 4 other tools
- [7] doi:10.7554/elife.93640 [code]
- Sibling chimerism among microglia in marmosets.Journal: eLifeIn common: cowplot, reshape2, ggplot2, 4 other tools
- [8] doi:10.1093/bioinformatics/btag592 [code]
- Network-based stratification of allele-specific expression reveals patient subgroups in Huntington's disease.Journal: Bioinformatics (Oxford, England)In common: cowplot, reshape2, ggplot2, 4 other tools
- [9] doi:10.1038/s41467-026-75722-1 [code]
- Single-nucleus analysis of the adult human olfactory epithelium uncovers shared neurogenesis programs with the brain.Journal: Nature communicationsIn common: cowplot, reshape2, ggplot2, 4 other tools
- [10] doi:10.1186/s13073-026-01704-z [code]
- Gene expression profiling enables refined parcellation of cortical layers in the heterogeneous human cerebral cortex.Journal: Genome medicineIn common: cowplot, reshape2, ggplot2, 4 other tools
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 227 scripts, and 31 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:8aadb5c547b42daa…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
