ecell / ecell4

An integrated software environment for multi-algorithm, multi-timescale, multi-spatial-representation simulation of various cellular phenomena
https://ecell4.e-cell.org/
GNU General Public License v3.0
17 stars 9 forks source link

Enable to split species attribute definition #19

Closed kaizu closed 4 years ago

kaizu commented 6 years ago

Before:

with species_attributes():
    A | {'D': Q_(1, 'um**2/s'), 'radius': Q_(5, 'nm'), 'location': 'W'}
    B | {'D': Q_(0, 'um**2/s'), 'radius': Q_(5, 'nm'), 'location': 'W'}

After:

with species_attributes():
    A | B | {'radius': Q_(5, 'nm'), 'location': 'W'}
    A | {'D': Q_(1, 'um**2/s')}
    B | {'D': Q_(0, 'um**2/s')}

This is useful when you want to set optional annotations.

kaizu commented 6 years ago
from ecell4 import *

with species_attributes():
    _ | {'key1': 'default'}  # default
    A | {'key1': 'value1'}
    B | {'key1': 'value2'}
    A | {'key2': 'value3'}

m = get_model()
sp1 = m.apply_species_attributes(Species('A'))
sp2 = m.apply_species_attributes(Species('B'))
sp3 = m.apply_species_attributes(Species('C'))
print(sp1.serial(), sp1.list_attributes())  # => A [('key1', 'value1'), ('key2', 'value3')]
print(sp2.serial(), sp2.list_attributes())  # => B [('key1', 'value2')]
print(sp3.serial(), sp3.list_attributes())  # => C [('key1', 'default')]

Lower declaration has higher priority. Thus, the default must be declared first. When you declare the same key for a species twice, the lower one is hired.

kaizu commented 6 years ago

Revert all changes related to this, and add a new member function to update attributes, update_species_attribute.

m = NetworkModel()
sp = Species('A')
sp.set_attribute('parrot', 'dead')
m.add_species_attribute(sp)
assert m.has_species_attribute(Species('A'))

sp = Species('A')
sp.set_attribute('parrot', 'ex-parrot')
# m.add_species_attribute(sp)  # causes an error
m.update_species_attribute(sp)  # updates attributes and returns False

There is no syntax to do this in the with species_attributes() statement yet.

kaizu commented 6 years ago

Current:

with species_attributes():
    A | {'D': Q_(1, 'um**2/s'), 'radius': Q_(5, 'nm'), 'dbid': 'SOME_ID_FOR_A'}
    B | {'D': Q_(1, 'um**2/s'), 'radius': Q_(5, 'nm'), 'dbid': 'SOME_ID_FOR_B'}

Proposal:

with species_attributes():
    default = {'D': Q_(1, 'um**2/s'), 'radius': Q_(5, 'nm')}
    A | default | {'dbid': 'SOME_ID_FOR_A'}
    B | default | {'dbid': 'SOME_ID_FOR_B'}
kaizu commented 4 years ago

See https://github.com/ecell/ecell4_base/issues/444

with species_attributes():
    A | {'dbid': 'SOME_ID_FOR_A'} | proceed
    B | {'dbid': 'SOME_ID_FOR_B'} | proceed
    _ | {'D': Q_(1, 'um**2/s'), 'radius': Q_(5, 'nm')}
kaizu commented 4 years ago

Use proceed.