feagi_structures/genomic/
sensory_cortical_unit.rs1use 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)] pub 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),* $(,)?],)? 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 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 pub const fn list_all() -> &'static [SensoryCorticalUnit] {
104 &[
105 $(
106 SensoryCorticalUnit::$variant_name,
107 )*
108 ]
109 }
110
111 pub const fn get_friendly_name(&self) -> &'static str {
113 match self {
114 $(
115 SensoryCorticalUnit::$variant_name => $friendly_name,
116 )*
117 }
118 }
119
120 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 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 pub const fn get_accepted_wrapped_io_data_type(&self) -> &'static str { match self {
141 $(
142 SensoryCorticalUnit::$variant_name => stringify!($accepted_wrapped_io_data_type),
143 )*
144 }
145 }
146
147 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 pub fn get_allowed_frame_change_handling(&self) -> Option<&'static [FrameChangeHandling]> { 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}
215sensor_cortical_units!(define_sensory_cortical_units_enum);