using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Text.Json.Serialization; namespace BaseCellSimulation.Enzyms { public enum EnzymType { Hill, MichelisMenten, Linear } public struct Substrate { public string Name { get; set; } public double Amount { get; set; } /// /// mM /// [JsonPropertyName("Km")] public ValueRange Km { get; set; } [JsonPropertyName("Hill")] public ValueRange n_Hill { get; set; } } public struct Product { public string Name { get; set; } public double Amount { get; set; } } public class Enzym { [JsonPropertyName("Name")] public string Name { get; set; } /// /// mM/S /// [JsonPropertyName("Vmax")] public ValueRange Vmax { get; set; } [JsonPropertyName("Type")] public EnzymType Type { get; set; } [JsonPropertyName("ConsumATPtoADP")] public double ConsumATPtoADP { get; set; } [JsonPropertyName("ProduceATPfromADP")] public double ProduceATPfromADP { get; set; } [JsonPropertyName("ConsumATPtoAMP")] public double ConsumATPtoAMP { get; set; } [JsonPropertyName("ProduceATPfromAMP")] public double ProduceATPfromAMP { get; set; } [JsonPropertyName("ConsumeNADtoNADH")] public double ConsumeNADtoNADH { get; set; } [JsonPropertyName("ProduceNADfromNADH")] public double ProduceNADfromNADH { get; set; } [JsonPropertyName("ConsumeGDPtoGTP")] public double ConsumeGDPtoGTP { get; set; } [JsonPropertyName("ProduceGDPfromGTP")] public double ProduceGDPfromGTP { get; set; } [JsonPropertyName("Substrates")] public List Substrates { get; set; } = new List(); [JsonPropertyName("Products")] public List Products { get; set; } = new List(); protected double rate; protected double Michaelis_Menten(CellRessources res) { double retVar = Vmax.Value; foreach (Substrate substrate in Substrates) { if (!res.Resources.TryGetValue(substrate.Name, out double ResAmount)) return 0.0; if (ResAmount <= 0.0) return 0.0; retVar *= ResAmount / (substrate.Km.Value + ResAmount); } return retVar; } protected double HillEquation(CellRessources res) { double retVar = Vmax.Value; foreach (Substrate substrate in Substrates) { if (!res.Resources.TryGetValue(substrate.Name, out double ResAmount)) return 0.0; if (ResAmount <= 0.0) return 0.0; retVar *= Math.Pow(ResAmount, substrate.n_Hill.Value) / (Math.Pow(substrate.Km.Value, substrate.n_Hill.Value) + Math.Pow(ResAmount, substrate.n_Hill.Value)); } return retVar; } public void ApplyChanges(CellRessources res, double dt) { double delta = rate * dt; foreach (Substrate substrate in Substrates) { if (res.Resources.TryGetValue(substrate.Name, out double oldVal)) { delta = Math.Min(delta, oldVal / substrate.Amount); } } foreach (Substrate substrate in Substrates) { if (res.Resources.TryGetValue(substrate.Name, out double oldVal)) { res.Resources[substrate.Name] = oldVal - substrate.Amount * delta; } } foreach (Product product in Products) { if (res.Resources.ContainsKey(product.Name)) { res.Resources[product.Name] += product.Amount * delta; } else { res.Resources[product.Name] = product.Amount * delta; } } if(ConsumATPtoADP > 0.0) res.ConsumeATP(ConsumATPtoADP * delta, false); if(ProduceATPfromADP > 0.0) res.RegenerateATP(ProduceATPfromADP * delta, false); if(ConsumATPtoAMP > 0.0) res.ConsumeATP(ConsumATPtoAMP * delta, true); if(ProduceATPfromAMP > 0.0) res.RegenerateATP(ProduceATPfromAMP * delta, true); if(ConsumeNADtoNADH > 0.0) res.TransferNADH(ConsumeNADtoNADH * delta, true); if(ProduceNADfromNADH > 0.0) res.TransferNADH(ProduceNADfromNADH * delta, false); if(ConsumeGDPtoGTP > 0.0) res.TransferGTP(ConsumeGDPtoGTP * delta, true); if(ProduceGDPfromGTP > 0.0) res.TransferGTP(ProduceGDPfromGTP * delta, false); } public void ComputeRate(CellRessources res) { switch (Type) { case EnzymType.Hill: rate = HillEquation(res); break; case EnzymType.MichelisMenten: rate = Michaelis_Menten(res); break; case EnzymType.Linear: rate = Vmax.Value * res.Resources[Substrates[0].Name]; break; } } } public abstract class InternalEnzym : Enzym { public abstract void ComputeRate(Resources res); } public abstract class MembranEnzyme : Enzym { public abstract double CalculateGradient(CellRessources res); public abstract void ComputeRate(double gradient, EnviromentState Env); } }