use super::dna_structures::DnaDataStructure;
use crate::error::OxirsResult;
#[derive(Debug, Clone)]
pub struct CellularDivision {
pub mitotic_apparatus: MitoticApparatus,
pub checkpoint_system: CheckpointSystem,
pub cycle_state: CellCycleState,
pub dna_content: Vec<DnaDataStructure>,
}
#[derive(Debug, Clone)]
pub struct MitoticApparatus {
pub centrosomes: (Centrosome, Centrosome),
pub spindle_apparatus: SpindleApparatus,
pub kinetochores: Vec<Kinetochore>,
pub division_state: DivisionState,
}
#[derive(Debug, Clone)]
pub struct SpindleApparatus {
pub kinetochore_microtubules: Vec<Microtubule>,
pub polar_microtubules: Vec<Microtubule>,
pub astral_microtubules: Vec<Microtubule>,
pub poles: (SpindlePole, SpindlePole),
}
#[derive(Debug, Clone)]
pub struct Centrosome {
pub centrioles: (Centriole, Centriole),
pub pericentriolar_material: PericentriolarMaterial,
pub position: Position3D,
}
#[derive(Debug, Clone)]
pub struct Centriole {
pub barrel: BarrelStructure,
pub triplets: Vec<TripletMicrotubule>,
pub orientation: Orientation,
}
#[derive(Debug, Clone)]
pub struct BarrelStructure {
pub diameter: f64,
pub length: f64,
pub wall_thickness: f64,
}
#[derive(Debug, Clone)]
pub struct TripletMicrotubule {
pub a_tubule: Microtubule,
pub b_tubule: Microtubule,
pub c_tubule: Microtubule,
}
#[derive(Debug, Clone)]
pub struct Microtubule {
pub protofilaments: Vec<Protofilament>,
pub length: f64,
pub dynamic_state: DynamicState,
pub plus_end: MicrotubuleEnd,
pub minus_end: MicrotubuleEnd,
}
#[derive(Debug, Clone)]
pub struct Protofilament {
pub tubulin_dimers: Vec<TubulinDimer>,
pub lateral_bonds: Vec<LateralBond>,
}
#[derive(Debug, Clone)]
pub struct TubulinDimer {
pub alpha_tubulin: AlphaTubulin,
pub beta_tubulin: BetaTubulin,
pub nucleotide_state: NucleotideState,
}
#[derive(Debug, Clone)]
pub struct AlphaTubulin {
pub molecular_weight: f64,
pub conformation: TubulinConformation,
}
#[derive(Debug, Clone)]
pub struct BetaTubulin {
pub molecular_weight: f64,
pub conformation: TubulinConformation,
pub gtp_binding_site: GtpBindingSite,
}
#[derive(Debug, Clone)]
pub struct CheckpointSystem {
pub spindle_checkpoint: SpindleCheckpoint,
pub dna_damage_checkpoint: DnaDamageCheckpoint,
pub replication_checkpoint: ReplicationCheckpoint,
}
#[derive(Debug, Clone)]
pub struct SpindleCheckpoint {
pub mad_proteins: Vec<MadProtein>,
pub bub_proteins: Vec<BubProtein>,
pub apc_c_regulation: ApcCRegulation,
}
#[derive(Debug, Clone)]
pub struct MadProtein {
pub protein_type: MadProteinType,
pub activity_level: f64,
pub localization: ProteinLocalization,
}
#[derive(Debug, Clone)]
pub struct BubProtein {
pub protein_type: BubProteinType,
pub activity_level: f64,
pub kinetochore_binding: bool,
}
#[derive(Debug, Clone)]
pub struct ApcCRegulation {
pub cdc20_level: f64,
pub cdh1_level: f64,
pub activity_state: ApcCActivityState,
}
#[derive(Debug, Clone)]
pub enum CellCycleState {
G1,
S,
G2,
M(MitosisPhase),
}
#[derive(Debug, Clone)]
pub enum MitosisPhase {
Prophase,
Prometaphase,
Metaphase,
Anaphase(AnaphaseStage),
Telophase,
}
#[derive(Debug, Clone)]
pub enum AnaphaseStage {
A, B, }
#[derive(Debug, Clone)]
pub enum DivisionState {
Interphase,
Mitosis(MitosisPhase),
Cytokinesis,
}
#[derive(Debug, Clone)]
pub struct Position3D {
pub x: f64,
pub y: f64,
pub z: f64,
}
#[derive(Debug, Clone)]
pub struct Orientation {
pub angle: f64,
pub axis: Vec3D,
}
#[derive(Debug, Clone)]
pub struct Vec3D {
pub x: f64,
pub y: f64,
pub z: f64,
}
#[derive(Debug, Clone)]
pub enum DynamicState {
Growing,
Shrinking,
Paused,
}
#[derive(Debug, Clone)]
pub struct MicrotubuleEnd {
pub cap_structure: CapStructure,
pub growth_rate: f64,
}
#[derive(Debug, Clone)]
pub enum CapStructure {
GtpCap,
GdpCap,
Frayed,
}
#[derive(Debug, Clone)]
pub struct LateralBond {
pub strength: f64,
pub bond_type: BondType,
}
#[derive(Debug, Clone)]
pub enum BondType {
Hydrogen,
VanDerWaals,
Electrostatic,
}
#[derive(Debug, Clone)]
#[allow(clippy::upper_case_acronyms)]
pub enum NucleotideState {
GTP,
GDP,
}
#[derive(Debug, Clone)]
pub enum TubulinConformation {
Straight,
Curved,
Intermediate(f64),
}
#[derive(Debug, Clone)]
pub struct GtpBindingSite {
pub occupied: bool,
pub binding_affinity: f64,
}
#[derive(Debug, Clone)]
pub struct SpindlePole {
pub centrosome: Centrosome,
pub microtubule_nucleation_sites: Vec<NucleationSite>,
}
#[derive(Debug, Clone)]
pub struct NucleationSite {
pub gamma_tubulin_complex: GammaTubulinComplex,
pub activity: f64,
}
#[derive(Debug, Clone)]
pub struct GammaTubulinComplex {
pub gamma_tubulin_count: usize,
pub associated_proteins: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct Kinetochore {
pub chromosome_attachment: bool,
pub microtubule_attachments: Vec<MicrotubuleAttachment>,
pub tension: f64,
}
#[derive(Debug, Clone)]
pub struct MicrotubuleAttachment {
pub microtubule_id: String,
pub attachment_strength: f64,
pub attachment_type: AttachmentType,
}
#[derive(Debug, Clone)]
pub enum AttachmentType {
Amphitelic, Syntelic, Merotelic, Monotelic, }
#[derive(Debug, Clone)]
pub struct PericentriolarMaterial {
pub gamma_tubulin: f64,
pub pericentrin: f64,
pub ninein: f64,
}
#[derive(Debug, Clone)]
pub struct DnaDamageCheckpoint {
pub atm_activity: f64,
pub atr_activity: f64,
pub p53_level: f64,
}
#[derive(Debug, Clone)]
pub struct ReplicationCheckpoint {
pub replication_forks: Vec<ReplicationFork>,
pub checkpoint_active: bool,
}
#[derive(Debug, Clone)]
pub struct ReplicationFork {
pub position: usize,
pub stalled: bool,
pub proteins: Vec<String>,
}
#[derive(Debug, Clone)]
pub enum MadProteinType {
Mad1,
Mad2,
Mad3,
}
#[derive(Debug, Clone)]
pub enum BubProteinType {
Bub1,
Bub3,
BubR1,
}
#[derive(Debug, Clone)]
pub enum ProteinLocalization {
Kinetochore,
SpindlePole,
Cytoplasm,
Nucleus,
}
#[derive(Debug, Clone)]
pub enum ApcCActivityState {
Active,
Inactive,
PartiallyActive(f64),
}
impl CellularDivision {
pub fn new() -> Self {
Self {
mitotic_apparatus: MitoticApparatus::new(),
checkpoint_system: CheckpointSystem::new(),
cycle_state: CellCycleState::G1,
dna_content: Vec::new(),
}
}
pub fn initiate_division(&mut self) -> OxirsResult<()> {
self.progress_to_mitosis()?;
self.execute_mitosis()?;
self.complete_division()?;
Ok(())
}
fn progress_to_mitosis(&mut self) -> OxirsResult<()> {
match self.cycle_state {
CellCycleState::G1 => {
self.cycle_state = CellCycleState::S;
self.replicate_dna()?;
self.cycle_state = CellCycleState::G2;
}
CellCycleState::G2 => {
if self.checkpoint_system.check_dna_integrity()? {
self.cycle_state = CellCycleState::M(MitosisPhase::Prophase);
}
}
_ => {
}
}
Ok(())
}
fn execute_mitosis(&mut self) -> OxirsResult<()> {
let current_phase = if let CellCycleState::M(ref phase) = self.cycle_state {
phase.clone()
} else {
return Ok(());
};
let new_phase = match current_phase {
MitosisPhase::Prophase => {
self.mitotic_apparatus.prepare_spindle()?;
MitosisPhase::Prometaphase
}
MitosisPhase::Prometaphase => {
self.mitotic_apparatus.attach_chromosomes()?;
MitosisPhase::Metaphase
}
MitosisPhase::Metaphase => {
if self
.checkpoint_system
.spindle_checkpoint
.check_alignment()?
{
MitosisPhase::Anaphase(AnaphaseStage::A)
} else {
MitosisPhase::Metaphase
}
}
MitosisPhase::Anaphase(stage) => match stage {
AnaphaseStage::A => {
self.separate_chromosomes()?;
MitosisPhase::Anaphase(AnaphaseStage::B)
}
AnaphaseStage::B => {
self.elongate_spindle()?;
MitosisPhase::Telophase
}
},
MitosisPhase::Telophase => {
self.reform_nuclei()?;
self.cycle_state = CellCycleState::G1;
return Ok(());
}
};
if let CellCycleState::M(ref mut phase) = self.cycle_state {
*phase = new_phase;
}
Ok(())
}
fn complete_division(&mut self) -> OxirsResult<()> {
self.mitotic_apparatus.reset()?;
let (daughter1, _daughter2) = self.distribute_dna_content()?;
self.dna_content = daughter1;
Ok(())
}
fn replicate_dna(&mut self) -> OxirsResult<()> {
let mut replicated = Vec::new();
for dna in &self.dna_content {
let mut copy = dna.clone();
copy.replication_machinery
.replicate_strand(&dna.primary_strand)?;
replicated.push(copy);
}
self.dna_content.extend(replicated);
Ok(())
}
fn separate_chromosomes(&mut self) -> OxirsResult<()> {
for kinetochore in &mut self.mitotic_apparatus.kinetochores {
kinetochore.tension = 0.0;
for attachment in &mut kinetochore.microtubule_attachments {
if matches!(attachment.attachment_type, AttachmentType::Amphitelic) {
attachment.attachment_strength *= 0.5; }
}
}
Ok(())
}
fn elongate_spindle(&mut self) -> OxirsResult<()> {
for microtubule in &mut self.mitotic_apparatus.spindle_apparatus.polar_microtubules {
microtubule.length *= 1.5; microtubule.dynamic_state = DynamicState::Growing;
}
Ok(())
}
fn reform_nuclei(&mut self) -> OxirsResult<()> {
Ok(())
}
fn distribute_dna_content(
&self,
) -> OxirsResult<(Vec<DnaDataStructure>, Vec<DnaDataStructure>)> {
let midpoint = self.dna_content.len() / 2;
let daughter1 = self.dna_content[..midpoint].to_vec();
let daughter2 = self.dna_content[midpoint..].to_vec();
Ok((daughter1, daughter2))
}
pub fn add_dna_content(&mut self, dna: DnaDataStructure) {
self.dna_content.push(dna);
}
pub fn current_state(&self) -> &CellCycleState {
&self.cycle_state
}
}
impl Default for MitoticApparatus {
fn default() -> Self {
Self::new()
}
}
impl MitoticApparatus {
pub fn new() -> Self {
Self {
centrosomes: (Centrosome::new(), Centrosome::new()),
spindle_apparatus: SpindleApparatus::new(),
kinetochores: Vec::new(),
division_state: DivisionState::Interphase,
}
}
pub fn prepare_spindle(&mut self) -> OxirsResult<()> {
self.division_state = DivisionState::Mitosis(MitosisPhase::Prophase);
self.centrosomes.0.position = Position3D {
x: -10.0,
y: 0.0,
z: 0.0,
};
self.centrosomes.1.position = Position3D {
x: 10.0,
y: 0.0,
z: 0.0,
};
self.spindle_apparatus.nucleate_microtubules()?;
Ok(())
}
pub fn attach_chromosomes(&mut self) -> OxirsResult<()> {
for i in 0..10 {
let kinetochore = Kinetochore {
chromosome_attachment: true,
microtubule_attachments: vec![MicrotubuleAttachment {
microtubule_id: format!("mt_{i}"),
attachment_strength: 1.0,
attachment_type: AttachmentType::Amphitelic,
}],
tension: 0.5,
};
self.kinetochores.push(kinetochore);
}
Ok(())
}
pub fn reset(&mut self) -> OxirsResult<()> {
self.division_state = DivisionState::Interphase;
self.kinetochores.clear();
self.spindle_apparatus = SpindleApparatus::new();
Ok(())
}
}
impl Default for SpindleApparatus {
fn default() -> Self {
Self::new()
}
}
impl SpindleApparatus {
pub fn new() -> Self {
Self {
kinetochore_microtubules: Vec::new(),
polar_microtubules: Vec::new(),
astral_microtubules: Vec::new(),
poles: (SpindlePole::new(), SpindlePole::new()),
}
}
pub fn nucleate_microtubules(&mut self) -> OxirsResult<()> {
for i in 0..20 {
let microtubule = Microtubule::new(format!("kt_mt_{i}"));
self.kinetochore_microtubules.push(microtubule);
}
for i in 0..10 {
let microtubule = Microtubule::new(format!("polar_mt_{i}"));
self.polar_microtubules.push(microtubule);
}
for i in 0..15 {
let microtubule = Microtubule::new(format!("astral_mt_{i}"));
self.astral_microtubules.push(microtubule);
}
Ok(())
}
}
impl Default for CheckpointSystem {
fn default() -> Self {
Self::new()
}
}
impl CheckpointSystem {
pub fn new() -> Self {
Self {
spindle_checkpoint: SpindleCheckpoint::new(),
dna_damage_checkpoint: DnaDamageCheckpoint::new(),
replication_checkpoint: ReplicationCheckpoint::new(),
}
}
pub fn check_dna_integrity(&self) -> OxirsResult<bool> {
let damage_level =
self.dna_damage_checkpoint.atm_activity + self.dna_damage_checkpoint.atr_activity;
Ok(damage_level < 0.1) }
}
impl Default for SpindleCheckpoint {
fn default() -> Self {
Self::new()
}
}
impl SpindleCheckpoint {
pub fn new() -> Self {
Self {
mad_proteins: vec![
MadProtein {
protein_type: MadProteinType::Mad1,
activity_level: 1.0,
localization: ProteinLocalization::Kinetochore,
},
MadProtein {
protein_type: MadProteinType::Mad2,
activity_level: 1.0,
localization: ProteinLocalization::Kinetochore,
},
],
bub_proteins: vec![
BubProtein {
protein_type: BubProteinType::Bub1,
activity_level: 1.0,
kinetochore_binding: true,
},
BubProtein {
protein_type: BubProteinType::Bub3,
activity_level: 1.0,
kinetochore_binding: true,
},
],
apc_c_regulation: ApcCRegulation {
cdc20_level: 0.5,
cdh1_level: 0.1,
activity_state: ApcCActivityState::Inactive,
},
}
}
pub fn check_alignment(&self) -> OxirsResult<bool> {
let mad_activity: f64 = self.mad_proteins.iter().map(|p| p.activity_level).sum();
Ok(mad_activity < 0.5)
}
}
impl Default for Centrosome {
fn default() -> Self {
Self::new()
}
}
impl Centrosome {
pub fn new() -> Self {
Self {
centrioles: (Centriole::new(), Centriole::new()),
pericentriolar_material: PericentriolarMaterial {
gamma_tubulin: 1.0,
pericentrin: 1.0,
ninein: 1.0,
},
position: Position3D {
x: 0.0,
y: 0.0,
z: 0.0,
},
}
}
}
impl Default for Centriole {
fn default() -> Self {
Self::new()
}
}
impl Centriole {
pub fn new() -> Self {
Self {
barrel: BarrelStructure {
diameter: 0.2,
length: 0.5,
wall_thickness: 0.02,
},
triplets: Vec::new(),
orientation: Orientation {
angle: 0.0,
axis: Vec3D {
x: 0.0,
y: 0.0,
z: 1.0,
},
},
}
}
}
impl Microtubule {
pub fn new(_id: String) -> Self {
Self {
protofilaments: Vec::new(),
length: 10.0,
dynamic_state: DynamicState::Growing,
plus_end: MicrotubuleEnd {
cap_structure: CapStructure::GtpCap,
growth_rate: 1.0,
},
minus_end: MicrotubuleEnd {
cap_structure: CapStructure::GdpCap,
growth_rate: 0.0,
},
}
}
}
impl Default for SpindlePole {
fn default() -> Self {
Self::new()
}
}
impl SpindlePole {
pub fn new() -> Self {
Self {
centrosome: Centrosome::new(),
microtubule_nucleation_sites: Vec::new(),
}
}
}
impl Default for DnaDamageCheckpoint {
fn default() -> Self {
Self::new()
}
}
impl DnaDamageCheckpoint {
pub fn new() -> Self {
Self {
atm_activity: 0.0,
atr_activity: 0.0,
p53_level: 0.1,
}
}
}
impl Default for ReplicationCheckpoint {
fn default() -> Self {
Self::new()
}
}
impl ReplicationCheckpoint {
pub fn new() -> Self {
Self {
replication_forks: Vec::new(),
checkpoint_active: false,
}
}
}
impl Default for CellularDivision {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cellular_division_creation() {
let division = CellularDivision::new();
assert!(matches!(division.cycle_state, CellCycleState::G1));
assert_eq!(division.dna_content.len(), 0);
}
#[test]
fn test_mitotic_apparatus() {
let apparatus = MitoticApparatus::new();
assert!(matches!(
apparatus.division_state,
DivisionState::Interphase
));
assert_eq!(apparatus.kinetochores.len(), 0);
}
#[test]
fn test_checkpoint_system() {
let checkpoint = CheckpointSystem::new();
assert!(checkpoint
.check_dna_integrity()
.expect("operation should succeed"));
}
}