570 lines
17 KiB
C#
570 lines
17 KiB
C#
using System;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
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();
|
|
[JsonPropertyName("energy")]
|
|
public EnergyPool energyPool;
|
|
public Dictionary<string, double> Resources => new Dictionary<string, double>();
|
|
|
|
public static CellRessources LoadRessources(string jsonPath)
|
|
{
|
|
string json = File.ReadAllText(jsonPath);
|
|
using var doc = JsonDocument.Parse(json);
|
|
var root = doc.RootElement;
|
|
var result = new CellRessources();
|
|
|
|
// deserialice energy
|
|
if (root.TryGetProperty("energy", out JsonElement energyElement))
|
|
{
|
|
result.energyPool = JsonSerializer.Deserialize<EnergyPool>(energyElement.GetRawText());
|
|
}
|
|
|
|
foreach(var property in root.EnumerateObject())
|
|
{
|
|
if (property.NameEquals("energy"))
|
|
continue; // already handled
|
|
|
|
if (property.Value.ValueKind == JsonValueKind.Number)
|
|
{
|
|
result.Resources[property.Name] = property.Value.GetDouble();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static void SaveRessources(CellRessources ressources, string jsonPath)
|
|
{
|
|
var options = new JsonSerializerOptions { WriteIndented = true };
|
|
string json = JsonSerializer.Serialize(ressources, options);
|
|
File.WriteAllText(jsonPath, json);
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
public void TransferGTP(double amount, bool toGDP)
|
|
{
|
|
if (toGDP)
|
|
{
|
|
if (Res.Energy.GTP < amount) amount = Res.Energy.GTP;
|
|
Res.Energy.GTP -= amount;
|
|
Res.Energy.GDP += amount;
|
|
}
|
|
else
|
|
{
|
|
if (Res.Energy.GDP < amount) amount = Res.Energy.GDP;
|
|
Res.Energy.GDP -= amount;
|
|
Res.Energy.GTP += 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.F1_6BP = 0.005;
|
|
cr.Res.Carbon.GA3P = 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
|
|
{
|
|
/// <summary>
|
|
/// Adenosine-triphosphate
|
|
/// </summary>
|
|
public double ATP;
|
|
/// <summary>
|
|
/// Adenosine diphosphate
|
|
/// </summary>
|
|
public double ADP;
|
|
/// <summary>
|
|
/// Adenosine monophosphat
|
|
/// </summary>
|
|
public double AMP;
|
|
|
|
/// <summary>
|
|
/// Nicotinamide adenine dinucleotide
|
|
/// </summary>
|
|
public double NAD;
|
|
|
|
/// <summary>
|
|
/// Nicotinamide adenine dinucleotide
|
|
/// </summary>
|
|
public double NADH;
|
|
|
|
/// <summary>
|
|
/// Nicotinamide adenine dinucleotide phosphate
|
|
/// </summary>
|
|
public double NADPH;
|
|
|
|
/// <summary>
|
|
/// Guanosintriphosphat
|
|
/// </summary>
|
|
public double GTP;
|
|
|
|
/// <summary>
|
|
/// Guanosindiphosphat
|
|
/// </summary>
|
|
public double GDP;
|
|
|
|
/// <summary>
|
|
/// inorganic phosphate
|
|
/// </summary>
|
|
public double Pi;
|
|
|
|
/// <summary>
|
|
/// Pyrophosphat
|
|
/// </summary>
|
|
public double PPi;
|
|
}
|
|
|
|
/// <summary>Inorganische Phosphate</summary>
|
|
public struct Phosphate
|
|
{
|
|
/// <summary>
|
|
/// inorganic phosphate
|
|
/// </summary>
|
|
public double Pi;
|
|
|
|
/// <summary>
|
|
/// Pyrophosphat
|
|
/// </summary>
|
|
public double PPi;
|
|
}
|
|
|
|
/// <summary>Kohlenstoff- / Glykolyse-Intermediaten</summary>
|
|
public struct CarbonPool
|
|
{
|
|
public double Glucose;
|
|
|
|
/// <summary>
|
|
/// Glucose-6-phosphate
|
|
/// </summary>
|
|
public double G6P;
|
|
|
|
/// <summary>
|
|
/// Fructose-6-phosphate
|
|
/// </summary>
|
|
public double F6P;
|
|
|
|
/// <summary>
|
|
/// Fructose 1,6-bisphosphate
|
|
/// </summary>
|
|
public double F1_6BP;
|
|
|
|
/// <summary>
|
|
/// Glycerinaldehyd-3-phosphat
|
|
/// </summary>
|
|
public double GA3P;
|
|
|
|
/// <summary>
|
|
/// 1,3-Bisphosphoglycerat
|
|
/// </summary>
|
|
public double PBG13;
|
|
|
|
/// <summary>
|
|
/// 3-Phosphoglycerat
|
|
/// </summary>
|
|
public double PG3;
|
|
|
|
/// <summary>
|
|
/// 2-Phosphoglycerat
|
|
/// </summary>
|
|
public double PG2;
|
|
|
|
/// <summary>
|
|
/// Phosphoenolpyruvat
|
|
/// </summary>
|
|
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;
|
|
|
|
/// <summary>
|
|
/// Nukleosidtriphosphate
|
|
/// </summary>
|
|
public double NTP;
|
|
|
|
/// <summary>
|
|
/// Desoxyribonukleotidtriphosphate
|
|
/// </summary>
|
|
public double dNTP;
|
|
public double mRNA;
|
|
public double DNA_damage;
|
|
public double AcetylCoA;
|
|
|
|
/// <summary>
|
|
/// S-Adenosylmethionin
|
|
/// </summary>
|
|
public double SAM;
|
|
|
|
/// <summary>
|
|
/// Methionine
|
|
/// </summary>
|
|
public double MET;
|
|
|
|
/// <summary>
|
|
/// S-Adenosylhomocystein
|
|
/// </summary>
|
|
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)
|
|
|
|
/// <summary>
|
|
/// reactive oxygen species
|
|
/// </summary>
|
|
public double ROS;
|
|
|
|
/// <summary>
|
|
/// NAtrium-Ionen
|
|
/// </summary>
|
|
public double Na;
|
|
|
|
/// <summary>
|
|
/// Kalium-Ionen
|
|
/// </summary>
|
|
public double K;
|
|
|
|
public double H2O2;
|
|
}
|
|
|
|
public struct Cofactor
|
|
{
|
|
public double B12;
|
|
}
|
|
|
|
public struct Folates
|
|
{
|
|
/// <summary>
|
|
/// Tetrahydrofolsäure
|
|
/// </summary>
|
|
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();
|
|
}
|
|
}
|