Skip to content

Add SONATA point-process cell support#51

Draft
ilkilic wants to merge 21 commits into
mainfrom
point-process
Draft

Add SONATA point-process cell support#51
ilkilic wants to merge 21 commits into
mainfrom
point-process

Conversation

@ilkilic

@ilkilic ilkilic commented Jan 9, 2026

Copy link
Copy Markdown
Collaborator

This PR adds support for SONATA point-process cells.

Point-process cells are instantiated from SONATA model_type = "point_process" and model_template, mapping directly to NEURON point mechanisms defined in HOC/MOD files.

What is included

  • New HocPointProcessCell for SONATA point-process populations
  • Mechanism instantiation driven by model_template (e.g. nrn:IntFire1, hoc:)
  • Integration with CircuitSimulation (instantiate_gids, callbacks, deletion)
  • Spike detection and recording compatible with existing simulation flow
  • Support for SONATA inputs and SynapseReplay via _add_stimuli
  • Compatibility with SONATA edge loading through existing SonataCircuitAccess

@codecov

codecov Bot commented Jan 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.37539% with 21 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
bluecellulab/cell/point_process.py 93.00% 10 Missing ⚠️
bluecellulab/point/point_connection.py 82.14% 5 Missing ⚠️
bluecellulab/circuit_simulation.py 80.95% 4 Missing ⚠️
tests/test_allen_v1/test_ringcells_allen_v1.py 96.66% 2 Missing ⚠️
Files with missing lines Coverage Δ
...ab/circuit/circuit_access/sonata_circuit_access.py 95.92% <100.00%> (+0.11%) ⬆️
bluecellulab/circuit/synapse_properties.py 69.23% <100.00%> (+1.23%) ⬆️
bluecellulab/point/connection_params.py 100.00% <100.00%> (ø)
bluecellulab/reports/utils.py 94.76% <100.00%> (+0.11%) ⬆️
bluecellulab/synapse/__init__.py 100.00% <100.00%> (ø)
bluecellulab/synapse/synapse_factory.py 91.30% <100.00%> (+0.49%) ⬆️
bluecellulab/synapse/synapse_types.py 85.43% <100.00%> (+2.40%) ⬆️
tests/test_allen_v1/test_ringcells_allen_v1.py 96.66% <96.66%> (ø)
bluecellulab/circuit_simulation.py 86.60% <80.95%> (+1.84%) ⬆️
bluecellulab/point/point_connection.py 82.14% <82.14%> (ø)
... and 1 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jamesgking jamesgking self-assigned this Mar 9, 2026
The logic for loading from sonata files is to swap out the list of parameters if the BBP TYPE is not present

Likewise, when instantiating a synapse object, if no TYPE field is present, assume it is for allen and
create a Exp2Syn synapse
…e instantiated.

The reporting adds try/except since these don't have a soma
… target point neurons

and deliver replay spikes to the proper netcon
Removed call to finalize for point process type cells since this is not needed
Updated allen tests to collection cell_info and get ExpSyn data as consequence
…re netcon code

Remove more unused code sections; can be added when use case example is available
Added additional test for invalid Mechanism given to HocPointProcessCell

@darshanmandge darshanmandge left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @jamesgking, for adding this to bluecellulab! I have left some comments.

logger = logging.getLogger(__name__)


class BasePointProcessCell(Cell):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inherits from Cell but never calls super().__init__(), so none of Cell's attributes (self.recordings, self.soma, self.cell, self.record_dt, etc.) are initialized. This means inherited methods like get_time(), get_recording(), etc., will crash with AttributeError. The bare except Exception: continue blocks added in utils.py may catch the errors though. Maybe initialising the minimum required attributes so inherited methods degrade gracefully instead of relying on catch-all exception handlers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's sync on this since originally this did not inherit, but this caused the linting to throw errors, I hear what you say about how inheriting should conform to the expected interface

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The linting issue can be because CircuitSimulation type-hints cells as Cell, so without inheritance the type checker complains. We can either:

  • Keep the inheritance but add a minimal set of Cell-compatible attributes in BasePointProcessCell.__init__ (recordings={}, soma=None, report_sites={}, etc.). It is a few lines change.
  • Extract a shared BaseCell ABC that both Cell and BasePointProcessCell implement, and update CircuitSimulation to reference that. This is cleaner but larger scope.
    WDYT?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can move forward with adding the attributes to BasePointProcessCell for now. I can try to simply init all the same fields with None/empty and see if tests fail

Comment thread bluecellulab/cell/point_process.py Outdated
Comment thread bluecellulab/cell/point_process.py Outdated
Comment thread bluecellulab/cell/point_process.py Outdated
Comment thread bluecellulab/cell/point_process.py Outdated
point_params = PointProcessConnParameters(syn_description[SynapseProperty.PRE_GID], syn_description[SynapseProperty.PRE_GID],
syn_description[SynapseProperty.AXONAL_DELAY])

self.pointConn = PointProcessConnection([point_params])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is assigned but never stored in self.connections or used anywhere else. The connection object is created and then effectively discarded on the next call. Is this intentional?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

properly stored now. Note that additional fields are needed when accessed later. I would like to discuss possible better organization of what I wrote

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. The change is fine.

If you want, the attributes (syn_description, delay_weights, hsynapse, syn_id) could be moved to PointProcessConnection.__init__ params with None defaults. Right now they're set externally after construction, which means the class definition doesn't document its own full interface.

Additionally, PointProcessConnection.info_dict calls self.syn_description.to_dict() without a check, if the object is ever constructed without setting syn_description, it'll crash. A small fix:

@property
def info_dict(self):
    synapse_dict: dict[str, Any] = {}
    if self.syn_description is not None:
        synapse_dict['syn_description'] = self.syn_description.to_dict()
        synapse_dict['syn_description'] = {
            str(k): v for k, v in synapse_dict['syn_description'].items()}
    return synapse_dict

This is mainly about making the class crash-safe if used elsewhere in the future.

Comment thread bluecellulab/reports/utils.py Outdated
Comment thread bluecellulab/reports/utils.py Outdated
Comment thread bluecellulab/circuit/synapse_properties.py Outdated
Comment thread tests/test_allen_v1/test_ringcells_allen_v1.py Outdated
Comment thread tests/test_allen_v1/test_ringcells_allen_v1.py Outdated
Comment thread bluecellulab/cell/point_process.py Outdated
point_params = PointProcessConnParameters(syn_description[SynapseProperty.PRE_GID], syn_description[SynapseProperty.PRE_GID],
syn_description[SynapseProperty.AXONAL_DELAY])

self.pointConn = PointProcessConnection([point_params])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about the weight_factor attribute in PointProcessConnection ? Is it assigned somewhere from the connection_override config file ?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code refactored and now accessed proper

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syn_connection_parameters is still received but unused in add_replay_synapse. The PointProcessConnection is created without weight_factor, so it always defaults to 1.0. We can extract the weight from syn_connection_parameters.get("Weight", 1.0) and pass it through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants