8 Basic Implementation Patterns
This chapter introduces the fundamental implementation patterns for Tercen operators. You’ll learn how to connect to Tercen’s data API, understand the context system, and implement the core computational logic that forms the foundation of every operator.
- Tercen Context system and data connection
- Core operator implementation patterns
- Data selection and manipulation techniques
- Basic computation workflows
- Result preparation and output formatting
8.1 Understanding Tercen Context
The Tercen Context is your operator’s gateway to the platform. It provides access to:
- Input data based on the current projection
- Metadata about the analysis workflow
- Functions for data selection and result submission
- Access to user-defined parameters
- Error handling and logging capabilities
8.1.1 Connection Identifiers
Every data step in Tercen has unique identifiers that your operator uses to connect:
8.2 Required Identifiers
- Workflow ID: Identifies the specific workflow containing your data
- Step ID: Identifies the specific data step within that workflow
These can be found in the data step URL: /w/{workflowId}/ds/{stepId}
Example URL: https://tercen.com/w/12345abc/ds/67890def
- Workflow ID: 12345abc
- Step ID: 67890def
8.2.1 Establishing Connection
library(tercen)
library(dplyr)
# Establish context
<- tercenCtx(
ctx workflowId = "YOUR_WORKFLOW_ID",
stepId = "YOUR_STEP_ID",
username = "admin", # for local instance
password = "admin", # for local instance
serviceUri = "http://tercen:5400/" # for local instance
)
# For cloud instance, use:
<- tercenCtx(
ctx workflowId="YOUR_WORKFLOW_ID",
stepId="YOUR_STEP_ID",
authToken="YOUR_TERCEN_TOKEN",
serviceUri="https://tercen.com/api/v1/"
)
from tercen.client import context as ctx
import numpy as np
# Establish context
= ctx.TercenContext(
tercenCtx ="YOUR_WORKFLOW_ID",
workflowId="YOUR_STEP_ID",
stepId="admin", # for local instance
username="admin", # for local instance
password="http://tercen:5400/" # for local instance
serviceUri
)
# For cloud instance (for example, on tercen.com), use:
= ctx.TercenContext(
tercenCtx ="YOUR_WORKFLOW_ID",
workflowId="YOUR_STEP_ID",
stepId="YOUR_TERCEN_TOKEN",
authToken="https://tercen.com/api/v1/"
serviceUri )
8.3 Data Exploration and Selection
Once connected, explore the available data structure:
# Basic data selection
%>% select(.y) # Get y-axis values
ctx %>% select(.y, .ci, .ri) # Get y values with indices
ctx
# Explore projection components
%>% cselect() # Column factors
ctx %>% rselect() # Row factors
ctx %>% colors() # Color factors
ctx %>% labels() # Label factors
ctx
# Get factor names
$cnames # Column factor names
ctx$rnames # Row factor names
ctx
# Convert to matrix format (if applicable)
%>% as.matrix() # Matrix representation ctx
# Basic data selection
'.y']) # Get y-axis values
tercenCtx.select(['.y', '.ci', '.ri']) # Get y values with indices
tercenCtx.select([
# Explore projection components
# Column factors
tercenCtx.cselect() # Row factors
tercenCtx.rselect() # Color factors
tercenCtx.colors() # Label factors
tercenCtx.labels()
# Get factor names
# Column factor names
tercenCtx.cnames # Row factor names
tercenCtx.rnames
# Use different dataframe libraries
'.y'], df_lib="pandas") # Pandas DataFrame
tercenCtx.select(['.y'], df_lib="polars") # Polars DataFrame tercenCtx.select([
8.3.1 Key API Functions
Function | Purpose | Returns |
---|---|---|
select() |
Get specific data columns | DataFrame with selected columns |
cselect() |
Get column factor data | DataFrame with column factors |
rselect() |
Get row factor data | DataFrame with row factors |
as.matrix() |
Convert to matrix format | Matrix (y-values as matrix) |
colors() |
Get color factor data | DataFrame with color factors |
labels() |
Get label factor data | DataFrame with label factors |
addNamespace() |
Add unique column names | Modified DataFrame |
save() |
Send results back to Tercen | Success confirmation |
8.4 Standard Operator Workflow
Every operator follows this fundamental pattern:
- Connect to Tercen using context
- Select required data components
- Compute your analytical results
- Save results with proper formatting
Start by exploring your data interactively using the selection functions. Understanding the data structure is crucial before implementing your computational logic.
8.5 Core Implementation Patterns
8.5.1 Pattern 1: Cell-wise Operations
The most common pattern computes results for each unique combination of row and column factors:
library(tercen)
library(dplyr)
# Connect to Tercen
<- tercenCtx(workflowId = "YOUR_WORKFLOW_ID", stepId = "YOUR_STEP_ID")
ctx
# Cell-wise computation pattern
<- ctx %>%
result # Step 1: Select required data components
select(.y, .ci, .ri) %>% # y-values with cell indices
# Step 2: Group by projection components (per-cell grouping)
group_by(.ri, .ci) %>% # Group by row and column indices
# Step 3: Compute your analysis
summarise(
mean_value = mean(.y, na.rm = TRUE),
count = n(),
.groups = 'drop'
%>%
)
# Step 4: Handle edge cases
mutate(
mean_value = ifelse(count == 0, NA_real_, mean_value)
)
# Step 5: Prepare output and save
<- ctx$addNamespace(result)
result $save(result) ctx
from tercen.client import context as ctx
import polars as pl
# Connect to Tercen
= ctx.TercenContext(workflowId="YOUR_WORKFLOW_ID", stepId="YOUR_STEP_ID")
tercenCtx
# Cell-wise computation pattern
= (
df
tercenCtx# Step 1: Select required data components
'.y', '.ci', '.ri'], df_lib="polars")
.select([
# Step 2: Group by projection components (per-cell grouping)
'.ci', '.ri'])
.group_by([
# Step 3: Compute your analysis
.agg(['.y').mean().alias('mean_value'),
pl.col('.y').count().alias('count')
pl.col(
])
# Step 4: Handle edge cases
.with_columns(['count') == 0)
pl.when(pl.col(None)
.then('mean_value'))
.otherwise(pl.col('mean_value')
.alias(
])
)
# Step 5: Prepare output and save
= tercenCtx.add_namespace(df)
df tercenCtx.save(df)
8.5.2 Pattern 2: Row-wise Operations
Compute results across columns for each row:
# Row-wise computation pattern
<- ctx %>%
result select(.y, .ri) %>% # y-values with row indices
group_by(.ri) %>% # Group by row indices only
summarise(
row_sum = sum(.y, na.rm = TRUE),
row_mean = mean(.y, na.rm = TRUE),
.groups = 'drop'
)
<- ctx$addNamespace(result)
result $save(result) ctx
# Row-wise computation pattern
= (
df
tercenCtx'.y', '.ri'], df_lib="polars")
.select(['.ri'])
.group_by([
.agg(['.y').sum().alias('row_sum'),
pl.col('.y').mean().alias('row_mean')
pl.col(
])
)
= tercenCtx.add_namespace(df)
df tercenCtx.save(df)
8.5.3 Pattern 3: Column-wise Operations
Compute results across rows for each column:
# Column-wise computation pattern
<- ctx %>%
result select(.y, .ci) %>% # y-values with column indices
group_by(.ci) %>% # Group by column indices only
summarise(
col_var = var(.y, na.rm = TRUE),
col_max = max(.y, na.rm = TRUE),
.groups = 'drop'
)
<- ctx$addNamespace(result)
result $save(result) ctx
# Column-wise computation pattern
= (
df
tercenCtx'.y', '.ci'], df_lib="polars")
.select(['.ci'])
.group_by([
.agg(['.y').var().alias('col_var'),
pl.col('.y').max().alias('col_max')
pl.col(
])
)
= tercenCtx.add_namespace(df)
df tercenCtx.save(df)
8.6 Handling Factor Data
When working with categorical data from row/column factors:
# Working with factors
<- ctx %>%
factor_data select(.y, .ci, .ri) %>%
left_join(ctx %>% cselect(), by = ".ci") %>% # Join column factors
left_join(ctx %>% rselect(), by = ".ri") # Join row factors
# Now you have access to the actual factor values, not just indices
# Working with factors
= tercenCtx.select(['.y', '.ci', '.ri'], df_lib="polars")
y_data = tercenCtx.cselect(df_lib="polars")
col_factors = tercenCtx.rselect(df_lib="polars")
row_factors
# Join to get factor values
= (
df
y_data=".ci", how="left")
.join(col_factors, on=".ri", how="left")
.join(row_factors, on )
8.7 Next Steps
Now that you understand the basic implementation patterns, the next chapter will cover advanced features including error handling, parameter management, and comprehensive testing strategies. These techniques are essential for creating robust, production-ready operators.