public static getMoleculeFromName ( string name, ArrayList molecules ) : Molecule, | ||
name | string | |
molecules | ArrayList | |
return | Molecule, |
/*! * \brief Load Molecules from a MoleculeSet * \param molSet The set to Load * \param allMolecules The list of all the molecules */ public void initMoleculesFromMoleculeSets(MoleculeSet molSet, ArrayList allMolecules) { Logger.Log("Medium::initMoleculesFromMoleculeSets medium#" + _numberId, Logger.Level.TRACE); Molecule newMol; Molecule startingMolStatus; _molecules = new ArrayList(); foreach (Molecule mol in allMolecules) { newMol = new Molecule(mol); startingMolStatus = ReactionEngine.getMoleculeFromName(mol.getName(), molSet.molecules); if (startingMolStatus == null) { newMol.setConcentration(0); } else { newMol.setConcentration(startingMolStatus.getConcentration()); } Logger.Log("Medium::initMoleculesFromMoleculeSets medium#" + _numberId + " add mol " + newMol.getName() + " with cc=" + newMol.getConcentration() , Logger.Level.TRACE ); _molecules.Add(newMol); } }
/*! * Find the Limiting reactant in the attribute _reactant * and return the factor as following : * * [MinReactant] / CoefReactant */ private float getLimitantFactor(ArrayList molecules) { Product minReact = null; bool b = true; Molecule mol = null; Molecule molMin = null; foreach (Product r in _reactants) { mol = ReactionEngine.getMoleculeFromName(r.getName(), molecules); if (b && mol != null) { molMin = mol; minReact = r; b = false; } else if (mol != null) { if (molMin != null && ((mol.getConcentration() / r.getQuantityFactor()) < (molMin.getConcentration() / minReact.getQuantityFactor()))) { molMin = mol; minReact = r; } } } if (minReact == null) { return(0f); } return(molMin.getConcentration() / minReact.getQuantityFactor()); }
//! Processing a reaction. /*! * \param molecules A list of molecules (not usefull here) * * A diffusion reaction based on fick model is calculated by using this formula : * dn/dt = c1 - c2 * P * A * Where: * - dn is the difference of concentration that will be applied * - c1 and c2 the concentration the molecules in the 2 Mediums * - P is the permeability coefficient * - A is the contact surface size between the two Mediums */ public override void react(ArrayList molecules) { ArrayList molMed1 = _medium1.getMolecules(); ArrayList molMed2 = _medium2.getMolecules(); Molecule mol2; float c1; float c2; float result; if (_P == 0f || _surface == 0f) { return; } foreach (Molecule mol1 in molMed1) { c1 = mol1.getConcentration(); mol2 = ReactionEngine.getMoleculeFromName(mol1.getName(), molMed2); if (mol2 != null && mol2.getFickFactor() > 0f) { c2 = mol2.getConcentration(); result = (c2 - c1) * _P * _surface * mol2.getFickFactor() * _reactionSpeed * ReactionEngine.reactionsSpeed; if (enableSequential) { mol2.addConcentration(-result); mol1.addConcentration(result); } else { mol2.subNewConcentration(result); mol1.addNewConcentration(result); } } } }
/*! * \brief Add a concentration to molecule corresponding to the name. * \param name The name of the Molecules. * \param value The value to Add. */ public void addMolConcentration(string name, float value) { Molecule mol = ReactionEngine.getMoleculeFromName(name, _molecules); if (mol != null) { mol.setConcentration(mol.getConcentration() + value); } }
/*! * This function is called at each frame. * It find the limiting reactant and consume as reactant and produce product * as much as possible. * * The formula is : * * delta = Min(Reactant_1 / Coef_1, Reactant_2 / Coef_2, ... , Reactant_n / Coef_n) * for each product P : [P] += delta * Coef_P * for each reactant R : [R] -= delta * Coef_R */ public override void react(ArrayList molecules) { if (!_isActive) { return; } float delta = getLimitantFactor(molecules); float energyCoef; float energyCostTot; if (delta > 0f && _energyCost > 0f && enableEnergy) { energyCostTot = _energyCost * delta; energyCoef = _medium.getEnergy() / energyCostTot; if (energyCoef > 1f) { energyCoef = 1f; } _medium.subEnergy(energyCostTot); } else { energyCoef = 1f; } delta *= energyCoef; Molecule mol; foreach (Product react in _reactants) { mol = ReactionEngine.getMoleculeFromName(react.getName(), molecules); if (enableSequential) { mol.subConcentration(delta * react.getQuantityFactor()); } else { mol.subNewConcentration(delta * react.getQuantityFactor()); } } foreach (Product prod in _products) { mol = ReactionEngine.getMoleculeFromName(prod.getName(), molecules); if (enableSequential) { mol.addConcentration(delta * prod.getQuantityFactor()); } else { mol.addNewConcentration(delta * prod.getQuantityFactor()); } } }
/*! * \details The degradation reaction following the formula above: * * [X] = degradationRate * [X] * * \param molecules The list of molecules */ public override void react(ArrayList molecules) { if (!_isActive) { return; } Molecule mol = ReactionEngine.getMoleculeFromName(_molName, molecules); float delta = mol.getDegradationRate() * mol.getConcentration(); if (enableSequential) { mol.subConcentration(mol.getDegradationRate() * mol.getConcentration() * _reactionSpeed * ReactionEngine.reactionsSpeed); } else { mol.subNewConcentration(delta * _reactionSpeed * ReactionEngine.reactionsSpeed); } }
/*! * \brief This function is called as Update in Monobehaviour. * \details This function is called in the Phenotype class in the Update function * This function should be implemented and all the graphical action has to be implemented in it. * \sa Phenotype */ public override void UpdatePhenotype() { //bool isThresholdEnabled = false; Molecule mol = ReactionEngine.getMoleculeFromName(MoleculeName, _molecules); if (mol == null) { return; } Debug.LogError("deprecated GetComponent calls"); if (mol.getConcentration() >= Threshold && gameObject.GetComponent("ParticleSystem") == null) { gameObject.AddComponent <ParticleSystem>(); } else if (mol.getConcentration() < Threshold && gameObject.GetComponent("ParticleSystem") != null) { Destroy(gameObject.GetComponent("ParticleSystem")); } // Instantiate(prefab, new Vector3(GetComponent.Transform.x, GetComponent.Transform.y, GetComponent.Transform.z), Quaternion.identity); }
/*! * \brief this function execute all the enzyme reactions * \details It's call execEnzymeReaction and substract to the substrate concentration what this function return. * This function also add this returned value to all the producted molecules. * \param molecules The list of molecules */ public override void react(ArrayList molecules) { if (!_isActive) { return; } Molecule substrate = ReactionEngine.getMoleculeFromName(_substrate, molecules); if (substrate == null) { Logger.Log("EnzymeReaction::react couldn't find substrate '" + _substrate + "'", Logger.Level.WARN); return; } //TODO introduce delta t here instead of 1f float delta = execEnzymeReaction(molecules) * 1f; float energyCoef; float energyCostTot; if (delta > 0f && _energyCost > 0f && enableEnergy) { energyCostTot = _energyCost * delta; energyCoef = _medium.getEnergy() / energyCostTot; if (energyCoef > 1f) { energyCoef = 1f; } _medium.subEnergy(energyCostTot); } else { energyCoef = 1f; } delta *= energyCoef; if (enableSequential) { substrate.subConcentration(delta); } else { substrate.subNewConcentration(delta); } foreach (Product pro in _products) { Molecule mol = ReactionEngine.getMoleculeFromName(pro.getName(), molecules); if (null != mol) { if (enableSequential) { mol.addConcentration(delta); } else { mol.addNewConcentration(delta); } } else { Logger.Log("EnzymeReaction::react couldn't find product '" + pro.getName() + "'", Logger.Level.WARN); } } }
/*! * Execute an enzyme reaction. * \details This function do all the calcul of an enzymatic reaction. * The formula is : * * [S] [S] * [I] * Vmax * ---- + beta * Vmax * ---------------- * Km alpha * Km * Ki * delta = ------------------------------------------------- * [S] [I] [S] * [I] * 1 + ---- + ---- + ----------------- * Km Ki alpha * Km * Ki * * with : Vmax -> Maximal production * S -> Substrate * I -> Effector * Km -> affinity between substrate and enzyme * Ki -> affinity between effector and enzyme * alpha -> Describe the competitivity of the effector (I) with the substrate (S). a >> 1 = competitive inhibition * a << 1 Uncompetitive inhibition * a = 1 Noncompetitive inhibition * beta -> Describe the extend of inhibition (< 1) or the extend of activation (> 1) * others configuration of beta and alpha are mixed inhibition. * * \reference http://depts.washington.edu/wmatkins/kinetics/inhibition.html * \return return the value that will be produce. * \param molecules The list of molecules. */ public float execEnzymeReaction(ArrayList molecules) { Molecule substrate = ReactionEngine.getMoleculeFromName(_substrate, molecules); Molecule enzyme = ReactionEngine.getMoleculeFromName(_enzyme, molecules); if (null == substrate) { Logger.Log("EnzymeReaction::react couldn't find substrate '" + _substrate + "'", Logger.Level.WARN); return(0); } if (null == enzyme) { Logger.Log("EnzymeReaction::react couldn't find enzyme '" + _enzyme + "'", Logger.Level.WARN); return(0); } float Vmax = _Kcat * enzyme.getConcentration(); float effectorConcentration = 0; if (_effector != "False") { Molecule effector = ReactionEngine.getMoleculeFromName(_effector, molecules); if (effector != null) { effectorConcentration = effector.getConcentration(); } else { Logger.Log("EnzymeReaction::react couldn't find effector '" + _effector + "'", Logger.Level.WARN); } } if (_alpha == 0) { _alpha = 0.0000000001f; Logger.Log("_alpha == 0", Logger.Level.WARN); } if (_Ki == 0) { _Ki = 0.0000000001f; Logger.Log("_Ki == 0", Logger.Level.WARN); } if (_Km == 0) { _Km = 0.0000000001f; Logger.Log("_Km == 0", Logger.Level.WARN); } float denominator = _alpha * _Km * _Ki; float bigDenominator = 1f + (substrate.getConcentration() / _Km) + (effectorConcentration / _Ki) + (substrate.getConcentration() * effectorConcentration / denominator); if (bigDenominator == 0) { Logger.Log("big denominator == 0", Logger.Level.WARN); return(0); } float v = ((Vmax * (substrate.getConcentration() / _Km)) + (_beta * Vmax * substrate.getConcentration() * effectorConcentration / denominator)) / bigDenominator; return(v); }
//! \brief Do all the allostery reaction for one tick /*! \details This function does this computation: * * delta = ( ([E] / K)^n ) / ( 1 + (([E] / K)^n) ) * [P] * [P] -= delta * [E] -= delta * [Prod] += delta * * With: * P -> Protein * E -> Effector * Prod -> Product * * * Reference : http://2007.igem.org/wiki/index.php?title=ETHZ/Model#Mathematical_Model * \param molecules Molecule list of the medium where the reaction take place */ public override void react(ArrayList molecules) { if (!_isActive) { return; } float delta; float m; Molecule effector = ReactionEngine.getMoleculeFromName(_effector, molecules); Molecule protein = ReactionEngine.getMoleculeFromName(_protein, molecules); Molecule product = ReactionEngine.getMoleculeFromName(_product, molecules); if (effector == null) { Debug.Log("Cannot find effector molecule named : " + effector); } else if (protein == null) { Debug.Log("Cannot find protein molecule named : " + protein); } else if (product == null) { Debug.Log("Cannot find product molecule named : " + product); } else { m = (float)Math.Pow(effector.getConcentration() / _K, _n); delta = (m / (1 + m)) * protein.getConcentration() * _reactionSpeed * ReactionEngine.reactionsSpeed; float energyCoef; float energyCostTot; if (delta > 0f && _energyCost > 0f && enableEnergy) { energyCostTot = _energyCost * delta; energyCoef = _medium.getEnergy() / energyCostTot; if (energyCoef > 1f) { energyCoef = 1f; } _medium.subEnergy(energyCostTot); } else { energyCoef = 1f; } delta *= energyCoef; if (enableSequential) { product.addConcentration(delta); protein.subConcentration(delta); effector.subConcentration(delta); } else { product.addNewConcentration(delta); protein.subNewConcentration(delta); effector.subNewConcentration(delta); } } }