Data Science Functions Reference ⚡
Functions Overview
Navigation
Use the Index below to jump to the details of a function.
🎯 Recommendations & Scoring
| Function | Purpose |
|---|---|
recommend |
End-to-end ProcessAI recommendation pipeline (candidate generation → scoring → ranking). |
candidate_score |
Score candidate settings based on user-interest metrics, quality tests, constraints, and duration. |
compute_recommendation_adherence |
Adherence score of active recommendations vs. actuals over time buckets. |
recommendation_achievement |
Per-period “achievement” score for a recommendation. |
🧠 Modeling & Inference
| Function | Purpose |
|---|---|
infer_from_model |
Run inference from a production ML/optimization model given metric-group inputs. |
infer_from_oql |
Run inference from any OQL-shaped inputs (optionally return probabilities). |
compute_regression_slos |
Compute regression SLOs (Correlation, R², MAPE, MSE, Nsamples) with group & cross-group rollups. |
linear_polyfit |
Fit degree-1 regression; return slope or status vs. thresholds. |
🧩 Segmentation & Clustering
| Function | Purpose |
|---|---|
threshold_segmentation |
Segment based on thresholds and optional interval changes. |
detect_ramp_up_from_downtime |
Detect ramp-up windows after downtime using learned thresholds. |
dummy_cluster |
Assign dummy cluster indices to rows. |
segment_repeatability |
Pairwise segment repeatability from process & outcome distances. |
discover_motifs |
Find time-series motifs via matrix profile (experimental). |
mpsearch |
Matrix profile search over a time window (experimental). |
📏 Distance & Similarity
| Function | Purpose |
|---|---|
compute_distance |
Distance to a reference vector with optional sort & column management. |
📊 Aggregation & Post-processing
| Function | Purpose |
|---|---|
final_aggregate |
Final pass aggregations over OQL results via JSON specs. |
accumulate_cost_savings |
Accumulate cost, projected cost, and savings from a cost-rate series. |
recommend_performance_recipe |
Surface top-performing stable segment’s “recipe” and opportunity vs. target. |
Function Details
• recommend
End-to-end recommendation workflow for ProcessAI (v0.1 alpha): candidate generation from stable periods, scoring (supports recsys and predictive_quality), optional penalties, and ranking.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Input table containing current/stable metrics, specs, tests, and any penalty inputs. |
action_metric_group_name |
list[str] | Aliases of actionable metric groups to swap. |
action_metric_group_uuid |
list[str] | UUIDs of actionable metric groups. |
quality_test_identifiers |
list[str] | Names/aliases of quality tests. |
model_identifiers |
list[str] | Model identifiers (MLFlow) per quality test. |
score_normalize |
list[str] | Per-test normalization (e.g., "as-is", "normalize", "log-normalize"). |
score_aggregate |
str | Score aggregation method (e.g., "additive"). |
candidate_index_cols |
list[str] | Columns that uniquely index candidate: must include id, start, end. |
infer_metric_group_name |
list[str] | None | Extra metric groups to feed into inference models (aliases). |
infer_metric_group_uuid |
list[str] | None | UUIDs matching infer_metric_group_name. |
current_prefix |
str | None | Prefix for current metrics in input_data. |
candidate_prefix |
str | None | Prefix for stable/candidate metrics in input_data. |
quality_spec_lsl_postfix |
str | None | Postfix for LSL columns. |
quality_spec_usl_postfix |
str | None | Postfix for USL columns. |
quality_spec_target_postfix |
str | None | Postfix for Target columns. |
penalty_col |
str | None | Column with multiplicative penalty factor. |
score_col |
str | None | Name of final score column. |
keep_cols |
list[str] | None | Columns to pass through to the result. |
verbose |
str | None | "full", "standard", or "silent". |
rename_cols |
str | None | Dict-in-string to rename output columns. |
first_cols |
list[str] | None | Columns to pin first in result order. |
local_candidate_stepsizes |
str | None | JSON dict of local search steps around current conditions. |
non_quality_col |
str | None | Column for non-quality objective. |
quality_score_multiplier_col |
str | None | Column to scale quality score. |
Example
WITH current_metric () AS (
AGGREGATE
avg(metric_group('<ACTION_MG_UUID_1>')) AS action_1,
avg(metric_group('<ACTION_MG_UUID_2>')) AS action_2,
avg(metric_group('<ACTION_MG_UUID_3>')) AS action_3,
avg(metric_group('<INFER_MG_UUID_1>')) AS infer_1,
avg(metric_group('<INFER_MG_UUID_2>')) AS infer_2,
avg(metric_group('<INFER_MG_UUID_3>')) AS infer_3,
avg(metric_group('<INFER_MG_UUID_4>')) AS infer_4
WHERE time FROM now()-1m TO now()
AND line.id = '<LINE_ID_1>'
SETTINGS backend=v1
),
current_test () AS (
AGGREGATE
lastIf(offline_quality.results.result, offline_quality.results.testid = '<QUALITY_TEST_NAME_1>') AS quality_test_1,
lastIf(offline_quality.results.result, offline_quality.results.testid = '<QUALITY_TEST_NAME_2>') AS quality_test_2,
lastIf(offline_quality.results.result, offline_quality.results.testid = '<QUALITY_TEST_NAME_3>') AS quality_test_3
WHERE time FROM now()-2h TO now()
AND line.id = '<LINE_ID_1>'
SETTINGS backend=v1
),
stable () AS (
AGGREGATE
interval.stable_period.start AS start,
interval.stable_period.end AS end,
avg(metric_group('<ACTION_MG_UUID_1>')) AS action_1,
avg(metric_group('<ACTION_MG_UUID_2>')) AS action_2,
avg(metric_group('<ACTION_MG_UUID_3>')) AS action_3,
coalesce(avg(interval.run.target('<QUALITY_MG_UUID_1>').lsl),0) AS quality_test_1_lsl,
avg(interval.run.target('<QUALITY_MG_UUID_1>').usl) AS quality_test_1_usl,
coalesce(avg(interval.run.target('<QUALITY_MG_UUID_2>').lsl),0) AS quality_test_2_lsl,
avg(interval.run.target('<QUALITY_MG_UUID_3>').usl) AS quality_test_3_usl,
avg(interval.run.target('<QUALITY_MG_UUID_1>').value) AS quality_test_1_target,
avg(interval.run.target('<QUALITY_MG_UUID_2>').value) AS quality_test_2_target,
avg(interval.run.target('<QUALITY_MG_UUID_3>').value) AS quality_test_3_target,
avg(metric_group('<REF_MG_UUID_1>')) AS ref_1,
avg(metric_group('<REF_MG_UUID_2>')) AS ref_2,
avg(metric_group('<REF_MG_UUID_3>')) AS ref_3,
avg(metric_group('<NON_QUALITY_MG_UUID_1>')) AS non_quality_1,
avg(metric_group('<NON_QUALITY_MG_UUID_2>')) AS non_quality_2
WHERE time FROM date_trunc(now()-7M, 'D') TO date_trunc(now(), 'D')
AND line.id = '<LINE_ID_1>'
AND product.id = '<PRODUCT_ID_1>'
AND interval.state.type = 'Uptime'
AND interval.stable_period.value != ''
GROUP BY interval.stable_period AS id
SETTINGS backend=v1
)
AGGREGATE
stable.id AS id,
stable.start AS start,
stable.end AS end,
current_metric.action_1 AS current_action_1,
current_metric.action_2 AS current_action_2,
current_metric.action_3 AS current_action_3,
stable.action_1 AS stable_action_1,
stable.action_2 AS stable_action_2,
stable.action_3 AS stable_action_3,
current_metric.infer_1 AS current_infer_1,
current_metric.infer_2 AS current_infer_2,
current_metric.infer_3 AS current_infer_3,
current_metric.infer_4 AS current_infer_4,
stable.quality_test_1_lsl AS quality_test_1_lsl,
stable.quality_test_1_usl AS quality_test_1_usl,
stable.quality_test_2_lsl AS quality_test_2_lsl,
stable.quality_test_3_usl AS quality_test_3_usl,
stable.quality_test_1_target AS quality_test_1_target,
stable.quality_test_2_target AS quality_test_2_target,
stable.quality_test_3_target AS quality_test_3_target,
current_test.quality_test_1 AS quality_test_1,
current_test.quality_test_2 AS quality_test_2,
current_test.quality_test_3 AS quality_test_3,
greatest(1 - abs(current_action_1 - stable_action_1) / greatest(current_action_1, 1e-9), 0) *
greatest(1 - abs(current_action_2 - stable_action_2) / greatest(current_action_2, 1e-9), 0) *
greatest(1 - abs(current_action_3 - stable_action_3) / greatest(current_action_3, 1e-9), 0) AS penalty_factor,
(stable.ref_1 * stable.ref_2 + stable.ref_3) AS quality_reference,
(stable.non_quality_1 * stable.non_quality_2) AS non_quality_col,
0.5 AS quality_score_multiplier_col
JOIN stable USING ()
JOIN current_metric USING ()
JOIN current_test USING ()
WHERE TIME FROM now()-6M TO now()
AND line.id = '<LINE_ID_1>'
HAVING quality_reference > 0
APPLY honk2science recommend(
action_metric_group_name = ['action_1','action_2','action_3'],
action_metric_group_uuid = ['<ACTION_MG_UUID_1>','<ACTION_MG_UUID_2>','<ACTION_MG_UUID_3>'],
quality_test_identifiers = ['quality_test_1','quality_test_2','quality_test_3'],
model_identifiers = ['<MODEL_IDENTIFIER_1>','<MODEL_IDENTIFIER_2>','<MODEL_IDENTIFIER_3>'],
score_normalize = ['as-is','normalize','log-normalize'],
score_aggregate = 'additive',
candidate_index_cols = ['id','start','end'],
infer_metric_group_name = ['infer_1','infer_2','infer_3'],
infer_metric_group_uuid = ['<INFER_MG_UUID_1>','<INFER_MG_UUID_2>','<INFER_MG_UUID_3>'],
current_prefix = 'current_',
candidate_prefix = 'stable_',
quality_spec_lsl_postfix = '_lsl',
quality_spec_usl_postfix = '_usl',
quality_spec_target_postfix = '_target',
penalty_col = 'penalty_factor',
score_col = 'rank_score',
keep_cols = ['quality_reference','stable_action_1','current_action_1','penalty_factor'],
verbose = 'silent',
rename_cols = "{'quality_reference':'my_first_name','current_action_1':'my_second_name'}",
first_cols = ['stable_action_1','penalty_factor'],
local_candidate_stepsizes = '{"infer_1":{"step_size":0.1,"max":10,"min":0},"infer_2":{"step_size":"<STEP_COL_NAME>","max":"<MAX_COL_NAME>","min":"<MIN_COL_NAME>"},"infer_3":{"step_size":0.1,"max":10,"min":0}}',
non_quality_col = 'non_quality_col',
quality_score_multiplier_col= 'quality_score_multiplier_col'
)
SETTINGS backend=v1;
Returns
OqlData with score_col plus candidate indexing columns (id, start, end) and any keep_cols.
Raises GRPCError – On invalid or missing inputs/models/scoring setup.
🔗 See also
candidate_score • infer_from_model • compute_recommendation_adherence
• candidate_score
Compute a per-candidate score using user-interest metric deltas, quality tests (online/offline or predicted), and constraint measures; optionally weight by candidate duration.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Candidate rows with current & stable values, specs, tests. |
user_interest_cols |
list[str] | Column aliases the user cares to change. |
user_interest_metric_groups |
list[str] | 1:1 metric-group UUIDs for user_interest_cols (order matters). |
quality_test_identifiers |
list[str] | Names of quality tests in input_data. |
model_identifiers |
list[str] | MLFlow model identifiers per quality test (order matters). |
constraint_measure_cols |
list[str] | Constraint columns (e.g., moisture, freeness). |
constraint_measure_scaling_factors |
list[float] | Scaling factors per constraint column. |
candidate_duration_col |
str | Column with candidate duration (or adjusted duration). |
candidate_score_col |
str | Output score column name (default: score). |
remove_cols |
list[str] | None | Columns to drop before returning. |
Example
WITH current_metric () AS (
AGGREGATE
avg(metric_group('<USER_INTEREST_MG_UUID_1>')) AS draw,
avg(metric_group('<USER_INTEREST_MG_UUID_2>')) AS steam,
avg(metric_group('<USER_INTEREST_MG_UUID_3>')) AS hpdt,
avg(metric_group('<CONSTRAINT_MG_UUID_1>')) AS moisture,
avg(metric_group('<CONSTRAINT_MG_UUID_2>')) AS freeness,
avg(metric_group('<CONSTRAINT_MG_UUID_3>')) AS speed,
avg(metric_group('<PQ_MG_UUID_1>')) AS predictive_quality_test_1,
avg(metric_group('<PQ_MG_UUID_2>')) AS predictive_quality_test_2
WHERE time FROM now()-1m TO now()
AND line.id = '<LINE_ID_1>'
SETTINGS backend=v1
),
current_test () AS (
AGGREGATE
abs(lastIf(offline_quality.results.minvalue, offline_quality.results.testid = '<QUALITY_TEST_NAME_1>')) AS current_quality_test_1,
abs(lastIf(offline_quality.results.minvalue, offline_quality.results.testid = '<QUALITY_TEST_NAME_2>')) AS current_quality_test_2
WHERE time FROM now()-2h TO now()
AND line.id = '<LINE_ID_1>'
SETTINGS backend=v1
)
AGGREGATE
interval.stable_period.start AS start,
interval.stable_period.end AS end,
avg(metric_group('<USER_INTEREST_MG_UUID_1>')) AS stable_draw,
avg(metric_group('<USER_INTEREST_MG_UUID_2>')) AS stable_steam,
avg(metric_group('<USER_INTEREST_MG_UUID_3>')) AS stable_hpdt,
avg(metric_group('<CONSTRAINT_MG_UUID_1>')) AS stable_moisture,
avg(metric_group('<CONSTRAINT_MG_UUID_2>')) AS stable_freeness,
avg(metric_group('<CONSTRAINT_MG_UUID_3>')) AS stable_speed,
coalesce(avg(interval.run.target('<PQ_MG_UUID_1>').lsl),0) AS quality_test_1_lsl,
avg(interval.run.target('<PQ_MG_UUID_1>').value) AS quality_test_1_target,
coalesce(avg(interval.run.target('<PQ_MG_UUID_2>').lsl),0) AS quality_test_2_lsl,
avg(interval.run.target('<PQ_MG_UUID_2>').usl) AS quality_test_2_usl,
avg(interval.run.target('<PQ_MG_UUID_2>').value) AS quality_test_2_target,
timeinif() AS duration,
least(duration/3600,2)/2 AS duration_adj,
current_metric.draw AS current_draw,
current_metric.steam AS current_steam,
current_metric.hpdt AS current_hpdt,
current_metric.moisture AS current_moisture,
current_metric.freeness AS current_freeness,
current_metric.speed AS current_speed,
coalesce(current_test.current_quality_test_1, current_metric.predictive_quality_test_1) AS quality_test_1,
coalesce(current_test.current_quality_test_2, current_metric.predictive_quality_test_2) AS quality_test_2
JOIN current_metric USING ()
JOIN current_test USING ()
WHERE time FROM date_trunc(now()-7M, 'D') TO date_trunc(now(), 'D')
AND line.id = '<LINE_ID_1>'
AND product.id = '<PRODUCT_ID_1>'
AND interval.state.type = 'Uptime'
GROUP BY interval.stable_period AS id
HAVING duration >= 3600
APPLY honk2science candidate_score(
user_interest_cols = ['draw','steam','hpdt'],
user_interest_metric_groups = ['<USER_INTEREST_MG_UUID_1>','<USER_INTEREST_MG_UUID_2>','<USER_INTEREST_MG_UUID_3>'],
quality_test_identifiers = ['quality_test_1','quality_test_2'],
model_identifiers = ['<MODEL_IDENTIFIER_1>','<MODEL_IDENTIFIER_2>'],
constraint_measure_cols = ['moisture','freeness','speed'],
constraint_measure_scaling_factors = [100,200,200],
candidate_duration_col = 'duration_adj',
candidate_score_col = 'score',
remove_cols = ['duration','duration_adj','current_draw','current_steam']
)
SETTINGS backend=v1;
Returns
OqlData with an added candidate_score_col and with any remove_cols dropped.
Raises
GRPCError – On invalid inputs or if no production model is found for a given model_identifier.
🔗 See also
recommend • infer_from_model
• compute_recommendation_adherence
Compute adherence of the active recommendation (per bucket) against actual metric-group values, returning per-metric scores and a rolled-up recommendation score.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Must include recommendations JSON and metric-group values. |
recommendations_col |
str | Column with JSON object of recommendations. |
metricgroup_cols |
list[str] | Actual metric columns to compare. |
metricgroup_uuids |
list[str] | UUIDs for each metric column (1:1 with metricgroup_cols). |
metricgroup_difference_functions |
list[str] | Difference fn per metric (e.g., "absolute"). |
metricgroup_lower_significant_thresholds |
list[float] | Lower “0-score” thresholds. |
metricgroup_lower_moderate_thresholds |
list[float] | Lower “0.5-score” thresholds. |
metricgroup_upper_significant_thresholds |
list[float] | Upper “0-score” thresholds. |
metricgroup_upper_moderate_thresholds |
list[float] | Upper “0.5-score” thresholds. |
bucket_col |
str | Timestamp bucket column. |
active_rec_col |
str | Active recommendation ID column. |
show_intermediate_calculations |
int | 1 to include intermediate columns (default 0). |
Example
AGGREGATE
avg(metric_group('<MG_UUID_1>')) AS mg_1,
avg(metric_group('<MG_UUID_2>')) AS mg_2,
avg(metric_group('<MG_UUID_3>')) AS mg_3,
JSON_QUERY(interval.process_ai_active_recommendation.value, '$.recommendation.process_metrics[*]') AS recs
WHERE TIME FROM '<START_TS_1>' TO '<END_TS_1>'
AND line.id = '<LINE_ID_1>'
GROUP BY interval.process_ai_active_recommendation AS active_rec, bucket 1m AS bucket_start
APPLY honk2science compute_recommendation_adherence(
recommendations_col = 'recs',
metricgroup_cols = ['mg_1','mg_2','mg_3'],
metricgroup_uuids = ['<MG_UUID_1>','<MG_UUID_2>','<MG_UUID_3>'],
metricgroup_difference_functions = ['absolute','absolute','absolute'],
metricgroup_lower_significant_thresholds = [5.2,5.4,7.6],
metricgroup_lower_moderate_thresholds = [4.2,3.4,2.6],
metricgroup_upper_significant_thresholds = [6.2,6.4,8.6],
metricgroup_upper_moderate_thresholds = [7.2,8.4,9.6],
bucket_col = 'bucket_start',
active_rec_col = 'active_rec'
);
Returns
Per active recommendation: active_rec, {metric}_start/end/final, and rolled-up final score over the time window.
Raises GRPCError – Schema mismatch or unequal list lengths for thresholds/functions. GRPCError – Negative thresholds.
🔗 See also
recommend • recommendation_achievement
• recommendation_achievement
Compute a per-period “achievement score” for a recommendation, based on distance of realized conditions vs. recommended.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Time-bucketed series with relevant process metrics. |
distance |
str | Distance metric (default "euclidean"). |
Example
AGGREGATE
avg(metric_group('<PROC_MG_UUID_1>')) AS '<PROC_SP_NAME_1>',
avg(metric_group('<PROC_MG_UUID_2>')) AS '<PROC_PV_NAME_1>',
avg(metric_group('<PROC_MG_UUID_3>')) AS '<PROC_PV_NAME_2>'
WHERE time FROM now()-14D TO now()
AND interval.ppo_run.value NOT IN ('')
AND interval.state.category.name IN ('Uptime')
AND line.id = '<LINE_ID_1>'
GROUP BY bucket 1m AS Bucket, line.name AS Line, interval.ppo_run.value AS ppo_value, interval.ppo_run.start AS ppo_start
SETTINGS backend=v1, timezone='UTC'
APPLY honk2science recommendation_achievement(distance='euclidean');
Returns
OqlData with [Bucket, ppo_start, recommendation_start, achievement_score].
Raises GRPCError – On invalid input data.
🔗 See also
compute_recommendation_adherence • compute_distance
• infer_from_model
Run inference using a production model with metric-group inputs (missing values are imputed with 0.0).
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Input rows (features in input_cols). |
model_identifier |
str | Production model ID. |
input_cols |
list[str] | Column aliases passed to the model (ordered). |
input_metric_group_uuid |
list[str] | UUIDs matching input_cols (ordered). |
inference_col |
str | None | Output prediction column name. |
keep_cols |
list[str] | None | Columns to retain in the output. |
Example
AGGREGATE
avg(metric_group('<MG_UUID_1>')) AS m1,
avg(metric_group('<MG_UUID_2>')) AS m2,
avg(metric_group('<MG_UUID_3>')) AS m3
WHERE time FROM now()-10m TO now()
AND line.id = '<LINE_ID_1>'
GROUP BY bucket 5m
APPLY honk2science infer_from_model(
model_identifier = '<MODEL_IDENTIFIER_1>',
input_cols = ['m1','m2','m3'],
input_metric_group_uuid = ['<MG_UUID_1>','<MG_UUID_2>','<MG_UUID_3>'],
inference_col = 'predicted_output',
keep_cols = ['bucket','m1','m2','m3']
)
SETTINGS backend=v1;
Returns
OqlData with keep_cols and inference_col.
Raises
GRPCError – Invalid input data or no production model for model_identifier.
🔗 See also
infer_from_oql • compute_regression_slos
• infer_from_oql
Model inference from arbitrary OQL-shaped inputs (may include offline quality, custom features, etc.). Missing values imputed with 0.0. Optionally returns class probabilities.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Input rows (features in input_cols). |
model_identifier |
str | Production model ID. |
input_cols |
list[str] | Feature columns passed to the model. |
inference_col |
str | None | Output prediction column. |
keep_cols |
list[str] | None | Columns to include in output. |
predict_proba |
str | "True" (case-insensitive) to request probabilities for classification; otherwise False. |
Example
AGGREGATE
avg(metric_group('<MG_UUID_1>')) AS m1,
lastIf(offline_quality.results.avgd_val, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_1>') AS q1
WHERE time FROM now()-10m TO now()
AND line.id = '<LINE_ID_1>'
GROUP BY bucket 5m
APPLY honk2science infer_from_oql(
model_identifier = '<MODEL_IDENTIFIER_1>',
input_cols = ['m1','q1'],
inference_col = 'predicted',
keep_cols = ['bucket','m1'],
predict_proba = 'True'
)
SETTINGS backend=v1;
Returns
OqlData with keep_cols and inference_col (and probabilities, if requested).
Raises
GRPCError – Invalid input data or no production model for model_identifier.
🔗 See also
infer_from_model
• compute_regression_slos
Compute regression SLOs per group and cross-group: Correlation, R², MAPE, MSE, Nsamples; also provides a group-normalized row.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Rows that contain target & prediction (optionally grouped). |
target_col |
str | Column name for the target. |
prediction_col |
str | Column name for the prediction. |
group_by_col |
str | Group key (e.g., product name). Use empty string for global only. |
Example
AGGREGATE
avgIf(offline_quality.results.result, offline_quality.results.testid = '<QUALITY_TEST_NAME_1>') AS target_col,
avg(metric_group('<MG_UUID_PRED>')) AS prediction_col,
product.name AS product
WHERE line.id = '<LINE_ID_1>'
AND time FROM now()-30D TO now()
GROUP BY bucket 5m
ORDER BY bucket DESC
HAVING target_col > 0
APPLY honk2science compute_regression_slos(
target_col = 'target_col',
prediction_col = 'prediction_col',
group_by_col = 'product'
);
Returns OqlData shaped like:
| group | Correlation | R2 | MAPE | MSE | Nsamples |
|---|---|---|---|---|---|
| Product 1 | … | … | … | … | … |
| Product 2 | … | … | … | … | … |
| Product Normalized | … | … | … | … | … |
| Cross Product | … | … | … | … | … |
Raises GRPCError – Invalid input.
🔗 See also
infer_from_model • infer_from_oql
• linear_polyfit
Fit a simple linear regression (degree 1) and return either the slope or a status vs. thresholds.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | DataFrame | Two or more points required. |
warning_threshold |
float | None | Optional warning threshold on slope. |
danger_threshold |
float | None | Optional danger threshold on slope. |
Returns
Tuple (column_name, value) where column_name is "slope" or "status".
Raises ValueError – Fewer than 2 points.
🔗 See also
compute_regression_slos
• threshold_segmentation
Segment a timeline using thresholds on selected metric groups, optionally splitting on interval changes (e.g., product), and with optional custom filtering of first/last batch/run.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Bucketed rows with metrics & interval context. |
interval_cols |
list[str] | None | Interval columns that define change points. |
threshold_metric_groups |
list[str] | Metric-group UUIDs for thresholding. |
threshold_file_identifier |
list[str] | [factory_id, line_id] (order matters). |
threshold_percentile |
str | Percentile label (e.g., "p80"). |
min_segment_duration_s |
int | Minimum segment length (seconds). |
bucket_size_s |
int | Bucket size (seconds). |
custom_filtering |
str | None | e.g., "filter_first_last_batch". |
batch_time_cols |
list[str] | None | [batch_start, batch_end] when filtering batches. |
run_time_cols |
list[str] | None | [run_start, run_end] when filtering runs. |
Example See example block in your inputs; typical pattern:
AGGREGATE
interval.state.event.start AS start_uptime,
interval.state.event.end AS end_uptime,
product.id AS product_id,
avg(metric_group('<THRESHOLD_MG_UUID_1>')) AS '<THRESHOLD_MG_UUID_1>',
avg(metric_group('<THRESHOLD_MG_UUID_2>')) AS '<THRESHOLD_MG_UUID_2>'
WHERE TIME FROM '<START_TS_2>' TO '<END_TS_2>'
AND interval.state.type = 'Uptime'
AND line.id = '<LINE_ID_1>'
GROUP BY bucket 5m AS start_bucket, interval.state.event AS event
APPLY honk2science threshold_segmentation(
interval_cols = ['product_id'],
threshold_metric_groups = ['<THRESHOLD_MG_UUID_1>','<THRESHOLD_MG_UUID_2>'],
threshold_file_identifier = ['<FACTORY_ID_1>','<LINE_ID_1>'],
threshold_percentile = 'p80',
min_segment_duration_s = 900,
bucket_size_s = 300
)
SETTINGS backend=v1, timezone='UTC';
Returns
OqlData with [line_id, start_timestamp, end_timestamp].
Raises InvalidInputError – On invalid inputs.
🔗 See also
detect_ramp_up_from_downtime
• detect_ramp_up_from_downtime
Identify ramp-up periods after downtime using learned thresholds on one or more metrics.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Bucketed uptime windows with metric averages. |
threshold_metric_groups |
list[str] | Metric-group UUIDs used for ramp-up detection. |
threshold_file_identifier |
list[str] | [factory_id, line_id] identity (order matters). |
threshold_percentile |
str | e.g., "p80". |
min_segment_duration_s |
int | Minimum ramp-up length (default 600s). |
bucket_size_s |
int | Bucket size in seconds (default 60s). |
Example
AGGREGATE
interval.state.event.start AS start_uptime,
interval.state.event.end AS end_uptime,
avg(metric_group('<METRIC_ID_1>')) AS '<METRIC_ID_1>'
WHERE TIME FROM '<START_TS_3>' TO '<END_TS_3>'
AND line.id = '<LINE_ID_1>'
AND interval.state.type = 'Uptime'
GROUP BY bucket 5m AS start_bucket, interval.state.event AS event
APPLY honk2science detect_ramp_up_from_downtime(
threshold_metric_groups = ['<METRIC_ID_1>'],
threshold_file_identifier = ['<FACTORY_ID_1>','<LINE_ID_1>'],
threshold_percentile = 'p80',
min_segment_duration_s = 600,
bucket_size_s = 300
)
SETTINGS backend=v1, timezone='UTC';
Returns
[line_id, ramp_up_start_timestamp, ramp_up_end_timestamp].
Raises InvalidInputError – On invalid inputs.
🔗 See also
threshold_segmentation
• dummy_cluster
Attach a simple cluster index to each row (placeholder clustering utility).
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Source rows. |
remove_cols |
list[str] | Columns to drop after clustering. |
add_cols |
list[str] | New column names to add. |
features |
list[str] | Feature columns used by the clustering stub. |
n_clusters |
int | Number of clusters. |
Returns
OqlData with a cluster_index (default name) plus any add_cols.
🔗 See also
segment_repeatability
• segment_repeatability
Compute repeatability between temporal segments from both process and outcome distances; aggregate via the median of num_neighbors.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Segment features & outcomes (wide table). |
id_cols |
list[str] | Segment identifier columns (e.g., id, start). |
process_cols |
list[str] | Process metric columns. |
outcome_cols |
list[str] | Outcome (quality/perf) columns. |
distance |
str | Distance function (e.g., "mape", "z-norm-euclidean"). |
num_neighbors |
int | k for median across nearest neighbors. |
Example
WITH stable (
id,
tensile_actual,
tensile_pred,
speed,
start,
end,
basis_weight,
tensile_lsl,
tensile_usl,
tensile_target,
basis_weight_lsl,
basis_weight_usl,
basis_weight_target,
v0,
v1,
v58
) AS (
AGGREGATE
avgIf(offline_quality.results.avgd_val, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_2>') AS tensile_actual,
avg(metric_group('<PREDICTION_MG_UUID_1>')) AS tensile_pred,
avg(metric_group('<PERFORMANCE_MG_UUID_1>')) AS speed,
interval.stable_period.start AS start,
interval.stable_period.end AS end,
avgIf(offline_quality.results.avgd_val, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_3>') AS basis_weight,
avgIf(offline_quality.results.reject_low, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_2>') AS tensile_lsl,
avgIf(offline_quality.results.reject_high, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_2>') AS tensile_usl,
avgIf(offline_quality.results.target, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_2>') AS tensile_target,
avgIf(offline_quality.results.reject_low, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_3>') AS basis_weight_lsl,
avgIf(offline_quality.results.reject_high, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_3>') AS basis_weight_usl,
avgIf(offline_quality.results.target, offline_quality.results.tag_name = '<QUALITY_TEST_NAME_3>') AS basis_weight_target,
avg(metric_group('<PROC_MG_UUID_4>')) AS headbox_wire_speed,
avg(metric_group('<PROC_MG_UUID_5>')) AS headbox_jet_velocity,
avg(metric_group('<PROC_MG_UUID_6>')) AS steam_flow_175,
avg(metric_group('<PROC_MG_UUID_7>')) AS wetend,
avg(metric_group('<PROC_MG_UUID_8>')) AS dryer_section_1_press,
avg(metric_group('<PROC_MG_UUID_9>')) AS dryer_section_2_press,
avg(metric_group('<PROC_MG_UUID_10>')) AS vent_stream_flow,
avg(metric_group('<PROC_MG_UUID_11>')) AS headbox_slice_opening,
avg(metric_group('<PROC_MG_UUID_12>')) AS v0,
avg(metric_group('<PROC_MG_UUID_13>')) AS v1,
avg(metric_group('<PROC_MG_UUID_14>')) AS v58
WHERE TIME FROM date_trunc(now()-6M, 'D') TO date_trunc(now(), 'D')
AND line.id = '<LINE_ID_1>'
AND product.id = '<PRODUCT_ID_1>'
AND interval.stable_period.value NOT IN ('')
GROUP BY interval.stable_period
SETTINGS backend=v1
)
AGGREGATE
stable.id,
stable.v0,
stable.v1,
stable.v58,
stable.tensile_pred AS 'Tensile MD',
stable.speed AS 'Machine Speed (ft/min)',
stable.start,
stable.end,
stable.basis_weight AS 'Basis Weight',
stable.tensile_actual AS 'hide Tensile Actual',
stable.tensile_lsl AS 'hide Tensile LSL',
stable.tensile_usl AS 'hide Tensile USL',
stable.tensile_target AS 'hide Tensile Target',
stable.basis_weight_lsl AS 'hide Basis Weight LSL',
stable.basis_weight_usl AS 'hide Basis Weight USL',
stable.basis_weight_target AS 'hide Basis Weight Target'
JOIN stable USING ()
WHERE TIME FROM date_trunc(now()-6M, 'D') TO date_trunc(now(), 'D')
AND line.id = '<LINE_ID_1>'
AND product.id = '<PRODUCT_ID_1>'
HAVING 'Tensile MD' > 'hide Tensile LSL'
AND 'Basis Weight' > 'hide Basis Weight LSL' AND 'Basis Weight' < 'hide Basis Weight USL'
AND 'Machine Speed (ft/min)' > 0
APPLY segment_repeatability(
id_cols = ['stable.start'],
process_cols = ['stable.v0','stable.v1','stable.v58'],
outcome_cols = ['Tensile MD'],
distance = 'z-norm-euclidean',
num_neighbors = 3
)
SETTINGS backend=v1;
Returns
OqlData with segment identifiers and:
- median_process_distance
- median_outcome_distance
- median_score (repeatability score)
Raises GRPCError – Invalid input.
🔗 See also
compute_distance • dummy_cluster
• discover_motifs
Find recurrent time-series motifs via matrix profile (experimental).
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
bytes | Raw series payload. |
subsequence_size |
int | Window length for motif search. |
Returns
Tuple (OqlData, dict) with motif results and metadata.
🔗 See also
mpsearch
• mpsearch
Run a matrix-profile-based search between search_start_time and search_end_time (experimental).
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
bytes | Raw series payload (aggregated time series bytes). |
search_start_time |
Timestamp | Start of search window. |
search_end_time |
Timestamp | End of search window. |
Examples
Example 1
AGGREGATE
avg(metric('<METRIC_UUID_1>'))
WHERE (TIME FROM '<PATTERN_START_TS>' TO '<PATTERN_END_TS>' OR TIME FROM now()-1M TO now())
AND line.id = '<LINE_ID_1>'
GROUP BY bucket 10s
APPLY honk2science mp_search(start_time = '<PATTERN_START_TS>', end_time = '<PATTERN_END_TS>');
-- org id <ORG_ID_1>
Sample Output
{"minimum_point": "<HIT_TS_1>", "mp_distance_profile": 4.369478225708008}
{"minimum_point": "<HIT_TS_2>", "mp_distance_profile": 9.4520902633667}
{"minimum_point": "<HIT_TS_3>", "mp_distance_profile": 7.951839447021484}
{"minimum_point": "<HIT_TS_4>", "mp_distance_profile": 4.002388954162598}
Returns
Tuple (OqlData, dict) with search hits and metadata (e.g., distance profiles).
🔗 See also
discover_motifs
• compute_distance
Compute distance from each row to a reference vector; optionally add a distance column, sort rows, and drop columns.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Input rows. |
reference_vector_col_names |
list[str] | Feature columns in order. |
reference_vector_col_values |
list[float] | Reference values in the same order. |
remove_cols |
list[str] | None | Columns to drop from result. |
add_distance_col |
str | None | Name for distance column. |
sort_by |
str | None | "ascending" (default) or "descending". |
distance |
str | Distance metric (default "euclidian"). |
Example
AGGREGATE
p50(metric_group('<MG_UUID_1>')) AS metric_group1,
p50(metric_group('<MG_UUID_2>')) AS metric_group2,
interval.state.event.end AS end_uptime
WHERE TIME FROM date_trunc(now()-90D, 'D') TO date_trunc(now(), 'D')
AND line.id = '<LINE_ID_1>'
AND interval.state.type = 'Uptime'
GROUP BY bucket 5m, interval.custom_interval.value AS custom_interval
APPLY honk2science compute_distance(
reference_vector_col_names = ['metric_group1','metric_group2'],
reference_vector_col_values = [<METRIC_GROUP1_REF>, <METRIC_GROUP2_REF>],
remove_cols = ['metric_group1'],
add_distance_col = 'distance',
sort_by = 'ascending',
distance = 'euclidian'
)
SETTINGS backend=v1, timezone='UTC';
Returns
OqlData with (optionally) add_distance_col and after applying remove_cols and sort_by.
Raises GRPCError – Invalid input.
🔗 See also
segment_repeatability • recommendation_achievement
• final_aggregate
Perform “final pass” aggregations over an OQL result using JSON specs (sum/avg, weighted aggregations, transforms, counter rebasing, and passthrough columns).
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Source rows after your main aggregation. |
group_by_cols |
list[str] | Columns to group the final aggregation by. |
aggregations |
list[str] | JSON strings describing each output column. |
Examples Aggregation:
APPLY honk2science final_aggregate(
group_by_cols = ['product'],
aggregations = [
'{"output_col":"x","input_col":"c1","weight_by":"c0","function":"sum","precision":2}',
'{"output_col":"y","input_col":"c2","weight_by":"","function":"avg"}'
]
);
Transform with passthrough
APPLY honk2science final_aggregate(
aggregations = [
'{"output_col":"rebased_tls","input_col":"TLS","function":"rebase_counter_by_min","passthrough_cols":["sampled_on"]}'
]
);
Returns OqlData with only the requested outputs (plus any passthroughs).
Raises GRPCError – Invalid input.
🔗 See also
compute_regression_slos
• accumulate_cost_savings
Accumulate Total Cost, Projected Total Initial Cost, and Total Cost Savings from a time-bucketed cost-rate series. If input_data is null, returns nulls.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Bucketed cost-rate time series. |
add_cols |
list[str] | Names of new columns (order matters). Defaults: ["Total Cost","Projected Total Initial Cost","Total Cost Savings"]. |
cost_rate_col |
str | Name of cost-rate column. |
initial_cost_rate |
float | Baseline cost rate at session start (0 ⇒ use first bucket). |
cost_rate_resolution_in_min |
int | Minutes per bucket (typically 1). |
calculation |
str | "absolute" or "percentage". |
Example
AGGREGATE
avg(metric_group('<COST_RATE_MG_UUID>')) AS "Cost Rate"
FROM TIME date_trunc('<SESSION_START_TS>','m') TO date_trunc(NOW(),'m')
WHERE line.id = '<LINE_ID_1>'
GROUP BY bucket 1 minute
HAVING "Cost Rate" > 0
APPLY honk2science accumulate_cost_savings(
cost_rate_col = 'Cost Rate',
initial_cost_rate = 5,
cost_rate_resolution_in_min = 1,
calculation = 'absolute',
add_cols = ['Total Cost','Projected Total Initial Cost','Total Cost Savings']
)
SETTINGS backend=clickhouse;
Returns OqlData with the three accumulation columns.
Raises
GRPCError – cost_rate_col missing.
GRPCError – add_cols not exactly 3 names.
🔗 See also
final_aggregate
• recommend_performance_recipe
For each combination (e.g., product×line), surface the percentile most performant stable segment and return its “recipe” metrics, plus average performance, opportunity %, and hours vs. target.
Arguments
| Name | Type | Description |
|---|---|---|
input_data |
OqlData | Stable-segment rows with recipe & performance columns. |
remove_cols |
list[str] | Columns to drop before returning. |
add_cols |
list[str] | New columns (order matters). Defaults: ["Avg Performance","Opportunity Duration","% Opportunity"]. |
combination |
list[str] | Grouping keys (one output row per combination). |
performance_col |
str | Performance column to rank/select. |
duration_col |
str | Segment duration column. |
target_col |
str | Performance target column. |
percentile |
float | Percentile to surface (default 0.95). |
Example
AGGREGATE
avg(<RECIPE_METRIC_1>) AS RECIPE_METRIC_1,
avg(<RECIPE_METRIC_2>) AS RECIPE_METRIC_2,
avg(<RECIPE_METRIC_3>) AS RECIPE_METRIC_3,
avg(<RECIPE_METRIC_4>) AS RECIPE_METRIC_4,
avg(metric_group('<PERFORMANCE_MG_UUID>')) AS Recipe_Performance,
min(interval.run.target('<TARGET_MG_UUID>').lsl) AS Target
WHERE TIME FROM now()-60D TO now()
AND line.id = '<LINE_ID_1>'
GROUP BY
interval.ppo_stable AS "Segment Start",
interval.run.product.id AS "Product",
line.id AS "Line"
APPLY honk2science recommend_performance_recipe(
combination = ['Product','Line'],
performance_col = 'Recipe_Performance',
target_col = 'Target',
percentile = 0.95,
remove_cols = ['Segment Start'],
add_cols = ['Performance Avg','% Opportunity','Opportunity Hours']
)
SETTINGS backend=v1;
Returns
OqlData with [combination keys, recipe metrics, performance, target, Avg Performance, % Opportunity, Opportunity Hours].
Raises
GRPCError – combination/remove_cols columns missing.
GRPCError – add_cols not exactly 3 names.
🔗 See also
final_aggregate • recommend