package affectors; import main.Node; import main.Globals; /** * This affector implements one half of a constant delay through a von Forrester equation. * This affector represents the flux INTO the delayed node from the previously delayed node and * is for use on cytoplasmic nodes only. Use {@link VonForresterB_ICAff} for the flux out of the delayed node. * Use the EC version for membrane nodes. *
* Effectively, this is a bucket brigade, or conveyor belt, where the delay is implemented * as a series of nodes, each a delayed version of the previous. Using too few delay * nodes will result in lowpass filtering. In general, you should look at the highest * frequency/most rapid change you care about, and use as many delay nodes as necessary * to preserve the features you want. *
* The parameter v is the velocity or rate that one delay node transfers into the * next. It should be equal to the number of delay nodes divided by the maximal * delay. *
* Formula
*
dNodeDelayN/dt = vNodeDelayN-1
*
* Parameters *
Current delayed node [NodeDelayN] | The delayed node * being calculated |
Previous delayed node [NodeDelayN-1] | The delayed node * feeding into this delayed node |
Velocity [v] | The rate of transfer into & out of this node. Should * be equal to the number of delay nodes/time of delay |
* Usage
*
*
* @author Kerry Kim
* @see VonForresterA_ECAff
* @see VonForresterB_ECAff
* @see VonForresterB_ICAff
*/
public class VonForresterA_ICAff extends Affector {
/* These store references to the parameters used by the Affector. For instance, if the
affector uses some rate as part of its formula, that rate should be a parameter and
needs to be declared here. You should give these parameters good names, such as
halfLife or rateConstant. The convention is that that first word in the name is
lowercase and all subsequent words are uppercase. You should replace this comment
with a description of the first parameter. */
/** The rate of transfer between von Forrester delay nodes. */
int v;
static final String affectorDescription = "Introduces a constant delay in a cytoplasmic node through von Forrester method";
static final String [] nodeDescriptions = {"Previous delay node"};
static final String [] paramDescriptions = {"Velocity"};
static final int [] whichSides = {-1};
public VonForresterA_ICAff() {}
protected void setLabelsAndTypes() {
setDescriptions(affectorDescription, nodeDescriptions, paramDescriptions);
/* This tells the rest of Ingeneue whether this Affector is supposed to
operate on Nodes that reside in the membrane. The default is that
an Affector operates only on cytoplasmic Nodes, or if it operates on
membrane Nodes then it only operates on the sum of the concentrations
across all faces of the cell. In either of these cases, you can just
delete this method call. Otherwise, you need to pass true as the first
argument (indicating that Affector operates on membrane Nodes) and the
sides of each Node as the second argument (see comment near whichSides above). */
//setSided(true, whichSides);
/* This tells the rest of Ingeneue whether the Affector uses the concentration
of the Node whose value it is helping determine. For instance, a Decay
Affector calculates its value based on the concentration of the Node it
is decaying. On the other hand, a translation Affector produces the same
amount of protein regardless of the concentration of the protein. In the first
of these cases, you need to inform the rest of Ingeneue that the formula uses
the concentration of the target Node. In the latter, you must inform Ingeneue
that it doesn't. The default is to assume that the Affector doesn't use the
target Node's concentration, so in that case you can just delete this method
call. */
// setContainsTarget(true);
/* These four flags tell the rest of Ingeneue some characteristics of
the Affector. ... and george, you have to remind me what they do. */
this.Type[GUI_CAPABLE] = 1;
this.Type[CERTIFICATION] = Affector.RETURNS_DERIV;
this.Type[MATHTYPE] = Affector.KK;
this.Type[TERMTYPE] = Affector.CONVERSION;
}
/* This is where the rest of Ingeneue gives this Affector indices to each parameter
that it uses. You should make a line for each parameter in the same order as
they are described in paramDescriptions above, and then assign the values from param_nums
as shown in the example below. */
public void setParameterNumbers(int [] param_nums)
{
v = param_nums[0];
}
/* This is the formula for this Affector.
Use Nodes[a].getIntegrationValue(side) to get the value of a node, where a is
the position of the node in the nodeDescriptions array (starting from 0).
Use params[parameterIndex] to get the value of a parameter, where parameterIndex
is the index value assigned in setParameterNumbers (for instance, firstParameter or
secondParameter in the example above).
Most Affectors should be multiplied by Globals.characteristicTime.
This example is the formula for DecayAff. */
public float getValue(Node which_node) {
return Globals.characteristicTime*Nodes[0].getIntegrationValue()*params[v];
}
}
&nodeDelayN
*
* &VonForresterA_ICAff nodeDelayN-1 v
*
* &endnodeDelayN