1use crate::{
18 GenomeMetadata, GenomeSignatures, GenomeStats, MorphologyRegistry, PhysiologyConfig,
19 RuntimeGenome,
20};
21use feagi_structures::genomic::cortical_area::CoreCorticalType;
22use feagi_structures::genomic::cortical_area::{CorticalArea, CorticalAreaDimensions};
23use feagi_structures::genomic::descriptors::GenomeCoordinate3D;
24use serde_json::Value;
25use std::collections::HashMap;
26
27pub const ESSENTIAL_GENOME_JSON: &str = include_str!("../genomes/essential_genome.json");
29
30pub const BAREBONES_GENOME_JSON: &str = include_str!("../genomes/barebones_genome.json");
32
33pub const TEST_GENOME_JSON: &str = include_str!("../genomes/test_genome.json");
35
36pub const VISION_GENOME_JSON: &str = include_str!("../genomes/vision_genome.json");
38
39pub fn get_default_neural_properties() -> HashMap<String, Value> {
41 let mut props = HashMap::new();
42 props.insert("per_voxel_neuron_cnt".to_string(), Value::from(1));
43 props.insert("synapse_attractivity".to_string(), Value::from(100.0));
44 props.insert("degeneration".to_string(), Value::from(0.0));
45 props.insert("psp_uniform_distribution".to_string(), Value::from(true));
46 props.insert("postsynaptic_current_max".to_string(), Value::from(10000.0));
47 props.insert("postsynaptic_current".to_string(), Value::from(500.0));
48 props.insert("firing_threshold".to_string(), Value::from(0.1));
49 props.insert("refractory_period".to_string(), Value::from(0));
50 props.insert("leak_coefficient".to_string(), Value::from(0.0));
51 props.insert("leak_variability".to_string(), Value::from(0.0));
52 props.insert("consecutive_fire_cnt_max".to_string(), Value::from(0));
53 props.insert("snooze_length".to_string(), Value::from(0));
54 props.insert("mp_charge_accumulation".to_string(), Value::from(false));
55 props.insert("mp_driven_psp".to_string(), Value::from(false));
56 props.insert("neuron_excitability".to_string(), Value::from(1.0));
57 props.insert("visualization".to_string(), Value::from(true));
58 props.insert("memory_twin_of".to_string(), Value::Null);
59 props.insert(
60 "cortical_mapping_dst".to_string(),
61 Value::Object(serde_json::Map::new()),
62 );
63 props
64}
65
66pub fn create_death_area() -> CorticalArea {
68 let cortical_id = CoreCorticalType::Death.to_cortical_id();
69 let cortical_type = cortical_id
70 .as_cortical_type()
71 .expect("Death cortical ID should map to Core type");
72
73 let mut area = CorticalArea::new(
74 cortical_id,
75 0, "Death".to_string(),
77 CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
78 GenomeCoordinate3D::new(0, 0, -20),
79 cortical_type,
80 )
81 .expect("Failed to create _death area");
82
83 let mut props = get_default_neural_properties();
84 props.insert("cortical_group".to_string(), Value::from("CORE"));
85 props.insert("2d_coordinate".to_string(), Value::from(vec![-10, -20]));
86 area.properties = props;
87 area
88}
89
90pub fn create_power_area() -> CorticalArea {
92 let cortical_id = CoreCorticalType::Power.to_cortical_id();
93 let cortical_type = cortical_id
94 .as_cortical_type()
95 .expect("Power cortical ID should map to Core type");
96
97 let mut area = CorticalArea::new(
98 cortical_id,
99 1, "Brain_Power".to_string(),
101 CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
102 GenomeCoordinate3D::new(0, 0, -20),
103 cortical_type,
104 )
105 .expect("Failed to create _power area");
106
107 let mut props = get_default_neural_properties();
108 props.insert("cortical_group".to_string(), Value::from("CORE"));
109 props.insert("2d_coordinate".to_string(), Value::from(vec![-10, -10]));
110 props.insert("firing_threshold".to_string(), Value::from(0.1));
111 props.insert("postsynaptic_current".to_string(), Value::from(500.0));
112 props.insert("neuron_excitability".to_string(), Value::from(100.0));
113 area.properties = props;
114 area
115}
116
117pub fn create_fatigue_area() -> CorticalArea {
119 let cortical_id = CoreCorticalType::Fatigue.to_cortical_id();
120 let cortical_type = cortical_id
121 .as_cortical_type()
122 .expect("Fatigue cortical ID should map to Core type");
123
124 let mut area = CorticalArea::new(
125 cortical_id,
126 2, "Fatigue".to_string(),
128 CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
129 GenomeCoordinate3D::new(0, 0, -30),
130 cortical_type,
131 )
132 .expect("Failed to create _fatigue area");
133
134 let mut props = get_default_neural_properties();
135 props.insert("cortical_group".to_string(), Value::from("CORE"));
136 props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 0]));
137 area.properties = props;
138 area
139}
140
141pub fn create_pain_area() -> CorticalArea {
143 let cortical_id = CoreCorticalType::Pain.to_cortical_id();
144 let cortical_type = cortical_id
145 .as_cortical_type()
146 .expect("Pain cortical ID should map to Core type");
147
148 let mut area = CorticalArea::new(
149 cortical_id,
150 3, "Pain".to_string(),
152 CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
153 GenomeCoordinate3D::new(0, 0, -40),
154 cortical_type,
155 )
156 .expect("Failed to create _pain area");
157
158 let mut props = get_default_neural_properties();
159 props.insert("cortical_group".to_string(), Value::from("CORE"));
160 props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 10]));
161 area.properties = props;
162 area
163}
164
165pub fn create_pleasure_area() -> CorticalArea {
167 let cortical_id = CoreCorticalType::Pleasure.to_cortical_id();
168 let cortical_type = cortical_id
169 .as_cortical_type()
170 .expect("Pleasure cortical ID should map to Core type");
171
172 let mut area = CorticalArea::new(
173 cortical_id,
174 4, "Pleasure".to_string(),
176 CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
177 GenomeCoordinate3D::new(0, 0, -50),
178 cortical_type,
179 )
180 .expect("Failed to create _pleasure area");
181
182 let mut props = get_default_neural_properties();
183 props.insert("cortical_group".to_string(), Value::from("CORE"));
184 props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 20]));
185 area.properties = props;
186 area
187}
188
189pub fn create_fear_area() -> CorticalArea {
191 let cortical_id = CoreCorticalType::Fear.to_cortical_id();
192 let cortical_type = cortical_id
193 .as_cortical_type()
194 .expect("Fear cortical ID should map to Core type");
195
196 let mut area = CorticalArea::new(
197 cortical_id,
198 5, "Fear".to_string(),
200 CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
201 GenomeCoordinate3D::new(0, 0, -60),
202 cortical_type,
203 )
204 .expect("Failed to create _fear area");
205
206 let mut props = get_default_neural_properties();
207 props.insert("cortical_group".to_string(), Value::from("CORE"));
208 props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 30]));
209 area.properties = props;
210 area
211}
212
213pub fn create_hope_area() -> CorticalArea {
215 let cortical_id = CoreCorticalType::Hope.to_cortical_id();
216 let cortical_type = cortical_id
217 .as_cortical_type()
218 .expect("Hope cortical ID should map to Core type");
219
220 let mut area = CorticalArea::new(
221 cortical_id,
222 6, "Hope".to_string(),
224 CorticalAreaDimensions::new(1, 1, 1).expect("Failed to create dimensions"),
225 GenomeCoordinate3D::new(0, 0, -70),
226 cortical_type,
227 )
228 .expect("Failed to create _hope area");
229
230 let mut props = get_default_neural_properties();
231 props.insert("cortical_group".to_string(), Value::from("CORE"));
232 props.insert("2d_coordinate".to_string(), Value::from(vec![-10, 40]));
233 area.properties = props;
234 area
235}
236
237pub fn create_minimal_genome(genome_id: String, genome_title: String) -> RuntimeGenome {
239 RuntimeGenome {
240 metadata: GenomeMetadata {
241 genome_id,
242 genome_title,
243 genome_description: "Minimal genome template".to_string(),
244 version: "2.0".to_string(),
245 timestamp: std::time::SystemTime::now()
246 .duration_since(std::time::UNIX_EPOCH)
247 .unwrap()
248 .as_secs_f64(),
249 brain_regions_root: None, },
251 cortical_areas: HashMap::new(),
252 brain_regions: HashMap::new(),
253 morphologies: MorphologyRegistry::new(),
254 physiology: PhysiologyConfig::default(),
255 signatures: GenomeSignatures {
256 genome: String::new(),
257 blueprint: String::new(),
258 physiology: String::new(),
259 morphologies: None,
260 },
261 stats: GenomeStats::default(),
262 }
263}
264
265pub fn create_genome_with_core_areas(genome_id: String, genome_title: String) -> RuntimeGenome {
267 let mut genome = create_minimal_genome(genome_id, genome_title);
268
269 let death_id =
271 crate::genome::parser::string_to_cortical_id("_death").expect("Valid cortical ID");
272 let power_id =
273 crate::genome::parser::string_to_cortical_id("_power").expect("Valid cortical ID");
274 let fatigue_id =
275 crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid cortical ID");
276 let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid cortical ID");
277 let pleasure_id =
278 crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid cortical ID");
279 let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid cortical ID");
280 let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid cortical ID");
281
282 genome.cortical_areas.insert(death_id, create_death_area());
283 genome.cortical_areas.insert(power_id, create_power_area());
284 genome
285 .cortical_areas
286 .insert(fatigue_id, create_fatigue_area());
287 genome.cortical_areas.insert(pain_id, create_pain_area());
288 genome
289 .cortical_areas
290 .insert(pleasure_id, create_pleasure_area());
291 genome.cortical_areas.insert(fear_id, create_fear_area());
292 genome.cortical_areas.insert(hope_id, create_hope_area());
293
294 genome
295}
296
297pub fn create_genome_with_core_morphologies(
299 genome_id: String,
300 genome_title: String,
301) -> RuntimeGenome {
302 let mut genome = create_minimal_genome(genome_id, genome_title);
303
304 add_core_morphologies(&mut genome.morphologies);
306
307 genome
308}
309
310pub fn ensure_core_components(genome: &mut RuntimeGenome) -> (usize, usize) {
325 let mut areas_added = 0;
326 let mut morphologies_added = 0;
327
328 let death_id =
330 crate::genome::parser::string_to_cortical_id("_death").expect("Valid cortical ID");
331 let power_id =
332 crate::genome::parser::string_to_cortical_id("_power").expect("Valid cortical ID");
333 let fatigue_id =
334 crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid cortical ID");
335 let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid cortical ID");
336 let pleasure_id =
337 crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid cortical ID");
338 let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid cortical ID");
339 let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid cortical ID");
340
341 if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(death_id) {
343 let death_area = create_death_area();
344 e.insert(death_area);
345 areas_added += 1;
346 tracing::info!("Added missing core area: _death (cortical_idx=0)");
347 }
348
349 if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(power_id) {
350 let power_area = create_power_area();
351 e.insert(power_area);
352 areas_added += 1;
353 tracing::info!("Added missing core area: _power (cortical_idx=1)");
354 }
355
356 if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(fatigue_id) {
357 let fatigue_area = create_fatigue_area();
358 e.insert(fatigue_area);
359 areas_added += 1;
360 tracing::info!("Added missing core area: _fatigue (cortical_idx=2)");
361 }
362
363 if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(pain_id) {
364 let pain_area = create_pain_area();
365 e.insert(pain_area);
366 areas_added += 1;
367 tracing::info!("Added missing core area: _pain (cortical_idx=3)");
368 }
369
370 if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(pleasure_id) {
371 let pleasure_area = create_pleasure_area();
372 e.insert(pleasure_area);
373 areas_added += 1;
374 tracing::info!("Added missing core area: _pleasure (cortical_idx=4)");
375 }
376
377 if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(fear_id) {
378 let fear_area = create_fear_area();
379 e.insert(fear_area);
380 areas_added += 1;
381 tracing::info!("Added missing core area: _fear (cortical_idx=5)");
382 }
383
384 if let std::collections::hash_map::Entry::Vacant(e) = genome.cortical_areas.entry(hope_id) {
385 let hope_area = create_hope_area();
386 e.insert(hope_area);
387 areas_added += 1;
388 tracing::info!("Added missing core area: _hope (cortical_idx=6)");
389 }
390
391 let required_morphologies = vec![
393 "block_to_block",
394 "projector",
395 "transpose_xy",
396 "transpose_yz",
397 "transpose_xz",
398 "sweeper",
399 "last_to_first",
400 "first_to_last",
401 "bitmask_encoder_x",
402 "bitmask_encoder_y",
403 "bitmask_encoder_z",
404 "bitmask_decoder_x",
405 "bitmask_decoder_y",
406 "bitmask_decoder_z",
407 "episodic_memory",
408 "memory_replay",
409 "associative_memory",
410 "rotator_z",
411 "all_to_0-0-0",
412 "0-0-0_to_all",
413 "tile",
414 "lateral_+x",
415 "lateral_-x",
416 "lateral_+y",
417 "lateral_-y",
418 "lateral_+z",
419 "lateral_-z",
420 ];
421
422 for morph_name in required_morphologies {
423 if !genome.morphologies.contains(morph_name) {
424 morphologies_added += 1;
425 }
426 }
427
428 if morphologies_added > 0 {
430 add_core_morphologies(&mut genome.morphologies);
431 tracing::info!("Added {} missing core morphologies", morphologies_added);
432 }
433
434 (areas_added, morphologies_added)
435}
436
437pub fn add_core_morphologies(registry: &mut MorphologyRegistry) {
439 use crate::{Morphology, MorphologyParameters, MorphologyType};
440
441 registry.add_morphology(
443 "block_to_block".to_string(),
444 Morphology {
445 morphology_type: MorphologyType::Vectors,
446 parameters: MorphologyParameters::Vectors {
447 vectors: vec![[0, 0, 0]],
448 },
449 class: "core".to_string(),
450 },
451 );
452
453 registry.add_morphology(
455 "projector".to_string(),
456 Morphology {
457 morphology_type: MorphologyType::Functions,
458 parameters: MorphologyParameters::Functions {},
459 class: "core".to_string(),
460 },
461 );
462
463 registry.add_morphology(
465 "transpose_xy".to_string(),
466 Morphology {
467 morphology_type: MorphologyType::Functions,
468 parameters: MorphologyParameters::Functions {},
469 class: "core".to_string(),
470 },
471 );
472
473 registry.add_morphology(
475 "transpose_yz".to_string(),
476 Morphology {
477 morphology_type: MorphologyType::Functions,
478 parameters: MorphologyParameters::Functions {},
479 class: "core".to_string(),
480 },
481 );
482
483 registry.add_morphology(
485 "transpose_xz".to_string(),
486 Morphology {
487 morphology_type: MorphologyType::Functions,
488 parameters: MorphologyParameters::Functions {},
489 class: "core".to_string(),
490 },
491 );
492
493 registry.add_morphology(
495 "sweeper".to_string(),
496 Morphology {
497 morphology_type: MorphologyType::Functions,
498 parameters: MorphologyParameters::Functions {},
499 class: "core".to_string(),
500 },
501 );
502
503 registry.add_morphology(
505 "last_to_first".to_string(),
506 Morphology {
507 morphology_type: MorphologyType::Functions,
508 parameters: MorphologyParameters::Functions {},
509 class: "core".to_string(),
510 },
511 );
512
513 registry.add_morphology(
515 "first_to_last".to_string(),
516 Morphology {
517 morphology_type: MorphologyType::Functions,
518 parameters: MorphologyParameters::Functions {},
519 class: "core".to_string(),
520 },
521 );
522
523 registry.add_morphology(
525 "episodic_memory".to_string(),
526 Morphology {
527 morphology_type: MorphologyType::Functions,
528 parameters: MorphologyParameters::Functions {},
529 class: "core".to_string(),
530 },
531 );
532
533 registry.add_morphology(
535 "memory_replay".to_string(),
536 Morphology {
537 morphology_type: MorphologyType::Functions,
538 parameters: MorphologyParameters::Functions {},
539 class: "core".to_string(),
540 },
541 );
542
543 registry.add_morphology(
545 "associative_memory".to_string(),
546 Morphology {
547 morphology_type: MorphologyType::Functions,
548 parameters: MorphologyParameters::Functions {},
549 class: "core".to_string(),
550 },
551 );
552
553 registry.add_morphology(
555 "rotator_z".to_string(),
556 Morphology {
557 morphology_type: MorphologyType::Functions,
558 parameters: MorphologyParameters::Functions {},
559 class: "core".to_string(),
560 },
561 );
562
563 registry.add_morphology(
565 "bitmask_encoder_x".to_string(),
566 Morphology {
567 morphology_type: MorphologyType::Functions,
568 parameters: MorphologyParameters::Functions {},
569 class: "core".to_string(),
570 },
571 );
572
573 registry.add_morphology(
575 "bitmask_encoder_y".to_string(),
576 Morphology {
577 morphology_type: MorphologyType::Functions,
578 parameters: MorphologyParameters::Functions {},
579 class: "core".to_string(),
580 },
581 );
582
583 registry.add_morphology(
585 "bitmask_encoder_z".to_string(),
586 Morphology {
587 morphology_type: MorphologyType::Functions,
588 parameters: MorphologyParameters::Functions {},
589 class: "core".to_string(),
590 },
591 );
592
593 registry.add_morphology(
595 "bitmask_decoder_x".to_string(),
596 Morphology {
597 morphology_type: MorphologyType::Functions,
598 parameters: MorphologyParameters::Functions {},
599 class: "core".to_string(),
600 },
601 );
602
603 registry.add_morphology(
605 "bitmask_decoder_y".to_string(),
606 Morphology {
607 morphology_type: MorphologyType::Functions,
608 parameters: MorphologyParameters::Functions {},
609 class: "core".to_string(),
610 },
611 );
612
613 registry.add_morphology(
615 "bitmask_decoder_z".to_string(),
616 Morphology {
617 morphology_type: MorphologyType::Functions,
618 parameters: MorphologyParameters::Functions {},
619 class: "core".to_string(),
620 },
621 );
622
623 registry.add_morphology(
625 "all_to_0-0-0".to_string(),
626 Morphology {
627 morphology_type: MorphologyType::Patterns,
628 parameters: MorphologyParameters::Patterns {
629 patterns: vec![[
630 vec![
631 crate::PatternElement::Wildcard,
632 crate::PatternElement::Wildcard,
633 crate::PatternElement::Wildcard,
634 ],
635 vec![
636 crate::PatternElement::Value(0),
637 crate::PatternElement::Value(0),
638 crate::PatternElement::Value(0),
639 ],
640 ]],
641 },
642 class: "core".to_string(),
643 },
644 );
645
646 registry.add_morphology(
648 "0-0-0_to_all".to_string(),
649 Morphology {
650 morphology_type: MorphologyType::Patterns,
651 parameters: MorphologyParameters::Patterns {
652 patterns: vec![[
653 vec![
654 crate::PatternElement::Value(0),
655 crate::PatternElement::Value(0),
656 crate::PatternElement::Value(0),
657 ],
658 vec![
659 crate::PatternElement::Wildcard,
660 crate::PatternElement::Wildcard,
661 crate::PatternElement::Wildcard,
662 ],
663 ]],
664 },
665 class: "core".to_string(),
666 },
667 );
668
669 registry.add_morphology(
671 "tile".to_string(),
672 Morphology {
673 morphology_type: MorphologyType::Composite,
674 parameters: MorphologyParameters::Composite {
675 src_seed: [16, 16, 1],
676 src_pattern: vec![[1, 0], [1, 0], [1, 0]],
677 mapper_morphology: "projector".to_string(),
678 },
679 class: "core".to_string(),
680 },
681 );
682
683 registry.add_morphology(
685 "lateral_+x".to_string(),
686 Morphology {
687 morphology_type: MorphologyType::Vectors,
688 parameters: MorphologyParameters::Vectors {
689 vectors: vec![[1, 0, 0]],
690 },
691 class: "core".to_string(),
692 },
693 );
694
695 registry.add_morphology(
697 "lateral_-x".to_string(),
698 Morphology {
699 morphology_type: MorphologyType::Vectors,
700 parameters: MorphologyParameters::Vectors {
701 vectors: vec![[-1, 0, 0]],
702 },
703 class: "core".to_string(),
704 },
705 );
706
707 registry.add_morphology(
709 "lateral_+y".to_string(),
710 Morphology {
711 morphology_type: MorphologyType::Vectors,
712 parameters: MorphologyParameters::Vectors {
713 vectors: vec![[0, 1, 0]],
714 },
715 class: "core".to_string(),
716 },
717 );
718
719 registry.add_morphology(
721 "lateral_-y".to_string(),
722 Morphology {
723 morphology_type: MorphologyType::Vectors,
724 parameters: MorphologyParameters::Vectors {
725 vectors: vec![[0, -1, 0]],
726 },
727 class: "core".to_string(),
728 },
729 );
730
731 registry.add_morphology(
733 "lateral_+z".to_string(),
734 Morphology {
735 morphology_type: MorphologyType::Vectors,
736 parameters: MorphologyParameters::Vectors {
737 vectors: vec![[0, 0, 1]],
738 },
739 class: "core".to_string(),
740 },
741 );
742
743 registry.add_morphology(
745 "lateral_-z".to_string(),
746 Morphology {
747 morphology_type: MorphologyType::Vectors,
748 parameters: MorphologyParameters::Vectors {
749 vectors: vec![[0, 0, -1]],
750 },
751 class: "core".to_string(),
752 },
753 );
754}
755
756pub fn load_essential_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
760 use crate::genome::loader::load_genome_from_json;
761 let mut genome = load_genome_from_json(ESSENTIAL_GENOME_JSON)?;
762 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
763 if areas_added > 0 || morphs_added > 0 {
764 tracing::info!(
765 "Essential genome: added {} core areas, {} core morphologies",
766 areas_added,
767 morphs_added
768 );
769 }
770 Ok(genome)
771}
772
773pub fn load_barebones_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
777 use crate::genome::loader::load_genome_from_json;
778 let mut genome = load_genome_from_json(BAREBONES_GENOME_JSON)?;
779 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
780 if areas_added > 0 || morphs_added > 0 {
781 tracing::info!(
782 "Barebones genome: added {} core areas, {} core morphologies",
783 areas_added,
784 morphs_added
785 );
786 }
787 Ok(genome)
788}
789
790pub fn load_test_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
794 use crate::genome::loader::load_genome_from_json;
795 let mut genome = load_genome_from_json(TEST_GENOME_JSON)?;
796 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
797 if areas_added > 0 || morphs_added > 0 {
798 tracing::info!(
799 "Test genome: added {} core areas, {} core morphologies",
800 areas_added,
801 morphs_added
802 );
803 }
804 Ok(genome)
805}
806
807pub fn load_vision_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
811 use crate::genome::loader::load_genome_from_json;
812 let mut genome = load_genome_from_json(VISION_GENOME_JSON)?;
813 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
814 if areas_added > 0 || morphs_added > 0 {
815 tracing::info!(
816 "Vision genome: added {} core areas, {} core morphologies",
817 areas_added,
818 morphs_added
819 );
820 }
821 Ok(genome)
822}
823
824#[cfg(test)]
825mod tests {
826 use super::*;
827
828 #[test]
829 fn test_create_minimal_genome() {
830 let genome = create_minimal_genome("test_genome".to_string(), "Test Genome".to_string());
831
832 assert_eq!(genome.metadata.genome_id, "test_genome");
833 assert_eq!(genome.metadata.version, "2.0");
834 assert_eq!(genome.cortical_areas.len(), 0);
835 assert_eq!(genome.morphologies.count(), 0);
836 }
837
838 #[test]
839 fn test_create_genome_with_core_areas() {
840 let genome =
841 create_genome_with_core_areas("test_genome".to_string(), "Test Genome".to_string());
842
843 assert_eq!(genome.metadata.genome_id, "test_genome");
844 assert_eq!(genome.cortical_areas.len(), 7);
845
846 let death_id = crate::genome::parser::string_to_cortical_id("_death").expect("Valid ID");
847 let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
848 let fatigue_id =
849 crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid ID");
850 let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid ID");
851 let pleasure_id =
852 crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid ID");
853 let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid ID");
854 let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid ID");
855 assert!(genome.cortical_areas.contains_key(&death_id));
856 assert!(genome.cortical_areas.contains_key(&power_id));
857 assert!(genome.cortical_areas.contains_key(&fatigue_id));
858 assert!(genome.cortical_areas.contains_key(&pain_id));
859 assert!(genome.cortical_areas.contains_key(&pleasure_id));
860 assert!(genome.cortical_areas.contains_key(&fear_id));
861 assert!(genome.cortical_areas.contains_key(&hope_id));
862
863 let power = genome.cortical_areas.get(&power_id).unwrap();
865 assert_eq!(power.cortical_id.as_base_64(), power_id.as_base_64());
866 assert_eq!(power.cortical_idx, 1);
867 assert_eq!(power.dimensions.width, 1);
868 assert_eq!(power.dimensions.height, 1);
869 assert_eq!(power.dimensions.depth, 1);
870 }
871
872 #[test]
873 fn test_create_genome_with_core_morphologies() {
874 let genome = create_genome_with_core_morphologies(
875 "test_genome".to_string(),
876 "Test Genome".to_string(),
877 );
878
879 assert_eq!(genome.metadata.genome_id, "test_genome");
880 assert!(genome.morphologies.count() > 0);
881 assert!(genome.morphologies.contains("block_to_block"));
882 assert!(genome.morphologies.contains("projector"));
883 assert!(genome.morphologies.contains("transpose_xy"));
884 assert!(genome.morphologies.contains("transpose_yz"));
885 assert!(genome.morphologies.contains("transpose_xz"));
886 assert!(genome.morphologies.contains("first_to_last"));
887 assert!(genome.morphologies.contains("lateral_+x"));
888 }
889
890 #[test]
891 fn test_add_core_morphologies() {
892 let mut registry = MorphologyRegistry::new();
893 add_core_morphologies(&mut registry);
894
895 assert!(registry.count() >= 11);
897 assert!(registry.contains("block_to_block"));
898 assert!(registry.contains("projector"));
899 assert!(registry.contains("transpose_xy"));
900 assert!(registry.contains("transpose_yz"));
901 assert!(registry.contains("transpose_xz"));
902 assert!(registry.contains("first_to_last"));
903 assert!(registry.contains("all_to_0-0-0"));
904 assert!(registry.contains("lateral_+x"));
905 assert!(registry.contains("lateral_-z"));
906 }
907
908 #[test]
909 fn test_embedded_genomes_exist() {
910 #[allow(clippy::const_is_empty)]
914 {
915 assert!(!ESSENTIAL_GENOME_JSON.is_empty());
916 assert!(!BAREBONES_GENOME_JSON.is_empty());
917 assert!(!TEST_GENOME_JSON.is_empty());
918 assert!(!VISION_GENOME_JSON.is_empty());
919 }
920 }
921
922 #[test]
923 fn test_load_essential_genome() {
924 let genome = load_essential_genome().expect("Failed to load essential genome");
925 assert!(!genome.cortical_areas.is_empty());
926 let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
928 assert!(genome.cortical_areas.contains_key(&power_id));
929 }
930
931 #[test]
932 fn test_ensure_core_components_adds_missing_areas() {
933 let mut genome = create_minimal_genome("test".to_string(), "Test".to_string());
935
936 assert_eq!(genome.cortical_areas.len(), 0);
937
938 let (areas_added, _) = ensure_core_components(&mut genome);
940
941 assert_eq!(areas_added, 7);
943
944 let death_id = crate::genome::parser::string_to_cortical_id("_death").expect("Valid ID");
945 let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
946 let fatigue_id =
947 crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid ID");
948 let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid ID");
949 let pleasure_id =
950 crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid ID");
951 let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid ID");
952 let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid ID");
953 assert!(genome.cortical_areas.contains_key(&death_id));
954 assert!(genome.cortical_areas.contains_key(&power_id));
955 assert!(genome.cortical_areas.contains_key(&fatigue_id));
956 assert!(genome.cortical_areas.contains_key(&pain_id));
957 assert!(genome.cortical_areas.contains_key(&pleasure_id));
958 assert!(genome.cortical_areas.contains_key(&fear_id));
959 assert!(genome.cortical_areas.contains_key(&hope_id));
960
961 assert_eq!(
963 genome.cortical_areas.get(&death_id).unwrap().cortical_idx,
964 0
965 );
966 assert_eq!(
967 genome.cortical_areas.get(&power_id).unwrap().cortical_idx,
968 1
969 );
970 assert_eq!(
971 genome.cortical_areas.get(&fatigue_id).unwrap().cortical_idx,
972 2
973 );
974 assert_eq!(genome.cortical_areas.get(&pain_id).unwrap().cortical_idx, 3);
975 assert_eq!(
976 genome
977 .cortical_areas
978 .get(&pleasure_id)
979 .unwrap()
980 .cortical_idx,
981 4
982 );
983 assert_eq!(genome.cortical_areas.get(&fear_id).unwrap().cortical_idx, 5);
984 assert_eq!(genome.cortical_areas.get(&hope_id).unwrap().cortical_idx, 6);
985 }
986
987 #[test]
988 fn test_ensure_core_components_adds_missing_morphologies() {
989 let mut genome = create_genome_with_core_areas("test".to_string(), "Test".to_string());
991
992 assert_eq!(genome.morphologies.count(), 0);
993
994 let (_, morphs_added) = ensure_core_components(&mut genome);
996
997 assert!(morphs_added > 0);
999 assert!(genome.morphologies.contains("block_to_block"));
1000 assert!(genome.morphologies.contains("projector"));
1001 assert!(genome.morphologies.contains("transpose_xy"));
1002 assert!(genome.morphologies.contains("transpose_yz"));
1003 assert!(genome.morphologies.contains("transpose_xz"));
1004 assert!(genome.morphologies.contains("first_to_last"));
1005 assert!(genome.morphologies.contains("episodic_memory"));
1006 assert!(genome.morphologies.contains("lateral_+x"));
1007 }
1008
1009 #[test]
1010 fn test_ensure_core_components_idempotent() {
1011 let mut genome = create_genome_with_core_areas("test".to_string(), "Test".to_string());
1013 add_core_morphologies(&mut genome.morphologies);
1014
1015 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
1017
1018 assert_eq!(areas_added, 0);
1020 assert_eq!(morphs_added, 0);
1021 }
1022}