InitalCommit

This commit is contained in:
WyanMueller
2025-11-16 10:30:26 +01:00
parent 8b0b73bba8
commit d2e409d10f
73 changed files with 3209 additions and 0 deletions
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
+115
View File
@@ -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
};
}
}
}
+101
View File
@@ -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));
}
}
}
+30
View File
@@ -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;
}
}
}
+50
View File
@@ -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;
}
}
}
+39
View File
@@ -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;
}
}
}
+55
View File
@@ -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");
}
}
}
}
}
+61
View File
@@ -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);
}
}
}
}
+70
View File
@@ -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);
}
}
}
}
+67
View File
@@ -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);
}
}
}
}
}
+61
View File
@@ -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);
}
}
}
}
+397
View File
@@ -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();
}
}
+20
View File
@@ -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;
}
}
}