Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions SWEET_python/city_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ def __init__(self, city_name: str):
"textiles",
"plastic",
"rubber",
"metal",
"glass",
"other",
},
"recycling": {
"wood",
Expand Down Expand Up @@ -1015,6 +1018,9 @@ def load_andre_params(self, row, backfill=False):
"textiles",
"plastic",
"rubber",
"metal",
"glass",
"other",
]
)
value1 = float(row["waste_treatment_incineration_percent"])
Expand Down Expand Up @@ -3074,6 +3080,9 @@ def import_basics(self, row) -> None:
"textiles",
"plastic",
"rubber",
"metal",
"glass",
"other",
]
)
self.recycling_components = set(
Expand Down Expand Up @@ -3482,6 +3491,9 @@ def _is_transient_db_error(err: Exception) -> bool:
"textiles",
"plastic",
"rubber",
"metal",
"glass",
"other",
]
)
self.recycling_components = set(
Expand Down Expand Up @@ -3751,6 +3763,9 @@ def _is_transient_db_error(err: Exception) -> bool:
"textiles",
"plastic",
"rubber",
"metal",
"glass",
"other",
]
)
self.recycling_components = set(
Expand Down
13 changes: 12 additions & 1 deletion SWEET_python/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,18 @@
"anaerobic_mass": None, # Set this either way not both
# Combustion params
"combustion_components": set(
["food", "green", "wood", "paper_cardboard", "textiles", "plastic", "rubber"]
[
"food",
"green",
"wood",
"paper_cardboard",
"textiles",
"plastic",
"rubber",
"metal",
"glass",
"other",
]
),
"combustion_fraction": 0.1,
"combustion_mass": None, # Set this either way not both
Expand Down
7 changes: 6 additions & 1 deletion SWEET_python/dst_allocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"compost": {"food", "green", "wood", "paper_cardboard"},
"anaerobic": {"food", "green", "wood", "paper_cardboard"},
"combustion": {"food", "green", "wood", "paper_cardboard",
"textiles", "plastic", "rubber"},
"textiles", "plastic", "rubber", "metal", "glass", "other"},
"recycling": {"wood", "paper_cardboard", "textiles", "plastic",
"rubber", "metal", "glass", "other"},
}
Expand All @@ -48,6 +48,11 @@
# so when combustion > 0 the three treatments spare combustibles for it. The
# per-type contention degree breaks ties within a tier (protects shared
# wood/paper). Max degree (3) << penalty, so the tiers never cross.
# NOTE: with the current config every waste type is combustion-eligible, so this
# penalty is added uniformly to all edges and is a no-op -- there are no
# non-combustible types to steer the other treatments onto, and the combustion
# remainder (total - compost - anaerobic - recycling) is independent of the
# allocation. Kept for the general case (if a non-combustible type is reintroduced).
_COMBUSTIBLE_PENALTY = 1000


Expand Down
7 changes: 7 additions & 0 deletions changelog/2026-07.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SWEET_python Changelog — July 2026

**Highlights:** All ten waste types are now eligible for combustion (incineration) diversion — `metal`, `glass`, and `other` were previously held out as non-combustible and routed only to recycling. Because the model computes methane only (no combustion CO₂), combustion simply diverts mass away from the landfill, so any combusted waste produces no methane. This is a model-output change: for a given incineration level, the combusted composition and the resulting net-of-diversion landfill stream shift.

