Upstream trees
This method returns the result nodes of a given impact category for a given path in an upstream contribution tree. The path is a sequence of technosphere-flows that describe the path to the parent node of the returned nodes. If the path is empty, the root of the tree is returned. Note that such an upstream tree can be infinitely deep when the calculated system has cycles.
Rest API | POST result/{result-id}/upstream-impacts-of/{impact-category} |
JSON-RPC | result/upstream-impacts-of |
Snake case | result.get_upstream_impacts_of |
Camel case | result.getUpstreamImpactsOf |
Return type | List[UpstreamNode] |
Parameter 1 | Ref[ImpactCategory] |
Parameter 2 | List[TechFlow] |
Examples
olca-ipc.ts
The TypeScript example below uses the olca-ipc.ts client API:
async function main() {
// connect to a local server running on port 8080
const client = o.IpcClient.on(8080);
const setup = o.CalculationSetup.of({
target: o.Ref.of({
id: "d3a9a9b2-ec3e-4811-8617-ae853573b50b",
refType: o.RefType.ProductSystem,
}),
impactMethod: o.Ref.of({
id: "07370e48-dde9-4248-9a9b-7255f701da89",
})
});
const result = await client.calculate(setup);
await result.untilReady();
// select the first best impact category and expand a tree for it
const indicator = (await result.getImpactCategories())[0];
console.log(`upstream tree for ${indicator.name}`);
await expand(result, indicator, []);
// as always, dispose the result
result.dispose();
}
async function expand(r: o.IpcResult, indicator: o.Ref, path: o.TechFlow[]) {
const level = path.length;
const indent = " ".repeat(level);
const unit = indicator.refUnit;
const nodes = await r.getUpstreamImpactsOf(indicator, path);
for (const node of nodes) {
if (node.result === 0) {
continue;
}
const name = node.techFlow?.provider?.name;
const value = node.result?.toExponential(2);
console.log(`${indent}- ${value} ${unit} :: ${name}`);
// we stop the expansion after 3 levels; you can set other cut-offs like
// result contributions etc.
if (level < 3) {
const next = path.slice();
next.push(node.techFlow!);
await expand(r, indicator, next);
}
}
}
main();
/*
upstream tree for Photochemical ozone formation
- 2.66e-2 kg NMVOC eq ...
- 2.66e-2 kg NMVOC eq ...
- 1.13e-2 kg NMVOC eq ...
- 4.69e-3 kg NMVOC eq ...
- 4.53e-3 kg NMVOC eq ...
- 1.41e-3 kg NMVOC eq ...
- 8.72e-3 kg NMVOC eq ...
- 4.18e-3 kg NMVOC eq ...
- 4.18e-3 kg NMVOC eq ...
- 1.01e-4 kg NMVOC eq ...
*/
olca-ipc.py
The Python example below uses the utree
module of the olca-ipc.py API which
makes working with upstream trees a bit more convenient:
import olca_schema as o
import olca_ipc as ipc
import olca_ipc.utree as utree
# maximum number of levels and child nodes that should be expanded
MAX_EXPAND_LEVELS = 3
MAX_EXPAND_NODES = 5
def main():
# calculate a result
client = ipc.Client()
setup = o.CalculationSetup(
target=o.Ref(
ref_type=o.RefType.Process,
id="2d1b0c1f-dd8f-3aea-bc50-bbd10acbd86d",
),
impact_method=o.Ref(id="99b9d86b-ec6f-4610-ba9f-68ebfe5691dd"),
)
result = client.calculate(setup)
result.wait_until_ready()
# select the first impact category for the tree
ref = result.get_impact_categories()[0]
print(f"\nTree for {ref.name}, results in {ref.ref_unit}:")
# create the upstream tree and expand it
root = utree.of(result, ref)
expand(root, 0)
# always dispose the result
result.dispose()
def expand(node: utree.Node, level: int):
"""This function recursively expands an upstream tree.
The maximum number of levels and maximum number of child nodes are defined
with the constants above. Note that an upstream tree can be
"""
indent = " " * level
print(f"{indent} - {node.provider.name} : {node.result}")
if level < MAX_EXPAND_LEVELS:
for c in node.childs[0:MAX_EXPAND_NODES]:
expand(c, level + 1)
if __name__ == "__main__":
main()