v1.0.0

Breaking Changes

  • weight_gradient takes a fifth positional argument, the current trial's group label: weight_gradient(lr, sol, w, feedback, group). There is no fallback method, so a custom learning rule that defines only the 4-argument method now raises a MethodError on the first trial. A rule that does not participate in gating can ignore the new argument; one that does should open with trial_gate_active(lr.group, group) || return zero(w) and define rule_group.

  • HebbianPlasticity, HebbianPresynapticPlasticity and HebbianModulationPlasticity each gained a trailing group field (6 → 7, 3 → 4 and 10 → 11 fields respectively). The keyword constructors are unchanged, but code calling the positional constructor, or reflecting over fieldnames/propertynames, must account for the extra field.

  • Rewriting the shipped composites on top of the new @composite macro normalised their fields. Keyword-argument names and default values are unchanged for every composite, so constructor calls behave exactly as before — but field order is now always name, namespace, graph, metadata, tags, <nodes...>, <extra fields...>, and a few incidental fields are gone:

    • Use get_components(blox) instead of blox.parts (CanonicalMicroCircuit, Striatum_MSN_Adam, Striatum_FSI_Adam, GPe_Adam, STN_Adam).
    • The kwargs field is no longer stored on LIFExciCircuit, LIFInhiCircuit, PINGNetwork, LateralAmygdalaCluster, LateralAmygdala or CentralAmygdala.
    • The connection_matrix/connection_matrices field is no longer stored on the four *_Adam composites or on LateralAmygdalaCluster. The keyword arguments of those names are unchanged — only the stored field is dropped.
    • Sub-blox fields generated from a @nodes block are no longer declared with concrete types (e.g. WinnerTakeAll's inhi, Striatum's matrisome, Thalamus's excis, all seven of BLA's populations). The values they hold are unchanged, but code reading fieldtype or relying on type-stable property access should use an @extra_fields block, which does keep annotations. Conversely name and namespace are now always declared ::Symbol and ::Union{Symbol, Nothing}.

    Positional new-style construction and getfield by index are not part of the public API; access sub-blox by name (str.matrisome).

  • (NeurobloxPharmaPrivate) CeL is now the PKCδ+/PKCδ- split composite. The flat single-pool CeL (field inhibs::Vector{HHInhiNeuron}) is gone; CeL now holds delta_plus and delta_minus populations with reciprocal HypergeometricRule GABA-A inhibition between them, plus the new keyword arguments frac_delta_plus, I_bg_delta_plus, I_bg_delta_minus, density_dp_dm, density_dm_dp, weight_dp_dm, weight_dm_dp and rng. Code reading cel.inhibs must use get_inhi_neurons(cel) (or cel.delta_plus/cel.delta_minus) instead.

  • (NeurobloxPharmaPrivate) A learning_rule on a Cortical => BLA, Cortical/LateralAmygdalaCluster => LateralAmygdalaCluster, or Cortical => LateralAmygdala connection now potentiates only the cortico-principal-cell synapses. Those wiring rules apply one connection to two destination populations, so previously the rule also reached the destination's feedforward-inhibitory neurons (vip/aac for BLA, the cluster's neuron_ff_inhi for a LateralAmygdalaCluster) — which potentiates feedforward inhibition alongside the excitatory drive, pushing the circuit the opposite way from the conditioning being modelled. CorticalAmygdalaRule delegates for every sub-rule, so this applies with a WeightMatrixRule, HypergeometricRule or DensityRule sub-rule alike. Connections without a learning rule are wired exactly as before, byte for byte.

  • A weight update that would drive a connection weight negative now raises an error naming the source and destination blox, instead of silently applying it. This affects any run_experiment!/run_trial! whose learning rule produces -Δw > w.

  • (NeurobloxPharmaPrivate) CA1Cluster's pv_cells field is now Vector{<:AbstractNeuron} rather than Vector{HHFSINeuron}, since the PV slot is selected by fsi_neuron_type. Code annotating that field as Vector{HHFSINeuron} must be widened.

  • (GraphDynamics) PartitionedGraphSystem has been removed; a GraphSystem now holds a g.flat_graph field with a PartitioningGraphSystem object which actively flattens and partitions the graph during solving.

  • (GraphDynamics) apply_discrete_event! and apply_continuous_event! now take a single combined subsystem view per affected subsystem (sys_view, covering both its states and its parameters, written through field-wise as sys_view.x[] = ...) instead of separate state and parameter view arguments. Connection events correspondingly take one sys_view_src and one sys_view_dst.

