InitalCommit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation
|
||||
{
|
||||
public struct cellInfo
|
||||
{
|
||||
public double time;
|
||||
public CellState state;
|
||||
public Dictionary<string, double> resources;
|
||||
public CellCaState caState;
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine($"Time: {time}, State: {state}");
|
||||
foreach (var kvp in resources)
|
||||
{
|
||||
sb.AppendLine($"{kvp.Key}: {kvp.Value}");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class Cell
|
||||
{
|
||||
private List<Organell> organelles = new();
|
||||
private CellRessources resources;
|
||||
private CellState state = CellState.Resting;
|
||||
private double time = 0.0;
|
||||
private Random rng = new();
|
||||
private CellCaState caState = new();
|
||||
|
||||
public EnviromentState EnviromentState { get { return resources.Env; } set { resources.Env = value; } }
|
||||
|
||||
public Cell()
|
||||
{
|
||||
organelles.Add(new Cytosol());
|
||||
organelles.Add(new Mitochondrion());
|
||||
organelles.Add(new Nucleus());
|
||||
organelles.Add(new Membrane());
|
||||
organelles.Add(new Lysosome());
|
||||
|
||||
resources = CellRessources.InitDefaults();
|
||||
|
||||
|
||||
// calcium baseline
|
||||
caState.CytosolicCa = 0.0001; // 100 nM
|
||||
caState.ER_Ca = 0.5; // 0.5 mM
|
||||
}
|
||||
|
||||
public void Step(double dt)
|
||||
{
|
||||
foreach (Organell organell in organelles)
|
||||
{
|
||||
organell.calculateRate(resources);
|
||||
}
|
||||
|
||||
foreach (Organell organell in organelles)
|
||||
{
|
||||
organell.applyChanges(resources, dt);
|
||||
}
|
||||
|
||||
CheckForDeath(dt);
|
||||
|
||||
time += dt;
|
||||
|
||||
}
|
||||
|
||||
private void CheckForDeath(double dt)
|
||||
{
|
||||
// Energie- und Calciumkritische Schwellen
|
||||
const double ATP_MIN = 0.05; // mM
|
||||
const double CA_TOXIC = 0.002; // 2 µM
|
||||
const double WASTE_MAX = 5.0; // mM
|
||||
|
||||
if (resources.Res.Energy.ATP < ATP_MIN || caState.CytosolicCa > CA_TOXIC || resources.Res.Protein.Waste > WASTE_MAX)
|
||||
{
|
||||
// langsamer Zelltod
|
||||
if (rng.NextDouble() < 0.1 * dt)
|
||||
state = CellState.Apoptosis;
|
||||
}
|
||||
|
||||
if (state == CellState.Apoptosis)
|
||||
{
|
||||
// Zelle verliert Ressourcen über Zeit
|
||||
resources.Res.Energy.ATP *= (1.0 - 0.05 * dt);
|
||||
resources.Res.Carbon.Glucose *= (1.0 - 0.03 * dt);
|
||||
resources.Res.Protein.AminoAcids *= (1.0 - 0.02 * dt);
|
||||
}
|
||||
}
|
||||
|
||||
public cellInfo GetCellInfo()
|
||||
{
|
||||
return new cellInfo
|
||||
{
|
||||
time = this.time,
|
||||
state = this.state,
|
||||
resources = new Dictionary<string, double>
|
||||
{
|
||||
{ "Glucose", resources.Res.Carbon.Glucose },
|
||||
{ "Oxygen", resources.Res.Oxygen },
|
||||
{ "ATP", resources.Res.Energy.ATP },
|
||||
{ "NAD", resources.Res.Energy.NAD },
|
||||
{ "NADH", resources.Res.Energy.NADH },
|
||||
{ "AminoAcids", resources.Res.Protein.AminoAcids }
|
||||
},
|
||||
caState = this.caState
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
using BaseCellSimulation.Enzyms;
|
||||
using BaseCellSimulation.Enzyms.Cytosol;
|
||||
using BaseCellSimulation.Enzyms.Cytosol.Ribosomen;
|
||||
|
||||
|
||||
namespace BaseCellSimulation
|
||||
{
|
||||
/// <summary>
|
||||
/// Cellliquid builds ATP and NADH out of Glucosis
|
||||
/// </summary>
|
||||
/// <param name="cellname"></param>
|
||||
/// <param name="vmax"></param>
|
||||
/// <param name="km"></param>
|
||||
public class Cytosol : Organell
|
||||
{
|
||||
public readonly List<InternalEnzym> enzyms = new List<InternalEnzym>();
|
||||
|
||||
double ROS_base_rate = 1e-6;
|
||||
|
||||
private readonly string name;
|
||||
|
||||
private double rosProduction;
|
||||
|
||||
private double vOx;
|
||||
|
||||
public Cytosol() : this("Cytosol") { }
|
||||
|
||||
public Cytosol(string cellname)
|
||||
{
|
||||
name = cellname;
|
||||
|
||||
enzyms.Add(new Aldolase());
|
||||
enzyms.Add(new AdenylateKinase());
|
||||
enzyms.Add(new Enolase());
|
||||
enzyms.Add(new GAPDH());
|
||||
enzyms.Add(new Hexokinasis());
|
||||
enzyms.Add(new Lactat_Dehydrogenase());
|
||||
enzyms.Add(new PhosphoFructokinase());
|
||||
enzyms.Add(new Phosphoglucose_Isomerase());
|
||||
enzyms.Add(new Phosphoglycerat_Kinase());
|
||||
enzyms.Add(new Phosphoglycerat_Mutase());
|
||||
enzyms.Add(new Pyruvat_Kinase());
|
||||
enzyms.Add(new Pyrophosphatase());
|
||||
enzyms.Add(new Methionin_Adenosyltransferase());
|
||||
enzyms.Add(new AHCY());
|
||||
enzyms.Add(new Methioninsynthase());
|
||||
enzyms.Add(new Ribosome());
|
||||
enzyms.Add(new AminoacylTRNASynthetase());
|
||||
enzyms.Add(new PeptidylTransferase());
|
||||
enzyms.Add(new NucleosideDiphosphateKinase());
|
||||
}
|
||||
|
||||
//Todo split in compute Rate and apply changes
|
||||
// Stoichiometrie: 1 Glu -> 2 ATP + 2 NADH (simplyfied)
|
||||
public void applyChanges(CellRessources Resources, double dt)
|
||||
{
|
||||
|
||||
|
||||
foreach (InternalEnzym enzym in enzyms)
|
||||
{
|
||||
enzym.ApplyChanges(Resources, dt);
|
||||
}
|
||||
|
||||
// Wenn O2 vorhanden: Pyruvat->CO2 + NADH via PDH/ TCA(vereinfacht)
|
||||
// Simpler oxidativer Pfad (nur wenn genug O2)
|
||||
|
||||
double oxUsage = Math.Min(Resources.Res.Carbon.Pyruvate, vOx * dt); // skaliert mit O2
|
||||
Resources.Res.Carbon.Pyruvate -= oxUsage;
|
||||
Resources.Res.Carbon.CO2 += oxUsage; // CO2 als Waste
|
||||
Resources.Res.Oxygen -= 6.0 * oxUsage; // oxidativer Stoffwechsel erzeugt NADH (vereinfachung) und ATP (nicht durch Glykolyse)
|
||||
Resources.TransferNADH(3.0 * oxUsage, false); // Beispielzahl
|
||||
Resources.RegenerateATP(12.0 * oxUsage); // sehr grobe Näherung für oxidative Phosphorylierung
|
||||
|
||||
//ROS - Produktion: steigt mit hohem NADH/ NAD Verhältnis und mittlerem / hohem O2
|
||||
Resources.Res.Ions.ROS += rosProduction * dt;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public string getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void calculateRate(CellRessources res)
|
||||
{
|
||||
foreach (InternalEnzym enzym in enzyms)
|
||||
{
|
||||
enzym.ComputeRate(res.Res);
|
||||
}
|
||||
double oxscaled = res.Res.Oxygen * 1000;
|
||||
vOx = (oxscaled > 1e-3 && res.Res.Carbon.Pyruvate > 0) ? 0.5 * (oxscaled / (oxscaled + 5.0)) : 0.0;
|
||||
if (oxscaled > 1e-3 && res.Res.Carbon.Pyruvate > 0)
|
||||
{
|
||||
}
|
||||
|
||||
double redoxRatio = (res.Res.Energy.NADH + 1e-12) / Math.Max(1e-12, res.Res.Energy.NAD);
|
||||
rosProduction = ROS_base_rate * redoxRatio * (oxscaled / (oxscaled + 5.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class AHCY : InternalEnzym
|
||||
{
|
||||
public AHCY()
|
||||
{
|
||||
Km = 0.02;
|
||||
Vmax = 0.3;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dSAH = Math.Min(rate * dt, res.Res.Protein.SAH);
|
||||
res.Res.Protein.SAH -= dSAH;
|
||||
res.Res.Protein.Homocystein += dSAH;
|
||||
res.Res.Protein.Adenosin += dSAH;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.SAH);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class AdenylateKinase : InternalEnzym
|
||||
{
|
||||
public AdenylateKinase()
|
||||
{
|
||||
Km = 0.1;
|
||||
Vmax = 5;
|
||||
Keq = 1.1;
|
||||
|
||||
KmRange = new(0.01, 0.5);
|
||||
VmaxRange = new(0.5, 15);
|
||||
KeqRange = new(0.9, 1.2);
|
||||
}
|
||||
|
||||
public double Keq { get; set; }
|
||||
|
||||
public ValueRange KeqRange;
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double d = rate * dt;
|
||||
|
||||
// Begrenzen, damit keine negativen Konzentrationen entstehen
|
||||
if (d > 0.0)
|
||||
{
|
||||
// Vorwärtsrichtung: 2 ADP -> ATP + AMP
|
||||
double limit = Math.Min(res.Res.Energy.ADP / 2.0, d);
|
||||
res.Res.Energy.ADP -= 2.0 * limit;
|
||||
res.Res.Energy.ATP += limit;
|
||||
res.Res.Energy.AMP += limit;
|
||||
}
|
||||
else if (d < 0.0)
|
||||
{
|
||||
// Rückwärtsrichtung: ATP + AMP -> 2 ADP
|
||||
double limit = Math.Min(Math.Min(res.Res.Energy.ATP, res.Res.Energy.AMP), -d);
|
||||
res.Res.Energy.ADP += 2.0 * limit;
|
||||
res.Res.Energy.ATP -= limit;
|
||||
res.Res.Energy.AMP -= limit;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
double numerator = res.Energy.ADP * res.Energy.ADP - res.Energy.ATP * res.Energy.AMP / Keq;
|
||||
double denominator = Km * Km + res.Energy.ADP * res.Energy.ADP;
|
||||
|
||||
rate = Vmax * (numerator / denominator); // Nettoreaktionsrate in mM/s
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Aldolase : InternalEnzym
|
||||
{
|
||||
public Aldolase()
|
||||
{
|
||||
Km = 0.1;
|
||||
Vmax = 10;
|
||||
|
||||
KmRange = new(0.01, 0.3);
|
||||
VmaxRange = new(2, 20);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, res.Res.Carbon.FBP);
|
||||
res.Res.Carbon.FBP -= used;
|
||||
res.Res.Carbon.GAP += 2 * used;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.FBP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Enolase : InternalEnzym
|
||||
{
|
||||
public Enolase()
|
||||
{
|
||||
Km = 0.1;
|
||||
Vmax = 10;
|
||||
|
||||
KmRange = new(0.01, 0.3);
|
||||
VmaxRange = new(2, 25);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, res.Res.Carbon.PG2);
|
||||
|
||||
res.Res.Carbon.PG2 -= used;
|
||||
res.Res.Carbon.PEP += used;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.PG2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class GAPDH : InternalEnzym
|
||||
{
|
||||
public GAPDH()
|
||||
{
|
||||
Km = 0.1;
|
||||
Km_NAD = 0.075;
|
||||
|
||||
Vmax = 10;
|
||||
|
||||
KmRange = new(0.01, 0.5);
|
||||
VmaxRange = new(2, 25);
|
||||
Km_NAD_Range = new(0.01, 0.2);
|
||||
}
|
||||
public double Km_NAD { get; set; }
|
||||
|
||||
public ValueRange Km_NAD_Range { get; private set; }
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, Math.Min(res.Res.Carbon.GAP, res.Res.Energy.NAD));
|
||||
res.Res.Carbon.GAP -= used;
|
||||
res.Res.Carbon.PBG13 += used;
|
||||
res.TransferNADH(used, false);
|
||||
res.Res.Ions.Protons += 1.0 * used;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
rate = Vmax * (res.Carbon.GAP / (Km + res.Carbon.GAP)) * (res.Energy.NAD / (Km_NAD + res.Energy.NAD));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Hexokinasis : InternalEnzym
|
||||
{
|
||||
public Hexokinasis() {
|
||||
Km = 0.05;
|
||||
Vmax = 5;
|
||||
|
||||
KmRange = new(0.01, 0.1);
|
||||
VmaxRange = new(0.5, 20);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, Math.Min(res.Res.Carbon.Glucose, res.Res.Energy.ATP));
|
||||
res.Res.Carbon.Glucose -= used;
|
||||
res.Res.Carbon.G6P += used;
|
||||
res.ConsumeATP(used);
|
||||
res.Res.Ions.Protons += used;
|
||||
}
|
||||
|
||||
//todo noch machen dass atpberücksichtigt wird
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.Glucose);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Lactat_Dehydrogenase : InternalEnzym
|
||||
{
|
||||
public Lactat_Dehydrogenase()
|
||||
{
|
||||
Km = 0.5;
|
||||
Vmax = 10;
|
||||
|
||||
KmRange = new(0.05,2);
|
||||
VmaxRange = new(2, 25);
|
||||
|
||||
Km_NADH = 0.05;
|
||||
Km_NADH_Range = new(0.005, 0.2);
|
||||
}
|
||||
|
||||
public double Km_NADH { get; set; }
|
||||
|
||||
public ValueRange Km_NADH_Range { get; set; }
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, Math.Min(res.Res.Carbon.Pyruvate, res.Res.Energy.NADH));
|
||||
|
||||
//LDH Lactat production and NAD+ regeneration
|
||||
res.Res.Carbon.Pyruvate -= used;
|
||||
res.Res.Carbon.Lactate += used;
|
||||
res.TransferNADH(used,true);
|
||||
|
||||
//Consume Protons
|
||||
res.Res.Ions.Protons -= 1.0 * used;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
double oxscaled = res.Oxygen * 1000;
|
||||
double o2Factor = Math.Max(0.0, 1.0 - oxscaled / (oxscaled + 10.0));
|
||||
rate = Vmax * o2Factor
|
||||
* (res.Carbon.Pyruvate / (Km + res.Carbon.Pyruvate))
|
||||
* (res.Energy.NADH / (Km_NADH + res.Energy.NADH));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using BaseCellSimulation.Enzyms.Membrane;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.WebRequestMethods;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Methionin_Adenosyltransferase : InternalEnzym
|
||||
{
|
||||
public double Km_ATP { get; set; }
|
||||
|
||||
public Methionin_Adenosyltransferase()
|
||||
{
|
||||
Km = 0.05;
|
||||
Vmax = 0.5;
|
||||
Km_ATP = 0.2;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dSAM = Math.Min(rate * dt,res.Res.Energy.ATP);
|
||||
res.Res.Protein.MET -= dSAM;
|
||||
res.Res.Protein.SAM += dSAM;
|
||||
res.Res.Energy.ATP -= dSAM;
|
||||
res.Res.Phosphate.PPi += dSAM;
|
||||
res.Res.Phosphate.Pi += dSAM;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
rate = Vmax * (res.Protein.MET / (Km + res.Protein.MET)) * (res.Energy.ATP / (Km_ATP + res.Energy.ATP));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Methioninsynthase : InternalEnzym
|
||||
{
|
||||
public Methioninsynthase()
|
||||
{
|
||||
Km = 0.015;
|
||||
Vmax = 0.2;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
// Berechne tatsächlich mögliche Umwandlung
|
||||
double dHcy = Math.Min(rate * dt, res.Res.Protein.Homocystein);
|
||||
dHcy = Math.Min(dHcy, res.Res.Folate.MethylTHF);
|
||||
dHcy = Math.Min(dHcy, res.Res.Cofactor.B12); // Co-Faktor limitierend
|
||||
|
||||
if (dHcy <= 0)
|
||||
return;
|
||||
|
||||
// Verbrauch von Substraten
|
||||
res.Res.Protein.Homocystein -= dHcy;
|
||||
res.Res.Folate.MethylTHF -= dHcy;
|
||||
|
||||
// Cofaktor-B12 wird nicht dauerhaft verbraucht (Katalytisch)
|
||||
// kann aber langsam inaktiviert werden, falls du das modellieren willst
|
||||
|
||||
// Bildung von Produkten
|
||||
res.Res.Protein.MET += dHcy;
|
||||
res.Res.Folate.THF += dHcy;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
// Aktivitätsfaktor abhängig vom verfügbaren B12
|
||||
double cofactorEffect = Math.Clamp(res.Cofactor.B12 / 0.01, 0.0, 1.0);
|
||||
|
||||
// Michaelis-Menten über Homocystein
|
||||
Michaelis_Menten(res.Protein.Homocystein);
|
||||
|
||||
rate *= cofactorEffect;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class NucleosideDiphosphateKinase : InternalEnzym
|
||||
{
|
||||
private const double k_eq = 0.25; // 0.25 / s → recht schnell, da NDK sehr aktiv ist
|
||||
|
||||
public NucleosideDiphosphateKinase()
|
||||
{
|
||||
Km = 0.05; // unspezifisch, da das Enzym viele Nukleotide akzeptiert
|
||||
Vmax = 1.0; // fiktiver Maximalumsatz (mmol/L·s)
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
var energy = res.Res.Energy;
|
||||
|
||||
// --- Austausch zwischen ATP und GTP ---
|
||||
double delta = (energy.ATP - energy.GTP) * k_eq * dt;
|
||||
|
||||
if (Math.Abs(delta) < 1e-9)
|
||||
return;
|
||||
|
||||
// Begrenzung: kein negativer Pool
|
||||
if (delta > 0)
|
||||
{
|
||||
delta = Math.Min(delta, energy.ATP);
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = Math.Max(delta, -energy.GTP);
|
||||
}
|
||||
|
||||
// Umsetzung: ATP -> GTP oder umgekehrt
|
||||
energy.ATP -= delta;
|
||||
energy.GTP += delta;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
double diff = Math.Abs(res.Energy.ATP - res.Energy.GTP);
|
||||
Michaelis_Menten(diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.WebRequestMethods;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class PhosphoFructokinase : InternalEnzym
|
||||
{
|
||||
public PhosphoFructokinase()
|
||||
{
|
||||
Km = 0.2;
|
||||
Vmax = 7;
|
||||
|
||||
KmRange = new(0.05, 0.5);
|
||||
VmaxRange = new(1, 25);
|
||||
}
|
||||
|
||||
public double Ki_ATP_PFK { get; set; }
|
||||
public double Ka_AMP_PFK { get; set; }
|
||||
public double h_AMP { get; set; }
|
||||
public double h_ATP { get; set; }
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, Math.Min(res.Res.Energy.ATP, res.Res.Carbon.F6P));
|
||||
res.Res.Carbon.F6P -= used;
|
||||
res.Res.Carbon.FBP += used;
|
||||
res.ConsumeATP(used);
|
||||
res.Res.Ions.Protons += used;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
double inhibition = 1.0 / (1.0 + Math.Pow(res.Energy.ATP / Ki_ATP_PFK, h_ATP)); // Hemmung durch ATP
|
||||
double activation = 1.0 + Math.Pow(res.Energy.AMP / Ka_AMP_PFK, h_AMP); // Aktivierung durch AMP
|
||||
rate = Michaelis_Menten(res.Carbon.F6P, Vmax * inhibition * activation, Km);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Phosphoglucose_Isomerase : InternalEnzym
|
||||
{
|
||||
public Phosphoglucose_Isomerase()
|
||||
{
|
||||
Km = 0.1;
|
||||
Vmax = 10;
|
||||
|
||||
KmRange = new(0.05, 0.2);
|
||||
VmaxRange = new(0.5, 30);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, res.Res.Carbon.G6P);
|
||||
res.Res.Carbon.G6P -= used;
|
||||
res.Res.Carbon.F6P += used;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.G6P);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Phosphoglycerat_Kinase : InternalEnzym
|
||||
{
|
||||
public Phosphoglycerat_Kinase()
|
||||
{
|
||||
Vmax = 10;
|
||||
Km = 0.1;
|
||||
|
||||
KmRange = new(0.01, 0.3);
|
||||
VmaxRange = new(2, 30);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, res.Res.Carbon.PBG13);
|
||||
res.Res.Carbon.PBG13 -= used;
|
||||
res.Res.Carbon.PG3 += used;
|
||||
res.RegenerateATP(used);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.PBG13);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Phosphoglycerat_Mutase : InternalEnzym
|
||||
{
|
||||
public Phosphoglycerat_Mutase()
|
||||
{
|
||||
Km = 0.1;
|
||||
Vmax = 10;
|
||||
|
||||
VmaxRange = new(2, 30);
|
||||
KmRange = new(0.01, 0.3);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, res.Res.Carbon.PG3);
|
||||
res.Res.Carbon.PG3 -= used;
|
||||
res.Res.Carbon.PG2 += used;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.PG3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Pyrophosphatase : InternalEnzym
|
||||
{
|
||||
public Pyrophosphatase()
|
||||
{
|
||||
Vmax = 2.0;
|
||||
Km = 0.01;
|
||||
|
||||
VmaxRange = new(1, 10);
|
||||
KmRange = new(0.001, 0.05);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dPPi = Math.Max(rate, res.Res.Phosphate.PPi);
|
||||
res.HydrolyzePPi(dPPi);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Phosphate.PPi);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol
|
||||
{
|
||||
public class Pyruvat_Kinase : InternalEnzym
|
||||
{
|
||||
public Pyruvat_Kinase()
|
||||
{
|
||||
Km = 0.1;
|
||||
Vmax = 10;
|
||||
|
||||
KmRange = new(0.01, 0.3);
|
||||
VmaxRange = new(2, 25);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, res.Res.Carbon.PEP);
|
||||
res.Res.Carbon.PEP -= used;
|
||||
res.Res.Carbon.Pyruvate += used;
|
||||
res.RegenerateATP(used);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.PEP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol.Ribosomen
|
||||
{
|
||||
public class AminoacylTRNASynthetase : InternalEnzym
|
||||
{
|
||||
public AminoacylTRNASynthetase()
|
||||
{
|
||||
Km = 0.1;
|
||||
Vmax = 1.5;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dAAtRNA = Math.Min(rate * dt, Math.Min(res.Res.Protein.AminoAcids, res.Res.Protein.tRNA));
|
||||
dAAtRNA = Math.Min(dAAtRNA, res.Res.Energy.ATP);
|
||||
|
||||
res.Res.Protein.AminoAcids -= dAAtRNA;
|
||||
res.Res.Protein.tRNA -= dAAtRNA;
|
||||
res.Res.Protein.Aminoacyl_tRNA += dAAtRNA;
|
||||
res.ConsumeATP(dAAtRNA);
|
||||
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.tRNA);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol.Ribosomen
|
||||
{
|
||||
public class PeptidylTransferase : InternalEnzym
|
||||
{
|
||||
public PeptidylTransferase()
|
||||
{
|
||||
Km = 0.05;
|
||||
Vmax = 5.0;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dPeptide = Math.Min(rate * dt, Math.Min(res.Res.Protein.Aminoacyl_tRNA, res.Res.Energy.GTP));
|
||||
|
||||
res.Res.Protein.Aminoacyl_tRNA -= dPeptide;
|
||||
res.Res.Protein.FunctionalProteins += dPeptide;
|
||||
res.Res.Energy.GTP -= dPeptide;
|
||||
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.Aminoacyl_tRNA);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol.Ribosomen
|
||||
{
|
||||
public class Ribosome : InternalEnzym
|
||||
{
|
||||
private TranslationFactor initiation;
|
||||
private TranslationFactor elongation;
|
||||
private TranslationFactor termination;
|
||||
|
||||
private const double ProteinPermRNA = 20.0;
|
||||
|
||||
int ribosomenState = 0;
|
||||
|
||||
public Ribosome()
|
||||
{
|
||||
Km = 0.5; // fiktiv (abhängig von mRNA)
|
||||
Vmax = 10.0; // z. B. 10 Aminosäuren pro Sekunde
|
||||
initiation = new TranslationFactor(TranslationFactor.FactorType.Initiation);
|
||||
elongation = new TranslationFactor(TranslationFactor.FactorType.Elongation);
|
||||
termination = new TranslationFactor(TranslationFactor.FactorType.Termination);
|
||||
}
|
||||
|
||||
private double availableAA = 0;
|
||||
private double dProtein = 0;
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
int safety = 0;
|
||||
while (safety++ < 10)
|
||||
{
|
||||
switch (ribosomenState)
|
||||
{
|
||||
|
||||
case 0:
|
||||
availableAA = res.Res.Protein.AminoAcids;
|
||||
dProtein = rate * dt;
|
||||
// Translation start -> Initiationsfaktoren verbrauchen GTP
|
||||
initiation.ApplyChanges(res, dt * 0.5);
|
||||
if (initiation.TranslationSpeed > 0)
|
||||
{
|
||||
dProtein = Math.Min(initiation.TranslationSpeed, dProtein);
|
||||
dProtein = Math.Min(dProtein, Math.Min(res.Res.Protein.mRNA, availableAA));
|
||||
res.Res.Protein.AminoAcids -= dProtein;
|
||||
res.Res.Protein.FunctionalProteins += dProtein;
|
||||
ribosomenState = 1;
|
||||
}
|
||||
else return;
|
||||
break;
|
||||
case 1:
|
||||
elongation.ApplyChanges(res, dt * dProtein * 0.1);
|
||||
if (elongation.TranslationSpeed > 0)
|
||||
{
|
||||
dProtein = Math.Min(elongation.TranslationSpeed, dProtein);
|
||||
// mRNA-Abnutzung: jede mRNA kann nur begrenzt oft benutzt werden
|
||||
double used_mRNA = dProtein / ProteinPermRNA;
|
||||
res.Res.Protein.mRNA -= used_mRNA;
|
||||
|
||||
// Abbauprodukte: ein Teil recycelt, ein Teil wird zu Waste
|
||||
double degraded = used_mRNA * 0.8;
|
||||
double lost = used_mRNA * 0.2;
|
||||
res.Res.Protein.Nucleotides += degraded; // Rückgewinn von Basen
|
||||
res.Res.Protein.Waste += lost; // Restliche RNA-Fragmente als Zellabfall
|
||||
ribosomenState = 2;
|
||||
}
|
||||
|
||||
else return;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
termination.ApplyChanges(res, dt * 0.01 * dProtein);
|
||||
if (termination.TranslationSpeed > 0)
|
||||
{
|
||||
res.ConsumeATP(dProtein * 4); // z. B. 4 ATP pro Peptidbindung -> ADP
|
||||
ribosomenState = 0;
|
||||
}
|
||||
else return;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
if (ribosomenState == 0) {
|
||||
if (res.Protein.AminoAcids <= 0.0 || res.Protein.mRNA <= 0.0)
|
||||
return;
|
||||
|
||||
double availablemRNA = res.Protein.mRNA;
|
||||
Michaelis_Menten(availablemRNA);
|
||||
initiation.ComputeRate(res);
|
||||
elongation.ComputeRate(res);
|
||||
termination.ComputeRate(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Cytosol.Ribosomen
|
||||
{
|
||||
/*
|
||||
* Faktor Aufgabe Energieverbrauch
|
||||
* IF (Initiation Factors) Ribosom startet Translation 1 GTP
|
||||
* EF-Tu, EF-G (Elongation) tRNA Positionierung, Translokation 1–2 GTP pro Zyklus
|
||||
* RF (Release Factors) Beendet Translation an Stoppcodon 1 GTP
|
||||
*/
|
||||
internal class TranslationFactor : InternalEnzym
|
||||
{
|
||||
public enum FactorType { Initiation, Elongation, Termination }
|
||||
public FactorType Type { get; }
|
||||
|
||||
public double TranslationSpeed;
|
||||
|
||||
public TranslationFactor(FactorType type)
|
||||
{
|
||||
Type = type;
|
||||
Km = 0.1;
|
||||
Vmax = 2.0;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Energy.GTP);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(rate * dt, res.Res.Energy.GTP);
|
||||
|
||||
res.Res.Energy.GTP -= used;
|
||||
res.Res.Energy.GDP += used;
|
||||
TranslationSpeed = used;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms
|
||||
{
|
||||
public abstract class Enzym
|
||||
{
|
||||
/// <summary>
|
||||
/// mM/S
|
||||
/// </summary>
|
||||
public double Vmax { get; set; }
|
||||
/// <summary>
|
||||
/// mM
|
||||
/// </summary>
|
||||
public double Km { get; set; }
|
||||
|
||||
public ValueRange VmaxRange { get; protected set; }
|
||||
|
||||
public ValueRange KmRange { get; protected set; }
|
||||
|
||||
protected double rate;
|
||||
|
||||
protected void Michaelis_Menten(double ressource)
|
||||
{
|
||||
rate = Michaelis_Menten(ressource, Vmax, Km);
|
||||
}
|
||||
|
||||
protected double Michaelis_Menten(double consumable,double vmax, double km)
|
||||
{
|
||||
return (vmax * consumable) / (km + consumable);
|
||||
}
|
||||
|
||||
public abstract void ApplyChanges(CellRessources res, double dt);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Lysosome
|
||||
{
|
||||
public class Cathepsin : InternalEnzym
|
||||
{
|
||||
public Cathepsin()
|
||||
{
|
||||
Vmax = 0.2; // mM/s, empirisch
|
||||
Km = 0.1; // mM
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.Waste);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double degraded = rate * dt;
|
||||
degraded = Math.Min(degraded, res.Res.Protein.Waste);
|
||||
|
||||
res.Res.Protein.Waste -= degraded;
|
||||
res.Res.Protein.AminoAcids += degraded * 0.5; // 50% verwertbar
|
||||
res.Res.Energy.ATP += degraded * 0.05; // kleine ATP-Rückgewinnung
|
||||
res.Res.Energy.NADH += degraded * 0.01; // minimale Redoxreaktion
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Lysosome
|
||||
{
|
||||
public class GenericLysosomalEnzyme : InternalEnzym
|
||||
{
|
||||
public GenericLysosomalEnzyme()
|
||||
{
|
||||
Vmax = 0.2;
|
||||
Km = 0.1;
|
||||
}
|
||||
|
||||
double redoxRatio = 0.0;
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
// --- Grundrate basierend auf Protein-Waste ---
|
||||
rate = Michaelis_Menten(res.Protein.Waste, Vmax, Km);
|
||||
|
||||
// --- Energieabhängigkeit ---
|
||||
double energyCharge = (res.Energy.ATP + 0.5 * res.Energy.ADP) /
|
||||
(res.Energy.ATP + res.Energy.ADP + res.Energy.AMP + 1e-9);
|
||||
rate *= Math.Clamp(energyCharge, 0.0, 1.0);
|
||||
|
||||
// --- Redoxabhängigkeit ---
|
||||
redoxRatio = res.Energy.NAD / (res.Energy.NAD + res.Energy.NADH + 1e-9);
|
||||
rate *= Math.Clamp(redoxRatio, 0.0, 1.0);
|
||||
|
||||
// --- pH-Abhängigkeit ---
|
||||
double acidFactor = 1.0 - 0.5 * Math.Clamp(res.Ions.Protons / 1.0, 0.0, 1.0);
|
||||
rate *= acidFactor;
|
||||
|
||||
// --- Stressfaktor bei hohen ROS ---
|
||||
double stressPenalty = res.Ions.ROS > 1.0 ? 0.5 : 1.0;
|
||||
rate *= stressPenalty;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources Resources, double dt)
|
||||
{
|
||||
var res = Resources.Res;
|
||||
var ca = Resources.Res.Ca;
|
||||
|
||||
ComputeRate(res);
|
||||
|
||||
double degraded = Math.Min(res.Protein.Waste, rate * dt);
|
||||
if (degraded <= 0.0)
|
||||
return;
|
||||
|
||||
// --- Protein-Abbau ---
|
||||
res.Protein.Waste -= degraded;
|
||||
|
||||
// --- Energieverbrauch & minimale Rückgewinnung ---
|
||||
double atpUsed = degraded * 0.15;
|
||||
double atpRecovered = degraded * 0.03 * ((res.Energy.ATP + 0.5 * res.Energy.ADP) /
|
||||
(res.Energy.ATP + res.Energy.ADP + res.Energy.AMP + 1e-9));
|
||||
Resources.ConsumeATP(atpUsed);
|
||||
res.Energy.ATP += atpRecovered;
|
||||
|
||||
// --- NAD+ → NADH Redoxreaktion ---
|
||||
double nadUsed = degraded * 0.08;
|
||||
double actualNadUsed = Math.Min(nadUsed, res.Energy.NAD);
|
||||
res.Energy.NAD -= actualNadUsed;
|
||||
res.Energy.NADH += actualNadUsed;
|
||||
|
||||
// --- Aminosäuren-Recycling ---
|
||||
double recyclingEfficiency = 0.4 + 0.3 * ((res.Energy.ATP + 0.5 * res.Energy.ADP) /
|
||||
(res.Energy.ATP + res.Energy.ADP + res.Energy.AMP + 1e-9));
|
||||
res.Protein.AminoAcids += degraded * recyclingEfficiency;
|
||||
|
||||
// --- Sekundäre Effekte: ROS, Heat, Protonen ---
|
||||
res.Ions.ROS += degraded * (1.0 - redoxRatio) * 0.01;
|
||||
res.Heat += degraded * 0.05;
|
||||
res.Ions.Protons += degraded * 0.005;
|
||||
|
||||
// --- Kalziumleckage als Stresssignal ---
|
||||
ca.CytosolicCa += degraded * 0.00002;
|
||||
|
||||
// --- Lysosomenaktivität für Feedback ---
|
||||
ca.LysosomeActivity = Math.Clamp(rate / Vmax, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Lysosome
|
||||
{
|
||||
public class LysosomalLipase : InternalEnzym
|
||||
{
|
||||
public LysosomalLipase()
|
||||
{
|
||||
Vmax = 0.1;
|
||||
Km = 0.05;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Lipids); // falls Lipide modelliert werden
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double degraded = rate * dt;
|
||||
degraded = Math.Min(degraded, res.Res.Lipids);
|
||||
|
||||
res.Res.Lipids -= degraded;
|
||||
res.Res.Energy.ATP += degraded * 0.02; // minimaler ATP Gewinn
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Lysosome
|
||||
{
|
||||
public class LysosomalNuclease : InternalEnzym
|
||||
{
|
||||
public LysosomalNuclease()
|
||||
{
|
||||
Vmax = 0.15;
|
||||
Km = 0.05;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.NucleicAcids); // falls RNA/DNA modelliert
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double degraded = rate * dt;
|
||||
degraded = Math.Min(degraded, res.Res.Protein.NucleicAcids);
|
||||
|
||||
res.Res.Protein.NucleicAcids -= degraded;
|
||||
res.Res.Protein.Nucleotides += degraded; // freiwerdende Nucleotide
|
||||
res.Res.Energy.ATP += degraded * 0.01;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Lysosome
|
||||
{
|
||||
public class LysosomalPhosphatase : InternalEnzym
|
||||
{
|
||||
public LysosomalPhosphatase()
|
||||
{
|
||||
Vmax = 0.1;
|
||||
Km = 0.05;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.PhosphorylatedSubstrates);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double degraded = rate * dt;
|
||||
degraded = Math.Min(degraded, res.Res.PhosphorylatedSubstrates);
|
||||
|
||||
res.Res.PhosphorylatedSubstrates -= degraded;
|
||||
res.Res.Phosphate.Pi += degraded;
|
||||
res.Res.Phosphate.PPi += degraded * 0.1; // falls Pyrophosphat entsteht
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane.GLUT
|
||||
{
|
||||
public class GLUT1 : MembranEnzyme
|
||||
{
|
||||
public GLUT1()
|
||||
{
|
||||
Km = 1.5; // Example Km value in mM
|
||||
Vmax = 0.5;
|
||||
|
||||
KmRange = new(1.0, 3.0);
|
||||
VmaxRange = new(0.1, 10.0);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double flux = Math.Min(res.Env.Glucose, rate * dt);
|
||||
res.Env.Glucose -= flux;
|
||||
res.Res.Carbon.Glucose += flux;
|
||||
}
|
||||
|
||||
public override double CalculateGradient(CellRessources res)
|
||||
{
|
||||
return res.Env.Glucose - res.Res.Carbon.Glucose;
|
||||
}
|
||||
|
||||
public override void ComputeRate(double gradient, EnviromentState Env)
|
||||
{
|
||||
if (gradient <= 0)
|
||||
{
|
||||
rate = 0;
|
||||
return;
|
||||
}
|
||||
Michaelis_Menten(gradient);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane.GLUT
|
||||
{
|
||||
public class GLUT2 : GLUT1
|
||||
{
|
||||
public GLUT2()
|
||||
{
|
||||
Km = 17.0; // Example Km value in mM
|
||||
Vmax = 1.2;
|
||||
|
||||
KmRange = new(15.0, 20.0);
|
||||
VmaxRange = new(1.0, 50.0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane.GLUT
|
||||
{
|
||||
public class GLUT3 : GLUT1
|
||||
{
|
||||
public GLUT3()
|
||||
{
|
||||
Km = 1.0;
|
||||
Vmax = 0.8;
|
||||
|
||||
KmRange = new(0.3, 1.0);
|
||||
VmaxRange = new(0.5, 20.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane.GLUT
|
||||
{
|
||||
public class GLUT4 : GLUT1
|
||||
{
|
||||
public GLUT4()
|
||||
{
|
||||
Km = 5.0; // Example Km value in mM for GLUT4
|
||||
Vmax = 0.6; // Higher Vmax for GLUT4
|
||||
ActivationThreshold = 0.3; // Example threshold for insulin activation
|
||||
|
||||
KmRange = new(4.0, 6.0);
|
||||
VmaxRange = new(0.2, 15.0);
|
||||
}
|
||||
|
||||
public double ActivationThreshold { get; set; }
|
||||
|
||||
public override void ComputeRate(double gradient, EnviromentState Env)
|
||||
{
|
||||
if (gradient <= 0)
|
||||
{
|
||||
rate = 0;
|
||||
return;
|
||||
}
|
||||
// GLUT4 is insulin-responsive, so we can add an insulin factor
|
||||
double insulinFactor = 0.5 * (Math.Tanh((Env.Insulin - ActivationThreshold) / 0.1) + 1.0); // Example: insulin increases rate up to 3x
|
||||
Michaelis_Menten(gradient);
|
||||
rate *= insulinFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane
|
||||
{
|
||||
public class KLeakChannel : MembranEnzyme
|
||||
{
|
||||
public double Permeability = 0.01; // 1/s, diffusionsbasiert
|
||||
|
||||
public override void ComputeRate(double gradient, EnviromentState env)
|
||||
{
|
||||
rate = Permeability * gradient;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double flux = rate * dt;
|
||||
res.Res.Ions.K -= flux; // aus der Zelle raus
|
||||
res.Env.K += flux;
|
||||
}
|
||||
|
||||
public override double CalculateGradient(CellRessources res)
|
||||
{
|
||||
return res.Res.Ions.K - res.Env.K;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane
|
||||
{
|
||||
public class MCT : MembranEnzyme
|
||||
{
|
||||
|
||||
public override double CalculateGradient(CellRessources res)
|
||||
{
|
||||
double hGradient = Math.Pow(10, -res.pH_in) / Math.Pow(10, -res.pH_ext);
|
||||
return res.Res.Carbon.Lactate - res.Env.Lactate * hGradient;
|
||||
}
|
||||
|
||||
public override void ComputeRate(double Gradient, EnviromentState env)
|
||||
{
|
||||
if (Gradient <= 0)
|
||||
{
|
||||
rate = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
Michaelis_Menten(Gradient);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double flux = rate * dt;
|
||||
|
||||
res.Res.Carbon.Lactate -= flux; // Laktat raus
|
||||
res.Env.Lactate += flux;
|
||||
res.Res.Ions.Protons -= flux; // Protonen raus (Symport)
|
||||
res.Env.Protons += flux;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane
|
||||
{
|
||||
/// <summary>
|
||||
/// Na+/Ca2+ Exchanger (3 Na⁺ in / 1 Ca²⁺ out)
|
||||
/// Einfaches Michaelis-Menten-basiertes Modell mit Gradienten
|
||||
/// </summary>
|
||||
public class NCX : MembranEnzyme
|
||||
{
|
||||
public double NaStoich = 3.0; // Na⁺ pro Ca²⁺
|
||||
public double CaStoich = 1.0;
|
||||
|
||||
/// <summary>
|
||||
/// Berechnet die Transport-Rate abhängig von zellinternen und externen Ionenkonzentrationen
|
||||
/// </summary>
|
||||
public override void ComputeRate(double gradient, EnviromentState env)
|
||||
{
|
||||
|
||||
// Michaelis-Menten-ähnliche Sättigung
|
||||
rate = Vmax * gradient / (Km + Math.Abs(gradient));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wendet den Transport auf die Zellressourcen an
|
||||
/// </summary>
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double flux = rate * dt;
|
||||
|
||||
// Na+ in die Zelle
|
||||
res.Res.Ions.Na += NaStoich * flux;
|
||||
res.Env.Na -= NaStoich * flux;
|
||||
|
||||
// Ca2+ aus der Zelle
|
||||
res.Res.Ca.CytosolicCa -= CaStoich * flux;
|
||||
res.Env.Ca += CaStoich * flux;
|
||||
|
||||
}
|
||||
|
||||
public override double CalculateGradient(CellRessources res)
|
||||
{
|
||||
// Gradienten: innen - außen
|
||||
double naGradient = res.Res.Ions.Na - res.Env.Na; // mM
|
||||
double caGradient = res.Res.Ca.CytosolicCa - res.Env.Ca; // mM
|
||||
|
||||
// Richtung: positiv = Ca raus / Na rein
|
||||
return (naGradient / NaStoich) - (caGradient / CaStoich);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane
|
||||
{
|
||||
public class NaK_ATPase : MembranEnzyme
|
||||
{
|
||||
public double ATPperCycle = 1.0;
|
||||
public double NaOutStoich = 3.0;
|
||||
public double KInStoich = 2.0;
|
||||
|
||||
public override void ComputeRate(double gradient, EnviromentState env)
|
||||
{
|
||||
|
||||
// niedriger Gradient → höhere Rate
|
||||
double effective = 1.0 / (1.0 + gradient);
|
||||
rate = Vmax * effective;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double flux = rate * dt;
|
||||
|
||||
// Verbrauch von ATP
|
||||
double atpNeeded = flux * ATPperCycle;
|
||||
if (res.Res.Energy.ATP < atpNeeded) flux *= res.Res.Energy.ATP / atpNeeded;
|
||||
|
||||
res.Res.Ions.Na -= NaOutStoich * flux; // Na raus
|
||||
res.Res.Ions.K += KInStoich * flux; // K rein
|
||||
res.Env.Na += NaOutStoich * flux;
|
||||
res.Env.K -= KInStoich * flux;
|
||||
res.ConsumeATP(atpNeeded);
|
||||
}
|
||||
|
||||
public override double CalculateGradient(CellRessources res)
|
||||
{
|
||||
return (res.Res.Ions.Na / res.Env.Na) * (res.Env.K / res.Res.Ions.K);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Membrane
|
||||
{
|
||||
// ----------------------------------------------------------
|
||||
// 3. PMCA – Ca²⁺-ATPase (Ca raus, ATP-abhängig)
|
||||
// ----------------------------------------------------------
|
||||
public class PMCA : MembranEnzyme
|
||||
{
|
||||
public double ATPperCycle = 1.0;
|
||||
|
||||
public override void ComputeRate(double caCyt, EnviromentState env)
|
||||
{
|
||||
// klassisch: Michaelis-Menten mit Ca²⁺-Abhängigkeit
|
||||
rate = Michaelis_Menten(caCyt, Vmax, Km);
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double flux = rate * dt;
|
||||
double atpNeeded = flux * ATPperCycle;
|
||||
|
||||
if (res.Res.Energy.ATP < atpNeeded) flux *= res.Res.Energy.ATP / atpNeeded;
|
||||
|
||||
res.Res.Ca.CytosolicCa -= flux; // Ca raus
|
||||
res.Env.Ca += flux;
|
||||
res.ConsumeATP(atpNeeded);
|
||||
}
|
||||
|
||||
public override double CalculateGradient(CellRessources res)
|
||||
{
|
||||
return res.Res.Ca.CytosolicCa; // PMCA is not driven by a concentration gradient
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// Noch gemacht werden
|
||||
namespace BaseCellSimulation.Enzyms.Mytochondrion
|
||||
{
|
||||
public class ANTTransporter : InternalEnzym
|
||||
{
|
||||
public ANTTransporter()
|
||||
{
|
||||
Vmax = 0.3;
|
||||
Km = 0.02; // mM ADP
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double adpAvailable = res.Res.Energy.ADP;
|
||||
double atpAvailable = res.Res.Energy.ATP;
|
||||
double transportable = Math.Min(adpAvailable, rate * dt);
|
||||
transportable = Math.Min(transportable, atpAvailable); // Sicherstellen, dass genug ATP zum Tausch vorhanden ist
|
||||
if (transportable <= 0) return;
|
||||
res.Res.Energy.ADP -= transportable;
|
||||
res.Res.Energy.ATP += transportable;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
double adp = res.Energy.ADP;
|
||||
Michaelis_Menten(adp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Mytochondrion
|
||||
{
|
||||
public class ATPSynthase : InternalEnzym
|
||||
{
|
||||
public ATPSynthase()
|
||||
{
|
||||
Vmax = 0.4;
|
||||
Km = 0.05; // ADP
|
||||
}
|
||||
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
|
||||
double used = Math.Min(res.Res.Energy.ADP, rate * dt);
|
||||
res.RegenerateATP(used);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
double gradient = Math.Clamp(res.Energy.NADH / (res.Energy.NAD + 1e-9), 0.0, 5.0);
|
||||
rate = Vmax * (gradient / (Km + gradient));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Mytochondrion
|
||||
{
|
||||
public class OxPhosEnzyme : InternalEnzym
|
||||
{
|
||||
public double PO_Ratio { get; set; } = 2.5;
|
||||
|
||||
public OxPhosEnzyme()
|
||||
{
|
||||
Vmax = 0.8;
|
||||
Km = 0.01;
|
||||
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double usedNADH = Math.Min(rate * dt, res.Res.Energy.NADH);
|
||||
if (usedNADH <= 0) return;
|
||||
|
||||
res.TransferNADH(usedNADH, true);
|
||||
|
||||
double o2Consumed = 0.5 * usedNADH;
|
||||
res.Res.Oxygen = Math.Max(0.0, res.Res.Oxygen - o2Consumed);
|
||||
|
||||
double atpMade = PO_Ratio * usedNADH;
|
||||
res.RegenerateATP(atpMade);
|
||||
|
||||
// ROS-Produktion
|
||||
double rosFactor = Math.Min(1.0, res.Res.Oxygen / 2.0);
|
||||
res.Res.Ions.H2O2 += usedNADH * 0.001 * rosFactor;
|
||||
res.Res.Protein.Waste += usedNADH * 0.001 * rosFactor;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
double nadh = res.Energy.NADH;
|
||||
Michaelis_Menten(nadh);
|
||||
|
||||
// Begrenzung durch O2
|
||||
double o2Limit = Math.Min(1.0, res.Oxygen / 0.05);
|
||||
rate *= o2Limit;
|
||||
|
||||
// ATP/ROS Feedback
|
||||
double atpFactor = Math.Clamp(res.Energy.ATP / 0.5, 0.0, 1.0);
|
||||
double wasteFactor = 1.0 / (1.0 + res.Protein.Waste / 10.0);
|
||||
rate *= atpFactor * wasteFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Mytochondrion
|
||||
{
|
||||
public class PyruvateDehydrogenase : InternalEnzym
|
||||
{
|
||||
public PyruvateDehydrogenase()
|
||||
{
|
||||
Vmax = 1.0; // mM/s
|
||||
Km = 0.05; // mM Pyruvat
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.Pyruvate);
|
||||
|
||||
// Aktivierung durch Ca²⁺
|
||||
double ca = res.Ca.CytosolicCa;
|
||||
double caBoost = 1.0 + 0.8 * (ca / (0.0005 + ca)); // bis ~1.8x Boost
|
||||
rate *= caBoost;
|
||||
|
||||
// Hemmung durch hohes NADH/NAD+ Verhältnis oder ATP
|
||||
double redox = res.Energy.NAD / (res.Energy.NAD + res.Energy.NADH + 1e-9);
|
||||
double energy = res.Energy.ATP / (res.Energy.ATP + res.Energy.ADP + 1e-9);
|
||||
rate *= redox * (1.0 - 0.5 * energy); // Hohe Energie hemmt
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(res.Res.Carbon.Pyruvate, rate * dt);
|
||||
|
||||
res.Res.Carbon.Pyruvate -= used;
|
||||
res.Res.Carbon.AcetylCoA += used;
|
||||
res.TransferNADH(used, false);
|
||||
res.Res.Carbon.CO2 += used;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Mytochondrion
|
||||
{
|
||||
public class TCAEnzyme : InternalEnzym
|
||||
{
|
||||
public TCAEnzyme()
|
||||
{
|
||||
Vmax = 0.1; // mM/s
|
||||
Km = 0.02; // mM Acetyl-CoA
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Carbon.AcetylCoA);
|
||||
// Abhängig vom Redoxstatus
|
||||
double redox = res.Energy.NAD / (res.Energy.NAD + res.Energy.NADH + 1e-9);
|
||||
rate *= redox;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double used = Math.Min(res.Res.Carbon.AcetylCoA, rate * dt);
|
||||
res.Res.Carbon.AcetylCoA -= used;
|
||||
res.TransferNADH(2 * used, false);
|
||||
//res.FADH2 += used;
|
||||
res.Res.Energy.GTP += used; // optional
|
||||
res.Res.Carbon.CO2 += 2 * used;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Nucleus
|
||||
{
|
||||
public class DNA_Polymerase_Delta : InternalEnzym
|
||||
{
|
||||
private const double EnergyCostATP = 0.5;
|
||||
|
||||
public DNA_Polymerase_Delta()
|
||||
{
|
||||
Km = 0.05;
|
||||
Vmax = 1.2;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dDna = Math.Min(rate * dt, res.Res.Protein.dNTP);
|
||||
dDna = res.Res.Energy.ATP >= dDna * EnergyCostATP ? dDna : res.Res.Energy.ATP / EnergyCostATP;
|
||||
res.Res.Protein.dNTP -= dDna;
|
||||
res.Res.Nucleus.ReplicationProgress += dDna;
|
||||
res.ConsumeATP(dDna * EnergyCostATP);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.dNTP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Nucleus
|
||||
{
|
||||
public class DNMT1 : InternalEnzym
|
||||
{
|
||||
public DNMT1()
|
||||
{
|
||||
Km = 0.01;
|
||||
Vmax = 0.25;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
// Berechne tatsächlich übertragene Methylmenge
|
||||
double dMethyl = Math.Min(rate * dt, res.Res.Protein.SAM);
|
||||
|
||||
// Chromatinzugänglichkeit moduliert Effektivität
|
||||
double accessibilityFactor = Math.Clamp(res.Res.Nucleus.ChromatinAccessibility / 0.005, 0.1, 1.0);
|
||||
dMethyl *= accessibilityFactor;
|
||||
|
||||
// SAM → SAH Umwandlung
|
||||
res.Res.Protein.SAM -= dMethyl;
|
||||
res.Res.Protein.SAH += dMethyl; // 1:1 Bildung
|
||||
|
||||
// Methylierung der DNA (vereinfachte Darstellung)
|
||||
res.Res.Nucleus.ChromatinAccessibility -= dMethyl * 0.005;
|
||||
if (res.Res.Nucleus.ChromatinAccessibility < 0)
|
||||
res.Res.Nucleus.ChromatinAccessibility = 0;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
double activityFactor = Math.Min(1.0, res.Nucleus.ReplicationProgress / 10.0);
|
||||
Michaelis_Menten(res.Protein.SAM * activityFactor);
|
||||
rate *= activityFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Nucleus
|
||||
{
|
||||
public class HistoneAcetyltransferase : InternalEnzym
|
||||
{
|
||||
public HistoneAcetyltransferase()
|
||||
{
|
||||
Km = 0.01;
|
||||
Vmax = 0.3;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dA = Math.Min(rate * dt, res.Res.Protein.AcetylCoA);
|
||||
res.Res.Protein.AcetylCoA -= dA;
|
||||
res.Res.Nucleus.ChromatinAccessibility = Math.Min(1.0, res.Res.Nucleus.ChromatinAccessibility + dA * 0.1);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.AcetylCoA);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Nucleus
|
||||
{
|
||||
public class HistoneDeacetylase : InternalEnzym
|
||||
{
|
||||
public HistoneDeacetylase()
|
||||
{
|
||||
Km = 0.02;
|
||||
Vmax = 0.25;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dD = Math.Min(rate * dt, Math.Min(res.Res.Nucleus.ChromatinAccessibility / 0.1, res.Res.Energy.NAD));
|
||||
res.Res.Energy.NAD -= dD;
|
||||
res.Res.Energy.NADH += dD * 0.5;
|
||||
res.Res.Nucleus.ChromatinAccessibility = Math.Max(0.0, res.Res.Nucleus.ChromatinAccessibility - dD * 0.1);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Energy.NAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Nucleus
|
||||
{
|
||||
public class PARP1 : InternalEnzym
|
||||
{
|
||||
private const double EnergyCostATP = 0.3;
|
||||
|
||||
public PARP1()
|
||||
{
|
||||
Km = 0.02;
|
||||
Vmax = 0.4;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dRepair = Math.Min(rate * dt, res.Res.Protein.DNA_damage);
|
||||
dRepair = res.Res.Energy.NAD >= dRepair * EnergyCostATP ? dRepair : res.Res.Energy.NAD / EnergyCostATP;
|
||||
res.Res.Energy.NAD -= dRepair * EnergyCostATP;
|
||||
res.Res.Energy.NADH += dRepair * 0.2;
|
||||
res.Res.Protein.DNA_damage -= dRepair * 0.8;
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.DNA_damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Nucleus
|
||||
{
|
||||
public class RNA_Polymerase_II : InternalEnzym
|
||||
{
|
||||
private const double EnergyCostATP = 0.3;
|
||||
|
||||
public RNA_Polymerase_II()
|
||||
{
|
||||
Km = 0.02;
|
||||
Vmax = 0.8;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double dM = Math.Min(rate * dt, res.Res.Protein.NTP);
|
||||
dM = res.Res.Energy.ATP >= dM * EnergyCostATP ? dM : res.Res.Energy.ATP / EnergyCostATP;
|
||||
res.Res.Protein.NTP -= dM;
|
||||
res.Res.Protein.mRNA += dM;
|
||||
res.ConsumeATP(dM * EnergyCostATP);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.NTP);
|
||||
rate *= res.Nucleus.ChromatinAccessibility;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms.Nucleus
|
||||
{
|
||||
public class Topoisomerase_II : InternalEnzym
|
||||
{
|
||||
private const double EnergyCostATP = 0.2;
|
||||
|
||||
public Topoisomerase_II()
|
||||
{
|
||||
Km = 0.03;
|
||||
Vmax = 0.5;
|
||||
}
|
||||
|
||||
public override void ApplyChanges(CellRessources res, double dt)
|
||||
{
|
||||
double repair = Math.Min(rate * dt, res.Res.Protein.DNA_damage);
|
||||
repair = res.Res.Energy.ATP >= repair * EnergyCostATP ? repair : res.Res.Energy.ATP / EnergyCostATP;
|
||||
res.Res.Protein.DNA_damage -= repair;
|
||||
res.ConsumeATP(repair * EnergyCostATP);
|
||||
}
|
||||
|
||||
public override void ComputeRate(Resources res)
|
||||
{
|
||||
Michaelis_Menten(res.Protein.DNA_damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation.Enzyms
|
||||
{
|
||||
public static class VmaxCalculator
|
||||
{
|
||||
private const double Avogadro = 6.02214076e23; // mol⁻¹
|
||||
|
||||
/// <summary>
|
||||
/// Berechnet Vmax (in mM/s) aus Enzymkinetik-Parametern.
|
||||
/// </summary>
|
||||
/// <param name="kcat">Turnover-Zahl des Enzyms (s⁻¹ pro Molekül)</param>
|
||||
/// <param name="enzymeCount">Anzahl der Enzymmoleküle in der Zelle</param>
|
||||
/// <param name="cellVolume_L">Zellvolumen in Litern (z. B. 1e-12 für typische Eukaryoten)</param>
|
||||
/// <returns>Vmax in mM/s</returns>
|
||||
public static double ComputeVmax(double kcat, double enzymeCount, double cellVolume_L)
|
||||
{
|
||||
// [E_total] = (enzymeCount / Avogadro) / cellVolume
|
||||
double enzymeConcentration_M = (enzymeCount / Avogadro) / cellVolume_L; // mol/L
|
||||
double vmax_M_per_s = kcat * enzymeConcentration_M; // mol/L/s
|
||||
|
||||
// Umrechnung auf mM/s
|
||||
return vmax_M_per_s * 1000.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Beispielausgabe für häufige Zellgrößen / Transporter.
|
||||
/// </summary>
|
||||
public static void Example()
|
||||
{
|
||||
// Beispielwerte: GLUT1, GLUT2, GLUT3, GLUT4
|
||||
double cellVolume = 1e-12; // Liter (≈ typische Säugetierzelle)
|
||||
double[] enzymeCounts = { 1e5, 1e6, 1e7 }; // niedrige, mittlere, hohe Expression
|
||||
double[] kcats = { 100, 500, 1000 }; // plausible Turnover-Werte
|
||||
|
||||
foreach (var kcat in kcats)
|
||||
{
|
||||
foreach (var enz in enzymeCounts)
|
||||
{
|
||||
double vmax = ComputeVmax(kcat, enz, cellVolume);
|
||||
Console.WriteLine($"kcat={kcat,5:F0} Enzyme={enz:E0} → Vmax={vmax:F2} mM/s");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using BaseCellSimulation.Enzyms;
|
||||
using BaseCellSimulation.Enzyms.Lysosome;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Resources;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation
|
||||
{
|
||||
/// <summary>
|
||||
/// Recicling center of the cell takes up waste and generates Amino acides and small amout of ATP
|
||||
/// </summary>
|
||||
/// <param name="cellname"></param>
|
||||
/// <param name="decayRate"></param>
|
||||
public class Lysosome : Organell
|
||||
{
|
||||
public readonly List<InternalEnzym> enzyms = new List<InternalEnzym>();
|
||||
|
||||
private readonly string name;
|
||||
|
||||
public Lysosome() : this("Lysosome") { }
|
||||
|
||||
public Lysosome(string cellname)
|
||||
{
|
||||
name = cellname;
|
||||
enzyms.Add(new Cathepsin());
|
||||
enzyms.Add(new GenericLysosomalEnzyme());
|
||||
enzyms.Add(new LysosomalLipase());
|
||||
enzyms.Add(new LysosomalNuclease());
|
||||
enzyms.Add(new LysosomalPhosphatase());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public string getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void applyChanges(CellRessources Resources, double dt)
|
||||
{
|
||||
|
||||
|
||||
foreach (InternalEnzym enzym in enzyms)
|
||||
{
|
||||
enzym.ApplyChanges(Resources, dt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void calculateRate(CellRessources res)
|
||||
{
|
||||
foreach (InternalEnzym enzym in enzyms)
|
||||
{
|
||||
enzym.ComputeRate(res.Res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using BaseCellSimulation.Enzyms;
|
||||
using BaseCellSimulation.Enzyms.Membrane;
|
||||
using BaseCellSimulation.Enzyms.Membrane.GLUT;
|
||||
|
||||
namespace BaseCellSimulation
|
||||
{
|
||||
/// <summary>
|
||||
/// Cell membrane small leakage and passive disposal of waste
|
||||
/// </summary>
|
||||
/// <param name="cellname"></param>
|
||||
/// <param name="glucoseImportRate"></param>
|
||||
/// <param name="oxygenImportRate"></param>
|
||||
/// <param name="wasteOuttakeRate"></param>
|
||||
public class Membrane : Organell
|
||||
{
|
||||
public readonly List<MembranEnzyme> enzyms = new List<MembranEnzyme>();
|
||||
public readonly List<GLUT1> glutTransporters = new List<GLUT1>();
|
||||
private readonly string name;
|
||||
|
||||
public Membrane() : this("Membrane") { }
|
||||
|
||||
public Membrane(string cellname)
|
||||
{
|
||||
this.name = cellname;
|
||||
enzyms.Add(new KLeakChannel());
|
||||
enzyms.Add(new MCT());
|
||||
enzyms.Add(new NaK_ATPase());
|
||||
enzyms.Add(new NCX());
|
||||
enzyms.Add(new PMCA());
|
||||
// Add GLUT transporters
|
||||
glutTransporters.Add(new GLUT1());
|
||||
}
|
||||
|
||||
public string getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void applyChanges(CellRessources res, double dt)
|
||||
{
|
||||
|
||||
foreach (MembranEnzyme enzyme in enzyms)
|
||||
{
|
||||
enzyme.ApplyChanges(res, dt);
|
||||
}
|
||||
foreach (GLUT1 glut in glutTransporters)
|
||||
{
|
||||
glut.ApplyChanges(res, dt);
|
||||
}
|
||||
// --- 5. Kleine Verluste anderer Stoffe (Diffusionslecks) ---
|
||||
res.Res.Carbon.Glucose = Math.Max(0, res.Res.Carbon.Glucose - 0.001 * dt);
|
||||
res.Res.Oxygen = Math.Max(0, res.Res.Oxygen - 0.001 * dt);
|
||||
}
|
||||
|
||||
public void calculateRate(CellRessources res)
|
||||
{
|
||||
foreach (MembranEnzyme enzyme in enzyms)
|
||||
{
|
||||
double gradient = enzyme.CalculateGradient(res);
|
||||
enzyme.ComputeRate(gradient, res.Env);
|
||||
}
|
||||
double glutGradient = glutTransporters[0].CalculateGradient(res);
|
||||
|
||||
foreach (GLUT1 glut in glutTransporters)
|
||||
{
|
||||
glut.ComputeRate(glutGradient, res.Env);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using BaseCellSimulation.Enzyms;
|
||||
using BaseCellSimulation.Enzyms.Mytochondrion;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace BaseCellSimulation
|
||||
{
|
||||
/// <summary>
|
||||
/// Powerplant of the cell generates ATP out od NADH and Oxygen
|
||||
/// </summary>
|
||||
/// <param name="cellName"></param>
|
||||
/// <param name="oxPhosVmax"></param>
|
||||
/// <param name="oxPhosKm"></param>
|
||||
/// <param name="pO_Ratio"></param>
|
||||
public class Mitochondrion : Organell
|
||||
{
|
||||
public List<Enzym> Enzyms { get; private set; } = new List<Enzym>();
|
||||
|
||||
|
||||
|
||||
private readonly string name;
|
||||
|
||||
public Mitochondrion() : this("Mitochondrion") {}
|
||||
|
||||
public Mitochondrion(string cellName)
|
||||
{
|
||||
name = cellName;
|
||||
Enzyms.Add(new PyruvateDehydrogenase());
|
||||
//Enzyms.Add(new Enzyms.Mytochondrion.ANTTransporter());
|
||||
Enzyms.Add(new OxPhosEnzyme());
|
||||
Enzyms.Add(new ATPSynthase());
|
||||
Enzyms.Add(new TCAEnzyme());
|
||||
}
|
||||
|
||||
|
||||
public string getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void applyChanges(CellRessources Resources, double dt)
|
||||
{
|
||||
|
||||
|
||||
foreach (Enzym enzym in Enzyms)
|
||||
{
|
||||
enzym.ApplyChanges(Resources, dt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void calculateRate(CellRessources res)
|
||||
{
|
||||
foreach (Enzym enzym in Enzyms)
|
||||
{
|
||||
if (enzym is InternalEnzym internalEnzym)
|
||||
{
|
||||
internalEnzym.ComputeRate(res.Res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using BaseCellSimulation.Enzyms;
|
||||
using BaseCellSimulation.Enzyms.Nucleus;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation
|
||||
{
|
||||
/// <summary>
|
||||
/// Cell Core produces RNA uses ATP generates small amount of waste
|
||||
/// </summary>
|
||||
/// <param name="cellname"></param>
|
||||
/// <param name="transcriptionRate"></param>
|
||||
/// <param name="atpPerNucloide"></param>
|
||||
public class Nucleus : Organell
|
||||
{
|
||||
public List<InternalEnzym> enzyms = new List<InternalEnzym>();
|
||||
|
||||
private readonly string name;
|
||||
|
||||
public Nucleus() : this("Nucleus") { }
|
||||
|
||||
public Nucleus(string cellname)
|
||||
{
|
||||
name = cellname;
|
||||
enzyms.Add(new DNA_Polymerase_Delta());
|
||||
enzyms.Add(new DNMT1());
|
||||
enzyms.Add(new HistoneAcetyltransferase());
|
||||
enzyms.Add(new HistoneDeacetylase());
|
||||
enzyms.Add(new PARP1());
|
||||
enzyms.Add(new Topoisomerase_II());
|
||||
enzyms.Add(new RNA_Polymerase_II());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public string getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void applyChanges(CellRessources Resources, double dt)
|
||||
{
|
||||
|
||||
foreach (InternalEnzym enzym in enzyms)
|
||||
{
|
||||
enzym.ApplyChanges(Resources, dt);
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateRate(CellRessources res)
|
||||
{
|
||||
foreach (InternalEnzym enzym in enzyms)
|
||||
{
|
||||
enzym.ComputeRate(res.Res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
using System;
|
||||
|
||||
namespace BaseCellSimulation
|
||||
{
|
||||
/// <summary>
|
||||
/// Container, der die aktuellen Ressourcen einer Zelle hält und Hilfsfunktionen bietet.
|
||||
/// </summary>
|
||||
public class CellRessources
|
||||
{
|
||||
public Resources Res;
|
||||
public EnviromentState Env = new();
|
||||
|
||||
// pH in mM-basiertem Hilfsformat (vereinfachte Umrechnung):
|
||||
public double pH_in => 3.0 - Math.Log10(Res.Ions.Protons + 1e-12);
|
||||
public double pH_ext => 3.0 - Math.Log10(Env.Protons + 1e-12);
|
||||
|
||||
// --- Hilfsfunktionen (unverändert / kommentiert) ---
|
||||
|
||||
public double GetEnergyLevel()
|
||||
{
|
||||
double totalATP = Res.Energy.ATP + 0.5 * Res.Energy.ADP + 0.1 * Res.Energy.AMP;
|
||||
double redoxEnergy = 0.3 * Res.Energy.NADH;
|
||||
double energy = totalATP + redoxEnergy;
|
||||
return Math.Clamp(energy / 5.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
public double EnergyCharge
|
||||
{
|
||||
get
|
||||
{
|
||||
double atp = Res.Energy.ATP;
|
||||
double adp = Res.Energy.ADP;
|
||||
double amp = Res.Energy.AMP;
|
||||
double total = atp + adp + amp;
|
||||
if (total < 1e-12) return 0.0;
|
||||
return (atp + 0.5 * adp) / total;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEnergyDeficient(double threshold = 0.3)
|
||||
{
|
||||
return Res.Energy.ATP < threshold;
|
||||
}
|
||||
|
||||
public double GetRedoxRatio()
|
||||
{
|
||||
double denominator = Math.Max(Res.Energy.NADH, 1e-9);
|
||||
return Res.Energy.NAD / denominator;
|
||||
}
|
||||
|
||||
public double GetStressLevel()
|
||||
{
|
||||
double stress = Res.Protein.Waste * 0.1 + Res.Ions.ROS * 0.5 + Res.Ions.Protons * 0.05;
|
||||
return Math.Clamp(stress, 0.0, 1.0);
|
||||
}
|
||||
|
||||
public bool IsUnderStress(double threshold = 0.5)
|
||||
{
|
||||
return GetStressLevel() > threshold;
|
||||
}
|
||||
|
||||
public void ConsumeATP(double amount, bool toAMP = false)
|
||||
{
|
||||
if (Res.Energy.ATP < amount) amount = Res.Energy.ATP;
|
||||
Res.Energy.ATP -= amount;
|
||||
if (toAMP)
|
||||
{
|
||||
Res.Energy.AMP += amount;
|
||||
Res.Phosphate.PPi += amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
Res.Energy.ADP += amount;
|
||||
Res.Phosphate.Pi += amount;
|
||||
}
|
||||
}
|
||||
|
||||
public void RegenerateATP(double amount, bool fromAMP = false)
|
||||
{
|
||||
if (fromAMP)
|
||||
{
|
||||
if (Res.Energy.AMP < amount) amount = Res.Energy.AMP;
|
||||
if (Res.Phosphate.Pi < 2 * amount) amount = Res.Phosphate.Pi / 2;
|
||||
Res.Energy.AMP -= amount;
|
||||
Res.Phosphate.Pi -= 2 * amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Res.Energy.ADP < amount) amount = Res.Energy.ADP;
|
||||
if (Res.Phosphate.Pi < amount) amount = Res.Phosphate.Pi;
|
||||
Res.Energy.ADP -= amount;
|
||||
Res.Phosphate.Pi -= amount;
|
||||
}
|
||||
Res.Energy.ATP += amount;
|
||||
}
|
||||
|
||||
public void HydrolyzePPi(double amount)
|
||||
{
|
||||
if (Res.Phosphate.PPi < amount) amount = Res.Phosphate.PPi;
|
||||
Res.Phosphate.PPi -= amount;
|
||||
Res.Phosphate.Pi += 2 * amount;
|
||||
}
|
||||
|
||||
public void TransferNADH(double amount, bool oxidize)
|
||||
{
|
||||
if (oxidize)
|
||||
{
|
||||
if (Res.Energy.NADH < amount) amount = Res.Energy.NADH;
|
||||
Res.Energy.NADH -= amount;
|
||||
Res.Energy.NAD += amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Res.Energy.NAD < amount) amount = Res.Energy.NAD;
|
||||
Res.Energy.NAD -= amount;
|
||||
Res.Energy.NADH += amount;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Initialisierung mit plausiblen Startwerten ---
|
||||
/// <summary>
|
||||
/// Erzeugt eine CellRessources-Instanz mit vernünftigen Startwerten (grobe physiologische Annahmen).
|
||||
/// Alle Werte in mM, falls nicht anders kommentiert.
|
||||
/// </summary>
|
||||
public static CellRessources InitDefaults()
|
||||
{
|
||||
var cr = new CellRessources();
|
||||
|
||||
// Energie-Pool (ATP/ADP/AMP etc.) — typisch: ATP im mm-Bereich
|
||||
cr.Res.Energy.ATP = 2.5; // mM, Gesamt-ATP (typischer Ruhewert 1-5 mM)
|
||||
cr.Res.Energy.ADP = 0.5; // mM
|
||||
cr.Res.Energy.AMP = 0.05; // mM
|
||||
cr.Res.Energy.NAD = 1.0; // mM (oxidierte Form)
|
||||
cr.Res.Energy.NADH = 0.1; // mM (reduzierte Form)
|
||||
cr.Res.Energy.GTP = 0.5; // mM
|
||||
cr.Res.Energy.GDP = 0.05; // mM
|
||||
|
||||
// Phosphate
|
||||
cr.Res.Phosphate.Pi = 10.0; // mM (anorganisches Phosphat)
|
||||
cr.Res.Phosphate.PPi = 0.01; // mM (Pyrophosphat, klein)
|
||||
|
||||
// Carbon- / Glykolyse-Pool (vereinfachte Startwerte)
|
||||
cr.Res.Carbon.Glucose = 1.0; // mM intrazellulär (abhängig von Aufnahme)
|
||||
cr.Res.Carbon.G6P = 0.05;
|
||||
cr.Res.Carbon.F6P = 0.02;
|
||||
cr.Res.Carbon.FBP = 0.005;
|
||||
cr.Res.Carbon.GAP = 0.01;
|
||||
cr.Res.Carbon.PBG13 = 0.005;
|
||||
cr.Res.Carbon.PG3 = 0.02;
|
||||
cr.Res.Carbon.PG2 = 0.01;
|
||||
cr.Res.Carbon.PEP = 0.01;
|
||||
cr.Res.Carbon.Pyruvate = 0.1;
|
||||
cr.Res.Carbon.Lactate = 1.0;
|
||||
cr.Res.Carbon.CO2 = 0.1;
|
||||
cr.Res.Carbon.AcetylCoA = 0.02;
|
||||
|
||||
// Proteine & Nukleotid-Pool
|
||||
cr.Res.Protein.AminoAcids = 5.0; // mM frei verfügbare Aminosäuren
|
||||
cr.Res.Protein.FunctionalProteins = 100; // arbitrary, relative Konzentration (nicht streng mM)
|
||||
cr.Res.Protein.Waste = 0.1; // kleiner Startwert
|
||||
cr.Res.Protein.NucleicAcids = 10.0;
|
||||
cr.Res.Protein.Nucleotides = 5.0;
|
||||
cr.Res.Protein.NTP = 2.0;
|
||||
cr.Res.Protein.dNTP = 0.05;
|
||||
cr.Res.Protein.mRNA = 0.01;
|
||||
cr.Res.Protein.DNA_damage = 0.0;
|
||||
cr.Res.Protein.AcetylCoA = 0.02;
|
||||
cr.Res.Protein.SAM = 0.1;
|
||||
cr.Res.Protein.MET = 0.1;
|
||||
cr.Res.Protein.SAH = 0.01;
|
||||
cr.Res.Protein.Homocystein = 0.01;
|
||||
cr.Res.Protein.Adenosin = 0.1;
|
||||
cr.Res.Protein.tRNA = 0.05;
|
||||
cr.Res.Protein.Aminoacyl_tRNA = 0.02;
|
||||
|
||||
// Ionen
|
||||
cr.Res.Ions.Protons = 0.0001; // mM -> entspricht ~pH7 (vereinfachte Umrechnung)
|
||||
cr.Res.Ions.ROS = 0.001; // kleine ROS-Basislast
|
||||
cr.Res.Ions.Na = 10.0; // Intrazelluläres Na+ ~ 5-15 mM (Zelltypabhängig)
|
||||
cr.Res.Ions.K = 140.0; // Intrazelluläres K+ ~ 140 mM
|
||||
cr.Res.Ions.H2O2 = 0.0001;
|
||||
|
||||
// Cofaktoren / Folate
|
||||
cr.Res.Cofactor.B12 = 1e-6;
|
||||
cr.Res.Folate.THF = 0.01;
|
||||
cr.Res.Folate.MethylTHF = 0.005;
|
||||
|
||||
// Zellkern-Ressourcen (vereinfachte Defaults)
|
||||
cr.Res.Nucleus.ChromatinAccessibility = 0.5;
|
||||
cr.Res.Nucleus.ReplicationProgress = 0.0;
|
||||
|
||||
// Calcium-Zustand (CellCaState hat sinnvolle Defaultwerte)
|
||||
cr.Res.Ca = new CellCaState()
|
||||
{
|
||||
CytosolicCa = 0.0001, // 100 nM -> 0.0001 mM
|
||||
ER_Ca = 0.5,
|
||||
LeakK = 0.001,
|
||||
SERCA_Vmax = 0.01,
|
||||
SERCA_Km = 0.0002,
|
||||
SERCA_ATP_per_twoCa = 1.0,
|
||||
LysosomeActivity = 0.1
|
||||
};
|
||||
|
||||
// Sonstige Ressourcen
|
||||
cr.Res.Oxygen = 0.2; // mM Lösungssauerstoff (abhängig von Umgebung)
|
||||
cr.Res.Heat = 0.0;
|
||||
cr.Res.Lipids = 10.0;
|
||||
cr.Res.PhosphorylatedSubstrates = 1.0;
|
||||
|
||||
// Umgebung / Extrazellulärwerte
|
||||
cr.Env.Glucose = 5.0; // Blutglukose ~5 mM
|
||||
cr.Env.Oxygen = 0.2; // mM
|
||||
cr.Env.Waste = 0.0;
|
||||
cr.Env.Lactate = 1.0;
|
||||
cr.Env.Insulin = 0.0;
|
||||
cr.Env.Protons = 0.0001; // ähnlich pH 7
|
||||
cr.Env.Na = 140.0; // extrazelluläres Na+ ~ 140 mM
|
||||
cr.Env.K = 4.0; // extrazelluläres K+ ~ 4-5 mM
|
||||
cr.Env.Ca = 1.2; // extrazelluläres Ca2+ ~1.1-1.3 mM
|
||||
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Datendefinitionen (geordnet und kommentiert)
|
||||
// ------------------------------------------------------------
|
||||
|
||||
/// <summary>Energiemengen: ATP/ADP/AMP + NAD/NADH + GTP/GDP</summary>
|
||||
public struct EnergyPool
|
||||
{
|
||||
public double ATP;
|
||||
public double ADP;
|
||||
public double AMP;
|
||||
public double NAD;
|
||||
public double NADH;
|
||||
public double GTP;
|
||||
public double GDP { get; internal set; }
|
||||
}
|
||||
|
||||
/// <summary>Inorganische Phosphate</summary>
|
||||
public struct Phosphate
|
||||
{
|
||||
public double Pi; // anorganisches Phosphat
|
||||
public double PPi; // Pyrophosphat
|
||||
}
|
||||
|
||||
/// <summary>Kohlenstoff- / Glykolyse-Intermediaten</summary>
|
||||
public struct CarbonPool
|
||||
{
|
||||
public double Glucose;
|
||||
public double G6P;
|
||||
public double F6P;
|
||||
public double FBP;
|
||||
public double GAP;
|
||||
public double PBG13;
|
||||
public double PG3;
|
||||
public double PG2;
|
||||
public double PEP;
|
||||
public double Pyruvate;
|
||||
public double Lactate;
|
||||
public double CO2;
|
||||
public double AcetylCoA;
|
||||
}
|
||||
|
||||
/// <summary>Proteine, Nukleotide, mRNA, etc.</summary>
|
||||
public struct ProteinPool
|
||||
{
|
||||
public double AminoAcids;
|
||||
public double FunctionalProteins;
|
||||
public double Waste;
|
||||
public double NucleicAcids;
|
||||
public double Nucleotides;
|
||||
public double NTP;
|
||||
public double dNTP;
|
||||
public double mRNA;
|
||||
public double DNA_damage;
|
||||
public double AcetylCoA;
|
||||
public double SAM;
|
||||
public double MET;
|
||||
public double SAH;
|
||||
public double Homocystein;
|
||||
public double Adenosin;
|
||||
internal double tRNA;
|
||||
internal double Aminoacyl_tRNA;
|
||||
}
|
||||
|
||||
/// <summary>Ionen und kleine Signalmoleküle</summary>
|
||||
public struct IonPool
|
||||
{
|
||||
public double Protons; // H+ (vereinfachte Einheit mM)
|
||||
public double ROS; // reactive oxygen species
|
||||
public double Na;
|
||||
public double K;
|
||||
public double H2O2;
|
||||
}
|
||||
|
||||
public struct Cofactor
|
||||
{
|
||||
public double B12;
|
||||
}
|
||||
|
||||
public struct Folates
|
||||
{
|
||||
public double THF { get; internal set; }
|
||||
public double MethylTHF { get; internal set; }
|
||||
}
|
||||
|
||||
public struct NucleusRessources
|
||||
{
|
||||
public double ChromatinAccessibility;
|
||||
public double ReplicationProgress;
|
||||
}
|
||||
|
||||
/// <summary>Gesammelte Ressourcen einer Zelle</summary>
|
||||
public struct Resources
|
||||
{
|
||||
public EnergyPool Energy;
|
||||
public Phosphate Phosphate;
|
||||
public CarbonPool Carbon;
|
||||
public ProteinPool Protein;
|
||||
public IonPool Ions;
|
||||
public CellCaState Ca;
|
||||
public NucleusRessources Nucleus;
|
||||
public Cofactor Cofactor;
|
||||
public Folates Folate;
|
||||
|
||||
public double Oxygen;
|
||||
public double Heat;
|
||||
public double Lipids;
|
||||
public double PhosphorylatedSubstrates;
|
||||
}
|
||||
|
||||
public enum CellState { Resting, Dividing, Apoptosis }
|
||||
|
||||
public enum CAToxicity { None, Mild, Severe, Lethal }
|
||||
|
||||
public class EnviromentState
|
||||
{
|
||||
public double Glucose;
|
||||
public double Oxygen;
|
||||
public double Waste;
|
||||
public double Lactate;
|
||||
public double Insulin;
|
||||
public double Protons;
|
||||
public double Na;
|
||||
public double K;
|
||||
public double Ca;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ein einfaches Modell des zellulären Calcium-Haushalts.
|
||||
/// Werte in mM; Defaultwerte sind phänotypisch realistisch gewählt.
|
||||
/// </summary>
|
||||
public struct CellCaState
|
||||
{
|
||||
public double CytosolicCa { get; set; } // zytosolisches Ca (mM), üblich ~100 nM = 0.0001 mM
|
||||
public double ER_Ca { get; set; } // ER Calcium (mM)
|
||||
public double LeakK { get; set; } // Leck-Koeffizient
|
||||
public double SERCA_Vmax { get; set; }
|
||||
public double SERCA_Km { get; set; } // Km in mM
|
||||
public double SERCA_ATP_per_twoCa { get; set; }
|
||||
public double LysosomeActivity { get; internal set; }
|
||||
|
||||
public const double ToxicityThresholdMild = 0.001; // 1 µM
|
||||
public const double ToxicityThresholdSevere = 0.01; // 10 µM
|
||||
public const double ToxicityThresholdLethal = 0.1; // 100 µM
|
||||
|
||||
public CellCaState()
|
||||
{
|
||||
CytosolicCa = 0.0001;
|
||||
ER_Ca = 0.5;
|
||||
LeakK = 0.001;
|
||||
SERCA_Vmax = 0.01;
|
||||
SERCA_Km = 0.0002;
|
||||
SERCA_ATP_per_twoCa = 1.0;
|
||||
LysosomeActivity = 0.1;
|
||||
}
|
||||
|
||||
public CAToxicity getCaToxicityLevel()
|
||||
{
|
||||
if (CytosolicCa >= ToxicityThresholdLethal) return CAToxicity.Lethal;
|
||||
else if (CytosolicCa >= ToxicityThresholdSevere) return CAToxicity.Severe;
|
||||
else if (CytosolicCa >= ToxicityThresholdMild) return CAToxicity.Mild;
|
||||
else return CAToxicity.None;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Organell
|
||||
{
|
||||
void applyChanges(CellRessources Resources, double dt);
|
||||
|
||||
void calculateRate(CellRessources res);
|
||||
|
||||
string getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BaseCellSimulation
|
||||
{
|
||||
public struct ValueRange
|
||||
{
|
||||
public double Start;
|
||||
public double End;
|
||||
|
||||
public ValueRange(double start, double end)
|
||||
{
|
||||
Start = start;
|
||||
End = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<!--If you are willing to use Windows/MacOS native APIs you will need to create 3 projects.
|
||||
One for Windows with net9.0-windows TFM, one for MacOS with net9.0-macos and one with net9.0 TFM for Linux.-->
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Desktop" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Include="Avalonia.Diagnostics" >
|
||||
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\CellSimulation\CellSimulation.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
|
||||
namespace CellSimulation.Desktop;
|
||||
|
||||
sealed class Program
|
||||
{
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
[STAThread]
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.WithInterFont()
|
||||
.LogToTrace();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<!-- This manifest is used on Windows only.
|
||||
Don't remove it as it might cause problems with window transparency and embedded controls.
|
||||
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
|
||||
<assemblyIdentity version="1.0.0.0" name="CellSimulation.Desktop"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.3.32811.315
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CellSimulation", "CellSimulation\CellSimulation.csproj", "{EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CellSimulation.Desktop", "CellSimulation.Desktop\CellSimulation.Desktop.csproj", "{ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3DA99C4E-89E3-4049-9C22-0A7EC60D83D8}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Directory.Packages.props = Directory.Packages.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaseCellSimulation", "BaseCellSimulation\BaseCellSimulation.csproj", "{7C692F24-01D5-47FB-957D-94E170351A05}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EBFA8512-1EA5-4D8C-B4AC-AB5B48A6D568}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ABC31E74-02FF-46EB-B3B2-4E6AE43B456C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7C692F24-01D5-47FB-957D-94E170351A05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7C692F24-01D5-47FB-957D-94E170351A05}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7C692F24-01D5-47FB-957D-94E170351A05}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7C692F24-01D5-47FB-957D-94E170351A05}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {83CB65B8-011F-4ED7-BCD3-A6CFA935EF7E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,15 @@
|
||||
<Application xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:CellSimulation"
|
||||
x:Class="CellSimulation.App"
|
||||
RequestedThemeVariant="Default">
|
||||
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
|
||||
|
||||
<Application.DataTemplates>
|
||||
<local:ViewLocator/>
|
||||
</Application.DataTemplates>
|
||||
|
||||
<Application.Styles>
|
||||
<FluentTheme />
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
@@ -0,0 +1,54 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Data.Core;
|
||||
using Avalonia.Data.Core.Plugins;
|
||||
using System.Linq;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using CellSimulation.ViewModels;
|
||||
using CellSimulation.Views;
|
||||
|
||||
namespace CellSimulation;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
|
||||
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
|
||||
DisableAvaloniaDataAnnotationValidation();
|
||||
desktop.MainWindow = new MainWindow
|
||||
{
|
||||
DataContext = new MainViewModel()
|
||||
};
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
|
||||
{
|
||||
singleViewPlatform.MainView = new MainView
|
||||
{
|
||||
DataContext = new MainViewModel()
|
||||
};
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
|
||||
private void DisableAvaloniaDataAnnotationValidation()
|
||||
{
|
||||
// Get an array of plugins to remove
|
||||
var dataValidationPluginsToRemove =
|
||||
BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();
|
||||
|
||||
// remove each entry found
|
||||
foreach (var plugin in dataValidationPluginsToRemove)
|
||||
{
|
||||
BindingPlugins.DataValidators.Remove(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" />
|
||||
<PackageReference Include="Avalonia.Fonts.Inter" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Include="Avalonia.Diagnostics">
|
||||
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||
<PackageReference Include="ScottPlot.Avalonia" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BaseCellSimulation\BaseCellSimulation.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Templates;
|
||||
using CellSimulation.ViewModels;
|
||||
|
||||
namespace CellSimulation;
|
||||
|
||||
public class ViewLocator : IDataTemplate
|
||||
{
|
||||
public Control? Build(object? param)
|
||||
{
|
||||
if (param is null)
|
||||
return null;
|
||||
|
||||
var name = param.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal);
|
||||
var type = Type.GetType(name);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
return (Control)Activator.CreateInstance(type)!;
|
||||
}
|
||||
|
||||
return new TextBlock { Text = "Not Found: " + name };
|
||||
}
|
||||
|
||||
public bool Match(object? data)
|
||||
{
|
||||
return data is ViewModelBase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace CellSimulation.ViewModels;
|
||||
|
||||
public partial class MainViewModel : ViewModelBase
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string _greeting = "Welcome to Avalonia!";
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace CellSimulation.ViewModels;
|
||||
|
||||
public abstract class ViewModelBase : ObservableObject
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="clr-namespace:CellSimulation.ViewModels"
|
||||
xmlns:ScottPlot="clr-namespace:ScottPlot.Avalonia;assembly=ScottPlot.Avalonia"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="CellSimulation.Views.MainView"
|
||||
x:DataType="vm:MainViewModel">
|
||||
<Design.DataContext>
|
||||
<!-- This only sets the DataContext for the previewer in an IDE,
|
||||
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
|
||||
<vm:MainViewModel />
|
||||
</Design.DataContext>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
<ColumnDefinition Width="4"></ColumnDefinition>
|
||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ScottPlot:AvaPlot Name="CellPlot"/>
|
||||
<GridSplitter Grid.Column="1" Background="Black" ResizeDirection="Columns" MinWidth="0"/>
|
||||
<StackPanel Grid.Column="2" Margin="20">
|
||||
<TextBlock Margin="0 5">Seconds of Symulation</TextBlock>
|
||||
<NumericUpDown x:Name="SecondInput" Value="4" Minimum="1"></NumericUpDown>
|
||||
<TextBlock Margin="0 5">Second Granularity</TextBlock>
|
||||
<NumericUpDown x:Name="Granularity" Value="0.1" Minimum="0.001" Maximum="0.7"></NumericUpDown>
|
||||
<Button x:Name="Simulate" Click="StartSimulation" Margin="0 5"> Simulate</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,77 @@
|
||||
using Avalonia.Controls;
|
||||
using BaseCellSimulation;
|
||||
using ScottPlot;
|
||||
using ScottPlot.Avalonia;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace CellSimulation.Views;
|
||||
|
||||
public partial class MainView : UserControl
|
||||
{
|
||||
List<cellInfo> cellData = new();
|
||||
|
||||
EnviromentState envState = new()
|
||||
{
|
||||
Glucose = 5.0, // mM — normaler Blutzuckerwert (~90 mg/dL)
|
||||
Oxygen = 0.2, // mM — entspricht ca. 5% O2 (physiologischer Bereich)
|
||||
Waste = 0.0, // mM — initial kein Abfallprodukt
|
||||
Lactate = 1.0, // mM — basaler Spiegel (wird bei anaerobem Stoffwechsel steigen)
|
||||
Insulin = 0.05, // µM — basal, kann bei Simulation von Stoffwechselantworten angepasst werden
|
||||
Protons = 0.00004, // mM — entspricht pH 7.4 (10^-7.4 mol/L)
|
||||
Na = 140.0, // mM — extrazelluläre Natriumkonzentration
|
||||
K = 4.5, // mM — extrazelluläre Kaliumkonzentration
|
||||
Ca = 0.0018
|
||||
};
|
||||
|
||||
public MainView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void StartSimulation(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
Cell cell = new();
|
||||
|
||||
cell.EnviromentState = envState;
|
||||
|
||||
decimal? granularity = Granularity.Value;
|
||||
|
||||
decimal? seconds = SecondInput.Value;
|
||||
|
||||
cellData = new();
|
||||
|
||||
for (int i = 0; i < seconds/granularity; i++)
|
||||
{
|
||||
envState.Glucose += 0.01;
|
||||
envState.Oxygen += 0.005;
|
||||
cell.Step((double)granularity);
|
||||
cellData.Add(cell.GetCellInfo());
|
||||
}
|
||||
|
||||
|
||||
AvaPlot avaPlot = CellPlot;
|
||||
avaPlot.Reset();
|
||||
avaPlot.Plot.Title("Cell Simulation Over Time");
|
||||
avaPlot.Plot.XLabel("Time (s)");
|
||||
avaPlot.Plot.YLabel("Concentration / Amount");
|
||||
var ATP = avaPlot.Plot.Add.Scatter(cellData.ConvertAll(c => c.time).ToArray(), cellData.ConvertAll(c => c.resources["ATP"]).ToArray());
|
||||
ATP.LegendText = "ATP";
|
||||
var Glucose = avaPlot.Plot.Add.Scatter(cellData.ConvertAll(c => c.time).ToArray(), cellData.ConvertAll(c => c.resources["Glucose"]).ToArray());
|
||||
Glucose.LegendText = "Glucose";
|
||||
var NADH = avaPlot.Plot.Add.Scatter(cellData.ConvertAll(c => c.time).ToArray(), cellData.ConvertAll(c => c.resources["NADH"]).ToArray());
|
||||
NADH.LegendText = "NADH";
|
||||
var NAD = avaPlot.Plot.Add.Scatter(cellData.ConvertAll(c => c.time).ToArray(), cellData.ConvertAll(c => c.resources["NAD"]).ToArray());
|
||||
NAD.LegendText = "NAD";
|
||||
var AminoAcids = avaPlot.Plot.Add.Scatter(cellData.ConvertAll(c => c.time).ToArray(), cellData.ConvertAll(c => c.resources["AminoAcids"]).ToArray());
|
||||
AminoAcids.LegendText = "AminoAcids";
|
||||
var CytosolicCa = avaPlot.Plot.Add.Scatter(cellData.ConvertAll(c => c.time).ToArray(), cellData.ConvertAll(c => c.caState.CytosolicCa).ToArray());
|
||||
CytosolicCa.LegendText = "Cytosolic Ca";
|
||||
var ER_Ca = avaPlot.Plot.Add.Scatter(cellData.ConvertAll(c => c.time).ToArray(), cellData.ConvertAll(c => c.caState.ER_Ca).ToArray());
|
||||
ER_Ca.LegendText = "ER Ca";
|
||||
avaPlot.Plot.Legend.Orientation = Orientation.Horizontal;
|
||||
avaPlot.Plot.ShowLegend(Edge.Bottom);
|
||||
avaPlot.Refresh();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:CellSimulation.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:views="clr-namespace:CellSimulation.Views"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="CellSimulation.Views.MainWindow"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
Title="CellSimulation">
|
||||
<views:MainView />
|
||||
</Window>
|
||||
@@ -0,0 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace CellSimulation.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<Project>
|
||||
<!-- https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management -->
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Avalonia packages -->
|
||||
<!-- Important: keep version in sync! -->
|
||||
<PackageVersion Include="Avalonia" Version="11.3.6" />
|
||||
<PackageVersion Include="Avalonia.Themes.Fluent" Version="11.3.6" />
|
||||
<PackageVersion Include="Avalonia.Fonts.Inter" Version="11.3.6" />
|
||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.6" />
|
||||
<PackageVersion Include="Avalonia.Desktop" Version="11.3.6" />
|
||||
<PackageVersion Include="Avalonia.iOS" Version="11.3.6" />
|
||||
<PackageVersion Include="Avalonia.Browser" Version="11.3.6" />
|
||||
<PackageVersion Include="Avalonia.Android" Version="11.3.6" />
|
||||
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageVersion Include="ScottPlot.Avalonia" Version="5.1.57" />
|
||||
<PackageVersion Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.0.1.15" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user