restructure and organize
This commit is contained in:
130
projects/minimal_dsp_recipe_example/run_minimal_recipe.m
Normal file
130
projects/minimal_dsp_recipe_example/run_minimal_recipe.m
Normal file
@@ -0,0 +1,130 @@
|
||||
% Minimal example for exchangeable DSP recipes.
|
||||
%
|
||||
% This script demonstrates the framework wiring only. Set run_ids to one or
|
||||
% more known runs before executing it.
|
||||
%
|
||||
% Signal and parameter flow:
|
||||
%
|
||||
% 1) *This script* here entry script defines run selection and DSP options.
|
||||
% - run_ids selects the measured/simulated records to process.
|
||||
% - dsp_options contains worker configuration, database connection values,
|
||||
% the recipe function handle, and the parameter sweep definition.
|
||||
%
|
||||
% 1.1) *DataStorage* expands dsp_options.userParameters into concrete jobs.
|
||||
% Example:
|
||||
% dsp_options.userParameters.dd_mode = [0, 1]
|
||||
% creates two jobs for each run_id:
|
||||
% job 1: userParameters.dd_mode = 0
|
||||
% job 2: userParameters.dd_mode = 1
|
||||
%
|
||||
% 2) *submitJobs* builds the job list.
|
||||
% For each run_id and each Warehouse index it forwards:
|
||||
% dsp_runid(run_id, "recipe", @dsp_recipe_minimal, ...
|
||||
% "userParameters", concreteParameterStruct, ...)
|
||||
%
|
||||
% 3) *runBatch* executes the job list.
|
||||
% submitJobs delegates execution to runBatch. runBatch is the generic
|
||||
% serial/parallel executor; it handles feval/parfeval, progress updates,
|
||||
% result callbacks, and error callbacks, but it has no DSP, DB, Warehouse,
|
||||
% or recipe-specific semantics.
|
||||
%
|
||||
% 4) *dsp_runid* is the worker.
|
||||
% It does not own DSP algorithm choices. It only:
|
||||
% - opens its own DB connection if mode/load/write requires it
|
||||
% - loads metadata for the run_id
|
||||
% - loads Tx_bits, Symbols, and received scope data
|
||||
% - synchronizes/limits Scpe_cell occurrences
|
||||
% - calls the selected recipe for each occurrence
|
||||
%
|
||||
% 5) The *recipe* is the project-specific DSP layer.
|
||||
% dsp_recipe_minimal receives exactly:
|
||||
% Scpe_sig_raw: one received scope/synchronized signal occurrence
|
||||
% Symbols: transmitted symbols/reference
|
||||
% Tx_bits: transmitted bit reference
|
||||
% fsym, M, duob_mode: metadata from the run
|
||||
% userParameters: one concrete parameter struct from the sweep
|
||||
%
|
||||
% 6) *Results* flow back as a standard output struct.
|
||||
% submitJobs auto-creates wh.sto fields from non-empty recipe output
|
||||
% fields. In this example, output.ffe_package creates wh.sto.ffe_package.
|
||||
|
||||
clearvars;
|
||||
|
||||
% === DSP settings ===
|
||||
% The recipe handle is the only DSP-specific dispatch point in this script.
|
||||
% Switch it to another function with the same signature to run another DSP
|
||||
% chain without changing submitJobs, runBatch, DB loading, or Warehouse logic.
|
||||
dsp_options = struct();
|
||||
dsp_options.mode = "run_id";
|
||||
dsp_options.recipe = @dsp_recipe_minimal;
|
||||
dsp_options.append_to_db = false;
|
||||
dsp_options.max_occurences = 1;
|
||||
dsp_options.debug_plots = true;
|
||||
|
||||
dsp_options.database_type = "mysql";
|
||||
mpi = 1;
|
||||
if mpi
|
||||
dsp_options.dataBase = "labor";
|
||||
dsp_options.storage_path = "W:\labdata\ECOC Silas\ecoc_2025";
|
||||
else
|
||||
dsp_options.dataBase = "labor_highspeed";
|
||||
dsp_options.storage_path = "W:\labdata\sioe_labor\";
|
||||
end
|
||||
dsp_options.server = "192.168.178.192";
|
||||
dsp_options.port = 3306;
|
||||
dsp_options.user = "silas";
|
||||
dsp_options.password = "silas";
|
||||
|
||||
db = DBHandler("dataBase", [dsp_options.dataBase],...
|
||||
"type", dsp_options.database_type,...
|
||||
"server", dsp_options.server,...
|
||||
"user", dsp_options.user, "password", dsp_options.password);
|
||||
|
||||
% Parameters are expanded by DataStorage and interpreted by the recipe.
|
||||
% submitJobs treats this struct as transport data only; semantic meaning
|
||||
% belongs to dsp_recipe_minimal or any replacement recipe.
|
||||
dsp_options.userParameters = struct();
|
||||
dsp_options.userParameters.dd_mode = [0,1];
|
||||
|
||||
fp = QueryFilter();
|
||||
if mpi
|
||||
fp.where('Runs', 'symbolrate', 'EQUALS', 112e9);
|
||||
fp.where('Runs', 'fiber_length', 'EQUALS', 0);
|
||||
fp.where('Runs', 'interference_path_length', 'EQUALS', 1000);
|
||||
fp.where('Runs', 'sir', 'EQUALS', 52);
|
||||
fp.where('Runs', 'db_mode', 'EQUALS', '"no_db"');
|
||||
fp.where('Runs', 'is_mpi', 'EQUALS', 1);
|
||||
fp.where('Runs', 'pam_level', 'EQUALS', 4);
|
||||
fp.where('Runs', 'wavelength', 'EQUALS', 1310);
|
||||
fp.where('Runs', 'v_bias', 'EQUALS', 2.65);
|
||||
else
|
||||
% fp.where('Runs', 'pam_level','EQUALS', 4);
|
||||
% fp.where('Runs', 'bitrate','EQUALS', 360e9);
|
||||
% fp.where('Runs', 'fiber_length','EQUALS', 2);
|
||||
% fp.where('Runs', 'is_mpi','EQUALS', 0);
|
||||
% fp.where('Runs', 'wavelength','EQUALS', 1310);
|
||||
% fp.where('Runs', 'db_mode','EQUALS', 0);
|
||||
% fp.where('Runs', 'rop_attenuation','EQUAL', 0);
|
||||
end
|
||||
|
||||
|
||||
[dataTable,~] = db.queryDB(fp, db.getTableFieldNames('Runs'));
|
||||
|
||||
run_ids = dataTable.run_id(1);
|
||||
|
||||
if isempty(run_ids)
|
||||
error("run_minimal_recipe:MissingRunIds", ...
|
||||
"Set run_ids to one or more known run IDs before running this example.");
|
||||
end
|
||||
|
||||
%% === Warehouse setup ===
|
||||
% DataStorage defines the parameter grid. Result containers are created by
|
||||
% submitJobs from returned recipe output fields.
|
||||
wh = DataStorage(dsp_options.userParameters);
|
||||
|
||||
%% === Run ===
|
||||
% submitJobs returns the raw per-job results and the filled Warehouse. For a
|
||||
% single run_id and dd_mode = [0, 1], results is a 2-by-1 cell array.
|
||||
[results, wh] = submitJobs(run_ids, dsp_options, processingMode.serial, ...
|
||||
"wh", wh, ...
|
||||
"waitbar", true);
|
||||
Reference in New Issue
Block a user