Skip to content

Standardize Units, Refactor Current Handling, and Enhance Examples#44

Merged
chaoming0625 merged 1 commit intomainfrom
example
Jul 25, 2025
Merged

Standardize Units, Refactor Current Handling, and Enhance Examples#44
chaoming0625 merged 1 commit intomainfrom
example

Conversation

@chaoming0625
Copy link
Copy Markdown
Collaborator

@chaoming0625 chaoming0625 commented Jul 25, 2025

Summary by Sourcery

Improve unit consistency and debugging in neuron and network models, refine external current registration, and enhance example scripts with better plotting and progress reporting.

Bug Fixes:

  • Add try/except around ion channel current computation to raise informative errors with channel context

Enhancements:

  • Refactor register_external_current to accept Hashable keys and use element id to prevent collisions
  • Consolidate current summation and area scaling in ThalamusNeuron.compute_derivative
  • Standardize units for conductances and synaptic parameters in the unified thalamus example
  • Update raster_plot to use set_xlabel/set_ylabel and reformat its signature
  • Remove redundant dt setting, add progress bar to for_loop, and add suptitle in example simulations

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Jul 25, 2025

Reviewer's Guide

This PR refactors the external current registration API and ion channel error handling, and brings unit consistency and formatting improvements to the example scripts.

Class diagram for refactored external current registration and error handling

classDiagram
    class Ion {
        _external_currents: dict
        +register_external_current(key: Hashable, fun: Callable)
    }
    class Channel {
        name
        root_type
    }
    class IonManager {
        +add(**elements)
        _get_ion_fun(ion, elem)
    }
    IonManager --> Channel : add
    Channel --> Ion : register_external_current
    Ion <.. IonManager : uses
    note for Ion "register_external_current now takes Hashable key and improved error message"
    note for IonManager "add() now registers external current with id(elem) as key"
Loading

Class diagram for improved error handling in compute_derivative

classDiagram
    class SingleCompartment {
        +compute_derivative(I_ext=0.*u.nA/u.cm**2)
        V
        C
        +sum_current_inputs(I_ext, V)
        +nodes(type, allowed_hierarchy)
    }
    class IonChannel {
        +current(V)
        +compute_derivative(V)
    }
    SingleCompartment --> IonChannel : nodes()
    note for SingleCompartment "compute_derivative now wraps IonChannel.current in try/except and raises ValueError with context"
Loading

Class diagram for ThalamusNeuron compute_derivative override

classDiagram
    class ThalamusNeuron {
        +compute_derivative(I_ext=0.*u.nA)
        area
        V
        C
        +sum_current_inputs(I_ext, V)
        +nodes(type, allowed_hierarchy)
    }
    ThalamusNeuron --|> SingleCompartment
    class SingleCompartment {
        +compute_derivative(I_ext=0.*u.nA/u.cm**2)
    }
    ThalamusNeuron --> IonChannel : nodes()
    note for ThalamusNeuron "compute_derivative now multiplies I_ext by area and matches new error handling"
Loading

File-Level Changes

Change Details Files
Update register_external_current signature and key usage
  • Change key type from str to Hashable in register_external_current
  • Use id(elem) instead of elem.name when registering external currents
braincell/_base.py
Add robust error handling around channel current computation
  • Wrap channel.current calls in try/except
  • Raise detailed ValueError on exception with channel context
braincell/_single_compartment.py
Enforce unit consistency for synaptic parameters and conductances
  • Apply u.mM unit to AMPA/GABAa alpha rates
  • Convert g_input from mA to mS and g_KL scaled by area (u.cm**2)
  • Add u.siemens unit to gap junction weight
examples/SC06_unified_thalamus_model.py
Refine ThalamusNeuron current integration
  • Override compute_derivative to sum currents via sum_current_inputs and scale by area
  • Retain channel derivative computation loop
examples/SC05_thalamus_single_compartment_neurons.py
Clean up example script formatting and API calls
  • Move global dt setting to top and remove redundant calls
  • Fix align_pre typo, add pbar argument to transform.for_loop
  • Replace ax.xlabel/ylabel/xlim with ax.set_* methods
  • Reformat multi-line function parameters for readability
