Skip to content

feat: collapse regional producers into one PDL-derived archetype (#33) - #39

Open
Hackatro wants to merge 7 commits into
mainfrom
33-collapse-braargusa-producers-into-one-pdl-derived-producer-archetype
Open

feat: collapse regional producers into one PDL-derived archetype (#33)#39
Hackatro wants to merge 7 commits into
mainfrom
33-collapse-braargusa-producers-into-one-pdl-derived-producer-archetype

Conversation

@Hackatro

Copy link
Copy Markdown
Contributor

Closes #33.

What this does

Three producer types were hardwired by country name, and a single pooled wholesaler
could buy from any of them. That wholesaler — not the European port — was where
"buy Brazilian or buy American" got decided.

This PR:

  • gives each producing region its own grain originator, sourcing only from its own
    farms, derived from the PDL rather than named in Python
  • moves origin choice to Rotterdam, which now buys cheapest-first up to its own
    throughput instead of summing whatever arrives
  • removes the last hand-written topology structures, so the agent roster, the flow
    graph and the exported map all derive from the scenario file

The behaviour to look at

Rotterdam handles 500 t/step; the three lanes deliver ~1,800 t. It has to turn volume
away, and price now decides which.

Arriving at Rotterdam Baseline Drought, day 45
Santos (Brazil) 500 400
Argentina 500 550
US 800 920
Total 1,800 1,870
Throughput 500 500

Under the drought cascade the cheapest lane changes twice, and the admitted mix
follows: 100% Brazil → 100% Argentina (day 0) → 100% US (day 45).

Guarded by tests/test_transport_routing.py, which asserts US > 0 and Brazil ==
Argentina == 0 at day 45.

Brazil does not vanish from Europe — Paranaguá still runs to Hamburg (300 t → 180 t),
and the Brazil originator's storage utilisation drops 35% → 21%.

Removed

SYNTHETIC, SYNTHETIC_NAMES, the synthetic-hub overlay, the FLOW_ADJACENCY
literal, SYNTHETIC_PLACEMENTS, and the bespoke per-origin sea-lane methods.

A node reaching the exporter with no resolvable metadata now raises instead of being
silently skipped — that failure previously looked identical to "the wholesalers
disappeared."

Verify

pytest
pytest tests/test_topology_snapshot.py -v
$env:PYTHONIOENCODING="utf-8"; python -m provider_simenv.main --pdl src/provider_simenv/scenarios/s1-soja.pdl.yaml
python -m provider_simenv.export_bundle --scenario 1

Exports 14 nodes / 14 edges, all derived.

Suggested review order

  1. agents/trader.py — the regional originator
  2. agents/transport.py — Rotterdam's demand target and cheapest-first admission
  3. topology.py — roster + flow derivation, and _pdl_stage_pairs ordering
  4. export_bundle.py — roster-derived node metadata
  5. everything else is follow-on

Known gaps, deliberately not fixed here

  • Single-origin admission. Because the port is oversupplied ~3.6× and the cheapest
    lane alone exceeds 500 t, the top-up branch never fires and Rotterdam buys from one
    lane at a time. This is a faithful consequence of the current pricing model, not a
    coding defect. Whether it is the intended model behaviour is an open question —
    happy to discuss on the PR.
  • A declared price shock nothing reads. The PDL declares the US emergency event as
    +15% supply and +25% price; only the supply half binds. Pre-existing.
  • The originator's demand target is inert. With one originator per region and
    nothing to substitute from, it always takes exactly what its region produced.
    Carried to Make transport roles and routing fully PDL-derived #38.

Scope note

Two visualisation helper scripts (visualize_csv.py, visualize_sql.py) and the
SQLite post-processing path in main.py were removed during the session. That was
not in the issue scope and is mixed into this range. Nothing references them any
more — flagging it so the wider-than-expected diff isn't a surprise.

Follow-up

#38 (38-make-transport-roles-and-routing-fully-pdl-derived) takes the identity half:
the eight place-named transport roles, the remaining hardcoded model-list lookups, and
the full routing test. Steps 14–15 already landed there.

"Result_Simulator_FeedManufacturers": ("feed_manufacturers", ["quantity_available", "unit_price"]),
"Result_Simulator_FeedTraders": ("feed_traders", ["quantity_available", "unit_price"]),
"Result_Simulator_EuFarmers": ("eu_farmers", ["feed_received", "livestock_output", "active"]),
"Result_Simulator_BraFarmers": ("brazil_farms", list(_PROPS_BY_ROLE[ROLE_PRODUCER])),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are there still the explicit mentions for brazil_farms etc. in the code here?

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.

Collapse BRA/ARG/USA producers into one PDL-derived producer archetype

2 participants