diff --git a/pathview/data/registry.json b/pathview/data/registry.json index 7d4ee5fa..de57c77e 100644 --- a/pathview/data/registry.json +++ b/pathview/data/registry.json @@ -169,7 +169,10 @@ "B", "C", "D", - "initial_value" + "initial_value", + "state_labels", + "input_labels", + "output_labels" ] }, "PT1": { @@ -327,6 +330,13 @@ "func" ] }, + "Polynomial": { + "blockClass": "Polynomial", + "importPath": "pathsim.blocks", + "params": [ + "coeffs" + ] + }, "Sin": { "blockClass": "Sin", "importPath": "pathsim.blocks", @@ -422,6 +432,14 @@ "switch_state" ] }, + "Splitter": { + "blockClass": "Splitter", + "importPath": "pathsim.blocks", + "params": [ + "fractions", + "carrier" + ] + }, "LUT": { "blockClass": "LUT", "importPath": "pathsim.blocks", @@ -479,6 +497,14 @@ "tau" ] }, + "FirstOrderHold": { + "blockClass": "FirstOrderHold", + "importPath": "pathsim.blocks", + "params": [ + "T", + "tau" + ] + }, "FIR": { "blockClass": "FIR", "importPath": "pathsim.blocks", @@ -488,6 +514,55 @@ "tau" ] }, + "DiscreteIntegrator": { + "blockClass": "DiscreteIntegrator", + "importPath": "pathsim.blocks", + "params": [ + "T", + "tau", + "initial_value" + ] + }, + "DiscreteDerivative": { + "blockClass": "DiscreteDerivative", + "importPath": "pathsim.blocks", + "params": [ + "T", + "tau" + ] + }, + "DiscreteStateSpace": { + "blockClass": "DiscreteStateSpace", + "importPath": "pathsim.blocks", + "params": [ + "A", + "B", + "C", + "D", + "T", + "tau", + "initial_value" + ] + }, + "DiscreteTransferFunction": { + "blockClass": "DiscreteTransferFunction", + "importPath": "pathsim.blocks", + "params": [ + "Num", + "Den", + "T", + "tau" + ] + }, + "TappedDelay": { + "blockClass": "TappedDelay", + "importPath": "pathsim.blocks", + "params": [ + "N", + "T", + "tau" + ] + }, "ADC": { "blockClass": "ADC", "importPath": "pathsim.blocks", diff --git a/scripts/config/pathsim/blocks.json b/scripts/config/pathsim/blocks.json index a97694a0..e8e48568 100644 --- a/scripts/config/pathsim/blocks.json +++ b/scripts/config/pathsim/blocks.json @@ -66,6 +66,7 @@ "Rescale", "Alias", "Switch", + "Splitter", "LUT", "LUT1D" ], diff --git a/scripts/generated/registry.json b/scripts/generated/registry.json index 7d4ee5fa..de57c77e 100644 --- a/scripts/generated/registry.json +++ b/scripts/generated/registry.json @@ -169,7 +169,10 @@ "B", "C", "D", - "initial_value" + "initial_value", + "state_labels", + "input_labels", + "output_labels" ] }, "PT1": { @@ -327,6 +330,13 @@ "func" ] }, + "Polynomial": { + "blockClass": "Polynomial", + "importPath": "pathsim.blocks", + "params": [ + "coeffs" + ] + }, "Sin": { "blockClass": "Sin", "importPath": "pathsim.blocks", @@ -422,6 +432,14 @@ "switch_state" ] }, + "Splitter": { + "blockClass": "Splitter", + "importPath": "pathsim.blocks", + "params": [ + "fractions", + "carrier" + ] + }, "LUT": { "blockClass": "LUT", "importPath": "pathsim.blocks", @@ -479,6 +497,14 @@ "tau" ] }, + "FirstOrderHold": { + "blockClass": "FirstOrderHold", + "importPath": "pathsim.blocks", + "params": [ + "T", + "tau" + ] + }, "FIR": { "blockClass": "FIR", "importPath": "pathsim.blocks", @@ -488,6 +514,55 @@ "tau" ] }, + "DiscreteIntegrator": { + "blockClass": "DiscreteIntegrator", + "importPath": "pathsim.blocks", + "params": [ + "T", + "tau", + "initial_value" + ] + }, + "DiscreteDerivative": { + "blockClass": "DiscreteDerivative", + "importPath": "pathsim.blocks", + "params": [ + "T", + "tau" + ] + }, + "DiscreteStateSpace": { + "blockClass": "DiscreteStateSpace", + "importPath": "pathsim.blocks", + "params": [ + "A", + "B", + "C", + "D", + "T", + "tau", + "initial_value" + ] + }, + "DiscreteTransferFunction": { + "blockClass": "DiscreteTransferFunction", + "importPath": "pathsim.blocks", + "params": [ + "Num", + "Den", + "T", + "tau" + ] + }, + "TappedDelay": { + "blockClass": "TappedDelay", + "importPath": "pathsim.blocks", + "params": [ + "N", + "T", + "tau" + ] + }, "ADC": { "blockClass": "ADC", "importPath": "pathsim.blocks", diff --git a/scripts/pathview_introspect.py b/scripts/pathview_introspect.py index a29f4707..867d3098 100644 --- a/scripts/pathview_introspect.py +++ b/scripts/pathview_introspect.py @@ -70,14 +70,16 @@ def first_line(docstring): def param_desc(docstring, name): - """Extract a `:param name:` description from an RST docstring.""" + """Extract the description of parameter `name` from an RST docstring, + the indented lines below its `name : type` line (or `a, name : type` + for parameters documented together).""" if not docstring: return "" pattern = ( - re.escape(name) - + r"\s*:\s*[^\n]*\n\s+(.+?)(?=\n\s*\w+\s*:|\n\n|$)" + r"^[ \t]*(?:\w+\s*,\s*)*" + re.escape(name) + + r"\s*:\s*[^\n]*\n\s+(.+?)(?=\n\s*\w+\s*:|\n\n|\Z)" ) - m = re.search(pattern, docstring, re.DOTALL) + m = re.search(pattern, docstring, re.DOTALL | re.MULTILINE) if m: return re.sub(r"\s+", " ", m.group(1).strip()) return "" diff --git a/src/lib/constants/dependencies.ts b/src/lib/constants/dependencies.ts index 64697edf..01581528 100644 --- a/src/lib/constants/dependencies.ts +++ b/src/lib/constants/dependencies.ts @@ -1,7 +1,7 @@ // Auto-generated by scripts/extract.py - DO NOT EDIT // Source: scripts/config/requirements-pyodide.txt, scripts/config/pyodide.json -export const PATHVIEW_VERSION = '0.15.3'; +export const PATHVIEW_VERSION = '0.20.0'; export const PYODIDE_VERSION = '0.29.4'; export const PYODIDE_CDN_URL = `https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full/pyodide.mjs`; diff --git a/src/lib/nodes/generated/blocks.ts b/src/lib/nodes/generated/blocks.ts index c9a872bf..0c56b4f6 100644 --- a/src/lib/nodes/generated/blocks.ts +++ b/src/lib/nodes/generated/blocks.ts @@ -1225,6 +1225,28 @@ export const extractedBlocks: Record = ], "icon": "\n \n \n \n \n \n \n \n\n" }, + "Splitter": { + "blockClass": "Splitter", + "description": "Splits the input into multiple outputs, weighted with fractions (SIMO).", + "docstringHtml": "

Splits the input into multiple outputs, weighted with fractions (SIMO).

\n
\n\\begin{equation*}\ny_i(t) = f_i \\cdot u(t)\n\\end{equation*}\n
\n

The fractions have to sum up to one, so the splitter conserves what flows\nthrough it, for example a mass or molar flow.

\n

With a carrier, the input is a stream of multiple channels, for example\nthe flows of multiple species. Every output is a stream with the same\nlayout and each channel is split with the same fractions.

\n
\n

Example

\n

Split a flow into two outputs with 90 and 10 percent:

\n
\nS = Splitter([0.9, 0.1])\n
\n

Split a stream of species flows, the ports 'in', 'out_0' and 'out_1'\nhave the layout of the carrier:

\n
\nclass Species(Carrier):\n    keys = ("H", "D", "T")\n\nS = Splitter([0.9, 0.1], carrier=Species())\n\nC = Connection(S["out_1"], B["in"])\n
\n
\n
\n

Note

\n

This block is purely algebraic and its operation (op_alg) will be called\nmultiple times per timestep, each time when Simulation._update(t) is\ncalled in the global simulation loop.

\n
\n
\n

Parameters

\n
\n
fractions : array_like
\n
fractions of the input for each output, must sum up to one
\n
carrier : Carrier | None
\n
layout of the input and output streams, single channel if 'None'
\n
\n
\n
\n

Attributes

\n
\n
op_alg : Operator
\n
internal algebraic operator
\n
\n
\n", + "params": { + "fractions": { + "type": "any", + "default": null, + "description": "fractions of the input for each output, must sum up to one" + }, + "carrier": { + "type": "any", + "default": null, + "description": "layout of the input and output streams, single channel if 'None'" + } + }, + "inputs": [ + "in" + ], + "outputs": null, + "icon": "\n \n \n \n\n" + }, "LUT": { "blockClass": "LUT", "description": "N-dimensional lookup table with linear interpolation functionality.", @@ -1844,7 +1866,7 @@ export const extractedBlocks: Record = export const blockConfig: Record = { Sources: ["Constant", "Source", "SinusoidalSource", "StepSource", "PulseSource", "TriangleWaveSource", "SquareWaveSource", "GaussianPulseSource", "ChirpPhaseNoiseSource", "ClockSource", "WhiteNoise", "PinkNoise", "RandomNumberGenerator"], Dynamic: ["Integrator", "Differentiator", "Delay", "ODE", "DynamicalSystem", "StateSpace", "PT1", "PT2", "LeadLag", "PID", "AntiWindupPID", "RateLimiter", "Backlash", "Deadband", "TransferFunctionNumDen", "TransferFunctionZPG", "ButterworthLowpassFilter", "ButterworthHighpassFilter", "ButterworthBandpassFilter", "ButterworthBandstopFilter"], - Algebraic: ["Adder", "Multiplier", "Divider", "Amplifier", "Function", "Polynomial", "Sin", "Cos", "Tan", "Tanh", "Abs", "Sqrt", "Exp", "Log", "Log10", "Mod", "Clip", "Pow", "Atan2", "Rescale", "Alias", "Switch", "LUT", "LUT1D"], + Algebraic: ["Adder", "Multiplier", "Divider", "Amplifier", "Function", "Polynomial", "Sin", "Cos", "Tan", "Tanh", "Abs", "Sqrt", "Exp", "Log", "Log10", "Mod", "Clip", "Pow", "Atan2", "Rescale", "Alias", "Switch", "Splitter", "LUT", "LUT1D"], Logic: ["GreaterThan", "LessThan", "Equal", "LogicAnd", "LogicOr", "LogicNot"], Discrete: ["SampleHold", "FirstOrderHold", "FIR", "DiscreteIntegrator", "DiscreteDerivative", "DiscreteStateSpace", "DiscreteTransferFunction", "TappedDelay", "ADC", "DAC", "Counter", "CounterUp", "CounterDown", "Relay", "Wrapper"], Recording: ["Scope", "Spectrum"], @@ -1918,6 +1940,7 @@ export const blockImportPaths: Record = { "SinusoidalSource": "pathsim.blocks", "Source": "pathsim.blocks", "Spectrum": "pathsim.blocks", + "Splitter": "pathsim.blocks", "Sqrt": "pathsim.blocks", "SquareWaveSource": "pathsim.blocks", "StateSpace": "pathsim.blocks",