Skip to content

Configuration

The GRAFT is configured through YAML files in app/configs/ and shared constants in app/configs/constants.py. No code changes are needed when tuning model parameters, switching data sources, or adjusting thresholds — edit the relevant file and restart the application.

FilePurpose
database_config.yamlWebSocket endpoint and SQLite database path
LinearRegression_config_NiceGUI.yamlLinear regression model and evaluation settings
LSTM_config_NiceGUI.yamlLSTM architecture, features, training, and evaluation settings
XGBoost_config_NiceGUI.yamlXGBoost hyperparameters, features, and evaluation settings
constants.pyRuntime constants, directory paths, labels — set once, used everywhere

Controls how the application connects to the live data source and where the local results database lives.

# WebSocket configuration
websocket:
# WebSocket endpoint for streaming experiment data
uri: wss://maple.containers.wur.nl/ws
# Base SQL query used by the WebSocket backend
base_query: SELECT * FROM public.pioreactor
# Local database configuration
database:
# SQLite database file used for metrics and predictions
path: metrics.db

websocket.uri — The WebSocket server to connect to. Update this if your Pioreactor instance moves to a different host.

websocket.base_query — The SQL query sent to the WebSocket backend. The application appends WHERE clauses for experiment filtering and time pagination automatically — do not add these manually.

database.path — Path to the local SQLite file where prediction results and evaluation metrics are stored. Relative paths are resolved from the project root.

data:
id_column: entity
metric_column: metric
plot_history_minutes: 20
target_column: optical_density
time_column: time
database:
path: "metrics.db"
forecast:
horizon_forecast: 15
horizon_minutes: 1
training:
window_train: 300
window_test: 50
lags:
number: 15
model:
linear_regression_path: trained_models/linear_regression_model.pkl
copy_X: True
fit_intercept: True
n_jobs: 1
preprocessing:
fill_method: bfill_ffill
resample_freq: 1min
value_column: value
feature_columns:
- optical_density
db_config: database_config.yaml
evaluation:
max_horizon: 6
rolling_window_size: 30
horizon_unit: "min"
min_points_for_correlation: 20
min_variance_for_correlation: 1e-4
ParameterDefaultDescription
forecast.horizon_forecast15Number of future time steps to predict
forecast.horizon_minutes1Duration of each time step in minutes
training.window_train300Number of most recent rows used for training
training.window_test50Number of rows held out for testing
lags.number15Number of lag features added to the feature matrix
preprocessing.resample_freq1minResampling frequency applied before training
evaluation.rolling_window_size30Rolling window of predictions used for metric computation
evaluation.min_points_for_correlation20Minimum matched points before computing R² / Spearman
data:
id_column: entity
metric_column: metric
plot_history_minutes: 20
target_column: optical_density
time_column: time
database:
path: "metrics.db"
forecast:
horizon_forecast: 15
horizon_minutes: 1
lags:
number: 60
gompertz:
enabled: true
adaptive_window: 300
refit_every: 10
min_points: 20
use_residual_learning: true
model:
sequence_length: 60
lstm_path: trained_models/lstm_model.keras
lstm_units: 100
dropout: 0.3
epochs: 5
batch_size: 32
optimizer: "adam"
loss: "mae"
max_rows: 10000
patience: 20
scale_target: false
preprocessing:
fill_method: bfill_ffill
use_log: true
resample_freq: 1min
value_column: value
feature_columns:
- optical_density
- temperature
- agitation_rate
- optical_density_roll3
- optical_density_roll5
- optical_density_roll10
- optical_density_std3
- optical_density_std5
- optical_density_diff1
- optical_density_diff_roll5
- experiment_elapsed_min
- tod_sin
- tod_cos
training:
window_train: 500
window_test: 50
evaluation:
max_horizon: 6
rolling_window_size: 30
horizon_unit: "min"
min_points_for_correlation: 20
min_variance_for_correlation: 1e-5
ParameterDefaultDescription
model.sequence_length60Look-back window (number of time steps fed into the LSTM)
model.lstm_units100Number of LSTM units per layer
model.dropout0.3Dropout rate applied during training
model.epochs5Maximum training epochs (early stopping via patience)
model.patience20Early stopping patience in epochs
model.scale_targetfalseWhether to normalise the target variable before training
preprocessing.use_logtrueApply log transform to optical density before training
gompertz.enabledtrueWhether to fit a Gompertz residual correction on top of LSTM
gompertz.adaptive_window300Recent points used for Gompertz fitting
gompertz.refit_every10Refit the Gompertz model every N predictions
lags.number60Number of lag features added to the input