## Changed
- Combustion (incineration) is now eligible for **all ten** waste types. Added `metal`, `glass`, and `other` to every combustion-eligibility set: the five live definitions in `city_params.py` (the `City.__init__` default plus the `load_csv_new`, `import_basics`, and two `import_basics_site` construction paths), the `params` template in `config.py`, and the `DEFAULT_ELIGIBILITY` mirror in `dst_allocation.py`. Previously combustion was restricted to seven types (food, green, wood, paper_cardboard, textiles, plastic, rubber), which modeled metal/glass/other as inert and recycling-only. Since the model is methane-only, combustion just removes mass from the landfill (combusted mass generates no methane), so this widens a mass-flow pathway rather than adding an emissions pathway. **Model-output change:** the per-type combustion composition now renormalizes over ten types (the existing types' shares drop and metal/glass/other pick up a share), and the leftover-combustible remainder available to the incineration slider grows to the full leftover after compost/anaerobic/recycling. ([#33](https://github.com/RMI/SWEET_python/pull/33))
- Documented that `dst_allocation.py`'s `spare_combustibles` two-tier cost degrades to a no-op under universal combustion eligibility: with no non-combustible types left, there is nothing to steer the other treatments onto and the combustion remainder (`total − compost − anaerobic − recycling`) no longer depends on the allocation. The mechanism is retained for the general case. Verified that feasibility and allocation are identical with the penalty on vs. off. ([#33](https://github.com/RMI/SWEET_python/pull/33))
1 change: 1 addition & 0 deletions changelog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The project does not publish semantic version tags, so releases are tracked by

Newest first:

- [2026-07](2026-07.md) — All ten waste types eligible for combustion (metal/glass/other added); methane-only model treats combustion as landfill diversion (model-output change)
- [2026-06](2026-06.md) — New single-site and city-level ADST modeling modules, min-cost max-flow rewrite of the city DST diversion allocator, physical-k fix for cold/dry sites, no more spurious negative food-waste mass
- [2026-05](2026-05.md) — SDST models from a landfill's actual open year (1950–2050), Central Asia/Afghanistan disposal-default fix, auto-Jira issue tooling, professional-comment cleanup
- [2026-04](2026-04.md) — SDST baseline/scenario oxidation hardening against pandas dtype bugs, new PM2.5/PM10 particulate emissions from flared methane
Expand Down
8 changes: 4 additions & 4 deletions dst_allocation_prototype.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@
"compost": {"food", "green", "wood", "paper_cardboard"},
"anaerobic": {"food", "green", "wood", "paper_cardboard"},
"combustion": {"food", "green", "wood", "paper_cardboard",
"textiles", "plastic", "rubber"},
"textiles", "plastic", "rubber", "metal", "glass", "other"},
"recycling": {"wood", "paper_cardboard", "textiles", "plastic",
"rubber", "metal", "glass", "other"},
}
NON_COMBUSTION = ("compost", "anaerobic", "recycling")
COMBUSTIBLE = ELIGIBILITY["combustion"] # types combustion can take
NON_COMBUSTIBLE = set(WASTE_TYPES) - COMBUSTIBLE # metal, glass, other
NON_COMBUSTIBLE = set(WASTE_TYPES) - COMBUSTIBLE # now empty: all types combustible

# 1e9 grid: feasibility decided to ~1e-9, far below slider/display precision.
SCALE = 10 ** 9
Expand Down Expand Up @@ -393,8 +393,8 @@ def wf(**kw):
"remainder 0 -> infeasible, must not ZeroDivisionError"),
("C-divzero combustion0 ok", wf(paper_cardboard=1.0),
{"compost": 0.60, "recycling": 0.40, "combustion": 0.0}, True, ""),
("C combustion on non-combustible only", wf(metal=1.0),
{"combustion": 0.10}, False, "remainder 0"),
("C combustion on metal only (now combustible)", wf(metal=1.0),
{"combustion": 0.10}, True, "all types combustible -> remainder 1.0"),
("C full 4-slider tight boundary",
wf(food=0.25, green=0.10, wood=0.05, paper_cardboard=0.15, plastic=0.15,
metal=0.10, glass=0.10, textiles=0.05),
Expand Down
3 changes: 2 additions & 1 deletion tests/test_dst_allocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ def solve_with_combustion(waste, targets):
{"compost": 0.60, "recycling": 0.40, "combustion": 0.05}, False),
("C_divzero_combustion0_ok", wf(paper_cardboard=1.0),
{"compost": 0.60, "recycling": 0.40, "combustion": 0.0}, True),
("C_combustion_noncombustible_only", wf(metal=1.0), {"combustion": 0.10}, False),
# metal/glass/other are now combustion-eligible: a 100%-metal city CAN combust.
("C_combustion_metal_now_combustible", wf(metal=1.0), {"combustion": 0.10}, True),
("C_full_4slider_tight_boundary",
wf(food=0.25, green=0.10, wood=0.05, paper_cardboard=0.15, plastic=0.15,
metal=0.10, glass=0.10, textiles=0.05),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_mass_checker_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
ELIG = {
"compost": ["food", "green", "wood", "paper_cardboard"],
"anaerobic": ["food", "green", "wood", "paper_cardboard"],
"combustion": ["food", "green", "wood", "paper_cardboard", "textiles", "plastic", "rubber"],
"combustion": ["food", "green", "wood", "paper_cardboard", "textiles", "plastic", "rubber", "metal", "glass", "other"],
"recycling": ["wood", "paper_cardboard", "textiles", "plastic", "rubber", "metal", "glass", "other"],
}

Expand Down