npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@physiomelinks/protocol-kit

v0.6.0

Published

Experiment protocols for PhLynx and CUFLynx: read, check, edit and preview the protocol_info, data items, prediction items and prediction plots of a circulatory_autogen obs_data.json, as CUFLynx edits them, and compute their features as circulatory_autoge

Readme

protocol-kit

Experiment protocols for PhLynx and CUFLynx: read, check, edit and preview the protocol_info, data_items, prediction_items and prediction_plots of a circulatory_autogen obs_data.json, as CUFLynx's "Edit obs_data" dialog edits them, and compute a run's features as circulatory_autogen does, the same way in both apps.

What it holds

  • Core (@physiomelinks/protocol-kit): plain JavaScript, no framework.
    • Reading and writing obs_data.json; loading and saving an unedited file reproduces it, unknown keys included.
    • Validating protocol_info as circulatory_autogen does, with its own error messages.
    • Expanding protocol shapes (steps, pulses, pacing trains, ramps) and traces.
    • Editing: adding, removing and moving experiments and sub-experiments, and setting values and inputs. Data and prediction items keep pointing at the right experiment and sub-experiment.
    • Previewing an input over time.
    • Prediction items: adding, changing and removing the items a run records, one at a time as CUFLynx's rows, and checking them as circulatory_autogen #536 does.
    • Features: a run's feature values, of its prediction items and its data items, computed from its recorded samples as circulatory_autogen computes them, to the bit.
    • Prediction plots: adding, changing, removing and checking prediction_plots, which plot a feature across experiments (an I–V curve, say), and pairing computed features into their points.
    • Data items: adding, changing and removing the measured data a calibration fits, every field CUFLynx edits, and checking them as circulatory_autogen #536 does, with its messages.
  • Editor (@physiomelinks/protocol-kit/editor): Vue 3 + PrimeVue 4 components that edit an obs_data document as CUFLynx's "Edit obs_data" dialog does. The host app supplies its model's variables, its preset, a confirm dialog and a colour palette.

