Skip to main content

feagi_structures/genomic/
sensory_cortical_unit.rs

1use crate::genomic::cortical_area::descriptors::CorticalSubUnitIndex;
2use crate::genomic::cortical_area::descriptors::CorticalUnitIndex;
3use crate::genomic::cortical_area::io_cortical_area_configuration_flag::{
4    FrameChangeHandling, PercentageNeuronPositioning,
5};
6use crate::genomic::cortical_area::{
7    CorticalAreaType, CorticalID, IOCorticalAreaConfigurationFlag,
8};
9use crate::sensor_cortical_units;
10use paste;
11use serde_json::{Map, Value};
12use std::collections::HashMap;
13use std::fmt::{Display, Formatter};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] // TODO move me!
16pub struct UnitTopology {
17    pub relative_position: [i32; 3],
18    pub channel_dimensions_default: [u32; 3],
19    pub channel_dimensions_min: [u32; 3],
20    pub channel_dimensions_max: [u32; 3],
21}
22
23macro_rules! define_sensory_cortical_units_enum {
24    (
25        SensoryCorticalUnit {
26            $(
27                $(#[doc = $doc:expr])?
28                $variant_name:ident => {
29                    friendly_name: $friendly_name:expr,
30                    accepted_wrapped_io_data_type: $accepted_wrapped_io_data_type:expr,
31                    cortical_id_unit_reference: $cortical_id_unit_reference:expr,
32                    number_cortical_areas: $number_cortical_areas:expr,
33                    cortical_type_parameters: {
34                        $($param_name:ident: $param_type:ty),* $(,)?
35                    },
36                    $(allowed_frame_change_handling: [$($allowed_frame:ident),* $(,)?],)? // TODO delete this!
37                    cortical_area_properties: {
38                        $($cortical_sub_unit_index:tt => ($io_cortical_area_configuration_flag_expr:expr, relative_position: [$rel_x:expr, $rel_y:expr, $rel_z:expr], channel_dimensions_default: [$dim_default_x:expr, $dim_default_y:expr, $dim_default_z:expr], channel_dimensions_min: [$dim_min_x:expr, $dim_min_y:expr, $dim_min_z:expr], channel_dimensions_max: [$dim_max_x:expr, $dim_max_y:expr, $dim_max_z:expr])),* $(,)?
39                    }
40                }
41            ),* $(,)?
42        }
43    ) => {
44        #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, serde::Serialize, serde::Deserialize)]
45        pub enum SensoryCorticalUnit {
46            $(
47                $(#[doc = $doc])?
48                $variant_name,
49            )*
50        }
51
52        impl SensoryCorticalUnit {
53            $(
54                paste::paste! {
55                    #[doc = "Get cortical area types array for " $friendly_name " using individual parameters."]
56                    pub const fn [<get_cortical_area_types_array_for_ $variant_name:snake _with_parameters >](
57                        $($param_name: $param_type),*) -> [CorticalAreaType; $number_cortical_areas] {
58                        [
59                            $(CorticalAreaType::BrainInput($io_cortical_area_configuration_flag_expr)),*
60                        ]
61                    }
62
63                    #[doc = "Get cortical IDs array for " $friendly_name " using individual parameters."]
64                    pub const fn [<get_cortical_ids_array_for_ $variant_name:snake _with_parameters >](
65                        $($param_name: $param_type,)* cortical_unit_index: CorticalUnitIndex) -> [CorticalID; $number_cortical_areas] {
66                        let cortical_unit_identifier: [u8; 3] = $cortical_id_unit_reference;
67                        [
68                            $(
69                                $io_cortical_area_configuration_flag_expr .as_io_cortical_id(true, cortical_unit_identifier, cortical_unit_index, CorticalSubUnitIndex::from($cortical_sub_unit_index))
70                            ),*
71                        ]
72                    }
73                }
74            )*
75
76            pub const fn get_snake_case_name(&self) -> &'static str {
77                match self {
78                    $(
79                        SensoryCorticalUnit::$variant_name => paste::paste!{ stringify!([<$variant_name:snake>]) },
80                    )*
81                }
82            }
83
84            /// Parse a sensory cortical unit from its snake_case name
85            ///
86            /// # Arguments
87            /// * `name` - The snake_case name (e.g., "simple_vision", "accelerometer")
88            ///
89            /// # Returns
90            /// * `Some(SensoryCorticalUnit)` - If name matches a known type
91            /// * `None` - If name is not recognized
92            pub fn from_snake_case_name(name: &str) -> Option<SensoryCorticalUnit> {
93                match name {
94                    $(
95                        paste::paste!{ stringify!([<$variant_name:snake>]) } => Some(SensoryCorticalUnit::$variant_name),
96                    )*
97                    _ => None,
98                }
99            }
100
101            /// Returns all available sensory cortical unit types.
102            /// This is useful for enumerating all possible sensor types in the system.
103            pub const fn list_all() -> &'static [SensoryCorticalUnit] {
104                &[
105                    $(
106                        SensoryCorticalUnit::$variant_name,
107                    )*
108                ]
109            }
110
111            /// Returns the friendly (human-readable) name for this sensory cortical unit type.
112            pub const fn get_friendly_name(&self) -> &'static str {
113                match self {
114                    $(
115                        SensoryCorticalUnit::$variant_name => $friendly_name,
116                    )*
117                }
118            }
119
120            /// Returns the 3-byte cortical ID unit reference for this type. // TODO delete me!
121            pub const fn get_cortical_id_unit_reference(&self) -> [u8; 3] {
122                match self {
123                    $(
124                        SensoryCorticalUnit::$variant_name => $cortical_id_unit_reference,
125                    )*
126                }
127            }
128
129            /// Returns the number of cortical areas this type creates.
130            pub const fn get_number_cortical_areas(&self) -> usize {
131                match self {
132                    $(
133                        SensoryCorticalUnit::$variant_name => $number_cortical_areas,
134                    )*
135                }
136            }
137
138            /// Returns the accepted wrapped IO data type name for this sensory unit type.
139            pub const fn get_accepted_wrapped_io_data_type(&self) -> &'static str { // TODO delete me!
140                match self {
141                    $(
142                        SensoryCorticalUnit::$variant_name => stringify!($accepted_wrapped_io_data_type),
143                    )*
144                }
145            }
146
147            /// Returns the default topology for all units of this cortical type.
148            pub fn get_unit_default_topology(&self) -> HashMap<CorticalSubUnitIndex, UnitTopology> {
149                match self {
150                    $(
151                        SensoryCorticalUnit::$variant_name => {
152                            let mut topology = HashMap::new();
153                            $(
154                                topology.insert(
155                                    CorticalSubUnitIndex::from($cortical_sub_unit_index),
156                                    UnitTopology {
157                                        relative_position: [$rel_x, $rel_y, $rel_z],
158                                        channel_dimensions_default: [$dim_default_x, $dim_default_y, $dim_default_z],
159                                        channel_dimensions_min: [$dim_min_x, $dim_min_y, $dim_min_z],
160                                        channel_dimensions_max: [$dim_max_x, $dim_max_y, $dim_max_z],
161                                    }
162                                );
163                            )*
164                            topology
165                        }
166                    )*
167                }
168            }
169
170
171            /// Returns the allowed frame change handling modes from the template, if restricted.
172            /// If None is returned, all frame change handling modes are allowed.
173            /// If Some is returned, only the specified modes are valid.
174            pub fn get_allowed_frame_change_handling(&self) -> Option<&'static [FrameChangeHandling]> { // TODO delete me!
175                match self {
176                    $(
177                        SensoryCorticalUnit::$variant_name => {
178                            $crate::get_allowed_frame_change_handling_impl!($($($allowed_frame),*)?)
179                        }
180                    )*
181                }
182            }
183
184            pub fn get_cortical_id_vector_from_index_and_serde_io_configuration_flags(&self, cortical_unit_index: CorticalUnitIndex, map: Map<String, Value>) -> Result<Vec<CorticalID>, crate::FeagiDataError> {
185                match self {
186                    $(
187                        SensoryCorticalUnit::$variant_name => {
188                            paste::paste! {
189                                let array = SensoryCorticalUnit::[<get_cortical_ids_array_for_ $variant_name:snake _with_parameters >](
190                                    $($param_type::try_from_serde_map(&map)?,)*
191                                    cortical_unit_index);
192                                return Ok(array.to_vec());
193                            }
194                        }
195                    )*
196                }
197            }
198
199
200
201        }
202
203        impl Display for SensoryCorticalUnit {
204            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
205                match self {
206                    $(
207                        SensoryCorticalUnit::$variant_name => write!(f, $friendly_name),
208                    )*
209                }
210    }
211        }
212    };
213
214}
215// Generate the SensoryCorticalUnit enum and all helper methods from the template
216sensor_cortical_units!(define_sensory_cortical_units_enum);