Foreground Interface
Foreground Interface
The Foreground interface enables construction and management of user-defined LCA models using fragments. It provides tools for creating modular, reusable product system models that can incorporate data from multiple sources.
Core Concept
The Foreground interface implements fragment-based modeling, where:
- Fragments represent observed material flows between activities
- Fragment trees model complete product systems as hierarchical structures
- Observations capture quantitative and qualitative model parameters
- Scenarios enable exploration of different model configurations
This approach enables data-free modeling: models can be shared and reused while preserving confidentiality of specific data values.
Key Methods
Entity Creation
new_quantity(name, ref_unit=None, **kwargs)
Create custom quantities for modeling.
1
2
3
4
5
# Create custom impact category
custom_impact = query.new_quantity(
'Water consumption impact',
ref_unit='m³ water-eq'
)
new_flow(name, ref_quantity=None, context=None, **kwargs)
Create custom flows for product system modeling.
1
2
3
4
5
6
7
8
9
10
11
# Create product flow
widget_flow = query.new_flow(
'Custom widget',
ref_quantity=mass_quantity
)
# Create elementary flow
waste_flow = query.new_flow(
'Industrial waste',
context=('technosphere',)
)
Fragment Construction
new_fragment(flow, direction, **kwargs)
Create fragment nodes representing observed exchanges.
1
2
3
4
5
6
7
8
9
10
11
12
# Create reference fragment (product output)
widget_fragment = query.new_fragment(
widget_flow,
direction='Output'
)
# Create child fragment (material input)
steel_input = query.new_fragment(
steel_flow,
direction='Input',
parent=widget_fragment
)
split_subfragment(fragment, replacement=None, **kwargs)
Split fragments into reusable submodels.
1
2
3
4
5
# Split complex fragment into reusable component
packaging_fragment = query.split_subfragment(
complex_fragment,
replacement=packaging_process
)
Fragment Discovery and Navigation
fragments_with_flow(flow, direction=None, **kwargs)
Find fragments that use specific flows.
1
2
3
4
5
6
7
8
# Find all fragments using electricity
electricity_fragments = list(query.fragments_with_flow(electricity_flow))
# Find fragments outputting steel
steel_outputs = list(query.fragments_with_flow(
steel_flow,
direction='Output'
))
child_flows(fragment, **kwargs)
Get immediate children of a fragment.
1
2
3
4
# Get direct inputs/outputs
children = list(query.child_flows(widget_fragment))
for child in children:
print(f"{child.direction}: {child.flow}")
tree(fragment, **kwargs)
Get complete fragment tree structure.
1
2
3
4
# Get full hierarchy
tree = query.tree(widget_fragment)
for node in tree:
print(f"{' ' * node.depth}{node.fragment}")
Observation and Parameterization
observe(fragment, exchange_value=None, anchor=None, name=None, scenario=None, **kwargs)
Record quantitative observations and model parameters.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Observe exchange value (material input rate)
query.observe(
steel_input,
exchange_value=2.5, # kg steel per widget
name='Steel input rate'
)
# Observe termination (supply source)
query.observe(
steel_input,
anchor=steel_production_process,
name='Steel supplier'
)
# Scenario-specific observation
query.observe(
energy_input,
exchange_value=15.0,
scenario='renewable_energy'
)
observe_unit_score(fragment, quantity, score, scenario=None, **kwargs)
Record pre-computed impact scores.
1
2
3
4
5
6
7
# Cache impact assessment result
query.observe_unit_score(
steel_fragment,
gwp_quantity,
score=2.8, # kg CO2-eq per kg steel
scenario='low_carbon'
)
Fragment Analysis
traverse(fragment, scenario=None, **kwargs)
Compute fragment activity levels and exchange values.
1
2
3
4
5
6
7
8
9
10
# Traverse default scenario
traversal = query.traverse(widget_fragment)
for flow in traversal:
print(f"{flow.fragment}: {flow.magnitude} {flow.flow}")
# Traverse specific scenario
renewable_traversal = query.traverse(
widget_fragment,
scenario='renewable_energy'
)
activity(fragment, scenario=None, **kwargs)
Get direct activity (first-level children only).
1
2
3
4
# Direct material/energy inputs
activities = query.activity(widget_fragment)
for activity in activities:
print(f"Direct: {activity.flow} = {activity.magnitude}")
cutoff_flows(fragment, scenario=None, **kwargs)
Identify unlinked flows requiring background data.
1
2
3
4
# Find flows needing external data
cutoffs = query.cutoff_flows(widget_fragment)
for cutoff in cutoffs:
print(f"Cutoff: {cutoff.flow} ({cutoff.direction})")
Impact Assessment
fragment_lcia(fragment, quantity_ref, scenario=None, **kwargs)
Perform LCIA on fragment model.
1
2
3
4
5
6
7
8
9
10
11
12
# Calculate climate impact
climate_result = query.fragment_lcia(
widget_fragment,
gwp_quantity,
scenario='baseline'
)
print(f"Total impact: {climate_result.total()} kg CO2-eq")
# Show contributions
for component in climate_result.components():
print(f"{component.fragment}: {component.result}")
Model Management
save(**kwargs)
Persist foreground model to storage.
1
2
# Save model and cached results
query.save(save_unit_scores=True)
parameters(fragment=None, **kwargs)
List observable parameters in the model.
1
2
3
4
5
# All model parameters
all_params = list(query.parameters())
# Parameters for specific fragment
widget_params = list(query.parameters(fragment=widget_fragment))
anchors(fragment, **kwargs)
List termination anchors for a fragment.
1
2
3
4
# Available supply options
anchors = list(query.anchors(steel_input))
for anchor in anchors:
print(f"Option: {anchor}")
Usage Patterns
Product System Modeling
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def build_product_model(query, product_name, main_flow):
"""Build hierarchical product system model"""
# Create reference fragment
product = query.new_fragment(main_flow, 'Output')
query.observe(product, name=product_name)
# Add material inputs
materials = [
('Steel', steel_flow, 2.5),
('Plastic', plastic_flow, 0.8),
('Electricity', electricity_flow, 12.0)
]
for name, flow, amount in materials:
material_input = query.new_fragment(
flow, 'Input', parent=product
)
query.observe(
material_input,
exchange_value=amount,
name=f"{name} input"
)
return product
Scenario Analysis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def compare_scenarios(query, fragment, scenarios):
"""Compare different model scenarios"""
results = {}
for scenario_name in scenarios:
# Traverse scenario
traversal = query.traverse(fragment, scenario=scenario_name)
# Calculate impact
impact = query.fragment_lcia(
fragment,
gwp_quantity,
scenario=scenario_name
)
results[scenario_name] = {
'flows': len(list(traversal)),
'impact': impact.total()
}
print(f"{scenario_name}: {impact.total()} kg CO2-eq")
return results
Model Validation and QC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def validate_fragment_model(query, fragment):
"""Validate fragment model completeness"""
print(f"Validating model: {fragment}")
# Check for unobserved fragments
tree = query.tree(fragment)
unobserved = []
for node in tree:
if not node.observed:
unobserved.append(node)
if unobserved:
print(f"Warning: {len(unobserved)} unobserved fragments")
for node in unobserved:
print(f" {node.fragment}")
# Check for cutoffs
cutoffs = query.cutoff_flows(fragment)
if cutoffs:
print(f"Info: {len(cutoffs)} cutoff flows")
for cutoff in cutoffs[:5]: # Show first 5
print(f" {cutoff.flow}")
# Check traversability
try:
traversal = list(query.traverse(fragment))
print(f"Model traverses successfully ({len(traversal)} flows)")
except Exception as e:
print(f"Error: Model traversal failed: {e}")
Modular Model Construction
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def create_modular_system(query):
"""Build system from reusable modules"""
# Create reusable packaging module
packaging = query.new_fragment(packaging_flow, 'Output')
cardboard = query.new_fragment(
cardboard_flow, 'Input', parent=packaging
)
query.observe(cardboard, exchange_value=0.1, name='Cardboard')
# Create main product using packaging module
product = query.new_fragment(widget_flow, 'Output')
# Reference packaging module
packaging_input = query.new_fragment(
packaging_flow, 'Input', parent=product
)
query.observe(packaging_input, anchor=packaging, name='Packaging')
return product, packaging
Error Handling
ForegroundRequired
: Operation requires Foreground interface but none found- May raise validation errors for malformed fragment structures
- Traversal errors for incomplete or circular fragment models
Implementation Notes
Fragment Types
- Reference fragments: Top-level product outputs
- Child fragments: Material/energy inputs and co-product outputs
- Balance fragments: Automatically computed flows (mass/energy balance)
Observation Persistence
Observations can be:
- Default: Applied to all scenarios
- Scenario-specific: Applied only to named scenarios
- Temporary: Not persisted to storage
Model Reusability
Fragment models support:
- Substitution: Replace anchors with different processes
- Scaling: Adjust exchange values proportionally
- Composition: Embed fragments within larger models
Authorization Requirements
Foreground operations typically require:
- Write access for model creation and modification
- Save permissions for model persistence
- Access to background data for anchor resolution
Relationship to Other Interfaces
- Basic: Entity creation and property access
- Exchange: Background process integration via anchors
- Quantity: Impact assessment of fragment models
- Index: Background data discovery for anchors
- Background: System-level inventory calculations
Next Steps
- Learn about Background Interface for system integration
- See Quantity Interface for impact assessment