Skip to content

perf: Optimise thermotaxis simulations - #44

Merged
chrisjz merged 39 commits into
mainfrom
feature/optimize-thermotaxis
Jan 26, 2026
Merged

perf: Optimise thermotaxis simulations#44
chrisjz merged 39 commits into
mainfrom
feature/optimize-thermotaxis

Conversation

@chrisjz

@chrisjz chrisjz commented Jan 26, 2026

Copy link
Copy Markdown
Member

Changes:

  • Add temperature safe zones for foraging allocations.
  • Add brave rewarding.
  • Add penalty on receiving damage.
  • Tweak thermotaxis configs as new baselines for benchmarking.
  • Create logbook 007 with thermotaxis benchmarking.
  • Log entire simulation configs.
  • Create new artifacts subdirectory for logbook artifacts. Move existing 005 logbook results there.

Addresses #37

Summary by CodeRabbit

  • New Features

    • Added 9 PPO thermotaxis baseline configs (3 tasks × 3 sizes).
    • Safe-zone biased food spawning to favor safe temperatures when enabled.
    • Brave-foraging bonus for collecting food in discomfort zones.
  • Behavior / Perception

    • Thermotaxis now emits richer classical signals (expanded temperature features).
    • Stronger immediate temperature-related health penalties and adjusted reward shaping.
  • Tests

    • Extensive tests for zones, brave-foraging, and safe-zone spawning.
  • Documentation

    • Published logbook 007 and updated experiments README.

✏️ Tip: You can customize this high-level summary in your review settings.

chrisjz added 30 commits January 4, 2026 13:47
Decently balances foraging vs navigating dangerous temperature zones
Baslines for all medium configs
@coderabbitai

coderabbitai Bot commented Jan 26, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds nine PPO thermotaxis baseline configs (3 tasks × 3 sizes), implements safe-zone biased food spawning and reward fields, extends sensory classical features (thermotaxis includes temperature deviation), applies brave-foraging and temperature HP-damage into runner rewards, and updates tests, docs, and example configs.

Changes