circulatory_autogen is the reference. Golden vectors generated by its own code (tests/resources/*-vectors.json) check that the shape expansion, validation and features here match it.

It does not run simulations. Each app runs protocols with its own engine: CUFLynx through circulatory_autogen and Myokit, PhLynx through libOpenCOR.

How it reads obs_data

It follows circulatory_autogen's semantics for obs_data.json, so a file means the same in PhLynx, CUFLynx and CA:

  • protocol_info configures the simulations and their perturbations: experiments (pre_times, sim_times, one row of sub-experiments each), the values parameters take in each sub-experiment (params_to_change), and the shapes and traces inputs follow over time (protocol_shapes, protocol_traces).
  • data_items and prediction_items refer to an experiment by its place (experiment_idx, 0 when left out) and to a sub-experiment by its place in it (subexperiment_idx). A data item without one is in the first sub-experiment; a prediction item without one records over its experiment's last, as circulatory_autogen #536 reads it.
  • Edits renumber both kinds of item when experiments or sub-experiments move or go, so none points at the wrong one.
  • A prediction item records the trace of the variable in operands, or with an operation (and operation_kwargs) a feature of it, one number over its sub-experiment, in one experiment. Items share item_name_for_plotting to be plotted as one group. An item with held-out data (value, std, data_type, obs_dt) is validated against it: edits keep those keys as they are, and never write them.
  • A data item is measured data: a value and std (one number, or a series of them every obs_dt) or a distribution (prob_dist_params), of the variables in operands or a feature of them (operation), scored by a cost (cost_type, by default gaussian_MLE) with a weight. Edits keep its keys as written, but write the legacy variable and name_for_plotting as data_item_name and trace_name_for_plotting.
  • A prediction plot (prediction_plots, a top-level list circulatory_autogen draws) pairs two groups of features experiment by experiment, by experiment_idx, or a group with an input's value in a sub-experiment of each; or draws a model output with an input, over time or against it, in each experiment. Edits keep it pointing at the same groups, sub-experiments and experiments.
  • Keys it doesn't know are kept, wherever they are.

Getting started (contributors)

You need Node.js 22 or later, and Yarn 4 through Corepack.

  1. Fork physiomelinks/protocol-kit on GitHub, then clone your fork:
    git clone https://github.com/<your-username>/protocol-kit.git
    cd protocol-kit
    git remote add upstream https://github.com/physiomelinks/protocol-kit.git
  2. Install:
    corepack enable
    yarn install
  3. Test and build:
    yarn test     # vitest
    yarn build    # the library, into dist/
  4. Keep your fork up to date:
    git fetch upstream
    git rebase upstream/main

Open pull requests against physiomelinks/protocol-kit main.

Using it in an app

Once published:

yarn add @physiomelinks/protocol-kit

To develop against a local checkout, point the app's package.json at it:

"@physiomelinks/protocol-kit": "portal:../protocol-kit"

A checkout has its own node_modules, so the app must keep one copy of the editor's peers. With Vite: resolve: { dedupe: ['vue', 'primevue', 'papaparse'] }.

import { parseObsData, validateProtocolInfo, readProtocolInfo } from '@physiomelinks/protocol-kit'

const { protocolInfo } = parseObsData(text)
const { errors, warnings, protocolInfo: valid } = validateProtocolInfo(protocolInfo)
const view = valid && readProtocolInfo(valid) // experiments, sub-experiments and inputs

Core API

Every function takes and gives plain JSON-like values; edits never change the document given.

| Module | What it does | Main exports | | --- | --- | --- | | obsDataDocument | Reads and writes obs_data, and finds it among an archive's files as CUFLynx does. | parseObsData, readObsDataParts, serialiseObsData, findObsDataExtra, buildObsDataLocation | | protocolValidation | Checks protocol_info as CA does, with its messages, then for what running it needs. | validateProtocolInfo, readAsCircAutogen, checkParamsToChange, PROTOCOL_INFO_KEYS | | protocolModel | Reads a valid protocol_info as experiments of sub-experiments, and each parameter's input in each. | readProtocolInfo, readShapeForm, buildShapeFromForm, nameExperiment, changesDuringWarmUp, readFromSubExperimentStart, findParametersAtModelValues | | protocolShapes | Expands pacing and ramp shapes into traces, as CA's protocol_shapes.py. | normaliseShape, expandShape, materialiseShapes, validateTraceReferences, ProtocolShapeError | | protocolEditing | Edits a document's protocol, renumbering its data and prediction items. | addExperiment, addEmptyExperiment, removeExperiment, moveExperiment, addSubExperiment, removeSubExperiment, setTiming, addParameter, removeParameter, setValue, setInput, setInputFromSubExperimentStart, alignWithWarmUp, findObservationsAt, ensureProtocol | | protocolPreview | Samples an input over time for drawing. | interpolateTrace, sampleInput, findValueRange, writePolylinePoints | | predictionItems | Edits a document's prediction items one at a time, each read as a row and written back as CUFLynx's editor does. | listPredictionItems, readPredictionItemRow, buildPredictionItem, createPredictionItem, addPredictionItem, updatePredictionItem, removePredictionItem, findFreeItemName, isValidationData | | operations | Computes the operations a feature can take as CA's funcs do, to the bit, and the samples a range takes. | applyOperation, sumPairwise, computeMean, sliceRange, sliceRangeBounds, COMPUTED_OPERATIONS, OperationError | | features | Computes a run's features from each sub-experiment's samples: its prediction items' as CA's features_from_segments does, its data items' as its cost loop does. | computeFeatures, computeDataItemFeatures | | predictionPlots | Edits and checks a document's prediction plots, and pairs features into their points. | addPredictionPlot, updatePredictionPlot, removePredictionPlot, validatePredictionPlots, listFeatureGroups, computePlotSeries, listPlotExperiments, findPlotsLosingInput, PREDICTION_PLOT_KINDS, PREDICTION_PLOT_KIND_KEYS, INPUT_REDUCTIONS | | predictionValidation | Checks prediction items as CA #536 does, with its messages, then each range for the run's dt. | readPredictionItemsAsCircAutogen, validatePredictionItems, checkOperationRange, findPredictionItemLimits, readPredictionItem, nameItemForPlotting, PREDICTION_ITEM_KEYS | | dataItems | Edits a document's data items, each read as a form's row and written back as CUFLynx's editor did. | listDataItems, isRowDataItem, addDataItem, updateDataItem, removeDataItem, readDataItem, buildDataItem, createDataItem, DATA_ITEM_FIELDS | | dataItemValidation | Checks data items as CA #536 reads them, with its messages, then each for an editor: kwargs, references, experiments. | readDataItemsAsCircAutogen, validateDataItems, checkOperationKwargs, checkCostKwargs, checkDataItemReferences, DATA_ITEM_KEYS | | dataItemVocabulary | CA #536's data types, plot types, default cost, operations and cost funcs, for an editor to offer. | DATA_ITEM_VOCABULARY, readObsDataOptions, DATA_TYPES, PLOT_TYPES, DEFAULT_COST_TYPE, DATA_ITEM_OPERATIONS, DATA_ITEM_COST_TYPES | | protocolCompatibility | Lists what CA, and so CUFLynx, can't run of a protocol. | findCircAutogenLimits | | protocolNames | Finds the variable a parameter names, as CA's name resolver does. | findNameCandidates, resolveParameterName | | experimentColours | Colours experiments as experiment_colors names them, or from a palette by place. | resolveExperimentColour, EXPERIMENT_PALETTE, MATPLOTLIB_COLOURS | | pythonFormat | Formats values as Python does, for CA's messages. | formatPythonG, formatPythonRepr, ... |

import { parseObsData, removeSubExperiment, serialiseObsData } from '@physiomelinks/protocol-kit'

const { document } = parseObsData(text)
const edited = removeSubExperiment(document, 0, 1) // items in it go; later ones move down
const bytes = serialiseObsData(edited) // an ArrayBuffer, indented with 2 spaces

Prediction items

import { addPredictionItem, createPredictionItem, listPredictionItems, updatePredictionItem, validatePredictionItems } from '@physiomelinks/protocol-kit'

let edited = addPredictionItem(document, {
  ...createPredictionItem(), // a trace, in the first experiment, over its last sub-experiment
  operands: ['i_Na/i_Na'], // left unnamed, it is named after its variable: i_Na/i_Na, else i_Na/i_Na_2...
  unit: 'uA_per_cm2',
  experiment: 1,
  subexperiment: 1, // from 0; null for the experiment's last
  operation: 'min_in_range', // '' for a trace
  operationKwargs: { start_frac: 0, end_frac: 0.2 },
  itemName: 'I_peak', // item_name_for_plotting: the group it is plotted in
  traceName: 'Sodium current', // trace_name_for_plotting
})
const rows = listPredictionItems(edited) // [{ index, name, operands, unit, experiment, subexperiment, operation, ... }]
edited = updatePredictionItem(edited, rows.at(-1).index, { name: 'I_peak_e1' })
const { errors, warnings, itemErrors } = validatePredictionItems(edited, { dt: 0.01 })

A row holds an item's fields under the names of readPredictionItemRow; buildPredictionItem writes only those that changed, so an item read and written back is the same, held-out data and keys it doesn't know of included. An item left unnamed is named after its variable, apart from every data and prediction item (findFreeItemName), as CA requires names unique. updatePredictionItem renames an item where other prediction items' operation_kwargs name it, and the prediction plots follow a group (item_name_for_plotting) renamed in its last item. A document the Outputs of 0.2 to 0.4 wrote (one item per experiment, sharing item_name_for_plotting) reads as a row per item.

validatePredictionItems gives CA's error for each item, and those of the whole list (names repeated across data and prediction items), where CA stops at the first (readPredictionItemsAsCircAutogen does too). It also checks that each *_in_range window takes a sample: CA reduces the samples from int(start_frac * (n - 1)) up to, not including, int(end_frac * (n - 1)) of the n = int(duration / dt) + 1 a sub-experiment records. Its warnings say which items need circulatory_autogen #536 (an operation, operation_kwargs or subexperiment_idx): released libcuflynx 0.7.3 and current CUFLynx reject them.

Data items

import { addDataItem, createDataItem, listDataItems, updateDataItem, validateDataItems } from '@physiomelinks/protocol-kit'

let edited = addDataItem(document, {
  ...createDataItem(), // a constant, the max of its variable, scored by CA's default cost
  name: 'V_peak', // data_item_name
  operands: ['membrane/V'],
  unit: 'mV',
  operation: 'max_in_range',
  operationKwargs: { start_frac: 0, end_frac: 0.5 },
  value: 20, // or a list for a series, with obsDt
  std: 1.5,
  experiment: 1,
  subexperiment: 0,
})
const [row] = listDataItems(edited) // { index, name, dataType, operands, value, std, costType, plotType, ... }
edited = updateDataItem(edited, row.index, { name: 'V_max', costType: 'gaussian_MLE_robust', costKwargs: { p_outlier: 0.1 } })
const { errors, warnings, itemErrors, itemWarnings, sharedErrors } = validateDataItems(edited)

A row holds an item's fields under the names CUFLynx's editor gave them (readDataItem): '' is no operation and the default cost, a plotType of null the data type's default and '' no marker ('None'), and labels left '' CA's defaults. buildDataItem writes only the fields that changed, so an item read and written back is the same, keys it doesn't know of included; updateDataItem renames an item where other data items' operation_kwargs name it. isRowDataItem(row, vocabulary) says whether the editor lists an item as a row, for a host counting them. Every edit gives each item an experiment_idx and subexperiment_idx once one has them, as CA refuses a column some lack.

readDataItemsAsCircAutogen reads data items as #536's parser does, stopping at its first error, pandas' quirks included. validateDataItems gives each item's errors, and goes on: CA's own for it, its experiment and sub-experiment in the protocol, its operation_kwargs and cost_kwargs against the funcs (checkOperationKwargs, checkCostKwargs, with difflib's suggestions), and references to items not computed before it; then what CA refuses of them together (names repeated across data and prediction items). It warns of an operation or cost func CA has not. It checks against DATA_ITEM_VOCABULARY, or a host's own: readObsDataOptions reads CUFLynx's /api/obs_data/options, user funcs included.

Features and prediction plots

import { addPredictionPlot, computeDataItemFeatures, computeFeatures, computePlotSeries, sliceRangeBounds, validatePredictionPlots } from '@physiomelinks/protocol-kit'

// Each sub-experiment's own samples, by operand: [experiment][sub] = { time, values: { 'i_Na/i_Na': Float64Array } }
const features = computeFeatures(document, segments) // [{ name, group, experiment, subexperiment, kwargs, value, unit, error }]
const measured = computeDataItemFeatures(document, segments) // the same, for each constant data item with an operation
const { start, end } = sliceRangeBounds(samples.length, measured[0].kwargs) // the samples it reduced, end excluded
const edited = addPredictionPlot(document, {
  name: 'Peak I_Na vs step potential',
  kind: 'feature_vs_input', // or 'feature_vs_feature' (x a group)
  x: { params_to_change: 'clamp/V_cmd', subexperiment_idx: 1, reduce: 'max' }, // reduce: for an input that is a trace
  y: 'I_peak', // a group: the items' item_name_for_plotting
  series: null, // or an input like x: a line per value
})
const traced = addPredictionPlot(edited, {
  name: 'V with the command',
  kind: 'input_and_output', // or 'output_vs_input': the output against the input
  input: { params_to_change: 'clamp/V_cmd' },
  output: 'membrane/V',
  experiments: [0, 2], // left out for all
})
const { errors, plotErrors, plotWarnings } = validatePredictionPlots(traced)
const [plot] = computePlotSeries(edited, features) // { x, y, series, points: [{ experiment, x, y, series, measured }], skipped, errors }

A sub-experiment's samples are those CA records for it: from the one taken once its values are set, to its end. A run that joins sub-experiments into one trace, and so starts each with the last sample of the one before, must split them so, or a feature over a window that starts the sub-experiment comes out differently. A constant may be given as a number or one sample, as libcuflynx's Myokit helper records it. A feature CA can't compute (a maximum over a range with no samples, say) is NaN with the error; a mean over none is NaN, as numpy's.

A data item's feature is over its own sub-experiment, the first when it names none. CA visits the sub-experiments in order, each experiment's in turn, and in each its data items in the order of data_items, so an operation_kwargs value may name an item computed before it there or in an earlier sub-experiment. Each feature's kwargs hold the values such names stand for, so sliceRangeBounds gives a host the samples an *_in_range operation took, to draw it over them.

The operations computed (COMPUTED_OPERATIONS) are max, min, mean and max_minus_min, each over all of its sub-experiment or, as *_in_range, over its start_frac to end_frac, and first_peak_time of the operands [t, V]: the time of V's first peak as scipy's find_peaks finds it (at least spike_min_thresh high, when given), in the sub-experiment's own time, or its last time when there is none. A host draws it as a vertical line.

A plot pairs, for each experiment its y group has an item in, that item's feature with the x group's in the same experiment (feature_vs_feature), or the value params_to_change[key][experiment][subexperiment_idx] (feature_vs_input). Where that is a trace, reduce makes it one number, as CA #591 does: 'final', 'mean', 'max', 'min' or {at: <seconds from the start of the sub-experiment>}; a number ignores it, and CA leaves out the point of a trace without one. input_and_output and output_vs_input draw a model output (output) with an input (input: {params_to_change}), over time on twin y axes or against it, in each experiment of experiments, all when it is left out; computePlotSeries gives them no points, as they draw a run's traces, but their input, output and experiments. validatePredictionPlots checks what CA does: each kind's keys and no others, a name of its own, the kind, and for the feature kinds the x it takes, groups that exist, are features (an operation, not a series) and have one item per experiment, x and y over the same experiments, and inputs set to a number or a trace in that sub-experiment of each experiment, with a reduce CA knows (its at no later than the end of a sub-experiment where the input is a trace); for the others, an input params_to_change sets, an output and experiments the protocol has. plotWarnings names a trace read without a reduce. Removing or moving an experiment renumbers the experiments a plot names; one left with none goes. Removing a sub-experiment moves an input reference down with it where every point is in that experiment; where one index can no longer name the same sub-experiment in each, or names the one removed, the plot goes, and findObservationsAt names it first.

Mounting the editor

The editor is a v-model on an obs_data document (document prop, update:document event): each edit passes on a new document, never changing the one given, so the host keeps it, saves it and undoes edits as it likes. It needs Vue 3.5, PrimeVue 4 (styled, with a theme such as Aura), papaparse and PrimeIcons.

<template>
  <ObsDataEditor v-model:document="obsData" :variables="variables" :get-value="getValue" preset="phlynx" />
</template>

<script setup>
import { ref } from 'vue'
import { ObsDataEditor } from '@physiomelinks/protocol-kit/editor'
import '@physiomelinks/protocol-kit/editor.css'
import 'primeicons/primeicons.css'

const obsData = ref(null) // e.g. parseObsData(text).document; null or a bare list offers to add protocol_info
const variables = [
  { name: 'membrane/g_Na', label: 'Sodium conductance', unit: 'mS_per_cm2', kind: 'constant', value: 0.12 },
  { name: 'membrane/V', unit: 'mV', kind: 'variable' },
]
const getValue = (name) => variables.find((variable) => variable.name === name)?.value
</script>

ObsDataEditor has a section for each key of the document, headed by the key as CUFLynx's dialog heads them:

  • protocol_info, on a timeline (ProtocolInfoEditor), or for a data-only document (a bare list of data items, or no protocol_info) the button "Add protocol_info".
  • data_items (DataItemsSection), then, with a protocol, prediction_items (PredictionItemsSection) and prediction_plots (PredictionPlotsSection): a row per item, its details under a chevron.

Clicking a row selects it: the timeline shows its experiment and tints its sub-experiment (a prediction item's last when it names none), as CUFLynx's dialog does.

| Prop | | | | --- | --- | --- | | document | Object \| Array \| null | The obs_data document (v-model:document). | | variables | Array<{name, label?, unit?, kind?, value?}> | The model's variables. name is as the protocol names it (component/variable, as params_to_change keys). Those of kind 'constant' or 'global_constant' can be added for the protocol to set; unit labels its lane, and a prediction item's when picked. The pickers search name and label. | | preset | 'cuflynx' \| 'phlynx' | Optional. The host's app: 'cuflynx' (the default) edits every column; 'phlynx' shows the data items read-only, without weight, cost and differentiability. Prediction items and plots are edited in both. | | getValue | (name) => number \| string \| undefined | Optional. A variable's value in the model, which a parameter starts from when added, and which tells the parameters left at it (below). By default, its value in variables. | | confirm | (options) => Promise<boolean> | Optional. Asks before removing something from the protocol; options has header, message, severity, acceptLabel and rejectLabel. By default, PrimeVue's ConfirmDialog (the editor shows its own, in the group protocol-kit-confirm) when the app has ConfirmationService, else the browser's confirm. Rows are removed without asking, as CUFLynx's are; the host's undo brings one back. | | palette | string[] | Optional. Colours of experiments the file doesn't colour (experiment_colors), by place. By default EXPERIMENT_PALETTE. | | warn | (protocolInfo) => string[] | Optional. The app's own warnings about the protocol, shown after the editor's: what it ignores, say. | | dt | number | Optional. The time between the samples a run records, to check that each prediction item's range takes some. | | showDataItems | boolean | Optional. Whether to show the data items; by default true. PhLynx passes its "Show data items" setting. | | dataItemColumns | string[] | Optional. The data items' columns, when not the preset's (below). | | dataItemsReadOnly | boolean | Optional. Whether the data items are only listed; by default as the preset says. | | vocabulary | Object | Optional. The operations, cost funcs, data and plot types offered; by default DATA_ITEM_VOCABULARY. CUFLynx passes its own: :vocabulary="readObsDataOptions(await getObsDataOptions())". |

The slot data-items-actions puts the host's buttons beside the data_items heading (CUFLynx's "Custom funcs").

Parameters at their model values. A parameter the protocol sets to its value in the model, as a plain number, in every experiment and sub-experiment (within rounding, a relative 1e-9) has no lane until asked for: a line below the others counts them, with a button to show and hide them. The document keeps them. The model's values come from getValue, else variables; a parameter whose value is unknown there, one added or edited while the editor is open, and one an error or warning names (whole, not as the start of a longer name) are always shown.

Times in the first sub-experiment. An input's times are from the start of its sub-experiment, the first one's too. CA starts an experiment's first sub-experiment, and its inputs' clock, with the warm-up, so an input written there is moved to start with the sub-experiment and holds its first value through the warm-up (setInputFromSubExperimentStart), and is shown again with the times it was given (readFromSubExperimentStart). An input a file has that changes during the warm-up is marked, and editing it writes the times shown from the start of the sub-experiment.

Data items. DataItemsSection has CUFLynx's rows, name | value | std | operation | exp | sub, and under the chevron the operands (each labelled x1, x2... as CA's func names them, time among the variables), trace label, unit, weight, cost_type (the default named) and its kwargs, plot_type, the operation's kwargs (another item's name for an operation of no operands), source and comment. A row CA would refuse is tinted red and says why, read-only too; one whose operation CA can't differentiate is tinted orange, with CUFLynx's warning. An item a row can't hold (a series, a frequency, a distribution, an operation the vocabulary hasn't) is kept as it is, and counted: "N non-editable item(s) (series / frequency / custom operation) will be preserved unchanged." Its columns are keys of DATA_ITEM_COLUMNS (name, value, std, operation, experiment, subexperiment, operands, traceName, unit, weight, cost, plot, operationKwargs, source, comment, and differentiable for the tint), and the presets (DATA_ITEM_COLUMN_PRESETS) name them:

  • 'cuflynx', for an app that calibrates: every column, editable.
  • 'phlynx', for an app that only runs the protocol: the data as measured, read-only, without weight, cost and differentiable. PhLynx hides the section with its "Show data items" setting.

Prediction items. PredictionItemsSection has a row per item, variable | unit | trace label | exp | sub | operation: the sub-experiment "(last)" or an index, the operation "(none)" or one of CA's. Under the chevron, its name, item label (item_name_for_plotting, CA's default as its placeholder) and the operation's kwargs, start_frac and end_frac for a range. A variable picked names an item left unnamed, and gives its unit. An item with held-out data is marked obs, its data kept. Each row shows CA's errors for it; the section warns what needs #536.

Prediction plots. PredictionPlotsSection has a row per plot, name | kind | settings: the kind a dropdown of the four, and only that kind's settings. feature_vs_feature: y and x groups of features, and series none or an input in a sub-experiment. feature_vs_input: y, x an input with its sub-experiment and reduce (and a time for "at a time"), and series. input_and_output and output_vs_input: the input, the output (picked from variables when the host gives them, else typed) and a box per experiment, every one ticked leaving experiments out. Choosing a kind writes its keys alone, keeping the name and carrying an input over. Each row shows the plot's errors, and its warnings.

Each section takes document, readOnly and, but for the plots, columns (a preset or a list of keys); it emits update:document, and the item sections select with the place of the row selected (selected). The entry also exports ProtocolCellEditor, InlineNumber, NumberInput, VariablePicker, INPUT_KINDS, findInputKind, DATA_ITEM_COLUMNS, DATA_ITEM_COLUMN_PRESETS, resolveDataItemColumns, isReadOnlyPreset, PREDICTION_ITEM_COLUMNS, PREDICTION_ITEM_COLUMN_PRESETS, resolvePredictionItemColumns, searchVariables, splitVariableName and isSettable. The editor registers PrimeVue's tooltip directive itself.

CSS variables. The components use the PrimeVue theme's tokens, so they follow the host's theme, light or dark. Each has a fallback (Aura's light value) for a host without them:

| Variable | Fallback | Used for | | --- | --- | --- | | --p-text-color | currentColor | Headings | | --p-text-muted-color | #64748b | Secondary text, units, captions | | --p-primary-color | #10b981 | Focus rings, the current experiment, links | | --p-content-background | #ffffff | Chips over lanes | | --p-content-hover-background | #f1f5f9 | Column heads, lanes, hovered experiments | | --p-content-border-color | #e2e8f0 | The experiment list's border, chips | | --p-inputtext-border-color | #cbd5e1 | The experiment name's border, on hover | | --p-orange-400, --p-orange-500 | #fb923c, #f97316 | Warnings: inputs CUFLynx can't run, inputs starting with the warm-up | | --p-red-500 | #ef4444 | Errors: inputs circulatory_autogen refuses, numbers that aren't |

Fixtures and golden vectors

tests/resources/ holds obs_data files from circulatory_autogen and CUFLynx (br-1977 with shapes and engine/pace, SN_simple with traces, NKE_pump, and others), and prediction_items_536_obs_data.json, prediction items as CA #536 reads them (operation, operation_kwargs, subexperiment_idx, held-out values). The round-trip tests check that loading and saving each without edits gives the same document, byte for byte when it is written as serialiseObsData writes it (JSON indented with 2 spaces), and that every edit leaves what it doesn't own untouched. Numbers are written as JavaScript writes them, so a file written by Python (1.0, -0.0, 1e-05) comes back with the same values but not the same bytes.

scripts/generate_ca_vectors.py runs circulatory_autogen's own shape expansion and validation and rewrites tests/resources/ca-vectors.json, for the shape cases in it and every *_obs_data.json fixture. It needs no packages. Run it when circulatory_autogen changes its protocol semantics, or a fixture is added, then fix whatever the tests show:

python scripts/generate_ca_vectors.py /path/to/circulatory_autogen

scripts/generate_prediction_vectors.py does the same for prediction items, with #536's own parser: it rewrites tests/resources/prediction-vectors.json, for its good and bad cases and every fixture with prediction items. It needs a Python with that circulatory_autogen's libcuflynx installed. The vectors record the commit they come from: #536's head (refs/pull/536/head).

/path/to/venv/bin/python scripts/generate_prediction_vectors.py /path/to/circulatory_autogen

scripts/generate_data_item_vectors.py does the same for data items, with the same Python: #536's parser on good and bad items and every fixture's, its operation_kwargs and cost_kwargs checks, and its vocabulary (data and plot types, the default cost, its operations and cost funcs, their kwargs), into tests/resources/data-item-vectors.json.

/path/to/venv/bin/python scripts/generate_data_item_vectors.py /path/to/circulatory_autogen

Licence

Apache 2.0

scripts/generate_operation_vectors.py runs circulatory_autogen's own operation funcs, its features_from_segments over a run of random samples, and its get_obs_output_dict over the same run's data items, sub-experiment by sub-experiment as its cost loop does, and rewrites tests/resources/operation-vectors.json: thousands of cases over series of many lengths (around numpy's blocks of 8 and 128), NaNs, infinities and signed zeros, with windows inside and outside 0 to 1, and the samples each window takes. The tests check each value to the bit. It needs a Python with that circulatory_autogen's libcuflynx installed:

python scripts/generate_operation_vectors.py /path/to/circulatory_autogen