use crate::{
GenomeMetadata, GenomeSignatures, GenomeStats, MorphologyRegistry, PhysiologyConfig,
RuntimeGenome,
};
use feagi_structures::genomic::cortical_area::CoreCorticalType;
use feagi_structures::genomic::cortical_area::{CorticalArea, CorticalAreaDimensions};
use feagi_structures::genomic::descriptors::GenomeCoordinate3D;
use serde_json::Value;
use std::collections::HashMap;
pub const ESSENTIAL_GENOME_JSON: &str = include_str!("../genomes/essential_genome.json");
pub const BAREBONES_GENOME_JSON: &str = include_str!("../genomes/barebones_genome.json");
pub const TEST_GENOME_JSON: &str = include_str!("../genomes/test_genome.json");
pub const VISION_GENOME_JSON: &str = include_str!("../genomes/vision_genome.json");
pub fn get_default_neural_properties() -> HashMap<String, Value> {
let mut props = HashMap::new();
props.insert("per_voxel_neuron_cnt".to_string(), Value::from(1));
props.insert("synapse_attractivity".to_string(), Value::from(100.0));
props.insert("degeneration".to_string(), Value::from(0.0));
props.insert("psp_uniform_distribution".to_string(), Value::from(true));
props.insert("postsynaptic_current_max".to_string(), Value::from(10000.0));
props.insert("postsynaptic_current".to_string(), Value::from(500.0));
props.insert("firing_threshold".to_string(), Value::from(0.1));
props.insert("refractory_period".to_string(), Value::from(0));
props.insert("leak_coefficient".to_string(), Value::from(0.0));
props.insert("leak_variability".to_string(), Value::from(0.0));
props.insert("consecutive_fire_cnt_max".to_string(), Value::from(0));
props.insert("snooze_length".to_string(), Value::from(0));
props.insert("mp_charge_accumulation".to_string(), Value::from(false));
props.insert("mp_driven_psp".to_string(), Value::from(false));
props.insert("neuron_excitability".to_string(), Value::from(1.0));
props.insert("visualization".to_string(), Value::from(true));
props.insert("memory_twin_of".to_string(), Value::Null);
props.insert(
"cortical_mapping_dst".to_string(),
Value::Object(serde_json::Map::new()),
);
props
}
pub fn create_death_area() -> CorticalArea {
let cortical_id = CoreCorticalType::Death.to_cortical_id();
let cortical_type = cortical_id
.as_cortical_type()
.expect("Death cortical ID should map to Core type");
let mut area = CorticalArea::new(
cortical_id,
0, "Death".to_string(),
CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
GenomeCoordinate3D::new(0, 0, -20),
cortical_type,
)
.expect("Failed to create _death area");
let mut props = get_default_neural_properties();
props.insert("cortical_group".to_string(), Value::from("CORE"));
props.insert("2d_coordinate".to_string(), Value::from(vec![-10, -20]));
area.properties = props;
area
}
pub fn create_power_area() -> CorticalArea {
let cortical_id = CoreCorticalType::Power.to_cortical_id();
let cortical_type = cortical_id
.as_cortical_type()
.expect("Power cortical ID should map to Core type");
let mut area = CorticalArea::new(
cortical_id,
1, "Brain_Power".to_string(),
CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
GenomeCoordinate3D::new(0, 0, -20),
cortical_type,
)
.expect("Failed to create _power area");
let mut props = get_default_neural_properties();
props.insert("cortical_group".to_string(), Value::from("CORE"));
props.insert("2d_coordinate".to_string(), Value::from(vec![-10, -10]));
props.insert("firing_threshold".to_string(), Value::from(0.1));
props.insert("postsynaptic_current".to_string(), Value::from(500.0));
props.insert("neuron_excitability".to_string(), Value::from(100.0));
area.properties = props;
area
}
pub fn create_fatigue_area() -> CorticalArea {
let cortical_id = CoreCorticalType::Fatigue.to_cortical_id();
let cortical_type = cortical_id
.as_cortical_type()
.expect("Fatigue cortical ID should map to Core type");
let mut area = CorticalArea::new(
cortical_id,
2, "Fatigue".to_string(),
CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
GenomeCoordinate3D::new(0, 0, -30),
cortical_type,
)
.expect("Failed to create _fatigue area");
let mut props = get_default_neural_properties();
props.insert("cortical_group".to_string(), Value::from("CORE"));
props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 0]));
area.properties = props;
area
}
pub fn create_pain_area() -> CorticalArea {
let cortical_id = CoreCorticalType::Pain.to_cortical_id();
let cortical_type = cortical_id
.as_cortical_type()
.expect("Pain cortical ID should map to Core type");
let mut area = CorticalArea::new(
cortical_id,
3, "Pain".to_string(),
CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
GenomeCoordinate3D::new(0, 0, -40),
cortical_type,
)
.expect("Failed to create _pain area");
let mut props = get_default_neural_properties();
props.insert("cortical_group".to_string(), Value::from("CORE"));
props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 10]));
area.properties = props;
area
}
pub fn create_pleasure_area() -> CorticalArea {
let cortical_id = CoreCorticalType::Pleasure.to_cortical_id();
let cortical_type = cortical_id
.as_cortical_type()
.expect("Pleasure cortical ID should map to Core type");
let mut area = CorticalArea::new(
cortical_id,
4, "Pleasure".to_string(),
CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
GenomeCoordinate3D::new(0, 0, -50),
cortical_type,
)
.expect("Failed to create _pleasure area");
let mut props = get_default_neural_properties();
props.insert("cortical_group".to_string(), Value::from("CORE"));
props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 20]));
area.properties = props;
area
}
pub fn create_fear_area() -> CorticalArea {
let cortical_id = CoreCorticalType::Fear.to_cortical_id();
let cortical_type = cortical_id
.as_cortical_type()
.expect("Fear cortical ID should map to Core type");
let mut area = CorticalArea::new(
cortical_id,
5, "Fear".to_string(),
CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
GenomeCoordinate3D::new(0, 0, -60),
cortical_type,
)
.expect("Failed to create _fear area");
let mut props = get_default_neural_properties();
props.insert("cortical_group".to_string(), Value::from("CORE"));
props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 30]));
area.properties = props;
area
}
pub fn create_hope_area() -> CorticalArea {
let cortical_id = CoreCorticalType::Hope.to_cortical_id();
let cortical_type = cortical_id
.as_cortical_type()
.expect("Hope cortical ID should map to Core type");
let mut area = CorticalArea::new(
cortical_id,
6, "Hope".to_string(),
CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
GenomeCoordinate3D::new(0, 0, -70),
cortical_type,
)
.expect("Failed to create _hope area");
let mut props = get_default_neural_properties();
props.insert("cortical_group".to_string(), Value::from("CORE"));
props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 40]));
area.properties = props;
area
}
pub fn create_minimal_genome(genome_id: String, genome_title: String) -> RuntimeGenome {
RuntimeGenome {
metadata: GenomeMetadata {
genome_id,
genome_title,
genome_description: "Minimal genome template".to_string(),
version: "2.0".to_string(),
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs_f64(),
brain_regions_root: None, },
cortical_areas: HashMap::new(),
brain_regions: HashMap::new(),
morphologies: MorphologyRegistry::new(),
physiology: PhysiologyConfig::default(),
signatures: GenomeSignatures {
genome: String::new(),
blueprint: String::new(),
physiology: String::new(),
morphologies: None,
},
stats: GenomeStats::default(),
}
}
pub fn create_genome_with_core_areas(genome_id: String, genome_title: String) -> RuntimeGenome {
let mut genome = create_minimal_genome(genome_id, genome_title);
let death_id =
crate::genome::parser::string_to_cortical_id("_death").expect("Valid cortical ID");
let power_id =
crate::genome::parser::string_to_cortical_id("_power").expect("Valid cortical ID");
let fatigue_id =
crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid cortical ID");
let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid cortical ID");
let pleasure_id =
crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid cortical ID");
let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid cortical ID");
let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid cortical ID");
genome.cortical_areas.insert(death_id, create_death_area());
genome.cortical_areas.insert(power_id, create_power_area());
genome
.cortical_areas
.insert(fatigue_id, create_fatigue_area());
genome.cortical_areas.insert(pain_id, create_pain_area());
genome
.cortical_areas
.insert(pleasure_id, create_pleasure_area());
genome.cortical_areas.insert(fear_id, create_fear_area());
genome.cortical_areas.insert(hope_id, create_hope_area());
genome
}
pub fn create_genome_with_core_morphologies(
genome_id: String,
genome_title: String,
) -> RuntimeGenome {
let mut genome = create_minimal_genome(genome_id, genome_title);
add_core_morphologies(&mut genome.morphologies);
genome
}
pub fn ensure_core_components(genome: &mut RuntimeGenome) -> (usize, usize) {
let mut areas_added = 0;
let mut morphologies_added = 0;
let death_id =
crate::genome::parser::string_to_cortical_id("_death").expect("Valid cortical ID");
let power_id =
crate::genome::parser::string_to_cortical_id("_power").expect("Valid cortical ID");
let fatigue_id =
crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid cortical ID");
let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid cortical ID");
let pleasure_id =
crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid cortical ID");
let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid cortical ID");
let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid cortical ID");
if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(death_id) {
let death_area = create_death_area();
e.insert(death_area);
areas_added += 1;
tracing::info!("Added missing core area: _death (cortical_idx=0)");
}
if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(power_id) {
let power_area = create_power_area();
e.insert(power_area);
areas_added += 1;
tracing::info!("Added missing core area: _power (cortical_idx=1)");
}
if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(fatigue_id) {
let fatigue_area = create_fatigue_area();
e.insert(fatigue_area);
areas_added += 1;
tracing::info!("Added missing core area: _fatigue (cortical_idx=2)");
}
if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(pain_id) {
let pain_area = create_pain_area();
e.insert(pain_area);
areas_added += 1;
tracing::info!("Added missing core area: _pain (cortical_idx=3)");
}
if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(pleasure_id) {
let pleasure_area = create_pleasure_area();
e.insert(pleasure_area);
areas_added += 1;
tracing::info!("Added missing core area: _pleasure (cortical_idx=4)");
}
if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(fear_id) {
let fear_area = create_fear_area();
e.insert(fear_area);
areas_added += 1;
tracing::info!("Added missing core area: _fear (cortical_idx=5)");
}
if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(hope_id) {
let hope_area = create_hope_area();
e.insert(hope_area);
areas_added += 1;
tracing::info!("Added missing core area: _hope (cortical_idx=6)");
}
let required_morphologies = vec![
"block_to_block",
"projector",
"centered_projector",
"transpose_xy",
"transpose_yz",
"transpose_xz",
"sweeper",
"last_to_first",
"first_to_last",
"bitmask_encoder_x",
"bitmask_encoder_y",
"bitmask_encoder_z",
"bitmask_decoder_x",
"bitmask_decoder_y",
"bitmask_decoder_z",
"episodic_memory",
"memory_replay",
"associative_memory",
"rotator_z",
"all_to_0-0-0",
"0-0-0_to_all",
"tile",
"lateral_+x",
"lateral_-x",
"lateral_+y",
"lateral_-y",
"lateral_+z",
"lateral_-z",
];
for morph_name in required_morphologies {
if !genome.morphologies.contains(morph_name) {
morphologies_added += 1;
}
}
if morphologies_added > 0 {
add_core_morphologies(&mut genome.morphologies);
tracing::info!("Added {} missing core morphologies", morphologies_added);
}
(areas_added, morphologies_added)
}
pub fn add_core_morphologies(registry: &mut MorphologyRegistry) {
use crate::{Morphology, MorphologyParameters, MorphologyType};
registry.add_morphology(
"block_to_block".to_string(),
Morphology {
morphology_type: MorphologyType::Vectors,
parameters: MorphologyParameters::Vectors {
vectors: vec![[0, 0, 0]],
},
class: "core".to_string(),
},
);
registry.add_morphology(
"projector".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"centered_projector".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"transpose_xy".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"transpose_yz".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"transpose_xz".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"sweeper".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"last_to_first".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"first_to_last".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"episodic_memory".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"memory_replay".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"associative_memory".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"rotator_z".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"bitmask_encoder_x".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"bitmask_encoder_y".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"bitmask_encoder_z".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"bitmask_decoder_x".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"bitmask_decoder_y".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"bitmask_decoder_z".to_string(),
Morphology {
morphology_type: MorphologyType::Functions,
parameters: MorphologyParameters::Functions {},
class: "core".to_string(),
},
);
registry.add_morphology(
"all_to_0-0-0".to_string(),
Morphology {
morphology_type: MorphologyType::Patterns,
parameters: MorphologyParameters::Patterns {
patterns: vec![[
vec![
crate::PatternElement::Wildcard,
crate::PatternElement::Wildcard,
crate::PatternElement::Wildcard,
],
vec![
crate::PatternElement::Value(0),
crate::PatternElement::Value(0),
crate::PatternElement::Value(0),
],
]],
},
class: "core".to_string(),
},
);
registry.add_morphology(
"0-0-0_to_all".to_string(),
Morphology {
morphology_type: MorphologyType::Patterns,
parameters: MorphologyParameters::Patterns {
patterns: vec![[
vec![
crate::PatternElement::Value(0),
crate::PatternElement::Value(0),
crate::PatternElement::Value(0),
],
vec![
crate::PatternElement::Wildcard,
crate::PatternElement::Wildcard,
crate::PatternElement::Wildcard,
],
]],
},
class: "core".to_string(),
},
);
registry.add_morphology(
"tile".to_string(),
Morphology {
morphology_type: MorphologyType::Composite,
parameters: MorphologyParameters::Composite {
src_seed: [16, 16, 1],
src_pattern: vec![[1, 0], [1, 0], [1, 0]],
mapper_morphology: "projector".to_string(),
},
class: "core".to_string(),
},
);
registry.add_morphology(
"lateral_+x".to_string(),
Morphology {
morphology_type: MorphologyType::Vectors,
parameters: MorphologyParameters::Vectors {
vectors: vec![[1, 0, 0]],
},
class: "core".to_string(),
},
);
registry.add_morphology(
"lateral_-x".to_string(),
Morphology {
morphology_type: MorphologyType::Vectors,
parameters: MorphologyParameters::Vectors {
vectors: vec![[-1, 0, 0]],
},
class: "core".to_string(),
},
);
registry.add_morphology(
"lateral_+y".to_string(),
Morphology {
morphology_type: MorphologyType::Vectors,
parameters: MorphologyParameters::Vectors {
vectors: vec![[0, 1, 0]],
},
class: "core".to_string(),
},
);
registry.add_morphology(
"lateral_-y".to_string(),
Morphology {
morphology_type: MorphologyType::Vectors,
parameters: MorphologyParameters::Vectors {
vectors: vec![[0, -1, 0]],
},
class: "core".to_string(),
},
);
registry.add_morphology(
"lateral_+z".to_string(),
Morphology {
morphology_type: MorphologyType::Vectors,
parameters: MorphologyParameters::Vectors {
vectors: vec![[0, 0, 1]],
},
class: "core".to_string(),
},
);
registry.add_morphology(
"lateral_-z".to_string(),
Morphology {
morphology_type: MorphologyType::Vectors,
parameters: MorphologyParameters::Vectors {
vectors: vec![[0, 0, -1]],
},
class: "core".to_string(),
},
);
}
pub fn load_essential_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
use crate::genome::loader::load_genome_from_json;
let mut genome = load_genome_from_json(ESSENTIAL_GENOME_JSON)?;
let (areas_added, morphs_added) = ensure_core_components(&mut genome);
if areas_added > 0 || morphs_added > 0 {
tracing::info!(
"Essential genome: added {} core areas, {} core morphologies",
areas_added,
morphs_added
);
}
Ok(genome)
}
pub fn load_barebones_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
use crate::genome::loader::load_genome_from_json;
let mut genome = load_genome_from_json(BAREBONES_GENOME_JSON)?;
let (areas_added, morphs_added) = ensure_core_components(&mut genome);
if areas_added > 0 || morphs_added > 0 {
tracing::info!(
"Barebones genome: added {} core areas, {} core morphologies",
areas_added,
morphs_added
);
}
Ok(genome)
}
pub fn load_test_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
use crate::genome::loader::load_genome_from_json;
let mut genome = load_genome_from_json(TEST_GENOME_JSON)?;
let (areas_added, morphs_added) = ensure_core_components(&mut genome);
if areas_added > 0 || morphs_added > 0 {
tracing::info!(
"Test genome: added {} core areas, {} core morphologies",
areas_added,
morphs_added
);
}
Ok(genome)
}
pub fn load_vision_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
use crate::genome::loader::load_genome_from_json;
let mut genome = load_genome_from_json(VISION_GENOME_JSON)?;
let (areas_added, morphs_added) = ensure_core_components(&mut genome);
if areas_added > 0 || morphs_added > 0 {
tracing::info!(
"Vision genome: added {} core areas, {} core morphologies",
areas_added,
morphs_added
);
}
Ok(genome)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_minimal_genome() {
let genome = create_minimal_genome("test_genome".to_string(), "Test Genome".to_string());
assert_eq!(genome.metadata.genome_id, "test_genome");
assert_eq!(genome.metadata.version, "2.0");
assert_eq!(genome.cortical_areas.len(), 0);
assert_eq!(genome.morphologies.count(), 0);
}
#[test]
fn test_create_genome_with_core_areas() {
let genome =
create_genome_with_core_areas("test_genome".to_string(), "Test Genome".to_string());
assert_eq!(genome.metadata.genome_id, "test_genome");
assert_eq!(genome.cortical_areas.len(), 7);
let death_id = crate::genome::parser::string_to_cortical_id("_death").expect("Valid ID");
let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
let fatigue_id =
crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid ID");
let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid ID");
let pleasure_id =
crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid ID");
let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid ID");
let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid ID");
assert!(genome.cortical_areas.contains_key(&death_id));
assert!(genome.cortical_areas.contains_key(&power_id));
assert!(genome.cortical_areas.contains_key(&fatigue_id));
assert!(genome.cortical_areas.contains_key(&pain_id));
assert!(genome.cortical_areas.contains_key(&pleasure_id));
assert!(genome.cortical_areas.contains_key(&fear_id));
assert!(genome.cortical_areas.contains_key(&hope_id));
let power = genome.cortical_areas.get(&power_id).unwrap();
assert_eq!(power.cortical_id.as_base_64(), power_id.as_base_64());
assert_eq!(power.cortical_idx, 1);
assert_eq!(power.dimensions.width, 1);
assert_eq!(power.dimensions.height, 1);
assert_eq!(power.dimensions.depth, 1);
}
#[test]
fn test_create_genome_with_core_morphologies() {
let genome = create_genome_with_core_morphologies(
"test_genome".to_string(),
"Test Genome".to_string(),
);
assert_eq!(genome.metadata.genome_id, "test_genome");
assert!(genome.morphologies.count() > 0);
assert!(genome.morphologies.contains("block_to_block"));
assert!(genome.morphologies.contains("projector"));
assert!(genome.morphologies.contains("centered_projector"));
assert!(genome.morphologies.contains("transpose_xy"));
assert!(genome.morphologies.contains("transpose_yz"));
assert!(genome.morphologies.contains("transpose_xz"));
assert!(genome.morphologies.contains("first_to_last"));
assert!(genome.morphologies.contains("lateral_+x"));
}
#[test]
fn test_add_core_morphologies() {
let mut registry = MorphologyRegistry::new();
add_core_morphologies(&mut registry);
assert!(registry.count() >= 11);
assert!(registry.contains("block_to_block"));
assert!(registry.contains("projector"));
assert!(registry.contains("centered_projector"));
assert!(registry.contains("transpose_xy"));
assert!(registry.contains("transpose_yz"));
assert!(registry.contains("transpose_xz"));
assert!(registry.contains("first_to_last"));
assert!(registry.contains("all_to_0-0-0"));
assert!(registry.contains("lateral_+x"));
assert!(registry.contains("lateral_-z"));
}
#[test]
fn test_embedded_genomes_exist() {
#[allow(clippy::const_is_empty)]
{
assert!(!ESSENTIAL_GENOME_JSON.is_empty());
assert!(!BAREBONES_GENOME_JSON.is_empty());
assert!(!TEST_GENOME_JSON.is_empty());
assert!(!VISION_GENOME_JSON.is_empty());
}
}
#[test]
fn test_load_essential_genome() {
let genome = load_essential_genome().expect("Failed to load essential genome");
assert!(!genome.cortical_areas.is_empty());
let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
assert!(genome.cortical_areas.contains_key(&power_id));
}
#[test]
fn test_ensure_core_components_adds_missing_areas() {
let mut genome = create_minimal_genome("test".to_string(), "Test".to_string());
assert_eq!(genome.cortical_areas.len(), 0);
let (areas_added, _) = ensure_core_components(&mut genome);
assert_eq!(areas_added, 7);
let death_id = crate::genome::parser::string_to_cortical_id("_death").expect("Valid ID");
let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
let fatigue_id =
crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid ID");
let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid ID");
let pleasure_id =
crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid ID");
let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid ID");
let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid ID");
assert!(genome.cortical_areas.contains_key(&death_id));
assert!(genome.cortical_areas.contains_key(&power_id));
assert!(genome.cortical_areas.contains_key(&fatigue_id));
assert!(genome.cortical_areas.contains_key(&pain_id));
assert!(genome.cortical_areas.contains_key(&pleasure_id));
assert!(genome.cortical_areas.contains_key(&fear_id));
assert!(genome.cortical_areas.contains_key(&hope_id));
assert_eq!(
genome.cortical_areas.get(&death_id).unwrap().cortical_idx,
0
);
assert_eq!(
genome.cortical_areas.get(&power_id).unwrap().cortical_idx,
1
);
assert_eq!(
genome.cortical_areas.get(&fatigue_id).unwrap().cortical_idx,
2
);
assert_eq!(genome.cortical_areas.get(&pain_id).unwrap().cortical_idx, 3);
assert_eq!(
genome
.cortical_areas
.get(&pleasure_id)
.unwrap()
.cortical_idx,
4
);
assert_eq!(genome.cortical_areas.get(&fear_id).unwrap().cortical_idx, 5);
assert_eq!(genome.cortical_areas.get(&hope_id).unwrap().cortical_idx, 6);
}
#[test]
fn test_ensure_core_components_adds_missing_morphologies() {
let mut genome = create_genome_with_core_areas("test".to_string(), "Test".to_string());
assert_eq!(genome.morphologies.count(), 0);
let (_, morphs_added) = ensure_core_components(&mut genome);
assert!(morphs_added > 0);
assert!(genome.morphologies.contains("block_to_block"));
assert!(genome.morphologies.contains("projector"));
assert!(genome.morphologies.contains("centered_projector"));
assert!(genome.morphologies.contains("transpose_xy"));
assert!(genome.morphologies.contains("transpose_yz"));
assert!(genome.morphologies.contains("transpose_xz"));
assert!(genome.morphologies.contains("first_to_last"));
assert!(genome.morphologies.contains("episodic_memory"));
assert!(genome.morphologies.contains("lateral_+x"));
}
#[test]
fn test_ensure_core_components_idempotent() {
let mut genome = create_genome_with_core_areas("test".to_string(), "Test".to_string());
add_core_morphologies(&mut genome.morphologies);
let (areas_added, morphs_added) = ensure_core_components(&mut genome);
assert_eq!(areas_added, 0);
assert_eq!(morphs_added, 0);
}
}