Creating Analyses

Building multi-algorithm workflows with DAGs

Creating Analyses

Analyses are sophisticated workflows that combine multiple algorithms into a Directed Acyclic Graph (DAG). They enable you to build complex multi-step geospatial analyses.

Why Use Analyses?

Analyses allow you to:

  • Chain algorithms - Output of one algorithm becomes input to the next
  • Build workflows - Create multi-step processing pipelines
  • Reuse components - Combine existing algorithms in new ways
  • Share workflows - Package complex analyses for others to use

Analysis vs Algorithm

AlgorithmAnalysis
Single processing stepMultiple processing steps
One containerMultiple containers (one per algorithm)
Simple input/outputDAG of connected algorithms
Building blockComplete workflow

Analysis Structure

Analysis
  └── Analysis Version(s)
        └── Analysis Config(s)
              └── Analysis Computation(s)

Similar to algorithms:

  • Analysis - Top-level metadata
  • Analysis Version - DAG structure with specific Algorithm Versions
  • Analysis Config - Configuration with specific Algorithm Configs
  • Analysis Computation - Runtime execution

Example: Traceability Analysis

A supply chain traceability analysis might consist of:

[Data Collection Algorithm]
         ↓
[Object Detection Algorithm]
         ↓
[Tracking Algorithm]
         ↓
[Route Analysis Algorithm]

Creating an Analysis

Step 1: Create Analysis

from elements.sdk.elements_sdk import ElementsSDK

sdk = ElementsSDK()

analysis = await sdk.analysis.create(
    name="supply-chain-traceability",
    author="Your Organization"
)

print(f"Analysis created: {analysis.id}")

Step 2: Create Analysis Version

Define the DAG structure:

from elements_api.async_client import ElementsAsyncClient

client = ElementsAsyncClient(host, port, secure=True, token=api_token)

# Define algorithm nodes
algorithm_nodes = []

# Node 1: Data Collection
node1 = client.models.analysis_pb2.AnalysisAlgorithmNode(
    name="data-collection",
    algorithm_version_id="algo-version-1-id",
    children={}  # No inputs, first node
)
algorithm_nodes.append(node1)

# Node 2: Object Detection (depends on data-collection)
node2 = client.models.analysis_pb2.AnalysisAlgorithmNode(
    name="object-detection",
    algorithm_version_id="algo-version-2-id",
    children={
        "input_1": "data-collection"  # Gets input from node 1
    }
)
algorithm_nodes.append(node2)

# Node 3: Tracking (depends on object-detection)
node3 = client.models.analysis_pb2.AnalysisAlgorithmNode(
    name="tracking",
    algorithm_version_id="algo-version-3-id",
    children={
        "input_1": "object-detection"
    }
)
algorithm_nodes.append(node3)

# Create analysis manifest
analysis_manifest = client.models.analysis_version_pb2.AnalysisManifest(
    manifest_version="0.1.0",
    metadata=client.models.analysis_version_pb2.AnalysisManifest.Metadata(
        version="1.0",
        description="Supply chain traceability analysis",
        tags=["supply-chain", "traceability"],
    ),
    algorithm_nodes=algorithm_nodes,
)

# Register analysis version
analysis_version_request = client.models.analysis_version_pb2.AnalysisVersionCreateRequest(
    analysis_id=analysis.id,
    analysis_manifest=analysis_manifest
)

analysis_version = await client.api.analysis_version.create(analysis_version_request)

print(f"Analysis version created: {analysis_version.id}")

Step 3: Create Analysis Configuration

Link each node to an Algorithm Config:

# Define config nodes
config_nodes = []

# Config for node 1
config_node1 = client.models.analysis_pb2.AnalysisAlgorithmConfigNode(
    name="data-collection",
    algorithm_config_id="algo-config-1-id"
)
config_nodes.append(config_node1)

# Config for node 2
config_node2 = client.models.analysis_pb2.AnalysisAlgorithmConfigNode(
    name="object-detection",
    algorithm_config_id="algo-config-2-id"
)
config_nodes.append(config_node2)

# Config for node 3
config_node3 = client.models.analysis_pb2.AnalysisAlgorithmConfigNode(
    name="tracking",
    algorithm_config_id="algo-config-3-id"
)
config_nodes.append(config_node3)

# Create analysis config
analysis_config_request = client.models.analysis_config_pb2.AnalysisConfigCreateRequest(
    name="production-traceability",
    analysis_version_id=analysis_version.id,
    algorithm_config_nodes=config_nodes,
)

analysis_config = await client.api.analysis_config.create(analysis_config_request)

print(f"Analysis config created: {analysis_config.id}")

Step 4: Run Analysis Computation

# Create analysis computation
analysis_computation_request = client.models.analysis_computation_pb2.AnalysisComputationCreateRequest(
    analysis_config_id=analysis_config.id,
    aoi_collection_id=aoi_collection_id,
    toi_id=toi_id,
)

analysis_computation = await client.api.analysis_computation.create(
    analysis_computation_request
)

# Run the computation
run_request = client.models.analysis_computation_pb2.AnalysisComputationRunRequest(
    ids=[analysis_computation.id]
)

await client.api.analysis_computation.run(run_request)

print(f"Analysis computation started: {analysis_computation.id}")

DAG Structure

Linear DAG (Sequential)

# A → B → C
children_map = {
    "A": {},           # No dependencies
    "B": {"input": "A"},   # Depends on A
    "C": {"input": "B"}    # Depends on B
}

Branching DAG (Parallel)

# A → B
#   → C
children_map = {
    "A": {},                # No dependencies
    "B": {"input": "A"},    # Depends on A
    "C": {"input": "A"}     # Also depends on A (parallel with B)
}

Merging DAG

# A → C
# B → C
children_map = {
    "A": {},                    # No dependencies
    "B": {},                    # No dependencies
    "C": {                      # Depends on both A and B
        "input_1": "A",
        "input_2": "B"
    }
}

Data Flow

In an Analysis:

  1. First nodes read data filtered by AOI and TOI
  2. Each node runs as an Algorithm Computation
  3. Output from one node becomes input to dependent nodes
  4. Final nodes produce the Analysis results

Data Type compatibility:

  • Output Data Type of node A must match input Data Type of node B
  • Validated when you create the Analysis Version

Showing in UI

For your Analysis to appear in the Elements UI, create an Analysis Configuration. Once created and shared appropriately, users can:

  • Browse available analyses in the UI
  • Select your analysis when creating projects
  • Configure parameters (via the Algorithm Configs)
  • Run analyses and view results

Next Steps