test: add tests for lookup
This commit is contained in:
@@ -52,7 +52,12 @@ class RevitCarbonAnalyzer:
|
||||
material_processor=self.material_processor, logger=Logging()
|
||||
)
|
||||
self.carbon_calculator = CarbonCalculator(
|
||||
steel_database=steel_database, timber_database=timber_database
|
||||
steel_database=steel_database.value
|
||||
if isinstance(steel_database, SteelDatabase)
|
||||
else steel_database,
|
||||
timber_database=timber_database.value
|
||||
if isinstance(timber_database, SteelDatabase)
|
||||
else timber_database,
|
||||
)
|
||||
|
||||
def analyze_model(self, model_root) -> dict:
|
||||
@@ -101,7 +106,17 @@ class RevitCarbonAnalyzer:
|
||||
|
||||
# Calculate carbon
|
||||
try:
|
||||
print(
|
||||
f"Processing element: {element_id}, category: {processed_element.category.value}"
|
||||
)
|
||||
print(
|
||||
f"Materials: {[m.properties.name for m in processed_element.materials]}"
|
||||
)
|
||||
carbon_results = self.carbon_calculator.calculate_carbon(processed_element)
|
||||
print(f"Carbon results: {carbon_results}")
|
||||
print(
|
||||
f"Total carbon: {sum(r.total_carbon for r in carbon_results.values())}"
|
||||
)
|
||||
return {
|
||||
"id": element_id,
|
||||
"status": "processed",
|
||||
|
||||
@@ -47,20 +47,19 @@ class EmissionFactorRegistry:
|
||||
"glt",
|
||||
"nlt",
|
||||
"dlt",
|
||||
"glue laminated timber",
|
||||
"nail laminated timber",
|
||||
"dowel laminated timber",
|
||||
],
|
||||
}
|
||||
|
||||
self._steel_aliases = {
|
||||
"hot rolled": ["hot-rolled", "hot_rolled", "hotrolled"],
|
||||
"hss": ["hollow structural section", "hollow section", "tube steel"],
|
||||
"plate": ["steel plate", "flat plate"],
|
||||
"hot rolled": ["hot-rolled", "hot_rolled", "hotrolled", "steel"],
|
||||
"hss": ["hollow structural section", "hollow section", "tube"],
|
||||
"plate": ["flat plate"],
|
||||
"rebar": ["reinforcing bar", "reinforcement"],
|
||||
"owsj": ["open web steel joist", "steel joist"],
|
||||
"fasteners": ["bolts", "screws", "nails", "rivets"],
|
||||
"metal deck": ["steel deck", "decking"],
|
||||
"metal deck": ["deck", "decking"],
|
||||
}
|
||||
|
||||
self._concrete_aliases = {
|
||||
@@ -94,14 +93,16 @@ class EmissionFactorRegistry:
|
||||
|
||||
@staticmethod
|
||||
def _normalize_material_name(name: str, aliases: Dict[str, list]) -> str:
|
||||
"""Normalize material name using centralized aliases"""
|
||||
"""Normalize material name using centralized aliases with substring matching"""
|
||||
name = name.lower()
|
||||
|
||||
# Check if name contains any alias
|
||||
for standard_name, variations in aliases.items():
|
||||
if name == standard_name:
|
||||
# Check standard names first
|
||||
for standard_name in aliases.keys():
|
||||
if standard_name in name:
|
||||
return standard_name
|
||||
|
||||
# Then check aliases
|
||||
for standard_name, variations in aliases.items():
|
||||
for variation in variations:
|
||||
if variation in name:
|
||||
return standard_name
|
||||
@@ -126,6 +127,8 @@ class EmissionFactorRegistry:
|
||||
normalized_name = self._normalize_material_name(
|
||||
material_name, self._timber_aliases
|
||||
)
|
||||
print(f"Looking up '{material_name}' in {database}")
|
||||
print(f"Normalized name: {normalized_name}")
|
||||
return db.get_factor(normalized_name)
|
||||
|
||||
def get_steel_factor(
|
||||
@@ -145,6 +148,8 @@ class EmissionFactorRegistry:
|
||||
normalized_name = self._normalize_material_name(
|
||||
material_name, self._steel_aliases
|
||||
)
|
||||
print(f"Looking up '{material_name}' in {database}")
|
||||
print(f"Normalized name: {normalized_name}")
|
||||
return db.get_factor(normalized_name)
|
||||
|
||||
def get_concrete_factor(
|
||||
|
||||
@@ -30,7 +30,11 @@ class CarbonCalculator:
|
||||
"""Calculate carbon emissions for an element's materials."""
|
||||
results = {}
|
||||
|
||||
print(f"Calculating carbon for {len(element.materials)} materials")
|
||||
for material in element.materials:
|
||||
print(f" Material: {material.properties.name}, type: {material.type}")
|
||||
print(f" Structural asset: {material.properties.structural_asset}")
|
||||
print(f" Volume: {material.properties.volume}, Mass: {material.mass}")
|
||||
try:
|
||||
result = self._calculate_material_carbon(material)
|
||||
results[material.properties.name] = result
|
||||
@@ -44,6 +48,7 @@ class CarbonCalculator:
|
||||
|
||||
def _calculate_material_carbon(self, material: Material) -> CarbonResult:
|
||||
"""Calculate carbon emissions for a single material."""
|
||||
print(f"Calculating for material type: {material.type}")
|
||||
if material.type == MaterialType.METAL:
|
||||
return self._calculate_metal_carbon(material)
|
||||
elif material.type == MaterialType.WOOD:
|
||||
@@ -60,9 +65,11 @@ class CarbonCalculator:
|
||||
|
||||
# Get factor from cache or registry
|
||||
if material.grade not in self._steel_factors_cache:
|
||||
print(f"Metal: {material.grade} → {self._steel_database}")
|
||||
factor = self._registry.get_steel_factor(
|
||||
material.grade, self._steel_database
|
||||
)
|
||||
print(f"Factor found: {factor}")
|
||||
if not factor:
|
||||
raise ValueError(
|
||||
f"No emission factor found for metal grade: {material.grade}"
|
||||
@@ -82,9 +89,13 @@ class CarbonCalculator:
|
||||
|
||||
# Get factor from cache or registry
|
||||
if structural_asset not in self._timber_factors_cache:
|
||||
print(
|
||||
f"Wood: {material.properties.structural_asset} → {self._timber_database}"
|
||||
)
|
||||
factor = self._registry.get_timber_factor(
|
||||
structural_asset, self._timber_database
|
||||
)
|
||||
print(f"Factor found: {factor}")
|
||||
if not factor:
|
||||
raise ValueError(
|
||||
f"No emission factor found for wood type: {structural_asset}"
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import pytest
|
||||
|
||||
from src.domain.carbon.databases.enums import TimberDatabase, SteelDatabase
|
||||
from src.domain.carbon.emission_factor_registry import EmissionFactorRegistry
|
||||
|
||||
|
||||
class TestRegistry:
|
||||
"""Test suite for the EmissionFactorRegistry"""
|
||||
|
||||
@pytest.fixture
|
||||
def registry(self):
|
||||
"""Create and return a registry instance"""
|
||||
return EmissionFactorRegistry()
|
||||
|
||||
def test_timber_database_lookup(self, registry):
|
||||
"""Test direct lookup of timber factors"""
|
||||
# Test each database
|
||||
factor = registry.get_timber_factor(
|
||||
"FE_CLT Floor Panel (1)", TimberDatabase.Athena2021.value
|
||||
)
|
||||
assert factor is not None
|
||||
assert factor.value == 69
|
||||
|
||||
factor = registry.get_timber_factor(
|
||||
"FE_Glulam", TimberDatabase.Binderholz2019.value
|
||||
)
|
||||
assert factor is not None
|
||||
assert factor.value == 118
|
||||
|
||||
def test_steel_database_lookup(self, registry):
|
||||
"""Test direct lookup of steel factors"""
|
||||
factor = registry.get_steel_factor(
|
||||
"Metal - Steel CSA G40", SteelDatabase.Type350MPa.value
|
||||
)
|
||||
assert factor is not None
|
||||
assert factor.value == 1.22
|
||||
|
||||
def test_invalid_database(self, registry):
|
||||
"""Test error handling for invalid database"""
|
||||
with pytest.raises(ValueError, match="Unknown timber database"):
|
||||
registry.get_timber_factor("CLT", "NonExistentDatabase")
|
||||
Reference in New Issue
Block a user