-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New interface for channels with cell.add_global_param()
#474
Comments
I dont quite understand this. could you elaborate? :) |
Ah, yes, I created this issue in a rush during a zoom meeting and forgot to add more details. We got feedback that it is unintuitive that things like reversal potentials or temperature are |
We (@kyralianaka @huangziwei @jnsbck) decided on the following: The This implies the following:
Additional improvements to
|
cell.add_membrane_property()
cell.add_membrane_param()
@r-makarov see above---we are sketching out a new structure for channels. If you have any feedback, that would be great! |
cell.add_membrane_param()
cell.add_global_param()
While we're at it, we should rename all |
or the other way around :) Linters complain about (but I think I also tend towards |
@michaeldeistler Sounds great! I'm in favor of all the proposed changes.
|
These suggestions are great! slow_K = K().change_name("slow_K")
cell.insert(slow_K)
Another thing I just noticed: The methods in channel / synapse are called update_states and init_state. I think we should settle for either singular or plural. |
Thanks!
Have you made any decision regarding the temperature adjustment factor |
More thoughts I had thinking about the new channel API:
Incl. all the feedback above, here is the following proposal. class Mechanism:
name = None
params: dict = None
states: dict = None
current_subscript: str = None
META: dict = None
def __init__(self, name = None):
self.name = self.__class__.__name__.lower() # <- replace property by attr, force lowercase
self.params = {} # <- all mechs have params and states
self.states = {} # will make code much nicer, since mech.params works for all mechs
self.current_subscript = self.name # <- rename subscript to make clear that current will be named "i_name"
self.META = {} # <- I think we could make this a default attr for all mechs
if name is not None:
self.change_name(name)
@property
def current_name(self): # retain the old current name, ensures all mech currents are of form "i_subscript"
return f"i_{self.current_subscript}"
def change_name(self, new_name):
for params_or_states in [self.params, self.states]:
for key in params_or_states:
if key.startswith(self.name):
new_key = key.replace(self.name, new_name)
params_or_states[new_key] = params_or_states.pop(key)
if self.current_subscript.startswith(self.name):
self.current_subscript = self.current_subscript.replace(self.name, new_name)
self.name = new_name
return self
@abstractmethod
def update_states(self, t, states, params, v, dt): # <- standardize order of args; add t for consistency
# convention usually is: (t, states, args) / (t, states, (params, v, dt))
return {}
@abstractmethod
def compute_current(self, t, states, params, v):
raise NotImplementedError
@abstractmethod
def init_states(self, t, states, params, v, dt): # <- rename to init_state**s**
return {}
@abstractmethod
def init_params(self, t, states, params, v, dt): # <- add init_params (see #507)
return {}
def _vectorfield(self, t, states, params, v): # <- make vectorield optionally accessible
return {}
class Channel(Mechanism):
def __init__(self, name = None):
super().__init__(name)
class Leak(Channel):
def __init__(self, name = None):
super().__init__(name)
self.params = {f"g_{self.name}": 0.01, f"E_{self.name}": -70.0}
def compute_current(self, t, states, params, v):
g, E = params[f"g_{self.name}"], params[f"E_{self.name}"]
return g * (v - E)
def update_states(self, t, states, params, v, dt):
return {}
def init_states(self, t, states, params, v, dt):
return {} Lemme know your thoughts! |
nice, I like it! Two things:
|
I disagree with 1. for the following reasons:
Regarding 2, yes, lets discuss ideas here. Also related to #592. ...to start a discussion. class Pump(Mechanism):
def __init__(self, name = None):
super().__init__(name)
self.ion = "ion" # <- we could also make this part of mech, since ultimately, Channels etc. also are associated with ions. Additional thoughst:
|
Should we also add a This would allow: branch = jx.Branch(ncomps=2)
channel = CustomChannel()
# insert channel into first comp
channel.set("g", 1.0)
branch.comp(0).insert(channel)
# change params and insert into 2nd comp
channel.set("g", 2.0)
branch.comp(1).insert(channel) |
then
e_k
can be accessed viaparams["e_k"]
.The text was updated successfully, but these errors were encountered: