Activity Modeling¶
This guide covers best practices for creating activities and structuring your LCA models in EcoSemantic.
What is an Activity?¶
An activity represents a process that transforms inputs into outputs. In LCA terminology:
- Transforming activity: Converts materials/energy into products (most common)
- Market activity: Aggregates multiple suppliers of the same product
- Treatment activity: Handles waste or provides disposal services
Activity Structure¶
Every activity in EcoSemantic has:
Activity:
code: unique_identifier # Required - used in calculations
name: Human readable name # Required - displayed in results
unit: kilogram # Required - unit of reference product
location: GLO # Optional - geographic scope
reference_product: Product X # Auto-generated if not specified
Exchanges:
- Production exchange # Required - the reference product
- Technosphere exchanges # Optional - material/energy inputs
- Biosphere exchanges # Optional - emissions/resources
Creating Activities¶
Step 1: Define the Activity¶
create_activity(
project_id="your-project-uuid",
code="steel_beam_production",
name="Steel Beam Production",
unit="kilogram",
location="DE"
)
Choosing a Code
- Use lowercase with underscores
- Make it descriptive but concise
- Must be unique within your project
- Examples:
solar_panel_assembly,battery_cell_prod,concrete_mixing
Step 2: Add the Production Exchange¶
Every activity needs a production exchange that defines its reference product:
create_custom_exchange(
activity_id="activity-uuid",
name="Steel beam, structural",
amount=1.0, # Typically 1.0 for the functional unit
unit="kilogram",
exchange_type="production"
)
Required
Without a production exchange, your activity cannot be used in calculations. EcoSemantic will automatically create a default production exchange when you create an activity, but you may want to customize it.
Step 3: Add Input Exchanges¶
Add material and energy inputs from ecoinvent:
# Find the activity code first
result = search_activities(
q="electricity low voltage",
database="ecoinvent-3.9.1-cutoff",
location="DE"
)
# Then create the exchange
create_database_exchange(
activity_id="activity-uuid",
amount=50.0, # 50 kWh of electricity
exchange_type="technosphere",
input_database="ecoinvent-3.9.1-cutoff",
input_activity_code="electricity_code_from_search"
)
Step 4: Add Environmental Exchanges (Optional)¶
Add direct emissions or resource consumption:
# Find the biosphere flow
result = search_biosphere(
q="carbon dioxide fossil",
database="ecoinvent-3.9.1-cutoff",
compartment="air"
)
# Create the emission exchange
create_database_exchange(
activity_id="activity-uuid",
amount=2.5, # 2.5 kg CO2 emitted
exchange_type="biosphere",
input_database="ecoinvent-3.9.1-cutoff",
input_biosphere_code="co2_code_from_search"
)
Functional Unit¶
The functional unit defines what you're analyzing. It should be:
- Quantifiable: A specific amount
- Comparable: Enables fair comparison between alternatives
- Relevant: Reflects the actual function of the product
Examples¶
| Product | Poor Functional Unit | Good Functional Unit |
|---|---|---|
| Light bulb | 1 bulb | 1000 hours of 800 lumens |
| Paint | 1 kg of paint | Coverage of 10 m² for 10 years |
| Transport | 1 trip | 1 tonne-kilometer |
| Packaging | 1 bag | Containing 1 kg of product |
Implementing in EcoSemantic¶
The functional unit is defined by:
- Activity unit: Set when creating the activity
- Production amount: Usually 1.0 in the production exchange
- Calculation quantity: Set when running the calculation
# Activity produces 1 kg (functional unit basis)
create_activity(
code="paint_production",
name="Paint Production",
unit="kilogram", # Per kg basis
...
)
# Calculate for 10 kg
calculate_custom(
activity_code="paint_production",
quantity=10.0, # 10 kg of paint
...
)
Linking to ecoinvent¶
Finding the Right Activity¶
Use search_activities to find ecoinvent processes:
# Search by product name
search_activities(q="steel low-alloyed", database="ecoinvent-3.9.1-cutoff")
# Filter by location
search_activities(q="electricity", database="ecoinvent-3.9.1-cutoff", location="US")
# Filter by unit
search_activities(q="transport freight", database="ecoinvent-3.9.1-cutoff", unit="ton kilometer")
Choosing Between Similar Activities¶
ecoinvent often has multiple activities for similar products. Consider:
| Factor | How to Choose |
|---|---|
| Location | Match your supply chain geography |
| Technology | Match the actual technology used |
| Time period | Use most recent relevant data |
| System model | EcoSemantic uses "cutoff" allocation |
Market vs Production Activities¶
- Market activities: Weighted average of all suppliers in a region
- Production activities: Specific production technology
When to Use Which
- Use markets when you don't know your specific supplier
- Use production when modeling a specific technology or supplier
Multi-Level Models¶
You can create hierarchical models by linking custom activities together.
Example: Electric Vehicle Battery¶
graph TD
A[Battery Pack Assembly] --> B[Battery Cell Production]
A --> C[Battery Management System]
A --> D[Cooling System]
B --> E[Cathode Production]
B --> F[Anode Production]
B --> G[Electrolyte Production]
style A fill:#e3f2fd
style B fill:#e8f5e9
style C fill:#fff3e0
style D fill:#fff3e0
style E fill:#f3e5f5
style F fill:#f3e5f5
style G fill:#f3e5f5
Creating Linked Custom Activities¶
# 1. Create sub-component activity
create_activity(
project_id="project-uuid",
code="cathode_production",
name="Lithium Cathode Production",
unit="kilogram"
)
# Add exchanges to cathode_production...
# 2. Create parent activity
create_activity(
project_id="project-uuid",
code="battery_cell",
name="Battery Cell Production",
unit="unit"
)
# 3. Link them together using input_database="custom"
create_custom_exchange(
activity_id="battery_cell_uuid",
name="Lithium cathode",
amount=0.5, # 0.5 kg per cell
unit="kilogram",
exchange_type="technosphere",
input_activity_code="cathode_production", # References the custom activity
input_database="custom" # CRITICAL: Must be "custom"
)
Critical: input_database='custom'
When linking custom activities within the same project, you must set
input_database="custom". This tells EcoSemantic to look for the activity
in your project rather than in ecoinvent.
Common Patterns¶
Pattern 1: Simple Foreground Process¶
One custom activity with ecoinvent background:
Your Custom Activity
├── Production: 1 kg product
├── Input: Electricity (from ecoinvent)
├── Input: Steel (from ecoinvent)
├── Input: Transport (from ecoinvent)
└── Emission: CO2 (to biosphere)
Pattern 2: Foreground System¶
Multiple linked custom activities:
Assembly Process (custom)
├── Production: 1 unit
├── Input: Component A (custom)
├── Input: Component B (custom)
└── Input: Packaging (ecoinvent)
Component A (custom)
├── Production: 1 kg
├── Input: Raw material (ecoinvent)
└── Input: Energy (ecoinvent)
Component B (custom)
├── Production: 1 unit
├── Input: Raw material (ecoinvent)
└── Input: Energy (ecoinvent)
Pattern 3: Scenario Comparison¶
Same product, different configurations:
Product - Scenario A (custom)
├── Production: 1 kg
├── Input: Material X (ecoinvent)
└── Input: Energy from coal (ecoinvent)
Product - Scenario B (custom)
├── Production: 1 kg
├── Input: Material Y (ecoinvent) # Different material
└── Input: Energy from solar (ecoinvent) # Different energy
Validation Checklist¶
Before running calculations, verify:
- [ ] Production exchange exists with amount > 0
- [ ] All inputs are linked to valid ecoinvent activities or custom activities
- [ ] Units are consistent across exchanges
- [ ] Amounts are positive for regular inputs (see Exchange Conventions)
- [ ] Database versions match - all ecoinvent references use the same version
- [ ] Custom links use
input_database="custom"
Troubleshooting¶
"Activity not found"¶
- Check the activity code is spelled correctly
- Verify the activity exists in your project
- For ecoinvent activities, confirm you're using the correct database version
"Missing production exchange"¶
- Every activity needs exactly one production exchange
- Check that
exchange_type="production"was set
"Circular reference detected"¶
- Activity A cannot require Activity B if Activity B requires Activity A
- Restructure your model to break the cycle
"Unit mismatch"¶
- The exchange unit must be compatible with the linked activity's unit
- Use
validate_unitto check valid units
Next Steps¶
- Exchange Conventions - Understand amount signs
- Environmental Flows - Working with emissions
- Tool Reference - Complete API documentation