Cohort / File(s) Summary
Baseline experiment configs
artifacts/logbooks/007/ppo_foraging_*/ppo_thermotaxis_foraging_*.yml, artifacts/logbooks/007/ppo_pursuit_*/ppo_thermotaxis_pursuit_predators_*.yml, artifacts/logbooks/007/ppo_stationary_*/ppo_thermotaxis_stationary_predators_*.yml
Adds 9 new YAML configs defining PPO hyperparameters, sensory modules, foraging/predator/health mechanics, and thermotaxis (hot/cold spots, zone thresholds, spot decay).
Example configs
configs/examples/ppo_thermotaxis_*.yml
Updates example configs: temperature ranges, lr warmup/decay, foraging/predator params, health/healing, and thermotaxis schema (comfort/discomfort/danger penalties, reward_discomfort_food, spot lists).
Sensory modules API
packages/quantum-nematode/quantumnematode/brain/modules.py
Adds classical_dim per SensoryModule (default 2), sets Thermotaxis to 3, updates to_classical(), extract_classical_features(), and get_classical_feature_dimension() to support variable-length classical features.
Environment & spawning
packages/quantum-nematode/quantumnematode/env/env.py
Adds ForagingParams.safe_zone_food_bias, ThermotaxisParams.reward_discomfort_food, _is_safe_temperature_zone() helper, and biases _initialize_foods()/spawn_food() toward safe temperature zones when configured.
Config loader
packages/quantum-nematode/quantumnematode/utils/config_loader.py
Propagates new safe_zone_food_bias and reward_discomfort_food fields from configs into Params objects.
Runner / reward integration
packages/quantum-nematode/quantumnematode/agent/runners.py
Grants brave-foraging bonus when food collected in DISCOMFORT zones, applies immediate HP-damage penalties into reward signals, and surfaces brave messages in food-collection logs.
Brain init logging cleanup
packages/quantum-nematode/quantumnematode/brain/arch/*.py
Removes informational config-print logging from multiple brain init files (mlp, modular, ppo, qmlp, spiking); no behavioral change.
Tests
packages/quantum-nematode/tests/.../test_runners.py, .../test_modules.py, .../env/test_env.py
Adds extensive tests for temperature HP damage, brave foraging bonuses, classical feature dimensions/extraction, and safe-zone food spawning (bias statistics and edge cases).
Docs & logbook
docs/experiments/README.md, docs/experiments/logbooks/007-ppo-thermotaxis-baselines.md
Adds experiment entry and a comprehensive logbook describing methodology, per-config results, tuning notes, and config evolution.
OpenSpec task doc
openspec/changes/add-multi-sensory-environment/tasks.md
Documents implemented safe-zone spawning approach and new safe_zone_food_bias param.
Scripts
scripts/run_simulation.py, scripts/run_evolution.py
Adds early/init logging for config loading and centralizes logger level setup in run_simulation.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant ConfigLoader as ConfigLoader
participant Env as DynamicForagingEnvironment
participant Runner as AgentRunner
participant Brain as PPOBrain
participant Logger as Logger

ConfigLoader->>Env: load ForagingParams (safe_zone_food_bias) and ThermotaxisParams (spots, reward_discomfort_food)
Env->>Env: _initialize_foods() (apply safe_zone_food_bias via _is_safe_temperature_zone)
Runner->>Env: step(action)
Env->>Env: compute temperature at agent pos (gradient + hot/cold spots)
Env->>Runner: observation (classical features + sensory inputs)
Runner->>Brain: forward(observation)
Brain-->>Runner: action
Runner->>Env: perform action (may collect food)
Env->>Runner: on food collect: apply reward, add brave bonus if DISCOMFORT, apply temp HP damage penalty
Runner->>Logger: log reward components (including brave_msg and HP damage)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

benchmark

🐰 I hopped across configs, code, and test—
Safe spots planted, brave snacks blessed—
Agents learn warmth, avoid the rest,
A joyful nibble, then back to the nest.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'perf: Optimise thermotaxis simulations' accurately summarizes the primary focus of the changeset, which involves performance optimization and configuration tuning of thermotaxis-based simulation scenarios.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Jan 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.48936% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../quantum-nematode/quantumnematode/brain/modules.py 80.00% 1 Missing and 1 partial ⚠️
...ckages/quantum-nematode/quantumnematode/env/env.py 89.47% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🤖 Fix all issues with AI agents
In
`@artifacts/logbooks/007/ppo_foraging_medium/ppo_thermotaxis_foraging_medium.yml`:
- Around line 75-77: Mismatch: target_foods_to_collect (20) is greater than
foods_on_grid (15), forcing respawn waits that contradict the comment about
"More food available...". Fix by either increasing the foraging.foods_on_grid
value to at least match foraging.target_foods_to_collect (or higher) so agents
don't rely on respawns, or change foraging.target_foods_to_collect down to <=
foods_on_grid; alternatively update the descriptive comment to explicitly state
that respawn/waiting is expected for medium difficulty. Reference the keys
target_foods_to_collect and foods_on_grid and ensure the comment describing food
availability is updated to reflect the chosen behavior.

In
`@artifacts/logbooks/007/ppo_pursuit_large/ppo_thermotaxis_pursuit_predators_large.yml`:
- Around line 18-20: The logbook header claims "Food biased toward safe
temperature zones" but the foraging configuration does not set the
safe_zone_food_bias key (it currently defaults to 0.0); either add the
safe_zone_food_bias field under the foraging section with the intended numeric
bias (e.g., >0) or edit the header/comment to remove the claim—apply the same
fix for the other occurrence referenced around lines 91-98 so the header and the
foraging.safe_zone_food_bias setting are consistent.

In `@configs/examples/ppo_thermotaxis_pursuit_predators_large.yml`:
- Around line 91-95: Header claims "Food biased toward safe temperature zones"
but the foraging block lacks the safe_zone_food_bias setting (defaults to 0.0).
Add an explicit safe_zone_food_bias key in the foraging section (e.g.,
safe_zone_food_bias: 0.8 or another appropriate non-zero value) to align the
config with the header, or alternatively update the header text to remove the
bias claim if you prefer uniform distribution.

In `@configs/examples/ppo_thermotaxis_stationary_predators_medium.yml`:
- Around line 86-87: The config sets foods_on_grid: 15 but
target_foods_to_collect: 20, which is inconsistent; either make
target_foods_to_collect <= foods_on_grid or increase foods_on_grid to match if
respawning is unintended, or add an explicit comment/flag indicating respawn
behavior is expected for medium difficulty; update the keys foods_on_grid and
target_foods_to_collect in ppo_thermotaxis_stationary_predators_medium.yml
accordingly so the intended behavior is clear and consistent.

In `@configs/examples/ppo_thermotaxis_stationary_predators_small.yml`:
- Around line 110-115: The config sets comfort_reward and discomfort_penalty to
0.0 which removes reward pressure for the stated “>60% comfort time” success
criterion; either restore a small shaping term (e.g., set comfort_reward > 0
and/or discomfort_penalty < 0) in the defaults or update the success-criteria
text to no longer imply reward-driven behavior, and add a clear documented
default and description for reward_discomfort_food alongside other config
defaults; update the config defaults and the documentation block so explicit
overrides remain visible and consistent (look for the comfort_reward,
discomfort_penalty, and reward_discomfort_food entries to change and document).

In `@docs/experiments/logbooks/007-ppo-thermotaxis-baselines.md`:
- Around line 503-506: The document contains an internal inconsistency: the
"Small/medium need comfort_reward: 0.05" entry (the numbered list around the
"Gradient decay matters" block) contradicts the "Final Configuration Summary"
that shows comfort_reward: 0.0; update the numbered list item to read
"Small/medium need comfort_reward: 0.0" (or add a short parenthetical note that
0.05 was an earlier iteration) so the "Small/medium need comfort_reward"
statement matches the actual config files (e.g.,
ppo_thermotaxis_foraging_small.yml) and the Final Configuration Summary.

In `@scripts/run_simulation.py`:
- Around line 243-251: Move the logging configuration block so it runs before
any log emissions (specifically before the first logger.info call that prints
the simulation seed); configure logger.disabled when log_level == "NONE" or set
logger.setLevel(log_level) and update each FileHandler's level (check
isinstance(handler, logging.FileHandler)) otherwise. Update the code around the
logger variable (the logging setup block currently shown) to execute before the
seed/info log to ensure --log-level NONE suppresses that output.
♻️ Duplicate comments (4)
configs/examples/ppo_thermotaxis_pursuit_predators_small.yml (2)

66-66: Same check on disabling damage penalty.
Line 66 mirrors the 0.0 penalty_health_damage change; please confirm it’s intended here as well.


111-116: Thermotaxis shaping neutralization noted.
Same concern as the stationary-small config about neutral comfort/discomfort shaping vs the success-criteria text.

configs/examples/ppo_thermotaxis_foraging_small.yml (2)

55-55: Same check on disabling damage penalty.
Line 55 sets penalty_health_damage to 0.0; confirming intent as in the other small baselines.


90-97: Thermotaxis shaping neutralization noted.
Same note as earlier small configs regarding comfort/discomfort shaping being zeroed.

🧹 Nitpick comments (5)
packages/quantum-nematode/tests/quantumnematode_tests/agent/test_runners.py (5)

660-663: Weak assertion doesn't validate brave bonus behavior.

The assertion assert agent._episode_tracker.rewards > 0 or agent._metrics_tracker.foods_collected > 0 is too permissive. It passes if either condition is true, but doesn't verify that the brave bonus was actually applied when food was collected in a discomfort zone.

Consider strengthening to verify the bonus was applied:

-        if agent._metrics_tracker.foods_collected > 0:
-            # Food collected means reward_goal was applied per food
-            # With reward_goal=2.0 and brave_bonus=0.5, each food gives at least 2.5
-            assert agent._episode_tracker.rewards > 0 or agent._metrics_tracker.foods_collected > 0
+        # If food was collected in discomfort zone, verify rewards include brave bonus
+        foods = agent._metrics_tracker.foods_collected
+        if foods > 0:
+            # Each food gives reward_goal (2.0) + brave_bonus (0.5) = 2.5 minimum
+            # Minus step penalties, rewards should still be positive with food collected
+            assert agent._episode_tracker.rewards > -foods * 2.5, (
+                f"Expected positive trend with {foods} foods collected at 2.5 each"
+            )

703-704: assert True is a no-op that doesn't validate zone handling.

This test claims to verify "comfort zone logic correctly skips brave bonus" but the assertion assert True validates nothing. If the brave bonus were incorrectly applied in comfort zones, this test would still pass.

Consider adding a meaningful assertion:

-        # Test passes if no errors - comfort zone logic correctly skips brave bonus
-        assert True
+        # Verify brave bonus was NOT applied (only reward_goal per food, no bonus)
+        # In comfort zone, each food gives exactly reward_goal (2.0)
+        if agent._metrics_tracker.foods_collected > 0:
+            # Check that total rewards align with food rewards minus step penalties
+            # Without brave bonus, rewards should be lower than with it
+            pass  # Or implement specific reward tracking for brave bonus

At minimum, consider tracking whether the brave bonus code path was executed.


738-740: Same issue: assert True doesn't validate danger zone behavior.

This test should verify that the brave bonus is not applied in danger zones, but assert True doesn't check anything.


774-777: Same issue: assert True doesn't validate disabled bonus behavior.

When reward_discomfort_food=0.0, the test should verify no bonus is applied, not just that no exception occurs.


571-618: Test logic validates penalty presence but not magnitude relationship.

The test comment says "more HP damage results in more penalty applications" but lines 615-618 only check that both rewards are negative. The test doesn't actually verify that reward_high_damage < reward_low_damage (i.e., more damage = more negative reward).

If the penalty is per-step regardless of damage amount, the assertion is correct but the test name/comment is misleading. Consider:

-        # Both should be negative (taking damage), and both should apply penalty per step
-        # The penalty is per-step when damage > 0, so with same steps, penalties are similar
-        assert reward_low_damage < 0, "Should have negative reward from HP damage penalty"
-        assert reward_high_damage < 0, "Should have negative reward from HP damage penalty"
+        # Both should be negative (taking damage)
+        # penalty_health_damage is applied per-step when damage > 0, regardless of amount
+        assert reward_low_damage < 0, "Should have negative reward from HP damage penalty"
+        assert reward_high_damage < 0, "Should have negative reward from HP damage penalty"
+        # Note: Penalties are similar because they're per-step, not proportional to damage

Or rename the test to test_temperature_hp_damage_penalty_applied_regardless_of_amount.

Comment thread configs/examples/ppo_thermotaxis_pursuit_predators_large.yml
Comment thread configs/examples/ppo_thermotaxis_stationary_predators_medium.yml
Comment thread configs/examples/ppo_thermotaxis_stationary_predators_small.yml
Comment thread docs/experiments/logbooks/007-ppo-thermotaxis-baselines.md Outdated
Comment thread scripts/run_simulation.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@configs/examples/ppo_thermotaxis_foraging_medium.yml`:
- Around line 59-60: The config sets reward_health_gain: 0.1 while
penalty_health_damage: 0.0 which effectively rewards taking damage then healing;
update the baseline by setting penalty_health_damage to a non-zero value (e.g.,
a small negative like 0.1 or a value that balances reward_health_gain) to
enforce the intended damage penalty, or alternatively add a clear
comment/documentation near reward_health_gain and penalty_health_damage stating
that damage is intentionally unpenalized in this baseline and why.

In `@configs/examples/ppo_thermotaxis_stationary_predators_large.yml`:
- Around line 119-127: The hot_spots and cold_spots temperature values are
inconsistent with cultivation_temperature (20.0); update the entries under
hot_spots and cold_spots so all hot_spots have temperatures > 20.0 (e.g.,
22.0–35.0) and all cold_spots have temperatures < 20.0 (e.g., 5.0–15.0);
specifically, change the cold_spots entry [25, 25, 25.0] to a value below 20.0
and change any hot_spots equal to 20.0 to >20.0 so the arrays hot_spots,
cold_spots, and the cultivation_temperature setting are consistent.
🧹 Nitpick comments (5)
docs/experiments/logbooks/007-ppo-thermotaxis-baselines.md (1)

108-115: Parameter table may cause confusion with tuned values.

The table shows danger_hp_damage as 2.0 for Small and 1.5 for Medium, but the detailed results sections document that these were tuned down (e.g., "Reduced danger_hp_damage: 1.5 → 1.0" for Medium configs at lines 207, 223, 239).

Consider either:

  1. Updating the table to show final tuned values, or
  2. Adding a note that these are initial values before tuning

This would help readers understand which values to use when replicating the experiments.

packages/quantum-nematode/tests/quantumnematode_tests/agent/test_runners.py (4)

564-570: Consider isolating the HP damage penalty assertion.

The test combines danger_penalty=-0.3 with penalty_health_damage=0.5, making it impossible to verify the HP damage penalty specifically contributed to the negative reward. For stronger test isolation, consider setting danger_penalty=0.0 (similar to the next test) to isolate the penalty_health_damage effect.

♻️ Suggested improvement
             thermotaxis=ThermotaxisParams(
                 enabled=True,
                 cultivation_temperature=20.0,
                 base_temperature=33.0,  # Danger zone (30-35°C)
                 gradient_strength=0.0,
                 danger_hp_damage=5.0,  # 5 HP damage per step
-                danger_penalty=-0.3,  # Zone penalty
+                danger_penalty=0.0,  # No zone penalty to isolate HP damage penalty
             ),

616-619: Test could verify the penalty-per-step claim.

The comment states the penalty is "applied per-step when damage > 0, regardless of amount," but the test only verifies both scenarios produce negative rewards. To confirm the penalty is indeed independent of damage amount (not proportional), consider asserting that both rewards are approximately equal, or if it's meant to be proportional, that higher damage produces more negative rewards.

♻️ Suggested assertion to verify fixed vs proportional penalty
         # Both should be negative (taking damage)
         # The penalty_health_damage is applied per-step when damage > 0, regardless of amount
         assert reward_low_damage < 0, "Should have negative reward from HP damage penalty"
         assert reward_high_damage < 0, "Should have negative reward from HP damage penalty"
+        # If penalty is fixed per-step (not proportional), rewards should be similar
+        # If proportional, high damage should be more negative
+        # Uncomment the appropriate assertion based on intended behavior:
+        # assert abs(reward_low_damage - reward_high_damage) < 0.1, "Fixed penalty per step"
+        # assert reward_high_damage < reward_low_damage, "Proportional penalty"

622-668: Tests verify execution but not reward values.

The brave foraging tests effectively validate that the code paths execute without errors and that zone detection works correctly. However, they don't verify that the reward_discomfort_food bonus is actually applied to rewards when food is collected in discomfort zones (or excluded in comfort/danger zones).

For stronger behavioral verification, consider capturing reward values before and after food collection, or comparing total rewards between episodes with and without the bonus configured.


751-788: Test verifies config immutability rather than behavioral correctness.

This test confirms that reward_discomfort_food remains 0.0 after the episode, which is useful for verifying config isn't accidentally mutated. However, it doesn't verify that no bonus was actually applied to rewards during food collection.

To strengthen this test, consider comparing total rewards between two episodes—one with the bonus disabled and one enabled—when food is collected in the same discomfort zone conditions.

Comment thread configs/examples/ppo_thermotaxis_foraging_medium.yml
Comment on lines +119 to +127
hot_spots:
- [75, 50, 25.0] # Hot zone right-center
- [25, 75, 20.0] # Hot zone upper-left
- [80, 80, 22.0] # Hot zone upper-right
# Scattered cold spots
cold_spots:
- [25, 25, 25.0] # Cold zone lower-left
- [75, 25, 20.0] # Cold zone lower-right
- [50, 85, 18.0] # Cold zone top-center

@coderabbitai coderabbitai Bot Jan 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Temperature values for hot/cold spots appear incorrectly configured.

The spot temperatures don't match their designations:

  • cold_spots have temps: 25.0°C, 20.0°C, 18.0°C — only 18.0°C is actually below base temperature (20°C)
  • hot_spots have temps: 25.0°C, 20.0°C, 22.0°C — one spot is exactly at base temperature (20°C)

The cold spot at [25, 25, 25.0] is actually 5°C warmer than base, making it a hot spot. This contradicts both the inline comments and the header documentation (lines 12-14).

Expected pattern for spots relative to cultivation_temperature: 20.0:

  • Hot spots should have temperatures > 20°C (e.g., 25-35°C range)
  • Cold spots should have temperatures < 20°C (e.g., 5-15°C range)
🔧 Suggested fix
       # Scattered hot spots
       hot_spots:
-        - [75, 50, 25.0]   # Hot zone right-center
-        - [25, 75, 20.0]   # Hot zone upper-left
-        - [80, 80, 22.0]   # Hot zone upper-right
+        - [75, 50, 30.0]   # Hot zone right-center
+        - [25, 75, 28.0]   # Hot zone upper-left
+        - [80, 80, 32.0]   # Hot zone upper-right
       # Scattered cold spots
       cold_spots:
-        - [25, 25, 25.0]   # Cold zone lower-left
-        - [75, 25, 20.0]   # Cold zone lower-right
-        - [50, 85, 18.0]   # Cold zone top-center
+        - [25, 25, 10.0]   # Cold zone lower-left
+        - [75, 25, 12.0]   # Cold zone lower-right
+        - [50, 85, 8.0]    # Cold zone top-center
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
hot_spots:
- [75, 50, 25.0] # Hot zone right-center
- [25, 75, 20.0] # Hot zone upper-left
- [80, 80, 22.0] # Hot zone upper-right
# Scattered cold spots
cold_spots:
- [25, 25, 25.0] # Cold zone lower-left
- [75, 25, 20.0] # Cold zone lower-right
- [50, 85, 18.0] # Cold zone top-center
hot_spots:
- [75, 50, 30.0] # Hot zone right-center
- [25, 75, 28.0] # Hot zone upper-left
- [80, 80, 32.0] # Hot zone upper-right
# Scattered cold spots
cold_spots:
- [25, 25, 10.0] # Cold zone lower-left
- [75, 25, 12.0] # Cold zone lower-right
- [50, 85, 8.0] # Cold zone top-center
🤖 Prompt for AI Agents
In `@configs/examples/ppo_thermotaxis_stationary_predators_large.yml` around lines
119 - 127, The hot_spots and cold_spots temperature values are inconsistent with
cultivation_temperature (20.0); update the entries under hot_spots and
cold_spots so all hot_spots have temperatures > 20.0 (e.g., 22.0–35.0) and all
cold_spots have temperatures < 20.0 (e.g., 5.0–15.0); specifically, change the
cold_spots entry [25, 25, 25.0] to a value below 20.0 and change any hot_spots
equal to 20.0 to >20.0 so the arrays hot_spots, cold_spots, and the
cultivation_temperature setting are consistent.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The third value is an intensity (temperature delta), not an absolute temperature. Looking at the code in temperature.py:

Hot spots: temp += intensity * exp(-distance/decay) — adds up to the intensity value
Cold spots: temp -= intensity * exp(-distance/decay) — subtracts up to the intensity value
So with base_temperature: 20.0:

Cold spot [25, 25, 25.0] creates temps down to -5°C at center (20 - 25)
Cold spot [75, 25, 20.0] creates temps down to 0°C at center (20 - 20)
Cold spot [50, 85, 18.0] creates temps down to 2°C at center (20 - 18)
The comments were indeed confusing though — I've updated them to clarify that these are intensity deltas, not absolute temperatures.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chrisjz, thank you for the clarification! You're absolutely right—I misunderstood the semantics. The third value is indeed an intensity delta applied exponentially from the spot center, not an absolute temperature.

Your calculations confirm the configuration is correct:

  • Cold spots subtract intensity: [25, 25, 25.0] → 20 - 25 = -5°C at center ✓
  • Hot spots add intensity: [75, 50, 25.0] → 20 + 25 = 45°C at center ✓

The updated comments in the file make this much clearer now with the explicit note about deltas and the exponential decay. My apologies for the confusion!


✏️ Learnings added
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 44
File: configs/examples/ppo_thermotaxis_stationary_predators_large.yml:0-0
Timestamp: 2026-01-26T07:21:11.709Z
Learning: In thermotaxis configuration files (e.g., configs/examples/ppo_thermotaxis_*.yml), hot_spots and cold_spots use the format [x, y, intensity] where intensity is a temperature DELTA from base_temperature, not an absolute temperature. Hot spots ADD intensity: temp += intensity * exp(-distance/decay). Cold spots SUBTRACT intensity: temp -= intensity * exp(-distance/decay). For example, with base_temperature 20.0, a cold spot [25, 25, 25.0] creates temperatures down to -5°C at its center (20 - 25), and a hot spot [75, 50, 25.0] creates temperatures up to 45°C at its center (20 + 25).

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 44
File: configs/examples/ppo_thermotaxis_foraging_medium.yml:59-60
Timestamp: 2026-01-26T07:09:11.198Z
Learning: In thermotaxis baseline configs (foraging, pursuit, stationary scenarios), penalty_health_damage was empirically found to perform better at 0.0 based on logbook 007 benchmarking results, despite the intuition that penalizing damage might improve learning.

Learnt from: chrisjz
Repo: SyntheticBrains/nematode PR: 44
File: artifacts/logbooks/007/ppo_foraging_medium/ppo_thermotaxis_foraging_medium.yml:75-77
Timestamp: 2026-01-26T05:54:41.207Z
Learning: In thermotaxis configuration files, it's acceptable for `target_foods_to_collect` to exceed `foods_on_grid` because food respawns dynamically during the episode, ensuring new food becomes available as the agent collects toward the target.

@chrisjz
chrisjz merged commit 8479831 into main Jan 26, 2026
5 checks passed
@chrisjz
chrisjz deleted the feature/optimize-thermotaxis branch January 26, 2026 07:22
chrisjz added a commit that referenced this pull request Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant