Repository navigation
pyfdn-system: one JSON document format for every pyFDN backend (design + schema sketch) - #250
SebastianJiroSchlecht wants to merge 9 commits into
Conversation
pyFDN renders the same network three ways -- process_fdn, the td operator tree, and FLAMO -- but only the vanilla FDN is saveable, and only as a build. A Kronecker or otherwise time-varying feedback matrix, a shimmer FDN, an SDN, a reverberation-enhancement system: none of them has any representation on disk. This proposes `pyfdn-system` v1: a two-tier document that keeps the flat `pyfdn-fdn-build` unchanged for vanilla networks and adds a neutral node graph for everything else, with baked `params` separated from `design` provenance per node, one canonical unit per quantity, and backend-specific rendering settings kept out of the system description. pyFDN owns the schema; nothing in core depends on adac. No code. The staged implementation plan is in section 7. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RPEJQF9mkLsQJnUPwwsd91
|
Looks cool! I like the idea that this JSON format essentially has a pyFDN centred vocabulary. A quick comment before I dig into the design: the name |
I understand that pyFDN implement those using FIR filters, but personally I much prefer the cascaded form for actual real-time implementation and I suspect Faust implementation would also prefer that form. I'm worried that storing these matrices as FIR might make downstream implementation more difficult. I know the FIR representation can be constructed from the cascaded one, but I'm not sure if the inverse is true.
I would suggest having an explicit channel count triplet [K,N,J] node where |
|
@jeremybbq yes, let's change the FDNsystem name.
I agree on the FIR matrix. Cacaded Matrices should be actually represented as cascded.
I understand the input and output channels for each module. But feedback loop channels might not be universally present for all modules. |
Adds pyFDN.system, a pure-data module with no backend imports: - FDNSystemDoc: metadata + sample_rate + render + exactly one of an unchanged pyfdn-fdn-build or a GraphNode tree. - GraphNode and an open leaf registry named after pyFDN's own vocabulary (gain, matrix, delay, sos, kronecker_matrix, time_varying_matrix, ...), with params mirroring the td operator constructors. - Channel counts derived from params, written per node as [in, out] and checked on read; errors name the node's path. - build_to_graph / graph_to_build using the assemble_fdn_core node names; graph_to_build refuses a non-vanilla graph by naming the node. - Cascaded matrices are stored as a series of matrix/delay stages, per review, rather than as an expanded FIR matrix. Brings docs/design/system-format.md over from #250 with the review decisions recorded in section 8. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4XLZMVqxGGYjfEDjTG6v7
# Conflicts: # docs/design/system-format.md
…arate system and results into two files formats
Metadata + additional pyfdn-results document:Hey everyone,
|
# Conflicts: # HISTORY.rst
- New pyFDN.auxiliary.graph_plot: plot_system_graph draws a pyfdn-system document, a GraphNode tree or an FDNBuild directly from its description, without building a FLAMO model or a td graph. A non-summing parallel is drawn as a stack rather than a sum. - plot_flamo_graph now shares that renderer (plot_node_tree); its output is unchanged. - Design doc: a separate pyfdn-results document is considered and not adopted, because any result is one line of pyFDN code away from the system document (§9). Provenance metadata stays. Records the plotting decision as §8.7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4XLZMVqxGGYjfEDjTG6v7
|
@almahova thanks for going through the proposal and for the commit. On your three points (decided with @SebastianJiroSchlecht):
Generated by Claude Code |
pyFDN.train exports a function params that shares its name with the submodule pyFDN.train.params. Importing it from .train let mypy resolve it to the submodule under some import orders; the new graph_plot import cycle hit that order and the lint job failed with "Name params already defined (by an import)". Importing from .train.params is unambiguous. Type-checking only; no runtime change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4XLZMVqxGGYjfEDjTG6v7
What this is
A design doc plus a first sketch of its PR 1 (the schema). It proposes
pyfdn-systemv1: one JSON document thatdescribes an FDN well enough for any of pyFDN's backends to render it, and
well enough to re-generate or re-train rather than only replay.
Full text:
docs/design/system-format.md. §8 records the decisions from review, and §9 the rejected results format.Opened as a draft so the format can be argued about before anything is built.
The implementation is staged as follow-up PRs (§7), each independently
useful and revertable.
Schema sketch (added after #255 merged)
src/pyFDN/system.pyis pure data with no backend imports, and it is not yet exported frompyFDN:FDNSystemDocholdsmetadata,sample_rate,renderand exactly one of an unchangedpyfdn-fdn-buildor agraph.GraphNodeplus an open leaf registry (register_node_type) with pyFDN's own names:gain,matrix,matrix_fir,delay,sos,kronecker_matrix,time_varying_kronecker_matrix,time_varying_matrix,pitch_shift,dc_blocker,identity. A leaf'sparamsare the matchingtdoperator's constructor arguments, minusfs.build_to_graph/graph_to_builduse theassemble_fdn_corenode names.graph_to_buildrefuses a non-vanilla graph and names the node it cannot convert.system_to_dict/system_from_dictandsave_fdn_system/load_fdn_system. Validation errors name the path of the offending node (/root/brA/feedback_loop).save_fdn_systemaddsmetadata.createdandmetadata.pyfdn_versionwhen they are missing (by @almahova).pyFDN.auxiliary.graph_plot.plot_system_graphdraws a system document, aGraphNodetree or anFDNBuildwithout building a FLAMO model ortdgraph.plot_flamo_graphnow uses the same renderer, and its output is unchanged.tests/test_system.py, including a build → graph → build round trip for every packaged preset, andtests/test_graph_plot.py.The branch also merges in current
main.Review decisions reflected in the sketch
seriesofmatrixanddelaystages, with itsdesignrecorded on theseriesnode. It is not expanded into amatrix_fir.delayallows zero-length lines for the per-channel shifts."channels": [in, out]and checked on load. The counts are still derived from the parameters, so a document cannot define a system in two ways. No system-level[K, N, J]: N is not defined for every graph (SDN, RES), and K and J are the root's channels.FDNSystemDoc. Renaming the gallery'sFDNSystemtuple is left to its own small PR, because it is a breaking change.renderis flat:nfft,alias_decay_db,block_size.FDNPresetis unchanged. Abuilddocument may carry the presetdesignnotes, so a preset converts to a system document without loss.Why
pyFDN renders the same network three ways —
process_fdn, thetdoperatortree, and FLAMO — and exactly one of those is saveable, only for vanilla
networks, only as an
FDNBuild. A Kronecker or otherwise time-varying feedbackmatrix, a shimmer FDN, an SDN, a reverberation-enhancement system, a coupled-room
model: none of them has any representation on disk.
tdhas no serialisation of any kind today.The proposal in five points
build(the existingpyfdn-fdn-buildv2,unchanged) for vanilla FDNs; a new
graphnode tree for everything else.build_to_graphlowers,graph_to_buildlifts and refuses a non-vanilla graph by name.typenamespace, owned by pyFDN.sos, notparallelSOSFilter.The registry is open, and a backend that cannot build a type fails loudly, naming it.
paramsis baked,designis how it was made — per node.nfft,alias_decay_db,block_sizelive in one top-levelrenderblock.graph_to_tddoes the block compensation.Relationship to adac
pyFDN owns the schema and every conversion in and out of it; nothing in pyFDN
core depends on adac. adac reads
pyfdn-systemdocuments downstream through a small vendored reader. See §2.2 and §6 of the doc.Compatibility
pyfdn-fdn-buildv2 is unchanged, byte-for-byte; abuilddocument embeds exactly whatfdn_build_to_dictwrites.plot_flamo_graphkeeps its signature and output; only its renderer moved toauxiliary/graph_plot.py.Follow-up work
pyFDNand add to the API reference, and whetherFDNPresetshould merge intoFDNSystemDoc.td.graph_to_td/td_to_graph, including the block-delay compensation.flamo_to_graph/graph_to_flamo, generalisingextract_build/build_to_flamo.graph_to_fauston the neutral types.FDNSystemnamed tuple (separate small PR).to_td,to_flamo,impulse_response) and the future ofFDNBuild, after this PR.Still open
.npzfor large arrays ({"$ref": ...}): not implemented; cascaded storage removes the most likely need.FDNPresetbecomes a thin alias ofFDNSystemDoc.🤖 Generated with Claude Code
https://claude.ai/code/session_01Q4XLZMVqxGGYjfEDjTG6v7