/* This is a template file for making a new Affector. It includes all the required methods for an Affector. Making your own affector is described in a tutorial accompanying Ingeneue. Basically, you have to change the TemplateAff name to one suitable for your affector, change the comments below and the descriptions at the top of the class. Then you have to declare the parameters for your Affector and put in the proper setup code in setLabelsAndTypes() and setParameterNumbers(). Finally, you need to put the formula for the Affector into getValue() and possibly into getNCValue(). */ package affectors; import main.Node; import main.Globals; /** This should be a description of what this Affector does and where it might be used. This description will show up in the online html documentation files. Even though it takes a couple minutes, it pays to do a decent job in these descriptions because the exact use for an Affector is the kind of thing you are likely to forget. The next section of this comments should show the formula being used. The third and fourth sections of this comments should contain a short description of each node or parameter used by the Affector, and an example of what the Affector would look like in a network file. We do the parameters section using a table, which makes it easier to read - if you don't know html, just make one copy of the line that starts with for each parameter and replace ANode with the parameter name and Describe node here with the parameters description.

Formula
dnodex/dt =

Parameters
ANode [nodex] Describe node here

Usage
&nodex

&DecayAff nodex H_nodex
&endnodex */ /* Change the name from TemplateAff to [YourAffectorsName]Aff. Note also that you will need to save your new affector in a file called [YourAffectorsName]Aff.java */ public class TemplateAff 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. */ int firstParameter; /** And replace this comment with a description of the second parameter, if there is one.*/ int secondParameter; /** And copy the above two lines for any more parameters you might need */ /* These next few lines give short descriptions of the Affector, the nodes used by the Affector, and the parameters used by the Affector. These descriptions are used by Ingeneue's interface to guide users in constructing models with a point and click interface - something that is currently not possible, but which we hope will be available within a year. */ /* This first string is a several word description of what the Affector does. */ static final String affectorDescription = "Short description of affector"; /* This list of strings describes, in one or a few words, the purpose of each node used by the Affector. Note that it is important to put the correct number of strings here, one per node, as the number of strings tells code which inputs a network file how many nodes it should be expecting. If the Affector uses no nodes, set nodeDescriptions = null. */ static final String [] nodeDescriptions = {"Node 1 Description", "Node 2 Description"}; /* This list of strings describes, in one or a few words, the purpose of each parameter used by the Affector. As with the node descriptions, it is important to get the right number of strings even if you don't put in the effort to make good descriptions. If there are no parameters, set paramDescriptions = null. */ static final String [] paramDescriptions = {"Parameter 1 Description", "Parameter 2 Description"}; /* This list of integers specifies whether each Node used by the Affector is in the same cell as the Affectors Node, or is a neighboring cell. Put -1 for Nodes in the same cell, 1 for Nodes in neighboring cells. The numbers here correspond to the descriptions in nodeDescriptions above. */ static final int [] whichSides = { -1 }; /** Constructor for this Affector. All Affectors must use a no-argument constructor, and currently there is no need to do anything in the constructor of most Affectors. You do need to change the name here from TemplateAff to [YourAffectorsName]Aff. */ public TemplateAff() {} /** Tells the rest of Ingeneue about this Affector. See the tutorial for the meaning of each line. */ protected void setLabelsAndTypes() { /* This function tells the rest of Ingeneue the descriptions of the Affector and each node and parameter used by the Affector. If there are no Nodes used by the Affector you can pass null in place of nodeDescriptions and similarly for paramDescriptions if there are no parameters. */ 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.HH; this.Type[TERMTYPE] = Affector.DEGRADATION; } /** 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) { firstParameter = param_nums[0]; secondParameter = param_nums[1]; } /** 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 (Nodes[0].getIntegrationValue(side) * (-Globals.characteristicTime / params[halfLife])); } /** If the Affector uses its own Node's concentration in making its calculation, then you this method should return the same value as getValue() divided by the concentration of the Affectors' Node. Thus, assuming Nodes[0] was this Affectors Node, the code here could be written: getValue() / Nodes[0].getIntegrationValue() Its better to just rewrite the formula, though, since the code will run faster without the extra method call and division. */ public float getNCValue(Node which_node) { return getValue(); } /* The end */ }