I'm trying to figure out how to use little b to describe multi-
compartment models.
I started by trying to write the simplest possible model that I could
think of: a single species that repartitions between two
compartments. Unfortunately, I can't even get this working.
Here's the code:
==============================
(in-package :b-user)
;; include non-dimensional library
(include b-user/ode-biochem) ; or (include b-user/3d-ode-biochem)
;;; define the species-types
(def-species-types compartment X)
Hi Dominic -
The best place to look is under Locations in
http://www.littleb.org/tutorial-biochem-quickstart.html. Reactions
need to be specified with respect to location-classes, not locations,
so they can be generalized for other situations. c1 and c2 are
locations based on the location-class COMPARTMENT.
Here (almost) is what you need to write:
{X @ membrane.inner -> X @ membrane.outer}.(set-rate-function 'mass-
action 1)
That will work for any compartments that are connected via a
membrane. What this is saying is that where there is a membrane (any
membrane), and an X exists in the location pointed at by :inner, a new
species will exist in the location pointed at by :outer.
It's necessary to write "membrane.inner" because we need to tell the
reaction-type constructor the location-class. In other situations,
little b infers this. For example, given
(def-species-types membrane R RL) ; receptor and receptor-ligand
complex
(def-species-types compartment L) ; ligand
; we can write just
{ R + L @ :outer -> RL}
You can think of this as a shorthand for
{R @ membrane + L @ membrane.outer -> RL @ membrane}
Next, specify that C1 and C2 are connected via a membrane M:
(define m [[membrane] :inner c1 :outer c2])
Now, when you eval
c1.(contains X)
which creates X.(in c1), little b will also infer that X.(in c2)
exists.
What I wrote above (for sake of explanation) was a unidirectional
reaction-type - here is the reversible reaction-type:
{X @ membrane.inner <-> X @ membrane.outer}.(set-rate-function 'mass-
action :fwd 1 :rev 2)
Hope that helps,
Aneil
On Sep 23, 6:30 pm, Dom Layfield <dom.layfi...@gmail.com> wrote:
> I'm trying to figure out how to use little b to describe multi-
> compartment models.
> I started by trying to write the simplest possible model that I could
> think of: a single species that repartitions between two
> compartments. Unfortunately, I can't even get this working.
> Here's the code:
> ==============================
> (in-package :b-user)
> ;; include non-dimensional library
> (include b-user/ode-biochem) ; or (include b-user/3d-ode-biochem)
> ;;; define the species-types
> (def-species-types compartment X)
I just read that document (http://www.littleb.org/tutorial-biochem- quickstart.html). One aspect that I found confusing is that it is not
obvious which identifiers are keywords, and which are variable names.
(I know this is not quite the right terminology for LISP, but I hope
you'll understand). For example, you write:
{[ion] @ :inner @ membrane ->> [ion] @ :outer}
In this case, ":inner" is clearly a keyword, but what about
"membrane"? Does this apply to all membranes? Or is this a specific
instance of a membrane-compartment called "membrane"? And what is
"[ion]"? Is this a randomly-chosen name for a species called "ion",
or is this a language keyword? In most cases, I (think) I was able
to figure out the answers, but it makes the examples confusing to a
newbie.
One suggestion I have that I think would help is to use different
fonts or colors to discriminate between keywords and variable names.
Anyway, I digress. Back to the specific issue...
On Sep 23, 9:40 pm, Aneil Mallavarapu <aneilba...@gmail.com> wrote:
> Reactions need to be specified with respect to location-classes, not locations,
> so they can be generalized for other situations. c1 and c2 are
> locations based on the location-class COMPARTMENT.
> Here (almost) is what you need to write:
> {X @ membrane.inner -> X @ membrane.outer}.(set-rate-function 'mass-
> action 1)
> That will work for any compartments that are connected via a
> membrane. What this is saying is that where there is a membrane (any
> membrane), and an X exists in the location pointed at by :inner, a new
> species will exist in the location pointed at by :outer.
> It's necessary to write "membrane.inner" because we need to tell the
> reaction-type constructor the location-class. In other situations,
> little b infers this. For example, given
> (def-species-types membrane R RL) ; receptor and receptor-ligand
> complex
> (def-species-types compartment L) ; ligand
> ; we can write just
> { R + L @ :outer -> RL}
> You can think of this as a shorthand for
> {R @ membrane + L @ membrane.outer -> RL @ membrane}
> Next, specify that C1 and C2 are connected via a membrane M:
> (define m [[membrane] :inner c1 :outer c2])
> Now, when you eval
> c1.(contains X)
> which creates X.(in c1), little b will also infer that X.(in c2)
> exists.
> What I wrote above (for sake of explanation) was a unidirectional
> reaction-type - here is the reversible reaction-type:
> {X @ membrane.inner <-> X @ membrane.outer}.(set-rate-function 'mass-
> action :fwd 1 :rev 2)
That is very clear, and very useful. Thank you.
So... that means
(1) that any mass transfer between compartments must explicitly
involve a membrane.
(2) that, when I write a rate-function describing transport across a
membrane, the rule applies to all membranes?
If that is correct, (1) makes the model description somewhat more
verbose but seems reasonable. But (2) seems very restrictive
indeed.
Little b is allowing me to make a specific connection, m, between
compartments c1 and c2. But I cannot set rate information that is
specific to m: I can only set generic rate information that applies to
all connections between all compartments.
In some ways, I can see that this might force the user to be very
explicit about transport mechanisms. For example, the transport rate
across a membrane may be determined principally by the density of a
transporter protein. In this case, I could set different rates for
different membranes by describing the differing concentration of the
transporter. Ditto for trans-membrane channels. But how do I handle
passive diffusion through different membrane types? Membrane
composition/structure is not identical for all membrane types, and
their permeability varies significantly. It seems anomalously
restrictive to prevent the user from specifying properties that are
specific to a particular instance.
And what if, when I define a "membrane" separating two compartments, I
intend to describe not a cell membrane (or nuclear membrane etc.) but
as an abstraction of an endothelium? How would I describe
paracellular transport (which will vary dramatically according to
whether endothelium is in brain, kidney, etc.)?
It seems to me that either I misunderstood completely (very probable),
or this is a significant and seemingly unnecessary restriction on what
sorts of systems can be described in little b.
Much of the power of little b is in its ability to write rules that
apply broadly (like {X @ membrane.inner <-> X @ membrane.outer}), but
specifics are necessary too. Why can't I write {X @ c1 <-> X @ c2} or
{X @ m.inner <-> X @ m.outer}? Or perhaps even being able to write
rules that apply to all membranes with a particular label/tag (e.g.
"blood_brain_barrier", "glomerular" etc., or "cell", "nuclear" etc.)
Little b's curly braces provide infix syntax. The expression in the tutorial is from an older version of little b:
{[ion] @ :inner @ membrane ->> [ion] @ :outer}
But, let me explain this anyway:
The expression contains 2 infix operators: @ and ->>
:INNER is, as you correctly pointed out, a LISP keyword
ION and MEMBRANE are Lisp symbols which are bound to predefined values. ION is a monomer defined by the user with defmonomer; MEMBRANE is a location class, defined in b/biochem/location.
Now, the new syntax (which I'll update the tutorial with) is: {[ion] @ membrane.inner ->> [ion] @ membrane.outer} or {[ion] @ membrane.inner ->> [ion] @ :outer] ; shorthand
The expression membrane.inner parsed by the LISP reader into (FLD MEMBRANE :INNER). The @ operator interprets this expression as stating a left hand side requirement for the [ION] species-type in the :INNER compartment with respect to a membrane, and a right-hand side requirement for it in the :OUTER compartment.
Aneil
On Tue, Sep 23, 2008 at 10:59 PM, Dom Layfield <dom.layfi...@gmail.com>wrote:
> I just read that document (http://www.littleb.org/tutorial-biochem- > quickstart.html <http://www.littleb.org/tutorial-biochem-quickstart.html>). > One aspect that I found confusing is that it is not > obvious which identifiers are keywords, and which are variable names. > (I know this is not quite the right terminology for LISP, but I hope > you'll understand). For example, you write:
> {[ion] @ :inner @ membrane ->> [ion] @ :outer}
> In this case, ":inner" is clearly a keyword, but what about > "membrane"? Does this apply to all membranes? Or is this a specific > instance of a membrane-compartment called "membrane"? And what is > "[ion]"? Is this a randomly-chosen name for a species called "ion", > or is this a language keyword? In most cases, I (think) I was able > to figure out the answers, but it makes the examples confusing to a > newbie.
> One suggestion I have that I think would help is to use different > fonts or colors to discriminate between keywords and variable names.
> Anyway, I digress. Back to the specific issue...
> On Sep 23, 9:40 pm, Aneil Mallavarapu <aneilba...@gmail.com> wrote: > > Reactions need to be specified with respect to location-classes, not > locations, > > so they can be generalized for other situations. c1 and c2 are > > locations based on the location-class COMPARTMENT.
> > Here (almost) is what you need to write: > > {X @ membrane.inner -> X @ membrane.outer}.(set-rate-function 'mass- > > action 1)
> > That will work for any compartments that are connected via a > > membrane. What this is saying is that where there is a membrane (any > > membrane), and an X exists in the location pointed at by :inner, a new > > species will exist in the location pointed at by :outer.
> > It's necessary to write "membrane.inner" because we need to tell the > > reaction-type constructor the location-class. In other situations, > > little b infers this. For example, given > > (def-species-types membrane R RL) ; receptor and receptor-ligand > > complex > > (def-species-types compartment L) ; ligand > > ; we can write just > > { R + L @ :outer -> RL} > > You can think of this as a shorthand for > > {R @ membrane + L @ membrane.outer -> RL @ membrane}
> > Next, specify that C1 and C2 are connected via a membrane M:
> > (define m [[membrane] :inner c1 :outer c2])
> > Now, when you eval > > c1.(contains X) > > which creates X.(in c1), little b will also infer that X.(in c2) > > exists.
> > What I wrote above (for sake of explanation) was a unidirectional > > reaction-type - here is the reversible reaction-type: > > {X @ membrane.inner <-> X @ membrane.outer}.(set-rate-function 'mass- > > action :fwd 1 :rev 2)
> That is very clear, and very useful. Thank you.
> So... that means > (1) that any mass transfer between compartments must explicitly > involve a membrane. > (2) that, when I write a rate-function describing transport across a > membrane, the rule applies to all membranes?
> If that is correct, (1) makes the model description somewhat more > verbose but seems reasonable. But (2) seems very restrictive > indeed.
> Little b is allowing me to make a specific connection, m, between > compartments c1 and c2. But I cannot set rate information that is > specific to m: I can only set generic rate information that applies to > all connections between all compartments.
> In some ways, I can see that this might force the user to be very > explicit about transport mechanisms. For example, the transport rate > across a membrane may be determined principally by the density of a > transporter protein. In this case, I could set different rates for > different membranes by describing the differing concentration of the > transporter. Ditto for trans-membrane channels. But how do I handle > passive diffusion through different membrane types? Membrane > composition/structure is not identical for all membrane types, and > their permeability varies significantly. It seems anomalously > restrictive to prevent the user from specifying properties that are > specific to a particular instance.
> And what if, when I define a "membrane" separating two compartments, I > intend to describe not a cell membrane (or nuclear membrane etc.) but > as an abstraction of an endothelium? How would I describe > paracellular transport (which will vary dramatically according to > whether endothelium is in brain, kidney, etc.)?
> It seems to me that either I misunderstood completely (very probable), > or this is a significant and seemingly unnecessary restriction on what > sorts of systems can be described in little b.
> Much of the power of little b is in its ability to write rules that > apply broadly (like {X @ membrane.inner <-> X @ membrane.outer}), but > specifics are necessary too. Why can't I write {X @ c1 <-> X @ c2} or > {X @ m.inner <-> X @ m.outer}? Or perhaps even being able to write > rules that apply to all membranes with a particular label/tag (e.g. > "blood_brain_barrier", "glomerular" etc., or "cell", "nuclear" etc.)
Thanks for the reply, and the clarification on the newer syntax.
I think perhaps you may have overlooked the second (and more
important) half of my post. I'm still perplexed as to why little b
prevents me from saying {species @ location -> etc.}, and only allows
{species @ location-class.subcompartment -> etc.}. As I tried to
explain, this seems like a major restriction, and I don't really see
why it should be that way.
Would really appreciate your comments on this issue...
In little b, reactions are based on reaction-types. The expression{species-type @ location -> ...}uses the reaction-type constructor operator *->*. You are actually constructing a reaction-type object here. Reaction-types are *location-independent - *they don't contain location information. Conceptually, reaction-types represent properties of molecules, whereas reactions represent a particular situation where a reaction-type occurs.
The practical benefit of this approach - referring to location-classes rather than location instances - is that reaction-types are shareable and reusable (the properties of molecules should hold in many different particular situations). For example, you are tempted to write something like this, where you have two locations, *cytoplasm *and *nucleus*, and a species-type, *A*: {a @ cytoplasm -> a @ nucleus} ; not valid little b code
What happens when you add a second cytoplasm and nucleus (call them cytoplasm2 and nucleus2)? You would have to duplicate and modify the reaction: {a @ cytoplasm2 -> a @ nucleus2} ; not valid little b code
This breaks modularity. The correct way to say express the idea in little b is: {a @ membrane.outer -> a @ membrane.inner}
Here, *membrane *is a location-class, not a location. There may be many membrane locations, with many associated inner and outer locations (e.g., cytoplasm2 and nuclei2). This one reaction-type suffices to describe all of those situations.
Hope that helps, Aneil
On Sat, Sep 27, 2008 at 12:56 PM, Dom Layfield <dom.layfi...@gmail.com>wrote:
> Thanks for the reply, and the clarification on the newer syntax.
> I think perhaps you may have overlooked the second (and more > important) half of my post. I'm still perplexed as to why little b > prevents me from saying {species @ location -> etc.}, and only allows > {species @ location-class.subcompartment -> etc.}. As I tried to > explain, this seems like a major restriction, and I don't really see > why it should be that way.
> Would really appreciate your comments on this issue...
Right: reactions are location-independent. That makes a lot of sense,
and I appreciate the philosophy of making rules as general as
possible.
I guess I wanted to hijack the reaction syntax and to use this to
describe transport phenomena. This was tempting, as it seemed that
the reaction-rate and location-specifying infrastructure could easily
be adapted to describe things that weren't really reactions.
(Arguably, you're already doing this when you write "{a @
membrane.outer -> a @ membrane.inner} ": this is not a chemical
reaction. But it makes sense to use this syntax, since you want this
to be a general rule that applies to all membranes.)
So let me rephrase my question. If it is inappropriate to use
reaction-types to describe (non-universal) species transport, then is
there a way in little b that I could describe transport phenomena that
have location-specific parameters? To repeat my example above, can I
describe passive diffusion across a membrane, with a permeability that
is specific to that particular membrane?
On Sep 28, 6:56 am, "Aneil Mallavarapu" <aneilba...@gmail.com> wrote:
> In little b, reactions are based on reaction-types. The
> expression{species-type @ location -> ...}uses the reaction-type
> constructor operator
> *->*. You are actually constructing a reaction-type object here.
> Reaction-types are *location-independent - *they don't contain location
> information. Conceptually, reaction-types represent properties of
> molecules, whereas reactions represent a particular situation where a
> reaction-type occurs.
> The practical benefit of this approach - referring to location-classes
> rather than location instances - is that reaction-types are shareable and
> reusable (the properties of molecules should hold in many different
> particular situations). For example, you are tempted to write something
> like this, where you have two locations, *cytoplasm *and *nucleus*, and a
> species-type, *A*:
> {a @ cytoplasm -> a @ nucleus} ; not valid little b code
> What happens when you add a second cytoplasm and nucleus (call them
> cytoplasm2 and nucleus2)? You would have to duplicate and modify the
> reaction:
> {a @ cytoplasm2 -> a @ nucleus2} ; not valid little b code
> This breaks modularity. The correct way to say express the idea in little
> b is:
> {a @ membrane.outer -> a @ membrane.inner}
> Here, *membrane *is a location-class, not a location. There may be many
> membrane locations, with many associated inner and outer locations (e.g.,
> cytoplasm2 and nuclei2). This one reaction-type suffices to describe all of
> those situations.
In the future, it's possible that little b will support up a non-generalizable (location-dependent) reaction syntax. I can see why this would be convenient. We just don't have time to work on this right now.
The easiest way to do this is to define the reaction-type in terms of a second species-type which sits in the membrane: {a @ :outer + b -> a @ :inner + b} where b is a membrane species-type
And don't forget to put that species-type in the membrane: m.(contains b)
If you want first-order mass-action kinetics with a constant of 1.5, write:
{a @ :outer + b -> a @ :inner + b}.(set-rate-function 'custom {a * :mass-action} :mass-action 1.5)
A On Mon, Sep 29, 2008 at 8:59 AM, Dom Layfield <dom.layfi...@gmail.com>wrote:
> Right: reactions are location-independent. That makes a lot of sense, > and I appreciate the philosophy of making rules as general as > possible.
> I guess I wanted to hijack the reaction syntax and to use this to > describe transport phenomena. This was tempting, as it seemed that > the reaction-rate and location-specifying infrastructure could easily > be adapted to describe things that weren't really reactions. > (Arguably, you're already doing this when you write "{a @ > membrane.outer -> a @ membrane.inner} ": this is not a chemical > reaction. But it makes sense to use this syntax, since you want this > to be a general rule that applies to all membranes.)
> So let me rephrase my question. If it is inappropriate to use > reaction-types to describe (non-universal) species transport, then is > there a way in little b that I could describe transport phenomena that > have location-specific parameters? To repeat my example above, can I > describe passive diffusion across a membrane, with a permeability that > is specific to that particular membrane?
> On Sep 28, 6:56 am, "Aneil Mallavarapu" <aneilba...@gmail.com> wrote: > > In little b, reactions are based on reaction-types. The > > expression{species-type @ location -> ...}uses the reaction-type > > constructor operator > > *->*. You are actually constructing a reaction-type object here. > > Reaction-types are *location-independent - *they don't contain location > > information. Conceptually, reaction-types represent properties of > > molecules, whereas reactions represent a particular situation where a > > reaction-type occurs.
> > The practical benefit of this approach - referring to location-classes > > rather than location instances - is that reaction-types are shareable and > > reusable (the properties of molecules should hold in many different > > particular situations). For example, you are tempted to write something > > like this, where you have two locations, *cytoplasm *and *nucleus*, and a > > species-type, *A*: > > {a @ cytoplasm -> a @ nucleus} ; not valid little b code
> > What happens when you add a second cytoplasm and nucleus (call them > > cytoplasm2 and nucleus2)? You would have to duplicate and modify the > > reaction: > > {a @ cytoplasm2 -> a @ nucleus2} ; not valid little b code
> > This breaks modularity. The correct way to say express the idea in > little > > b is: > > {a @ membrane.outer -> a @ membrane.inner}
> > Here, *membrane *is a location-class, not a location. There may be many > > membrane locations, with many associated inner and outer locations (e.g., > > cytoplasm2 and nuclei2). This one reaction-type suffices to describe all > of > > those situations.
> In the future, it's possible that little b will support up a
> non-generalizable (location-dependent) reaction syntax. I can see why this
> would be convenient. We just don't have time to work on this right now.
> The easiest way to do this is to define the reaction-type in terms of a
> second species-type which sits in the membrane:
> {a @ :outer + b -> a @ :inner + b}
> where b is a membrane species-type
> And don't forget to put that species-type in the membrane:
> m.(contains b)
> If you want first-order mass-action kinetics with a constant of 1.5, write:
> {a @ :outer + b -> a @ :inner + b}.(set-rate-function 'custom {a *
> :mass-action} :mass-action 1.5)
> In the future, it's possible that little b will support up a > non-generalizable (location-dependent) reaction syntax. I can see why this > would be convenient. We just don't have time to work on this right now.
> The easiest way to do this is to define the reaction-type in terms of a > second species-type which sits in the membrane: > {a @ :outer + b -> a @ :inner + b} > where b is a membrane species-type
> And don't forget to put that species-type in the membrane: > m.(contains b)
> If you want first-order mass-action kinetics with a constant of 1.5, write:
> {a @ :outer + b -> a @ :inner + b}.(set-rate-function 'custom {a * > :mass-action} :mass-action 1.5)
> A
> On Mon, Sep 29, 2008 at 8:59 AM, Dom Layfield <dom.layfi...@gmail.com>wrote:
>> Right: reactions are location-independent. That makes a lot of sense, >> and I appreciate the philosophy of making rules as general as >> possible.
>> I guess I wanted to hijack the reaction syntax and to use this to >> describe transport phenomena. This was tempting, as it seemed that >> the reaction-rate and location-specifying infrastructure could easily >> be adapted to describe things that weren't really reactions. >> (Arguably, you're already doing this when you write "{a @ >> membrane.outer -> a @ membrane.inner} ": this is not a chemical >> reaction. But it makes sense to use this syntax, since you want this >> to be a general rule that applies to all membranes.)
>> So let me rephrase my question. If it is inappropriate to use >> reaction-types to describe (non-universal) species transport, then is >> there a way in little b that I could describe transport phenomena that >> have location-specific parameters? To repeat my example above, can I >> describe passive diffusion across a membrane, with a permeability that >> is specific to that particular membrane?
>> On Sep 28, 6:56 am, "Aneil Mallavarapu" <aneilba...@gmail.com> wrote: >> > In little b, reactions are based on reaction-types. The >> > expression{species-type @ location -> ...}uses the reaction-type >> > constructor operator >> > *->*. You are actually constructing a reaction-type object here. >> > Reaction-types are *location-independent - *they don't contain location >> > information. Conceptually, reaction-types represent properties of >> > molecules, whereas reactions represent a particular situation where a >> > reaction-type occurs.
>> > The practical benefit of this approach - referring to location-classes >> > rather than location instances - is that reaction-types are shareable >> and >> > reusable (the properties of molecules should hold in many different >> > particular situations). For example, you are tempted to write something >> > like this, where you have two locations, *cytoplasm *and *nucleus*, and >> a >> > species-type, *A*: >> > {a @ cytoplasm -> a @ nucleus} ; not valid little b code
>> > What happens when you add a second cytoplasm and nucleus (call them >> > cytoplasm2 and nucleus2)? You would have to duplicate and modify the >> > reaction: >> > {a @ cytoplasm2 -> a @ nucleus2} ; not valid little b code
>> > This breaks modularity. The correct way to say express the idea in >> little >> > b is: >> > {a @ membrane.outer -> a @ membrane.inner}
>> > Here, *membrane *is a location-class, not a location. There may be many >> > membrane locations, with many associated inner and outer locations >> (e.g., >> > cytoplasm2 and nuclei2). This one reaction-type suffices to describe >> all of >> > those situations.