package affectors; import java.io.PrintWriter; import java.util.Enumeration; import java.util.Vector; import main.Node; import main.Cell; import main.Globals; /** This is a meta-affector which sums together transcriptional activation terms while keeping the total transcription rate less than or equal to 1. Each sub-affector is assumed to be giving a probability per some unit time of the transcription machinery binding to the promoter and starting transcription. MultiEnhancerAff figures out the total probability of the transcription machinery based on the individual probabilities.

Formula
dnodex/dt = 1 - (1 - alpha_T1/max_alpha * T1)(1 - alpha_T2/max_alpha * T2) ... (1 - alpha_Tn/max_alpha * Tn)
where T1 ... Tn are the sub-affector values and max_alpha is the max of all the alpha's

Parameters
There needs to be one alpha parameter per subaffector. The alphas give the relative weights of each subaffectors contribution to the total value.

Usage
&nodex

&EnhancerRegionAff
&MultiEnhancerAff alpha_AC alpha_SC
&TxnSiteActivatorAff AC K_ACsc nu_ACsc
&TxnSiteActivatorAff SC K_SCsc nu_SCsc
&endMultiEnhancerAff
&endEnhancerRegionAff
&endnodex */ public class MultiEnhancerAff extends EnhancerRegionAff implements Cloneable { int [] alphas; static final String desc = "Probabilistic sum of several other affectors"; static final int [] whichSides = { -1 }; public MultiEnhancerAff() { } protected void setLabelsAndTypes() { setDescriptions(this.desc, null, null); setSided(true, whichSides); this.Type[GUI_CAPABLE] = 0; this.Type[CERTIFICATION] = Affector.RETURNS_DERIV; this.Type[MATHTYPE] = Affector.FF; // ???? None really fit this.Type[TERMTYPE] = Affector.PRODUCTION; } public void setParameterNumbers(int [] param_nums) { if(param_nums.length != numAffectors) { System.out.println("Error: Number of alpha parameters does not match number of affectors in MultiEnhancer meta-affector"); return; } alphas = new int[param_nums.length]; for(int i = 0; i < param_nums.length; i++) alphas[i] = param_nums[i]; } /** Overrides Affector.getValue() to multiply together the values from all the subsidiary affectors. */ public float getValue(Node which_node) { float value = 1f; int i; // Find scaling for alphas float max_alpha = 0.0000001f; for(i = 0; i < numAffectors; i++) { if(params[alphas[i]] > max_alpha) max_alpha = params[alphas[i]]; } for(i = 0; i < numAffectors; i++) { float aff_val = affectors[i].getValue(which_node) * params[alphas[i]] / max_alpha; if(aff_val > 1.0) aff_val = 1f; value *= (1f - aff_val); } return (1f - value); } /** Overrides Affector.getNCValue() to multiply together the values from all the subsidiary affectors. */ public float getNCValue(Node which_node) { if(containsTarget) { float value = 1f; int i; // Find scaling for alphas float max_alpha = 0.0000001f; for(i = 0; i < numAffectors; i++) { if(params[alphas[i]] > max_alpha) max_alpha = params[alphas[i]]; } for(i = 0; i < numAffectors; i++) { float aff_val = affectors[i].getNCValue(which_node) * params[alphas[i]] / max_alpha; if(aff_val > 1.0) aff_val = 1f; value *= (1f - aff_val); } return (1f - value); } else return super.getNCValue(which_node); } /* The rest of these functions are overrides of Affector functions so that they work right for this class. */ public Affector copy() { MultiEnhancerAff element = null; try { element = (MultiEnhancerAff)this.clone(); } catch(CloneNotSupportedException e) { System.out.println("Error cloning MultiEnhancerAff: " + e.toString()); } element.affectors = new Affector[3]; element.numAffectors = 0; for(int i = 0; i < numAffectors; i++) { element.addAffector(affectors[i].copy()); } element.this_debug_num = debug_num++; return element; } }