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 "centered_projector",
396 "transpose_xy",
397 "transpose_yz",
398 "transpose_xz",
399 "sweeper",
400 "last_to_first",
401 "first_to_last",
402 "bitmask_encoder_x",
403 "bitmask_encoder_y",
404 "bitmask_encoder_z",
405 "bitmask_decoder_x",
406 "bitmask_decoder_y",
407 "bitmask_decoder_z",
408 "episodic_memory",
409 "memory_replay",
410 "associative_memory",
411 "rotator_z",
412 "all_to_0-0-0",
413 "0-0-0_to_all",
414 "tile",
415 "lateral_+x",
416 "lateral_-x",
417 "lateral_+y",
418 "lateral_-y",
419 "lateral_+z",
420 "lateral_-z",
421 ];
422
423 for morph_name in required_morphologies {
424 if !genome.morphologies.contains(morph_name) {
425 morphologies_added += 1;
426 }
427 }
428
429 if morphologies_added > 0 {
431 add_core_morphologies(&mut genome.morphologies);
432 tracing::info!("Added {} missing core morphologies", morphologies_added);
433 }
434
435 (areas_added, morphologies_added)
436}
437
438pub fn add_core_morphologies(registry: &mut MorphologyRegistry) {
440 use crate::{Morphology, MorphologyParameters, MorphologyType};
441
442 registry.add_morphology(
444 "block_to_block".to_string(),
445 Morphology {
446 morphology_type: MorphologyType::Vectors,
447 parameters: MorphologyParameters::Vectors {
448 vectors: vec![[0, 0, 0]],
449 },
450 class: "core".to_string(),
451 },
452 );
453
454 registry.add_morphology(
456 "projector".to_string(),
457 Morphology {
458 morphology_type: MorphologyType::Functions,
459 parameters: MorphologyParameters::Functions {},
460 class: "core".to_string(),
461 },
462 );
463
464 registry.add_morphology(
466 "centered_projector".to_string(),
467 Morphology {
468 morphology_type: MorphologyType::Functions,
469 parameters: MorphologyParameters::Functions {},
470 class: "core".to_string(),
471 },
472 );
473
474 registry.add_morphology(
476 "transpose_xy".to_string(),
477 Morphology {
478 morphology_type: MorphologyType::Functions,
479 parameters: MorphologyParameters::Functions {},
480 class: "core".to_string(),
481 },
482 );
483
484 registry.add_morphology(
486 "transpose_yz".to_string(),
487 Morphology {
488 morphology_type: MorphologyType::Functions,
489 parameters: MorphologyParameters::Functions {},
490 class: "core".to_string(),
491 },
492 );
493
494 registry.add_morphology(
496 "transpose_xz".to_string(),
497 Morphology {
498 morphology_type: MorphologyType::Functions,
499 parameters: MorphologyParameters::Functions {},
500 class: "core".to_string(),
501 },
502 );
503
504 registry.add_morphology(
506 "sweeper".to_string(),
507 Morphology {
508 morphology_type: MorphologyType::Functions,
509 parameters: MorphologyParameters::Functions {},
510 class: "core".to_string(),
511 },
512 );
513
514 registry.add_morphology(
516 "last_to_first".to_string(),
517 Morphology {
518 morphology_type: MorphologyType::Functions,
519 parameters: MorphologyParameters::Functions {},
520 class: "core".to_string(),
521 },
522 );
523
524 registry.add_morphology(
526 "first_to_last".to_string(),
527 Morphology {
528 morphology_type: MorphologyType::Functions,
529 parameters: MorphologyParameters::Functions {},
530 class: "core".to_string(),
531 },
532 );
533
534 registry.add_morphology(
536 "episodic_memory".to_string(),
537 Morphology {
538 morphology_type: MorphologyType::Functions,
539 parameters: MorphologyParameters::Functions {},
540 class: "core".to_string(),
541 },
542 );
543
544 registry.add_morphology(
546 "memory_replay".to_string(),
547 Morphology {
548 morphology_type: MorphologyType::Functions,
549 parameters: MorphologyParameters::Functions {},
550 class: "core".to_string(),
551 },
552 );
553
554 registry.add_morphology(
556 "associative_memory".to_string(),
557 Morphology {
558 morphology_type: MorphologyType::Functions,
559 parameters: MorphologyParameters::Functions {},
560 class: "core".to_string(),
561 },
562 );
563
564 registry.add_morphology(
566 "rotator_z".to_string(),
567 Morphology {
568 morphology_type: MorphologyType::Functions,
569 parameters: MorphologyParameters::Functions {},
570 class: "core".to_string(),
571 },
572 );
573
574 registry.add_morphology(
576 "bitmask_encoder_x".to_string(),
577 Morphology {
578 morphology_type: MorphologyType::Functions,
579 parameters: MorphologyParameters::Functions {},
580 class: "core".to_string(),
581 },
582 );
583
584 registry.add_morphology(
586 "bitmask_encoder_y".to_string(),
587 Morphology {
588 morphology_type: MorphologyType::Functions,
589 parameters: MorphologyParameters::Functions {},
590 class: "core".to_string(),
591 },
592 );
593
594 registry.add_morphology(
596 "bitmask_encoder_z".to_string(),
597 Morphology {
598 morphology_type: MorphologyType::Functions,
599 parameters: MorphologyParameters::Functions {},
600 class: "core".to_string(),
601 },
602 );
603
604 registry.add_morphology(
606 "bitmask_decoder_x".to_string(),
607 Morphology {
608 morphology_type: MorphologyType::Functions,
609 parameters: MorphologyParameters::Functions {},
610 class: "core".to_string(),
611 },
612 );
613
614 registry.add_morphology(
616 "bitmask_decoder_y".to_string(),
617 Morphology {
618 morphology_type: MorphologyType::Functions,
619 parameters: MorphologyParameters::Functions {},
620 class: "core".to_string(),
621 },
622 );
623
624 registry.add_morphology(
626 "bitmask_decoder_z".to_string(),
627 Morphology {
628 morphology_type: MorphologyType::Functions,
629 parameters: MorphologyParameters::Functions {},
630 class: "core".to_string(),
631 },
632 );
633
634 registry.add_morphology(
636 "all_to_0-0-0".to_string(),
637 Morphology {
638 morphology_type: MorphologyType::Patterns,
639 parameters: MorphologyParameters::Patterns {
640 patterns: vec![[
641 vec![
642 crate::PatternElement::Wildcard,
643 crate::PatternElement::Wildcard,
644 crate::PatternElement::Wildcard,
645 ],
646 vec![
647 crate::PatternElement::Value(0),
648 crate::PatternElement::Value(0),
649 crate::PatternElement::Value(0),
650 ],
651 ]],
652 },
653 class: "core".to_string(),
654 },
655 );
656
657 registry.add_morphology(
659 "0-0-0_to_all".to_string(),
660 Morphology {
661 morphology_type: MorphologyType::Patterns,
662 parameters: MorphologyParameters::Patterns {
663 patterns: vec![[
664 vec![
665 crate::PatternElement::Value(0),
666 crate::PatternElement::Value(0),
667 crate::PatternElement::Value(0),
668 ],
669 vec![
670 crate::PatternElement::Wildcard,
671 crate::PatternElement::Wildcard,
672 crate::PatternElement::Wildcard,
673 ],
674 ]],
675 },
676 class: "core".to_string(),
677 },
678 );
679
680 registry.add_morphology(
682 "tile".to_string(),
683 Morphology {
684 morphology_type: MorphologyType::Composite,
685 parameters: MorphologyParameters::Composite {
686 src_seed: [16, 16, 1],
687 src_pattern: vec![[1, 0], [1, 0], [1, 0]],
688 mapper_morphology: "projector".to_string(),
689 },
690 class: "core".to_string(),
691 },
692 );
693
694 registry.add_morphology(
696 "lateral_+x".to_string(),
697 Morphology {
698 morphology_type: MorphologyType::Vectors,
699 parameters: MorphologyParameters::Vectors {
700 vectors: vec![[1, 0, 0]],
701 },
702 class: "core".to_string(),
703 },
704 );
705
706 registry.add_morphology(
708 "lateral_-x".to_string(),
709 Morphology {
710 morphology_type: MorphologyType::Vectors,
711 parameters: MorphologyParameters::Vectors {
712 vectors: vec![[-1, 0, 0]],
713 },
714 class: "core".to_string(),
715 },
716 );
717
718 registry.add_morphology(
720 "lateral_+y".to_string(),
721 Morphology {
722 morphology_type: MorphologyType::Vectors,
723 parameters: MorphologyParameters::Vectors {
724 vectors: vec![[0, 1, 0]],
725 },
726 class: "core".to_string(),
727 },
728 );
729
730 registry.add_morphology(
732 "lateral_-y".to_string(),
733 Morphology {
734 morphology_type: MorphologyType::Vectors,
735 parameters: MorphologyParameters::Vectors {
736 vectors: vec![[0, -1, 0]],
737 },
738 class: "core".to_string(),
739 },
740 );
741
742 registry.add_morphology(
744 "lateral_+z".to_string(),
745 Morphology {
746 morphology_type: MorphologyType::Vectors,
747 parameters: MorphologyParameters::Vectors {
748 vectors: vec![[0, 0, 1]],
749 },
750 class: "core".to_string(),
751 },
752 );
753
754 registry.add_morphology(
756 "lateral_-z".to_string(),
757 Morphology {
758 morphology_type: MorphologyType::Vectors,
759 parameters: MorphologyParameters::Vectors {
760 vectors: vec![[0, 0, -1]],
761 },
762 class: "core".to_string(),
763 },
764 );
765}
766
767pub fn load_essential_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
771 use crate::genome::loader::load_genome_from_json;
772 let mut genome = load_genome_from_json(ESSENTIAL_GENOME_JSON)?;
773 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
774 if areas_added > 0 || morphs_added > 0 {
775 tracing::info!(
776 "Essential genome: added {} core areas, {} core morphologies",
777 areas_added,
778 morphs_added
779 );
780 }
781 Ok(genome)
782}
783
784pub fn load_barebones_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
788 use crate::genome::loader::load_genome_from_json;
789 let mut genome = load_genome_from_json(BAREBONES_GENOME_JSON)?;
790 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
791 if areas_added > 0 || morphs_added > 0 {
792 tracing::info!(
793 "Barebones genome: added {} core areas, {} core morphologies",
794 areas_added,
795 morphs_added
796 );
797 }
798 Ok(genome)
799}
800
801pub fn load_test_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
805 use crate::genome::loader::load_genome_from_json;
806 let mut genome = load_genome_from_json(TEST_GENOME_JSON)?;
807 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
808 if areas_added > 0 || morphs_added > 0 {
809 tracing::info!(
810 "Test genome: added {} core areas, {} core morphologies",
811 areas_added,
812 morphs_added
813 );
814 }
815 Ok(genome)
816}
817
818pub fn load_vision_genome() -> Result<RuntimeGenome, crate::types::EvoError> {
822 use crate::genome::loader::load_genome_from_json;
823 let mut genome = load_genome_from_json(VISION_GENOME_JSON)?;
824 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
825 if areas_added > 0 || morphs_added > 0 {
826 tracing::info!(
827 "Vision genome: added {} core areas, {} core morphologies",
828 areas_added,
829 morphs_added
830 );
831 }
832 Ok(genome)
833}
834
835#[cfg(test)]
836mod tests {
837 use super::*;
838
839 #[test]
840 fn test_create_minimal_genome() {
841 let genome = create_minimal_genome("test_genome".to_string(), "Test Genome".to_string());
842
843 assert_eq!(genome.metadata.genome_id, "test_genome");
844 assert_eq!(genome.metadata.version, "2.0");
845 assert_eq!(genome.cortical_areas.len(), 0);
846 assert_eq!(genome.morphologies.count(), 0);
847 }
848
849 #[test]
850 fn test_create_genome_with_core_areas() {
851 let genome =
852 create_genome_with_core_areas("test_genome".to_string(), "Test Genome".to_string());
853
854 assert_eq!(genome.metadata.genome_id, "test_genome");
855 assert_eq!(genome.cortical_areas.len(), 7);
856
857 let death_id = crate::genome::parser::string_to_cortical_id("_death").expect("Valid ID");
858 let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
859 let fatigue_id =
860 crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid ID");
861 let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid ID");
862 let pleasure_id =
863 crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid ID");
864 let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid ID");
865 let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid ID");
866 assert!(genome.cortical_areas.contains_key(&death_id));
867 assert!(genome.cortical_areas.contains_key(&power_id));
868 assert!(genome.cortical_areas.contains_key(&fatigue_id));
869 assert!(genome.cortical_areas.contains_key(&pain_id));
870 assert!(genome.cortical_areas.contains_key(&pleasure_id));
871 assert!(genome.cortical_areas.contains_key(&fear_id));
872 assert!(genome.cortical_areas.contains_key(&hope_id));
873
874 let power = genome.cortical_areas.get(&power_id).unwrap();
876 assert_eq!(power.cortical_id.as_base_64(), power_id.as_base_64());
877 assert_eq!(power.cortical_idx, 1);
878 assert_eq!(power.dimensions.width, 1);
879 assert_eq!(power.dimensions.height, 1);
880 assert_eq!(power.dimensions.depth, 1);
881 }
882
883 #[test]
884 fn test_create_genome_with_core_morphologies() {
885 let genome = create_genome_with_core_morphologies(
886 "test_genome".to_string(),
887 "Test Genome".to_string(),
888 );
889
890 assert_eq!(genome.metadata.genome_id, "test_genome");
891 assert!(genome.morphologies.count() > 0);
892 assert!(genome.morphologies.contains("block_to_block"));
893 assert!(genome.morphologies.contains("projector"));
894 assert!(genome.morphologies.contains("centered_projector"));
895 assert!(genome.morphologies.contains("transpose_xy"));
896 assert!(genome.morphologies.contains("transpose_yz"));
897 assert!(genome.morphologies.contains("transpose_xz"));
898 assert!(genome.morphologies.contains("first_to_last"));
899 assert!(genome.morphologies.contains("lateral_+x"));
900 }
901
902 #[test]
903 fn test_add_core_morphologies() {
904 let mut registry = MorphologyRegistry::new();
905 add_core_morphologies(&mut registry);
906
907 assert!(registry.count() >= 11);
909 assert!(registry.contains("block_to_block"));
910 assert!(registry.contains("projector"));
911 assert!(registry.contains("centered_projector"));
912 assert!(registry.contains("transpose_xy"));
913 assert!(registry.contains("transpose_yz"));
914 assert!(registry.contains("transpose_xz"));
915 assert!(registry.contains("first_to_last"));
916 assert!(registry.contains("all_to_0-0-0"));
917 assert!(registry.contains("lateral_+x"));
918 assert!(registry.contains("lateral_-z"));
919 }
920
921 #[test]
922 fn test_embedded_genomes_exist() {
923 #[allow(clippy::const_is_empty)]
927 {
928 assert!(!ESSENTIAL_GENOME_JSON.is_empty());
929 assert!(!BAREBONES_GENOME_JSON.is_empty());
930 assert!(!TEST_GENOME_JSON.is_empty());
931 assert!(!VISION_GENOME_JSON.is_empty());
932 }
933 }
934
935 #[test]
936 fn test_load_essential_genome() {
937 let genome = load_essential_genome().expect("Failed to load essential genome");
938 assert!(!genome.cortical_areas.is_empty());
939 let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
941 assert!(genome.cortical_areas.contains_key(&power_id));
942 }
943
944 #[test]
945 fn test_ensure_core_components_adds_missing_areas() {
946 let mut genome = create_minimal_genome("test".to_string(), "Test".to_string());
948
949 assert_eq!(genome.cortical_areas.len(), 0);
950
951 let (areas_added, _) = ensure_core_components(&mut genome);
953
954 assert_eq!(areas_added, 7);
956
957 let death_id = crate::genome::parser::string_to_cortical_id("_death").expect("Valid ID");
958 let power_id = crate::genome::parser::string_to_cortical_id("_power").expect("Valid ID");
959 let fatigue_id =
960 crate::genome::parser::string_to_cortical_id("_fatigue").expect("Valid ID");
961 let pain_id = crate::genome::parser::string_to_cortical_id("_pain").expect("Valid ID");
962 let pleasure_id =
963 crate::genome::parser::string_to_cortical_id("_pleasure").expect("Valid ID");
964 let fear_id = crate::genome::parser::string_to_cortical_id("_fear").expect("Valid ID");
965 let hope_id = crate::genome::parser::string_to_cortical_id("_hope").expect("Valid ID");
966 assert!(genome.cortical_areas.contains_key(&death_id));
967 assert!(genome.cortical_areas.contains_key(&power_id));
968 assert!(genome.cortical_areas.contains_key(&fatigue_id));
969 assert!(genome.cortical_areas.contains_key(&pain_id));
970 assert!(genome.cortical_areas.contains_key(&pleasure_id));
971 assert!(genome.cortical_areas.contains_key(&fear_id));
972 assert!(genome.cortical_areas.contains_key(&hope_id));
973
974 assert_eq!(
976 genome.cortical_areas.get(&death_id).unwrap().cortical_idx,
977 0
978 );
979 assert_eq!(
980 genome.cortical_areas.get(&power_id).unwrap().cortical_idx,
981 1
982 );
983 assert_eq!(
984 genome.cortical_areas.get(&fatigue_id).unwrap().cortical_idx,
985 2
986 );
987 assert_eq!(genome.cortical_areas.get(&pain_id).unwrap().cortical_idx, 3);
988 assert_eq!(
989 genome
990 .cortical_areas
991 .get(&pleasure_id)
992 .unwrap()
993 .cortical_idx,
994 4
995 );
996 assert_eq!(genome.cortical_areas.get(&fear_id).unwrap().cortical_idx, 5);
997 assert_eq!(genome.cortical_areas.get(&hope_id).unwrap().cortical_idx, 6);
998 }
999
1000 #[test]
1001 fn test_ensure_core_components_adds_missing_morphologies() {
1002 let mut genome = create_genome_with_core_areas("test".to_string(), "Test".to_string());
1004
1005 assert_eq!(genome.morphologies.count(), 0);
1006
1007 let (_, morphs_added) = ensure_core_components(&mut genome);
1009
1010 assert!(morphs_added > 0);
1012 assert!(genome.morphologies.contains("block_to_block"));
1013 assert!(genome.morphologies.contains("projector"));
1014 assert!(genome.morphologies.contains("centered_projector"));
1015 assert!(genome.morphologies.contains("transpose_xy"));
1016 assert!(genome.morphologies.contains("transpose_yz"));
1017 assert!(genome.morphologies.contains("transpose_xz"));
1018 assert!(genome.morphologies.contains("first_to_last"));
1019 assert!(genome.morphologies.contains("episodic_memory"));
1020 assert!(genome.morphologies.contains("lateral_+x"));
1021 }
1022
1023 #[test]
1024 fn test_ensure_core_components_idempotent() {
1025 let mut genome = create_genome_with_core_areas("test".to_string(), "Test".to_string());
1027 add_core_morphologies(&mut genome.morphologies);
1028
1029 let (areas_added, morphs_added) = ensure_core_components(&mut genome);
1031
1032 assert_eq!(areas_added, 0);
1034 assert_eq!(morphs_added, 0);
1035 }
1036}