New Features

  • Added ConditioningEnvironment, an environment for conditioning protocols where the circuit makes no classification and is never scored (unlike ClassificationEnvironment, it stores no category — though ImageStimulus still requires a category column in the input data). Its trial_groups field labels each trial with the conditioning pathway it belongs to, and it throws an ArgumentError if that label count does not match N_trials. The type hierarchy is now ConditioningEnvironment <: AbstractImageEnvironment <: AbstractEnvironment, with ClassificationEnvironment also re-parented onto AbstractImageEnvironment, which carries their shared ImageStimulus-backed stimulus presentation. run_experiment! and run_warmup are no longer typed to ClassificationEnvironment: they accept any AbstractEnvironment that supplies N_trials, t_trial, a mutable current_trial, and a method of NeurobloxPharma.update_trial_stimulus! (which is provided for AbstractImageEnvironment).

  • HebbianPlasticity, HebbianPresynapticPlasticity and HebbianModulationPlasticity all gained a group keyword argument, restricting the weight update to the trials the environment labels group and leaving the weight unchanged on every other trial — the rule returns a zero gradient before it touches the solution, so a gated-off trial costs no interpolation. This lets one run_experiment! call drive a multi-stage conditioning protocol, pairing each trial's stimulus with its own designated plastic pathway: a group=:fear rule on one route and a group=:reward rule on another condition each on its own trials, at its own rate.

  • Added the trial-gating extension points trial_group_labels(env), current_trial_group(env), possible_trial_groups(env), rule_group(lr), trial_gate_active(group, current_group) and validate_rule_groups(learning_rules, env). An environment declares its groups by overriding trial_group_labels alone — one label per trial, in trial order — and both current_trial_group (which the gate reads) and possible_trial_groups (which validation reads) derive from it, so the two cannot fall out of step. A rule gated to a group its environment can never produce is now a hard error at run_trial!, and at the top of run_experiment! before any warmup solve, rather than a rule that silently never fires.

  • Agent gained an action_selection keyword argument. It defaults to inferring the policy from the graph (warning when there is none); pass nothing to declare that the agent deliberately makes no scored choice, as in a conditioning protocol, which suppresses that warning. Such an agent reports feedback = 1 and action = 0 on every trial, so the run_experiment! trace comes back with correct all true and action all 0; nothing is scored, but the trace's trial/time columns and any monitor output are still meaningful.

  • Agent also gained a tspan keyword argument (default (0.0, 1.0)) setting the timespan of a single trial. run_experiment! overrides it with the environment's trial length, so it only matters when driving trials directly with run_trial!.

  • Added drop_learning_rule(conn), which returns conn with its learning_rule keyword replaced by NoLearningRule(), and returns conn itself unchanged when it carries none. Composite wiring rules that apply one connection to two destination populations use it to keep plasticity on the population it was meant for. Stateful fields such as a HypergeometricRule's rng are shared by reference, so the sequence of random draws is unchanged. It requires the rule type to support Accessors.@set on its kwargs, which DefaultRule does not.

  • Added @composite, a macro for defining composite blox that combines @blox's constructor-signature header with @graph's @nodes/@connections body. Every top-level assignment in @nodes becomes a field of the struct, the five mandatory fields (name, namespace, graph, metadata, tags) and the metadata/tags keyword arguments are emitted for you, nodes inherit the composite's namespace automatically, and an optional @extra_fields block adds further fields initialised after the graph is built. The supertype defaults to AbstractComposite and may be overridden with StructName(; ...) <: SuperType. Every composite shipped with Neuroblox is now defined this way; hand-written composite structs continue to work unchanged.

  • Added the convenience macros @nodes name expr/@connections name expr, which build a new graph named name whose body is an implicit @nodes/@connections block, and their mutating counterparts @nodes! g expr/@connections! g expr, which add to an existing graph g.

  • Composite blox are now generic over the neuron types filling their functional slots. Every composite that builds neurons takes *_neuron_type keyword arguments — exci_neuron_type, inhi_neuron_type, fsi_neuron_type, msn_neuron_type, da_neuron_type — each paired with a *_neuron_kwargs NamedTuple forwarded to that neuron's constructor. Slots are keyed by role, so e.g. BLA's cck/aac/sst/vip populations all follow inhi_neuron_type. Defaults for these slots are unchanged, so existing code that does not pass them builds the same neurons as before:

    using NeurobloxPharma, NeurobloxPharmaPrivate  # the *Mod neuron types are private
    
    Cortical(; name=:ctx, density=0.1,
               exci_neuron_type = HHExciNeuronMod,
               inhi_neuron_type = HHInhiNeuronMod,
               inhi_neuron_kwargs = (; G_GIRK = 0.1))
  • (NeurobloxPharmaPrivate) Added a generalized neuromodulator receptor system, in which receptors drive the postsynaptic neuron's d* accumulator inputs to modulate ion channels, rather than modulating synaptic gain. It comprises the ChannelModNeuron/FullChannelModNeuron neuron unions and receptor/rule families for dopamine (D1Receptor, D2Receptor, D4Receptor; D1Rule, D2Rule, D4Rule), acetylcholine (ACh_Neurotransmitter, M1Receptor, M2Receptor, M4Receptor; M1Rule, M2Rule, M4Rule), noradrenaline (NE_Neurotransmitter, Beta1Receptor, Beta2Receptor, Alpha1Receptor, Alpha2Receptor; Beta1Rule, Alpha1Rule, Alpha2Rule), serotonin (HT_Neurotransmitter, HT1AReceptor, HT2AReceptor, HT2CReceptor, HT4Receptor; HT1ARule, HT2ARule, HT2CRule, HT4Rule), opioids (MOR_Neurotransmitter, MuORReceptor, MuORRule) and endocannabinoids (eCB_Neurotransmitter, CB1Receptor), plus GABABReceptor.

  • (NeurobloxPharmaPrivate) Added six generalized-channel neuron types — HHExciNeuronMod, HHInhiNeuronMod, HHMSNeuronMod, HHFSINeuronMod, HHExciCaNeuronMod and HHVTADANeuronMod — which extend their base neurons with KIR, GIRK, Cav1.3, SK, Kv7/M, NaP and HCN/Ih conductances (all zero-conductance by default) and expose the d* accumulator inputs the neuromodulator rules write into.

  • (NeurobloxPharmaPrivate) Added the ascending-arousal source nuclei LCMod, DRNMod, PAGMod, PPTMod, BFMod and VLPAGMod — hybrid NGNMM_theta neural-mass plus single-HH-neuron composites whose output neuron is reached with the new get_output_neuron, and which project onto other composites through the neuromodulator rules.

  • The neuromodulator rules that drive ion-channel modulation (D1Rule, D2Rule, D4Rule, M1Rule, M2Rule, M4Rule, Beta1Rule, Alpha1Rule, Alpha2Rule, HT1ARule, HT2ARule, HT2CRule, HT4Rule, MuORRule) raise an informative error when wired onto a neuron that has no d* accumulator inputs, naming the neuron and pointing at the relevant *_neuron_type argument, rather than building a graph that only fails at solve time.

  • (NeurobloxPharmaPrivate) The VTA/VTAAssembly dopaminergic projections now select their modulation pathway from the postsynaptic neuron type, via the new da_d1_rule/da_d2_rule: neurons exposing the generalized channel-modulation inputs take the D1Receptor/D2Receptor ion-channel pathway, MSNs take MsnD1Receptor/MsnD2Receptor, and other neurons take PyrD1Receptor/PyrD2Receptor. Defaults are unchanged for composites built from the default neuron types.

  • (NeurobloxPharmaPrivate) Added default_vta_G_h(da_neuron_type), giving the default Ih conductance for a VTAAssembly's DA neurons (and, scaled, for VTA's G_h_a1). HHVTADANeuronMod's Ih activation is ~3-4x stronger near rest than HHVTADANeuron's, so it defaults to a proportionally smaller conductance.

  • (NeurobloxPharmaPrivate) VTAAssembly is now exported.

  • (NeurobloxPharmaPrivate) Added CeLDeltaPlus and CeLDeltaMinus, the standalone-graph-node split of CeL's PKCδ+ / PKCδ- subpopulations, so a GUI rendering one block per graph node can read out each independently. Like CeL they are generic over the neuron type via inhi_neuron_type/inhi_neuron_kwargs. Two differences from CeL to be aware of: the δ+/δ- mutual inhibition must be wired explicitly at circuit level (two HypergeometricRules), and the split blocks carry no astrocyte and expose no astrocyte_* keyword — see the docstrings for both, and for the pooled-astrocyte migration path. Every generic CeL wiring dispatch has a mirrored method for the split blocks, plus a new block-to-block dispatch for the δ+/δ- inhibition; the three CeL-composite-only helper rules below are deliberately not defined for them, since a plain rule wired onto the block itself replaces each. Parity with CeL is locked in by NeurobloxPharmaPrivate/test/cel_split_parity.jl.

  • (NeurobloxPharmaPrivate) Added the CeL-composite wiring rules CeLSplitRule (wires a source onto delta_plus/delta_minus with independent densities and weights), CeLDeltaPlusRule (CeL => CeM restricted to the PKCδ+ arm) and VLPAGDeltaPlusRule (PAG dopamine onto PKCδ+ only).

  • (NeurobloxPharmaPrivate) CeL now contains one pooled FastGABAGlycineAstrocyte spanning both subpopulations, with astrocyte_params, astrocyte_input_weight=1.0 and astrocyte_output_weight=0.0 keyword arguments. It is present by default but inert at the default output weight; inspect it through the astrocytes field.

  • (NeurobloxPharmaPrivate) CoreleaseConnection, DARule, MsnGluRule, AstRule and the astrocyte output connections accept the new *NeuronMod neuron types as endpoints, and a FastGABAGlycineAstrocyte => AbstractHHInhiNeuron BasicConnection was added.

  • Every blox and composite now carries a tags::Set{Symbol} field, set with a tags keyword argument (a Symbol or any collection of Symbols; default empty) and read with get_tags. Tags mark a subset of blox of one type — e.g. γ1-subunit-containing GABA-A synapses — without defining a new type. Connection rules forward tags to the synapse, receptor and transmitter blox they create, e.g. src => dst, HypergeometricRule(; density=0.06, tags=:gamma1); a tagged connection blox gets a tag-suffixed name (gaba_a_gamma1), so it is never shared with the same neuron's untagged synapses. A composite's tags are stored on the composite only and are not copied onto its components. Also added the helpers to_tags, tagged_name and build_tagged.

  • @experiment lines accept a where clause restricting the selected blox by tag: (GABA_A_Synapse where :gamma1 ∈ tags), τ₂ -> τ₂ * dose. The predicate is any Bool expression of tags (so ||, && and ∉ work, as do variables from the caller's scope), and it composes with the composite and typed-connection selectors, e.g. ((GABA_A_Synapse ∈ (itc => cel)) where :gamma1 ∈ tags). A where line that matches no blox is an error, so a misspelled tag cannot silently turn a drug intervention into a no-op.

  • Added HebbianPresynapticPlasticity, a learning rule whose weight update depends on presynaptic activity alone (w += feedback * K * x_pre), with no postsynaptic term and no W_lim bound. By default state_pre is the presynaptic SpikeMonitor's spikes_cumulative, bound automatically per connection while wiring, and t_pre = nothing evaluates it at the end of the trial.

  • synapse_wiring_rule! for conductance synapses has been consolidated into a single method on (::AbstractNeuron, ::AbstractReceptor, ::AbstractNeuron). The two wiring topologies are now selected by the trait needs_postsynaptic_voltage(::AbstractReceptor): false (the default) wires only the presynaptic drive into the synapse, while true also feeds in the postsynaptic neuron, for receptors that compute their voltage-dependent current internally. A new receptor that fits either topology now only needs the trait, not a bespoke synapse_wiring_rule! method; hand-written methods are more specific and continue to take precedence.

  • ImageStimulus can now accept any Tables.jl data-input source (or a CSV filepath), rather than just a DataFrame or a filepath.

  • (GraphDynamics) A PolyesterScheduler() scheduling object has been added which allows for parallelizing solves using Polyester.jl. This option helps performance during ODE solves where GC time dominates if multithreaded.

  • (GraphDynamics) If any subsystem in a problem has a parameter named dtmax, then the smallest dtmax parameter in the system is forwarded as a keyword argument to ODEProblem and SDEProblems to limit the maximum stepsizes allowed by the solver.

  • (GraphDynamics) If a connection type overrides GraphDynamics.connection_needs_ctx to give true, then connections of that type will be given a fourth ctx argument which gives it access to the full list of states_partitioned, params_partitioned, and connection_matrices when accumulating inputs.

  • (GraphDynamics) GraphDynamics integrates with Latexify.jl to latexify the equations of a GraphSystem.

Bug Fixes

  • Structural ==/isequal/hash now cover AbstractObserver (e.g. SpikeMonitor) as well as AbstractBlox. Without this, get_spike_monitor!'s memoization missed on a plain GraphSystem, so calling it twice for the same neuron — or mixing an explicit get_spike_monitor! loop with a learning rule that creates its own — threw a duplicate-node error.
  • Learning rules now bind their SpikeMonitor endpoints on any neuron type, not only AbstractHHExciNeuron. A rule attached to a composite wiring rule that also creates edges onto feedforward inhibitory neurons previously left state_pre/state_post as nothing and failed at the end of the first trial with ArgumentError: Incorrect specification of idxs.
  • The default HHInhiNeuron => WinnerTakeAll wiring rule now dispatches on AbstractHHInhiNeuron, so a WinnerTakeAll built with a different HH inhibitory neuron in its inhi_neuron_type slot still wires. HHFSINeuron and HHVTADANeuron are deliberately still excluded.
  • (NeurobloxPharmaPrivate) Fixed the Cortical => ITCdm, CeL and CeM wiring rules, and the ITCdm/ITCvm => Cortical wiring rules, which called the undefined get_inh_neurons and so threw an UndefVarError.

v0.9.0

API Changes

  • Added a graph finalization step that runs after flattening, before problem construction. The finalization pass walks the nodes of the composite and flattened graphs and calls the (no-op-by-default) hook GraphDynamics.finalize!(g, node, lookup); define methods on your node types to post-process structure that depends on the whole flattened graph (e.g. neuromodulatory wiring onto every synapse targeting a neuron). lookup is a (; incoming, outgoing) pair of identity-keyed maps from each node to the connections into and out of it.
  • Breaking: all blox subtypes of AbstractStimulus have been renamed to follow a consistent XStimulus convention: ConstantInput → ConstantStimulus, PoissonSpikeTrain → PoissonSpikeTrainStimulus, PulsesInput → PulsesStimulus, VoltageClampSource → VoltageClampStimulus, DBS → DBSStimulus, ProtocolDBS → ProtocolDBSStimulus
  • Blox are now classified as AbstractSimple and AbstractComposite (the definition of composites is unchanged; simples are blox that carry dynamics, and currently include everything that is not a composite).
  • Breaking: the connection system has been overhauled. Both add_connection! and system_wiring_rule! now dispatch on a connection struct. Connections are now classified as DynamicalConnection between AbstractSimple, or WiringRule. The former have equations and exist at the flattened graph level, while the latter are used to determine the topology of the graph. Users should now create their own structs to define new kinds of wiring rules.
  • Added extract_vars(prob, syms) which builds a nested ComponentVector carrying the current values of the requested parameters from an ODEProblem. The nesting mirrors the ₊-separated namespace hierarchy of Neuroblox blox names, enabling direct property access (e.g. v.blox1.ω) and use as a flat vector.
  • Added apply_vars(prob, v) which takes a (possibly mutated) ComponentVector produced by extract_vars and returns a new ODEProblem with those parameter values applied. Inverse of extract_vars.
  • Breaking: the ProtocolDBSStimulus and BurstStimulus constructors no longer accept a start_time; the start time is computed from the other parameters.
  • HHFSINeuron conductance states (G, Gₛ) and their driving parameters (τ, τₛ, a, b) have been moved out of the neuron into a new companion receptor blox GABA_A_FSI_Synapse. This matches the architecture of HHExciNeuron/HHInhiNeuron. Breaking: any code that accessed fsi.G or fsi.Gₛ directly must be updated to use the synapse blox instead.
  • NeurobloxOptimization.jl has been added as a utility package for certain optimization tasks involving Neuroblox.jl. See the documentation for more details on using this.
  • Breaking: numerous neuron types were renamed for naming consistency (Inhib/Inh → Inhi, and moving qualifiers ahead of Neuron): HHNeuronExci → HHExciNeuron, HHNeuronInhib → HHInhiNeuron, HHNeuronFSI → HHFSINeuron, PINGNeuronExci → PINGExciNeuron, PINGNeuronInhib → PINGInhiNeuron, LIFInhNeuron → LIFInhiNeuron, LIFExciInhNeuron → LIFExciInhiNeuron, LIFInhCircuit → LIFInhiCircuit.
  • Blox generated by @blox now carry a metadata::Dict{Symbol, Any} field, populated via a metadata keyword argument, and a tags::Set{Symbol} field (see New Features). GreedyPolicy, ImageStimulus, and the @nodes/@connections graph DSL likewise accept metadata, and GraphSystems support graph-level metadata via a @graph_metadata block.
  • Added a per-parameter metadata system: parameters declared in @blox can carry metadata, queryable with param_metadata, along with new symbol-introspection helpers param_symbols, state_symbols, input_symbols, and output_symbols.
  • The @experiment macro now handles module-qualified blox names and composite blox with composite components, and can remap connection weights and parameters of intermediate blox.
  • Added an explicit transmitter/receptor synapse model, including the abstract type AbstractNeurotransmitter, transmitter blox (Glu_Neurotransmitter, GABA_Neurotransmitter, DA_Neurotransmitter), two-state receptor blox (Glu_AMPA_Receptor_2state, GABA_A_Receptor_2state, subtyping AbstractGABA_A_Receptor_2state; receptor subunit variants are expressed with tags), and a Kinetic2StateRule connection type. The conductance-based wiring rule is now named ConductanceRule.
  • Breaking: synapse/receptor parameters were migrated out of neuron blox onto dedicated synapse/receptor blox (accessed via the exported get_synapse, get_transmitter, and get_receptor), and the g synaptic-gain parameter was removed. ==, isequal, and hash are now defined field-wise for all AbstractBlox.
  • Added VTA and nucleus accumbens blox to NeurobloxPharma — NacShell, HHMSNeuron, and the receptors PyrNMDAR, PyrAMPAR, PyrD1Receptor, PyrD2Receptor — along with the MsnGluRule and PyrGluRule connection rules, and DARule in NeurobloxPharmaPrivate.
  • Added a SpikeMonitor observer (<: AbstractObserver) which factors spike-counting states out of neurons into a separate node.
  • Added a PINGNetwork composite blox implementing a pyramidal-interneuron gamma network.
  • Added an abstract type AbstractHHExciNeuron <: AbstractExciNeuron shared by the Hodgkin-Huxley excitatory neuron types.
  • Breaking: params_with_substrings and states_with_substrings were collapsed into a single syms_with_substrings function (with an excluded_substrs keyword argument).
  • Breaking: the get_connection_matrix function has been removed.
  • Breaking: the I_bg_ar background-current keyword argument of Cortical was renamed to I_bg.
  • STA synapses are now shared per destination neuron by default; pass fully_unique_sta = true to get a distinct Glu_AMPA_STA_Synapse per source-destination pair.
  • Composite wiring rules now raise an informative error when passed a pre-existing synapse/transmitter/receptor blox, or when no connection rule applies to a pair of blox.
  • Fixed WeightMatrixRule connecting the source and destination neurons in the wrong order.
  • Breaking: subcortical_connection_matrix now produces acyclic (DAG) connectivity, changing the default wiring of subcortical structures such as Thalamus. Simulations of those structures will give different numerical results than under v0.8.

v0.8.0

API Changes

  • ModelingToolkit is no longer used by Neuroblox. All interfaces have moved over to GraphDynamics.jl as the backend.
  • A @blox macro has been added for defining blox types compatible with GraphDynamics
  • A @wiring_rule macro has been added for defining what should happen when two blox are connected
  • A @connection macro has been added for defining the action of connection types on subsystems, along with event connections
  • Instead of storing a system and connector object, composite blox (i.e. <:AbstractComposite) now store a graph field which holds a GraphSystem of the internal connections.
  • A @graph! macro has been added for modifying already existing GraphSystems.
  • Agent and ClassificationEnvironment no longer take name and namespace keyword arguments.
  • An @experiment macro has been added to easily modify many parameters of an ODEProblem
  • Blox now support continuous events
  • Blox which used discrete events for spike detection, now set dtmax parameters which limit the maximum timestep a solver is allowed to take.
  • GraphSystems and ODEProblems can now be saved and loaded using save_graph, load_graph, save_problem, and load_problem
  • A MultipointConnection type has been added which allows one to write connection rules between two blox that reference other extra blox.
  • A large library of receptor types has been added to NeurobloxPharma including
    • GABA_B_Synapse
    • NMDA_Synapse
    • MorandiFullNMDAR
    • MorandiNMDAR
    • MsnNMDAR
    • MsnAMPAR
    • MsnD1Receptor
    • MsnD2Receptor
    • HTR5
    • CaTRPM4R
    • Alpha7ERnAChR
    • MuscarinicR
    • Beta2nAChR
  • Several new neuron types have been added for interacting with the receptor library
    • BaxterSensoryNeuron
    • TRNNeuron
    • MuscarinicNeuron
    • VTADANeuron
    • VTAGABANeuron
  • The API pages in our documentation have been restructured and extended with a lot more docstrings. There are now new pages under API for :
    • Neuron, Neural mass and Composite blox definitions
    • Constructing, saving and loading graphs
    • Receptor definitions
    • Reinforcement learning
    • Plotting recipes
    • Utility functions
    • Adding user-defined blox
    • Adding user-defined connections
    • Defining experiments by changing model parameters and initial conditions
  • A tutorial on choosing receptors between neuronal connections was added in the documentation.

v0.7.0

API Changes

  • Neuroblox.jl has been re-organized into a collection of sub-packages which can be used individually. This shouldn't cause any changes for the end user if they simply do using Neuroblox since Neuroblox itself now just re-exports the sub-packages. Currently our public subpackages are:

    • NeurobloxBase.jl fundamental shared infrastructure for making Neuroblox work
    • NeurobloxBasics.jl some common, generic neuroscience primitives
    • NeurobloxDBS.jl infrastructure and models specific to our work on deep brain stimulation
    • NeurobloxPharma.jl infrastructure and models specific to our pharmacological work and the corticostriatal circuit
  • The run_experiment! function now no longer takes a verbose::Bool keyword argument, but instead can take a monitor keyword argument, which is passed to the update_monitor! callback will be run after each experiment trial with information about that trial. We provide ProgressMeterMonitor as a simple replacement for the functionality that the old verbose=true option gave.

  • The naming of many objects from Neuroblox.jl has been updated and made more consistent. Abstract types now all start with Abstract in their type name, and we have removed the suffix Blox from the types that had them e.g. HHExciNeuronBlox was renamed to HHExciNeuron, and NeuralMassBlox was renamed AbstractNeuralMass.

  • A @graph macro has been added to simplify the process of making Neuroblox.jl graphs to pass to system_from_graph.

v0.3

Initial Release!

GraphDynamics pre-1.0 history

GraphDynamics.jl used to be versioned and released separately from Neuroblox, with its own changelog. From v1.0 onwards it shares the version number and changelog of the rest of Neuroblox; its earlier release notes are preserved here.

GraphDynamics v0.7.0

Breaking changes

  • apply_discrete_event!, apply_continuous_event!, and ForeachConnectedSubsystem have had their vstates and vparams arguments combined into a sys_view argument, which gives a view into the affected system for (and the connection form gets a sys_view_src and sys_view_dst). This sys_view can have it's fields be updated in place like so:
function GraphDynamics.apply_discrete_event!(integrator, sys_view, sys::Subsystem{MyType}, _)
    sys_view.x[] = sys.y
end

This will modify the x state or parameter of the system when the event triggers.

  • apply_subsystem_noise!'s first argument is now modified in the same way as the view arguments of apply_discrete_event!. One would now write e.g.
function GraphDynamics.apply_subsystem_noise!(vstate, sys::Subsystem{BrownianParticle}, t)
    # No noise in position, so we don't modify vstate[:x]
    vstate.v[] = sys.σ    # White noise in velocity with amplitude σ
end

rather than vstate[:v] = sys.σ

GraphDynamics v0.6.0

Diff since v0.5.0

Breaking changes

Switched computed_properties and computed_properties_with_inputs to take a type tag instead of subsystem argument. Now, instead of adding methods like

function GraphDynamics.computed_properties_with_inputs(::Subsystem{Particle})
    a(sys, input) = input.F / sys.m
    (; a)
end

users should do

function GraphDynamics.computed_properties_with_inputs(::Type{Particle})
    a(sys, input) = input.F / sys.m
    (; a)
end

GraphDynamics v0.5.0

Diff since v0.4.9

Breaking changes

  • Removed the fallback (cr::ConnectionRule)(src, dst, t) = cr(src, dst) which was added previously to avoid breakage when we made connection rules take a time argument in addition to the src and dst subsystems. The presence of this method was a bit of a annoying crutch
  • Changed the arguments of discrete_event_condition from just (conn, t) to (conn, t, sys_src, sys_dst) so that events can trigger based off information in the source or destination subsystems as well
  • Changed the arguments of has_discrete_events from just (typeof(conn),) for connection events to (typeof(conn), get_tag(src), get_tag(dst)), i.e. it now also can depend on the types of the source and dest subsystems
  • Changed the arguments of event_times from just (conn,) to (conn, sys_src, sys_dst) for connection events.