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 APIPOST result/{result-id}/upstream-impacts-of/{impact-category}
JSON-RPCresult/upstream-impacts-of
Snake caseresult.get_upstream_impacts_of
Camel caseresult.getUpstreamImpactsOf
Return typeList[UpstreamNode]
Parameter 1Ref[ImpactCategory]
Parameter 2List[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 olca-ipc.py client API:

import olca_ipc as ipc
import olca_schema as o


def main():

    # calculate a result
    client = ipc.Client(8080)
    setup = o.CalculationSetup(
        target=o.Ref(
            id="d3a9a9b2-ec3e-4811-8617-ae853573b50b",
            ref_type=o.RefType.ProductSystem,
        ),
        impact_method=o.Ref(id="07370e48-dde9-4248-9a9b-7255f701da89"),
    )
    result = client.calculate(setup)
    result.wait_until_ready()

    # select the first best impact category and expand a tree for it
    indicator = result.get_impact_categories()[0]
    print(f"upstream tree for {indicator.name}")
    expand(result, indicator, [])

    # as always, dispose the result
    result.dispose()


def expand(r: ipc.IpcResult, indicator: o.Ref, path: list[o.TechFlow]):
    level = len(path)
    indent = "  " * level
    unit = indicator.ref_unit
    nodes = r.get_upstream_impacts_of(indicator, path)
    for node in nodes:
        if node.result == 0 or not node.tech_flow:
            continue
        name = node.tech_flow.provider.name
        value = node.result
        print(f"{indent}- {value:.2E} {unit} :: {name}")

        # we stop the expansion after 3 levels; you can set other cut-offs like
        # result contributions etc.
        if level < 3:
            expand(r, indicator, path + [node.tech_flow])
    pass


if __name__ == "__main__":
    main()