feagi_structures/genomic/cortical_area/cortical_area.rs
1// Copyright 2025 Neuraville Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5CorticalArea data structure (genome representation).
6
7Pure data definition - no business logic.
8Transformation methods live in feagi-bdu.
9Moved from feagi-core/crates/feagi-bdu/src/models/cortical_area.rs
10*/
11
12use super::{CorticalAreaDimensions, CorticalAreaType, CorticalID};
13use crate::genomic::descriptors::GenomeCoordinate3D;
14use crate::FeagiDataError;
15use serde::{Deserialize, Serialize};
16use std::collections::HashMap;
17
18/// Cortical area metadata (genome representation)
19///
20/// Pure data structure containing static genome metadata.
21/// Runtime operations and transformations are implemented in feagi-bdu.
22///
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct CorticalArea {
25 /// Unique typed cortical identifier
26 pub cortical_id: CorticalID,
27
28 /// Integer index assigned by ConnectomeManager
29 pub cortical_idx: u32,
30
31 /// Human-readable name
32 pub name: String,
33
34 /// 3D dimensions (width, height, depth in voxels)
35 pub dimensions: CorticalAreaDimensions,
36
37 /// 3D position in genome space
38 pub position: GenomeCoordinate3D,
39
40 /// Cortical area type (encoding method and functional classification)
41 pub cortical_type: CorticalAreaType,
42
43 /// Additional user-defined properties
44 /// Note: See PROPERTIES_STRUCT_MIGRATION_PROPOSAL.md for future struct-based design
45 #[serde(default)]
46 pub properties: HashMap<String, serde_json::Value>,
47}
48
49impl CorticalArea {
50 /// Create a new cortical area with validation
51 ///
52 /// # Arguments
53 ///
54 /// * `cortical_id` - Unique typed cortical identifier
55 /// * `cortical_idx` - Integer index for fast lookups
56 /// * `name` - Human-readable name
57 /// * `dimensions` - 3D dimensions (width, height, depth)
58 /// * `position` - 3D position in genome space
59 /// * `cortical_type` - Cortical area type (encoding method)
60 ///
61 /// # Errors
62 ///
63 /// Returns error if name is empty
64 ///
65 pub fn new(
66 cortical_id: CorticalID,
67 cortical_idx: u32,
68 name: String,
69 dimensions: CorticalAreaDimensions,
70 position: GenomeCoordinate3D,
71 cortical_type: CorticalAreaType,
72 ) -> Result<Self, FeagiDataError> {
73 // Validate name
74 if name.trim().is_empty() {
75 return Err(FeagiDataError::BadParameters(
76 "name cannot be empty".to_string(),
77 ));
78 }
79
80 // Note: CorticalID validation happens in CorticalID constructors
81 // Note: dimensions validation happens in CorticalAreaDimensions::new()
82
83 Ok(Self {
84 cortical_id,
85 cortical_idx,
86 name,
87 dimensions,
88 position,
89 cortical_type,
90 properties: HashMap::new(),
91 })
92 }
93
94 /// Get a property value by key
95 pub fn get_property(&self, key: &str) -> Option<&serde_json::Value> {
96 self.properties.get(key)
97 }
98
99 /// Get the total number of voxels in this area
100 pub fn total_voxels(&self) -> u32 {
101 self.dimensions.total_voxels()
102 }
103}