The LSTM uses 13 engineered features derived from raw sensor data:

FeatureDescription
optical_densityRaw OD reading
temperatureTemperature (°C)
agitation_rateAgitation speed (RPM)
optical_density_roll3/5/10Rolling mean over 3, 5, 10 steps
optical_density_std3/5Rolling standard deviation over 3, 5 steps
optical_density_diff1First-order difference
optical_density_diff_roll5Rolling mean of first-order differences
experiment_elapsed_minMinutes since experiment start
tod_sin / tod_cosSine and cosine encoding of time-of-day
db_config: database_config.yaml
forecast:
horizon_forecast: 15
horizon_minutes: 1
lags:
number: 60
model:
learning_rate: 0.01
max_depth: 6
n_estimators: 100
objective: reg:squarederror
tree_method: hist
subsample: 0.8
colsample_bytree: 0.8
reg_lambda: 1.0
preprocessing:
fill_method: bfill_ffill
use_log: true
resample_freq: 1min
value_column: value
feature_columns:
- optical_density
- temperature
- agitation_rate
- optical_density_roll3
- optical_density_roll5
- optical_density_roll10
- optical_density_std3
- optical_density_std5
- optical_density_diff1
- optical_density_diff_roll5
- experiment_elapsed_min
- tod_sin
- tod_cos
training:
window_train: 500
window_test: 50
data:
id_column: entity
metric_column: metric
plot_history_minutes: 20
target_column: optical_density
time_column: time
database:
path: "metrics.db"
gompertz:
enabled: true
adaptive_window: 300
refit_every: 10
min_points: 20
use_residual_learning: true
evaluation:
max_horizon: 6
rolling_window_size: 30
horizon_unit: "min"
min_points_for_correlation: 20
min_variance_for_correlation: 1e-4
ParameterDefaultDescription
model.n_estimators100Number of boosting rounds
model.max_depth6Maximum tree depth — increase for more complex patterns
model.learning_rate0.01Step size shrinkage to prevent overfitting
model.subsample0.8Fraction of rows sampled per tree
model.colsample_bytree0.8Fraction of features sampled per tree
model.reg_lambda1.0L2 regularisation term
gompertz.enabledtrueFit a Gompertz residual correction on top of XGBoost
preprocessing.use_logtrueApply log transform to optical density

XGBoost uses the same 13 engineered feature columns as the LSTM — see the LSTM feature table above.

Defines application-wide runtime constants, directory paths, and display labels. These are set once and used across all modules.

ConstantDefaultDescription
RUN_INTERVAL180Seconds between automatic prediction runs
MAX_PLOT_POINTS1000Maximum data points rendered per chart
AVERAGE_FREQ"1min"Default resampling frequency for plots
ConstantPathDescription
PACKAGE_DIRProject rootBase directory for config file resolution
USER_DATA_DIR~/.graft/User-writable runtime data directory
MODEL_DIR~/.graft/trained_models/Saved model artefacts

Subdirectories results/, logs/, data/, and trained_models/ are created automatically inside USER_DATA_DIR on first run.

METRIC_LABELS maps internal column names to human-readable axis labels:

KeyDisplay Label
optical_densityOptical Density (OD)
growth_rateGrowth Rate (1/h)
agitation_rateAgitation Rate (RPM)
temperatureTemperature (°C)

MODEL_METRIC_LABELS maps evaluation metric keys to display labels:

KeyDisplay Label
mseMean Squared Error (MSE)
rmseRoot Mean Squared Error (RMSE)
r2R² Score
spearmanSpearman Correlation
maeMean Absolute Error (MAE)
mapeMAPE (%)
direction_accuracyDirection Accuracy (%)
smapesMAPE (%)
max_errorMaximum Error

You do not need to edit YAML files directly. All model parameters — training window sizes, forecast horizons, hyperparameters, and preprocessing settings — can be adjusted from within the dashboard itself on the Model Control page.

  1. Open the dashboard at http://localhost:8080
  2. Navigate to the Model Control page
  3. Adjust the parameters using the input controls

Model configuration

  1. Click Run to apply the new settings and retrain or re-run the model

Model configuration 2

The YAML files in app/configs/ serve as the default values loaded on startup. Any changes made in the app take effect immediately for that session.