examples/SC06_unified_thalamus_model.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey @chaoming0625 - I've reviewed your changes - here's some feedback:

  • The repeated synapse setup patterns (align_pre, AMPA/GABAa parameters, comm, out) could be refactored into a helper or factory to reduce boilerplate and improve readability.
  • Avoid using Python’s id(elem) for external current registration keys—consider a stable, descriptive identifier (e.g. elem.name) to make debugging and introspection easier.
  • When wrapping exceptions in compute_derivative, use “raise ValueError(…) from e” so the original traceback is preserved for easier debugging.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The repeated synapse setup patterns (align_pre, AMPA/GABAa parameters, comm, out) could be refactored into a helper or factory to reduce boilerplate and improve readability.
- Avoid using Python’s id(elem) for external current registration keys—consider a stable, descriptive identifier (e.g. elem.name) to make debugging and introspection easier.
- When wrapping exceptions in compute_derivative, use “raise ValueError(…) from e” so the original traceback is preserved for easier debugging.

## Individual Comments

### Comment 1
<location> `examples/SC06_unified_thalamus_model.py:392` </location>
<code_context>
     elements = np.where(spikes > 0.)
     index = elements[1]
     time = times[elements[0]]
     ax.plot(time, index, marker + color, markersize=markersize)
     if xlabel:
-        ax.xlabel(xlabel)
+        ax.set_xlabel(xlabel)
     if ylabel:
-        ax.ylabel(ylabel)
+        ax.set_ylabel(ylabel)
     if xlim:
-        ax.xlim(xlim)
+        ax.set_xlim(xlim)


</code_context>

<issue_to_address>
Fixed incorrect method calls for axis labeling and limits.

Using the correct set_* methods prevents attribute errors when labeling axes and setting limits in matplotlib.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
    elements = np.where(spikes > 0.)
    index = elements[1]
    time = times[elements[0]]
=======
    elements = np.where(spikes > 0.)
    index = elements[1]
    time = times[elements[0]]
    ax.plot(time, index, marker + color, markersize=markersize)
    if xlabel:
        ax.set_xlabel(xlabel)
    if ylabel:
        ax.set_ylabel(ylabel)
    if xlim:
        ax.set_xlim(xlim)
>>>>>>> REPLACE

</suggested_fix>

### Comment 2
<location> `braincell/_single_compartment.py:229` </location>
<code_context>
         for key, ch in self.nodes(IonChannel, allowed_hierarchy=(1, 1)).items():
-            I_ext = I_ext + ch.current(self.V.value)
-
+            try:
+                I_ext = I_ext + ch.current(self.V.value)
+            except Exception as e:
+                raise ValueError(
+                    f"Error in computing current for ion channel '{key}': \n"
+                    f"{ch}\n"
+                    f"Error: {e}"
+                )
         self.V.derivative = I_ext / self.C
-
</code_context>

<issue_to_address>
Added error handling for ion channel current computation.

Consider handling more specific exceptions instead of catching all Exceptions to prevent masking unrelated errors.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 389 to 391
elements = np.where(spikes > 0.)
index = elements[1]
time = times[elements[0]]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion (bug_risk): Fixed incorrect method calls for axis labeling and limits.

Using the correct set_* methods prevents attribute errors when labeling axes and setting limits in matplotlib.

Suggested change
elements = np.where(spikes > 0.)
index = elements[1]
time = times[elements[0]]
elements = np.where(spikes > 0.)
index = elements[1]
time = times[elements[0]]
ax.plot(time, index, marker + color, markersize=markersize)
if xlabel:
ax.set_xlabel(xlabel)
if ylabel:
ax.set_ylabel(ylabel)
if xlim:
ax.set_xlim(xlim)

Comment on lines +229 to +236
try:
I_ext = I_ext + ch.current(self.V.value)
except Exception as e:
raise ValueError(
f"Error in computing current for ion channel '{key}': \n"
f"{ch}\n"
f"Error: {e}"
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: Added error handling for ion channel current computation.

Consider handling more specific exceptions instead of catching all Exceptions to prevent masking unrelated errors.

f"Error in computing current for ion channel '{key}': \n"
f"{ch}\n"
f"Error: {e}"
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion (code-quality): Explicitly raise from a previous error (raise-from-previous-error)

Suggested change
)
) from e

@chaoming0625
Copy link
Copy Markdown
Collaborator Author

@sourcery-ai title

@sourcery-ai sourcery-ai Bot changed the title Refactor external current registration and error handling; update typ… Standardize Units, Refactor Current Handling, and Enhance Examples Jul 25, 2025
@chaoming0625 chaoming0625 merged commit 13d1344 into main Jul 25, 2025
24 checks passed
@chaoming0625 chaoming0625 deleted the example branch July 25, 2025 14:04
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.

1 participant