Repository: feagi/feagi (language: python)

Issue:
Updates from Neuraville Inc
This PR syncs with latest Neuraville Inc. development code.
Updates from Neuraville Inc
This PR syncs with latest Neuraville Inc. development code.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/docker-image-feagi.yml b/.github/workflows/docker-update-stable.yml
similarity index 95%
rename from .github/workflows/docker-image-feagi.yml
rename to .github/workflows/docker-update-stable.yml
index 4ea34bd64..76b7b3c39 100644
--- a/.github/workflows/docker-image-feagi.yml
+++ b/.github/workflows/docker-update-stable.yml
@@ -31,4 +31,4 @@ jobs:
           context: docker/
           platforms: linux/amd64,linux/arm64
           push: true
-          tags: neuraville/feagi:latest
+          tags: neuraville/feagi:stable
diff --git a/community_genomes/README.md b/community_genomes/README.md
new file mode 100644
index 000000000..07e51a155
--- /dev/null
+++ b/community_genomes/README.md
@@ -0,0 +1,39 @@
+# FEAGI Community Genome Repository
+
+Welcome to the **FEAGI Community Genome Repository**! We invite all FEAGI community members to contribute their functional genomes to this folder. As the collection of community genomes grows, the organization of this folder will evolve accordingly. For now, please ensure that each genome submission is stored in a dedicated folder. 
+
+### Submission Guidelines:
+- **Title & Description**: Each submission should include a clearly defined title and a detailed description that reflects the functionality of the genome.
+- **README**: It’s highly encouraged to include a `README.md` file in markdown format, outlining the purpose and features of the genome.
+  
+### Example Folder Structure:
+```plaintext
+community_genomes/
+  ├── genome_name/
+  │   ├── genome.json
+  │   ├── README.md
+  │   └── supplementary_files/
+```
+
+
+### Contribution Process:
+1. **Fork** this repository.
+2. **Clone** your fork locally.
+3. Add your genome folder and related files.
+4. **Commit** your changes and push them to your fork.
+5. Submit a **Pull Request** to this repository for review.
+
+### Genome Validation
+Please ensure your genome is functional before submitting it to the repository. If you are uncertain, refer to the [FEAGI documentation](https://github.com/feagi/feagi/wiki) for testing instructions.
+
+### Licensing
+By submitting a genome to this repository, you agree to share it under a **Creative Commons License**.
+
+### Acknowledgment
+If you base your genome on someone else’s work, please acknowledge them in your submission’s `README.md` file.
+
+### Online Repository
+For a comprehensive, ranked genome repository, visit: [FEAGI Hub](https://www.neurorobotics.studio/hub).
+
+### Support
+For any questions or assistance, feel free to reach out through our [Discord](https://discord.gg/link) or create an issue in this repository.
diff --git a/docker/.env b/docker/.env
index df737390c..59997c469 100644
--- a/docker/.env
+++ b/docker/.env
@@ -26,11 +26,7 @@ FEAGI_HOST_INTERNAL=feagi
 FEAGI_API_PORT=8000
 FEAGI_OPU_PORT=30000
 
-# Host IP address that Gadot container will share with FEAGI
-GADOT_HOST=127.0.0.1
-GADOT_HOST_INTERNAL=127.0.0.1
-GODOT_WEBSOCKET_HOST=127.0.0.1
-GADOT_WEBSOCKET_PORT=9050
+# Host IP address that Godot container will share with FEAGI
 WS_BRIDGE_PORT=9050
 WS_WEBCAM_PORT=9051
 WS_MICROBIT_PORT=9052
@@ -39,7 +35,7 @@ GODOT_GENERIC_IP=127.0.0.1
 
 # URLS for GUI
 GAZEBO_URL=http://127.0.0.1:6080
-GADOT_URL=http://127.0.0.1:6081
+GODOT_URL=http://127.0.0.1:6081
 ANALYTICS_URL=http://127.0.0.1:6082
 FEAGI_URL=http://127.0.0.1:8000
 URL_BRAIN_PONG=None
diff --git a/docker/Dockerfile b/docker/Dockerfile
index c33a34d41..7f27453da 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -6,11 +6,8 @@ ARG BRANCH="main"
 ENV Running_In_CONTAINER Yes
 
 RUN mkdir -p /opt/source-code/feagi/
-RUN git clone $REPO /opt/source-code/feagi
-WORKDIR /opt/source-code/feagi
-RUN git fetch --all
-RUN git checkout $BRANCH
-
+RUN echo "branch: " $BRANCH
+RUN git clone $REPO -b $BRANCH /opt/source-code/feagi
 
 WORKDIR /opt/source-code/feagi/src
 ENV PYTHONPATH "${PYTHONPATH}:/opt/source-code/feagi"
diff --git a/docker/archive/Gazebo_apple_silicone.yml b/docker/archive/Gazebo_apple_silicone.yml
index 2167244a7..8e6be5c5e 100644
--- a/docker/archive/Gazebo_apple_silicone.yml
+++ b/docker/archive/Gazebo_apple_silicone.yml
@@ -65,7 +65,7 @@ services:
     ports:
       - "6081:8080"
       - "9050:9050"
-      - "30001:30001" # ZMQ port for feagi to connect for Gadot
+      - "30001:30001" # ZMQ port for feagi to connect for Godot
     env_file:
       - ./.env
     privileged: true
diff --git a/docker/archive/apple_silicon_feagi.yml b/docker/archive/apple_silicon_feagi.yml
index a7378af0c..3e533fca3 100644
--- a/docker/archive/apple_silicon_feagi.yml
+++ b/docker/archive/apple_silicon_feagi.yml
@@ -100,7 +100,7 @@ services:
     platform: linux/arm64
     ports:
       - "9050:9050"
-      - "30001:30001" # ZMQ port for feagi to connect for Gadot
+      - "30001:30001" # ZMQ port for feagi to connect for Godot
     env_file:
       - ./.env
     privileged: true
diff --git a/docker/archive/feagi-OnlyGodot.yml b/docker/archive/feagi-OnlyGodot.yml
index df9f25dca..b25966681 100644
--- a/docker/archive/feagi-OnlyGodot.yml
+++ b/docker/archive/feagi-OnlyGodot.yml
@@ -27,7 +27,7 @@ services:
           memory: '2g'
     ports:
       - "9050:9050"
-      - "30001:30001" # ZMQ port for feagi to connect for Gadot
+      - "30001:30001" # ZMQ port for feagi to connect for Godot
     env_file:
       - ./.env
     privileged: true
diff --git a/docker/archive/feagi.yml b/docker/archive/feagi.yml
index d035b88da..c5c231a58 100644
--- a/docker/archive/feagi.yml
+++ b/docker/archive/feagi.yml
@@ -99,7 +99,7 @@ services:
           memory: '2g'
     ports:
       - "9050:9050"
-      - "30001:30001" # ZMQ port for feagi to connect for Gadot
+      - "30001:30001" # ZMQ port for feagi to connect for Godot
     env_file:
       - ./.env
     privileged: true
diff --git a/docker/archive/templates/full_template.yml b/docker/archive/templates/full_template.yml
index 42c9537b4..64d3e0c29 100644
--- a/docker/archive/templates/full_template.yml
+++ b/docker/archive/templates/full_template.yml
@@ -95,7 +95,7 @@ services:
     ports:
       - "6081:8080"
       - "9050:9050"
-      - "30001:30001" # ZMQ port for feagi to connect for Gadot
+      - "30001:30001" # ZMQ port for feagi to connect for Godot
     env_file:
       - ./.env
     privileged: true
diff --git a/docker/archive/webcam_javascript.yml b/docker/archive/webcam_javascript.yml
index 860da4710..554c2566e 100644
--- a/docker/archive/webcam_javascript.yml
+++ b/docker/archive/webcam_javascript.yml
@@ -26,7 +26,7 @@ services:
           memory: '2g'
     ports:
       - "9050:9050"
-      - "30001:30001" # ZMQ port for feagi to connect for Gadot
+      - "30001:30001" # ZMQ port for feagi to connect for Godot
     env_file:
       - ./.env
     privileged: true
diff --git a/docker/playground.yml b/docker/playground.yml
index fec258740..e0bf1caa0 100644
--- a/docker/playground.yml
+++ b/docker/playground.yml
@@ -33,7 +33,7 @@ services:
           memory: '1g'
     ports:
       - "9050:9050"
-      - "30001:30001" # ZMQ port for feagi to connect for Gadot
+      - "30001:30001" # ZMQ port for feagi to connect for Godot
     env_file:
       - ./.env
     privileged: true
diff --git a/src/api/routers/v1/cortical_area.py b/src/api/routers/v1/cortical_area.py
index 89b273f13..14d7eca6a 100644
--- a/src/api/routers/v1/cortical_area.py
+++ b/src/api/routers/v1/cortical_area.py
@@ -72,6 +72,10 @@ async def fetch_cortical_properties(cortical_id: CorticalId):
             dim_y = cortical_data["block_boundaries"][1]
             dim_z = cortical_data["block_boundaries"][2]
 
+            leak_variability = cortical_data.get('leak_variability', 0)
+            if not leak_variability:
+                leak_variability = 0
+
             cortical_properties = {
                 "cortical_id": cortical_area,
                 "cortical_name": cortical_data['cortical_name'],
@@ -108,7 +112,7 @@ async def fetch_cortical_properties(cortical_id: CorticalId):
                 "neuron_firing_threshold_limit": cortical_data['firing_threshold_limit'],
                 "neuron_refractory_period": cortical_data['refractory_period'],
                 "neuron_leak_coefficient": cortical_data['leak_coefficient'],
-                "neuron_leak_variability": cortical_data['leak_variability'],
+                "neuron_leak_variability": leak_variability,
                 "neuron_consecutive_fire_count": cortical_data['consecutive_fire_cnt_max'],
                 "neuron_snooze_period": cortical_data['snooze_length'],
                 "neuron_degeneracy_coefficient": cortical_data['degeneration'],
@@ -469,6 +473,10 @@ async def fetch_multiple_cortical_properties(cortical_id_list: CorticalIdList):
                     cortical_data['2d_coordinate'].append(None)
                     cortical_data['2d_coordinate'].append(None)
 
+                leak_variability = cortical_data.get('leak_variability', 0)
+                if not leak_variability:
+                    leak_variability = 0
+
                 cortical_properties = {
                     "cortical_id": cortical_area,
                     "cortical_name": cortical_data['cortical_name'],
@@ -505,7 +513,7 @@ async def fetch_multiple_cortical_properties(cortical_id_list: CorticalIdList):
                     "neuron_firing_threshold_limit": cortical_data['firing_threshold_limit'],
                     "neuron_refractory_period": cortical_data['refractory_period'],
                     "neuron_leak_coefficient": cortical_data['leak_coefficient'],
-                    "neuron_leak_variability": cortical_data['leak_variability'],
+                    "neuron_leak_variability": leak_variability,
                     "neuron_consecutive_fire_count": cortical_data['consecutive_fire_cnt_max'],
                     "neuron_snooze_period": cortical_data['snooze_length'],
                     "neuron_degeneracy_coefficient": cortical_data['degeneration'],
diff --git a/src/api/routers/v1/feagi_agent.py b/src/api/routers/v1/feagi_agent.py
index 7a4dd7567..35e329ea0 100644
--- a/src/api/routers/v1/feagi_agent.py
+++ b/src/api/routers/v1/feagi_agent.py
@@ -17,13 +17,14 @@
 
 import os
 
-from fastapi import APIRouter, HTTPException, Request
+from fastapi import APIRouter, HTTPException, Request, Depends
 
 from ...schemas import *
 from ...commons import *
 
 from src.inf import runtime_data
 from src.inf.messenger import Sub
+from ...dependencies import check_brain_running
 
 
 router = APIRouter()
@@ -67,6 +68,7 @@ async def agent_properties(agent_id: str):
         agent_info["agent_router_address"] = runtime_data.agent_registry[agent_id]["agent_router_address"]
         agent_info["agent_version"] = runtime_data.agent_registry[agent_id]["agent_version"]
         agent_info["controller_version"] = runtime_data.agent_registry[agent_id]["controller_version"]
+        agent_info["capabilities"] = runtime_data.agent_registry[agent_id].get("capabilities", {})
         return agent_info
     else:
         raise HTTPException(status_code=400, detail="Requested agent not found!")
@@ -160,7 +162,8 @@ async def gazebo_robot_default_files():
 
 
 @router.post("/manual_stimulation")
-async def trigger_manual_stimulation(stimulation: ManualStimulation):
+async def trigger_manual_stimulation(stimulation: ManualStimulation,
+                                     _: str = Depends(check_brain_running)):
     """
     Stimulation needs to be in the following format:
     {
diff --git a/src/api/routers/v1/training.py b/src/api/routers/v1/training.py
index 31b9345e9..69c4017a7 100644
--- a/src/api/routers/v1/training.py
+++ b/src/api/routers/v1/training.py
@@ -111,17 +111,119 @@ async def training_report():
     return runtime_data.training_stats
 
 
+@router.get("/brain_fitness")
+async def brain_average_fitness_value():
+    """
+    Calculates fitness score based on the defined fitness criteria
+    """
+    cumulative_score = 0
+    try:
+        counter = 0
+        for stat in runtime_data.fitness_stats:
+            fitness_score = 0
+            counter += 1
+            criteria = stat.get("FITNESS_KEYS")
+            if criteria:
+                for criterion in stat["FITNESS_KEYS"]:
+                    if criterion not in runtime_data.fitness_criteria:
+                        raise HTTPException(status_code=400, detail=f"{criterion} is not defied as a fitness criteria!"
+                                                                    f"Use post:/fitness_criteria to define it first.")
+                    fitness_score += stat["FITNESS_KEYS"][criterion] * runtime_data.fitness_criteria[criterion]
+            cumulative_score += fitness_score
+
+        if counter == 0:
+            return 1
+        else:
+            runtime_data.fitness_score = cumulative_score / counter
+            return runtime_data.fitness_score
+    except Exception as e:
+        raise HTTPException(status_code=400, detail=f"Error during fitness calculation as {e}")
+
+
+@router.get("/fitness_criteria")
+async def fetch_fitness_criteria():
+    """
+    Returns the effective fitness criteria
+    """
+    return runtime_data.fitness_criteria
+
+
+@router.post("/fitness_criteria")
+async def configure_fitness_criteria(fitness_criteria: dict):
+    """
+    Configure the weights associated with each fitness criteria.
+
+    Important: Total weights has to equal to 1.
+
+    Actual game stats will be weighted based on the defined criteria and produce a single fitness value between 0 and 1.
+    ```json
+    {
+        "time_alive": 0.4,
+        "max_level_reached": 0.2,
+        "score_trying_to_max": 1.0,
+        "score_trying_to_min": -1.0,
+        "something_custom": 0.4
+    }
+    ```
+
+    """
+
+    key_sum = 0
+    for criterion in fitness_criteria:
+        key_sum += fitness_criteria[criterion]
+
+    if key_sum != 1:
+        raise HTTPException(status_code=400, detail=f"The sum of all FITNESS_KEYS should be equal to 1")
+
+    runtime_data.fitness_criteria = fitness_criteria
+
+
 @router.get("/fitness_stats")
-async def fetch_fitness_stats():
+async def reset_fitness_stats():
     """
-    updates fitness stats
+    Resets fitness stats
     """
     return runtime_data.fitness_stats
 
 
 @router.put("/fitness_stats")
-async def capture_fitness_stats(fitness_stats: FitnessStats):
+async def capture_fitness_stats_instance(fitness_stats: dict):
+    """
+    updates fitness stats. Data should be in a dictionary form following the structure defined under /fitness_criteria
+
+    Sample:
+    ```json
+    {
+    "FITNESS_KEYS":
+        {
+            "time_alive": 672,
+            "max_level_reached": 2,
+            "score_trying_to_max": 78,
+            "score_trying_to_min": 42,
+            "something_custom": 23
+        },
+    "METADATA":
+        {
+            "event": "changed such and such environment variable"
+        }
+    }
+    ```
+    Note: Metadata is optional and to provide additional context.
+
+    """
+
+    if "FITNESS_KEYS" not in fitness_stats:
+        raise HTTPException(status_code=400, detail=f"FITNESS_KEYS is not defined as a dictionary key")
+
+    if "METADATA" not in fitness_stats:
+        fitness_stats["METADATA"] = {}
+
+    runtime_data.fitness_stats.append(fitness_stats)
+
+
+@router.delete("/fitness_stats")
+async def reset_fitness_stats():
     """
-    updates fitness stats
+    Resets fitness stats
     """
-    runtime_data.training_stats = fitness_stats
+    runtime_data.fitness_stats = []
diff --git a/src/api/schemas.py b/src/api/schemas.py
index dbc540808..2156985ca 100644
--- a/src/api/schemas.py
+++ b/src/api/schemas.py
@@ -285,10 +285,6 @@ class Id(BaseModel):
     id: str
 
 
-class FitnessStats(BaseModel):
-    fitness_stats: dict
-
-
 class RobotController(BaseModel):
     motor_power_coefficient: float
     motor_power_coefficient = 0.5
@@ -351,6 +347,6 @@ class UserPreferences(BaseModel):
 class BrainVisualization(BaseModel):
     global_visualization: bool = True
 
-      
+
 class ManualStimulation(BaseModel):
     stimulation_payload: dict = None
diff --git a/src/evo/genome_processor.py b/src/evo/genome_processor.py
index db75d8da3..a68731f66 100644
--- a/src/evo/genome_processor.py
+++ b/src/evo/genome_processor.py
@@ -477,8 +477,12 @@ def genome_morphology_updator(genome):
 
 
 def is_memory_cortical_area(cortical_area):
-    if "MEMORY" in runtime_data.genome["blueprint"][cortical_area]["sub_group_id"]:
-        return True
+    cortical_obj = runtime_data.genome["blueprint"].get(cortical_area)
+    if cortical_obj:
+        if "MEMORY" in runtime_data.genome["blueprint"][cortical_area]["sub_group_id"]:
+            return True
+        else:
+            return False
     else:
         return False
 
diff --git a/src/evo/neuroembryogenesis.py b/src/evo/neuroembryogenesis.py
index 54d89636c..aa67cb45d 100644
--- a/src/evo/neuroembryogenesis.py
+++ b/src/evo/neuroembryogenesis.py
@@ -36,6 +36,7 @@
 import datetime
 import shutil
 import concurrent.futures
+from src.evo.connectome import reuse
 from src.evo import neuron, synapse, stats, genetics, voxels
 from src.evo.genome_editor import save_genome
 from src.evo.genome_processor import genome_v1_v2_converter
@@ -206,7 +207,7 @@ def voxelogenesis(cortical_area):
     for x in range(x_dim):
         for y in range(y_dim):
             for z in range(z_dim):
-                voxel_id = voxels.block_reference_builder([x, y, z])
+                voxel_id = (x, y, z)
                 runtime_data.voxel_dict[cortical_area][voxel_id] = set()
 
 
diff --git a/src/evo/neuron.py b/src/evo/neuron.py
index 2d4b59e53..ea6f15cc3 100644
--- a/src/evo/neuron.py
+++ b/src/evo/neuron.py
@@ -144,7 +144,7 @@ def create_neuron(cortical_area, voxel):
     if neuron_count < 1 or not neuron_count:
         neuron_count = 1
 
-    neuron_location = block_ref_2_id(voxel)
+    neuron_location = tuple(voxel)
 
     # Create a new Neuron in target destination
     for _ in range(int(neuron_count)):
diff --git a/src/evo/stats.py b/src/evo/stats.py
index ab0837742..6198379ff 100644
--- a/src/evo/stats.py
+++ b/src/evo/stats.py
@@ -284,7 +284,7 @@ def opu_activity_report(cortical_area):
             z_report = []
             # The Z axis is captures the primary property of the OPU such as speed, color, angle, etc
             for primary_variable in range(block_boundaries[2]):
-                block_ref = block_reference_builder([device, secondary_variable, primary_variable])
+                block_ref = (device, secondary_variable, primary_variable)
                 z_report.append(percent_active_neurons_in_block(block_ref=block_ref,
                                                                 cortical_area=cortical_area))
                 # device_activity_report.append(percent_active_neurons_in_block(block_ref=block_ref,
diff --git a/src/evo/synapse.py b/src/evo/synapse.py
index 7c85eb314..78e123444 100644
--- a/src/evo/synapse.py
+++ b/src/evo/synapse.py
@@ -125,7 +125,6 @@ def neighbor_builder(cortical_area, brain, genome, brain_gen, cortical_area_dst)
     synapse_count = 0
 
     mappings = runtime_data.genome["blueprint"][cortical_area]['cortical_mapping_dst'][cortical_area_dst]
-
     for morphology in mappings:
         try:
             # subregion definition is the start and end points of a vector defining a subregion
@@ -133,7 +132,6 @@ def neighbor_builder(cortical_area, brain, genome, brain_gen, cortical_area_dst)
             # src_subregions with be a collection of all subregions associated with a select composite morphology
             morphology_properties = runtime_data.genome["neuron_morphologies"][morphology["morphology_id"]]
             mapper_morphology = None
-
             src_subregions = set()
             if morphology_properties["type"] == "composite":
                 src_subregions = define_subregions(cortical_area=cortical_area,
diff --git a/src/evo/synaptogenesis_rules.py b/src/evo/synaptogenesis_rules.py
index 977fb1578..f5bab0146 100644
--- a/src/evo/synaptogenesis_rules.py
+++ b/src/evo/synaptogenesis_rules.py
@@ -93,6 +93,8 @@ def neighbor_finder(cortical_area_src, cortical_area_dst, src_neuron_id, morphol
     psc_base = runtime_data.genome["blueprint"][cortical_area_src]['postsynaptic_current']
     post_synaptic_current = psc_multiplier * psc_base
 
+    src_block_boundaries = runtime_data.genome["blueprint"][cortical_area_src]["block_boundaries"]
+
     try:
         if runtime_data.genome["neuron_morphologies"][neuron_morphology]["type"] == "vectors":
             for vector in runtime_data.genome["neuron_morphologies"][neuron_morphology]["parameters"]["vectors"]:
@@ -108,9 +110,19 @@ def neighbor_finder(cortical_area_src, cortical_area_dst, src_neuron_id, morphol
         elif runtime_data.genome["neuron_morphologies"][neuron_morphology]["type"] == "patterns":
             for pattern in runtime_data.genome["neuron_morphologies"][neuron_morphology]["parameters"]["patterns"]:
 
-                candidate_list = match_patterns(src_voxel=src_voxel, cortical_area_dst=cortical_area_dst,
-                                                pattern=pattern, morphology_scalar=morphology_scalar
-                                                , src_subregion=src_subregion)
+                dst_block_boundaries = runtime_data.genome["blueprint"][cortical_area_dst]["block_boundaries"]
+
+                source_pattern = pattern[0]
+                destination_pattern = pattern[1]
+                candidate_list = []
+                # for src_candidate in src_generator:
+                dst_generator = find_destination_coordinates(src_pattern=source_pattern,
+                                                             dst_pattern=destination_pattern,
+                                                             dst_cortical_boundary=dst_block_boundaries,
+                                                             src_coordinate=src_voxel)
+                for dst_candidate in dst_generator:
+                    candidate_list.append(dst_candidate)
+
                 if candidate_list:
                     for candidate in candidate_list:
                         raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
@@ -143,12 +155,59 @@ def neighbor_finder(cortical_area_src, cortical_area_dst, src_neuron_id, morphol
                                                  s=10, src_subregion=src_subregion)
                 raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
                 # candidate_voxel_list.append([candidate, post_synaptic_current])
+
+            elif neuron_morphology == "last_to_first":
+                src_cortical_dim = runtime_data.genome['blueprint'][cortical_area_src]["block_boundaries"]
+                if src_voxel == [src_cortical_dim[0] - 1, src_cortical_dim[1] - 1, src_cortical_dim[2] - 1]:
+                    raw_candidate_list.add((0, 0, 0))
+
             elif neuron_morphology == "projector":
                 candidate_list = syn_projector(cortical_area_src, cortical_area_dst,
                                                src_neuron_id, src_subregion=src_subregion)
                 for candidate in candidate_list:
                     raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
-                    # candidate_voxel_list.append([candidate, post_synaptic_current])
+
+            elif neuron_morphology == "projector_xy":
+                candidate_list = syn_projector(cortical_area_src, cortical_area_dst,
+                                               src_neuron_id, src_subregion=src_subregion, transpose=("y", "x", "z"))
+                for candidate in candidate_list:
+                    raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
+
+            elif neuron_morphology == "projector_xz":
+                candidate_list = syn_projector(cortical_area_src, cortical_area_dst,
+                                               src_neuron_id, src_subregion=src_subregion, transpose=("z", "y", "x"))
+                for candidate in candidate_list:
+                    raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
+
+            elif neuron_morphology == "projector_yz":
+                candidate_list = syn_projector(cortical_area_src, cortical_area_dst,
+                                               src_neuron_id, src_subregion=src_subregion, transpose=("x", "z", "y"))
+                for candidate in candidate_list:
+                    raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
+
+            elif neuron_morphology == "project_from_end_x":
+                if src_voxel[0] == src_block_boundaries[0] - 1:
+                    candidate_list = syn_projector(cortical_area_src, cortical_area_dst,
+                                                   src_neuron_id, src_subregion=src_subregion,
+                                                   project_last_layer_of="x")
+                    for candidate in candidate_list:
+                        raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
+
+            elif neuron_morphology == "project_from_end_y":
+                if src_voxel[1] == src_block_boundaries[1] - 1:
+                    candidate_list = syn_projector(cortical_area_src, cortical_area_dst,
+                                                   src_neuron_id, src_subregion=src_subregion,
+                                                   project_last_layer_of="y")
+                    for candidate in candidate_list:
+                        raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
+
+            elif neuron_morphology == "project_from_end_z":
+                if src_voxel[2] == src_block_boundaries[2] - 1:
+                    candidate_list = syn_projector(cortical_area_src, cortical_area_dst,
+                                                   src_neuron_id, src_subregion=src_subregion,
+                                                   project_last_layer_of="z")
+                    for candidate in candidate_list:
+                        raw_candidate_list.add((candidate[0], candidate[1], candidate[2]))
 
             elif neuron_morphology == "memory":
                 syn_memory(src_cortical_area=cortical_area_src, dst_cortical_area=cortical_area_dst)
@@ -166,7 +225,7 @@ def neighbor_finder(cortical_area_src, cortical_area_dst, src_neuron_id, morphol
         print(traceback.format_exc())
 
     for candidate in raw_candidate_list:
-        candidate_voxel_list.append([list(candidate), post_synaptic_current])
+        candidate_voxel_list.append([tuple(candidate), post_synaptic_current])
 
     if candidate_voxel_list:
         candidate_neuron_list = \
@@ -175,6 +234,21 @@ def neighbor_finder(cortical_area_src, cortical_area_dst, src_neuron_id, morphol
         return candidate_neuron_list
 
 
+# todo: use the following function
+def validate_pattern(pattern):
+    valid_patterns = {"*", "?", "!"}
+    for p in pattern:
+        if isinstance(p, list) and len(p) == 3:
+            for axis_pattern in p:
+                if axis_pattern not in valid_patterns:
+                    try:
+                        int(axis_pattern)
+                    except ValueError:
+                        raise ValueError(f"Invalid pattern value: {axis_pattern}")
+        else:
+            raise ValueError("Pattern must be a list of three elements per axis.")
+
+
 def match_vectors(src_voxel, cortical_area_dst, vector, morphology_scalar, src_subregion):
     scaled_vector = [prod(x) for x in zip(vector, morphology_scalar)]
     candidate_vector = [sum(x) for x in zip(src_voxel, scaled_vector)]
@@ -182,92 +256,98 @@ def match_vectors(src_voxel, cortical_area_dst, vector, morphology_scalar, src_s
         if item < 0:
             return None
     within_limits = voxels.block_size_checker(cortical_area=cortical_area_dst,
-                                              block=voxels.block_reference_builder(candidate_vector))
+                                              block=(candidate_vector[0], candidate_vector[1], candidate_vector[2]))
     if within_limits:
         return [candidate_vector]
 
 
-def match_patterns(src_voxel, cortical_area_dst, pattern, morphology_scalar, src_subregion):
+def check_pattern_validity(pattern):
+    """
+    Checks the validity of a pattern
+    """
+    valid_patterns = {"*", "?", "!"}
+    for element in pattern:
+        if element not in valid_patterns:
+            try:
+                value = int(element)
+                if not (0 <= value):
+                    return False
+            except ValueError:
+                return False
+    return True
+
+
+def find_source_coordinates(src_pattern, src_cortical_boundary):
+    """
+    Generator that yields coordinates within the cortical boundary that match the given pattern.
+
+    :param src_pattern: A tuple (x, y, z) where each element can be an integer or "*".
+                        "*" matches all positions along that axis.
+    :param src_cortical_boundary: A list [x, y, z] defining the size of the cortical cube.
+    :yield: Coordinates (as tuples) that match the pattern within the cortical boundaries.
     """
-    Matches source voxels to destination voxels
+    # Generate ranges based on pattern and boundary
+    x_range = range(src_cortical_boundary[0]) if src_pattern[0] == "*" else [src_pattern[0]]
+    y_range = range(src_cortical_boundary[1]) if src_pattern[1] == "*" else [src_pattern[1]]
+    z_range = range(src_cortical_boundary[2]) if src_pattern[2] == "*" else [src_pattern[2]]
+
+    # Use a generator expression to yield each matching coordinate
+    for x in x_range:
+        for y in y_range:
+            for z in z_range:
+                yield [x, y, z]
 
-    Expected pattern format:    [source pattern, destination pattern] e.g. [["*", "?", 3], [2, "*", "?"]]
 
+def find_destination_coordinates(dst_cortical_boundary, src_coordinate, src_pattern, dst_pattern):
     """
-    voxel_list = list()
-    dst_block_boundaries = runtime_data.genome["blueprint"][cortical_area_dst]["block_boundaries"]
-
-    if len(pattern) != 2:
-        print("Error! Pattern was not defined correctly.. "
-              "should be similar to e.g. [[\"*\", \"?\", 3], [2, \"*\", \"?\"]]\n Current is as:", pattern)
-
-    src_pattern_x, src_pattern_y, src_pattern_z = pattern[0]
-    dst_pattern_x, dst_pattern_y, dst_pattern_z = pattern[1]
-
-    src_x, src_y, src_z = src_voxel
-
-    for dst_x in range(dst_block_boundaries[0]):
-        for dst_y in range(dst_block_boundaries[1]):
-            for dst_z in range(dst_block_boundaries[2]):
-
-                matching_condition_x = \
-                    (
-                            dst_pattern_x == "*"
-                            or
-                            (dst_pattern_x == "?" and
-                             (src_x == dst_x))
-                            or
-                            (dst_pattern_x == "!" and
-                             (src_x != dst_x))
-                            or
-                            (dst_pattern_x == dst_x and
-                             (src_pattern_x == "*" or
-                              (src_pattern_x == "?" and src_x == dst_x) or
-                              (src_pattern_x == "!" and src_x != dst_x) or
-                              (src_pattern_x == src_x)))
-                    )
-
-                matching_condition_y = \
-                    (
-                            dst_pattern_y == "*"
-                            or
-                            (dst_pattern_y == "?" and
-                             (src_y == dst_y))
-                            or
-                            (dst_pattern_y == "!" and
-                             (src_y != dst_y))
-                            or
-                            (dst_pattern_y == dst_y and
-                             (src_pattern_y == "*" or
-                              (src_pattern_y == "?" and src_y == dst_y) or
-                              (src_pattern_y == "!" and src_y != dst_y) or
-                              (src_pattern_y == src_y)))
-                    )
-
-                matching_condition_z = \
-                    (
-                            dst_pattern_z == "*"
-                            or
-                            (dst_pattern_z == "?" and
-                             (src_z == dst_z))
-                            or
-                            (dst_pattern_z == "!" and
-                             (src_z != dst_z))
-                            or
-                            (dst_pattern_z == dst_z and
-                             (src_pattern_z == "*" or
-                              (src_pattern_z == "?" and src_z == dst_z) or
-                              (src_pattern_z == "!" and src_z != dst_z) or
-                              (src_pattern_z == src_z)))
-                    )
-
-                if matching_condition_x and matching_condition_y and matching_condition_z:
-                    voxel_list.append([dst_x, dst_y, dst_z])
-
-
-    # todo: account for morphology scalar
-
-    return voxel_list
+    Generator that yields destination coordinates within the cortical boundary
+    that match the given pattern based on the source coordinate.
+
+    :param dst_cortical_boundary: A list [x, y, z] defining the size of the destination cube.
+    :param src_coordinate: A list [int, int, int] representing the coordinate on the source object.
+    :param dst_pattern: A tuple (x, y, z) where each element can be "*", "?", "!", or an int.
+                        "*" matches any position along that axis.
+                        "?" matches the corresponding source coordinate.
+                        "!" matches any coordinate except the corresponding source coordinate.
+                        int specifies an exact match on that axis.
+    :yield: Destination coordinates (as tuples) that match the pattern within the destination boundaries.
+    """
+    # Generate ranges based on dst_pattern, dst_cortical_boundary, and src_coordinate
+    x_range = (
+        range(dst_cortical_boundary[0]) if dst_pattern[0] == "*"
+        else [src_coordinate[0]] if (dst_pattern[0] == "?" and src_coordinate[0] < dst_cortical_boundary[0] and
+                                     (src_coordinate[0] == src_pattern[0] or src_pattern[0] in ["*", "?"]))
+        else [i for i in range(dst_cortical_boundary[0]) if i != src_coordinate[0]] if dst_pattern[0] == "!"
+        else [dst_pattern[0]] if (isinstance(dst_pattern[0], int) and
+                                  (src_pattern[0] == src_coordinate[0] or src_pattern[0] == "*" or
+                                   (src_pattern[0] == "?" and dst_pattern[0] == src_coordinate[0]))) else []
+    )
+
+    y_range = (
+        range(dst_cortical_boundary[1]) if dst_pattern[1] == "*"
+        else [src_coordinate[1]] if (dst_pattern[1] == "?" and src_coordinate[1] < dst_cortical_boundary[1] and
+                                     (src_coordinate[1] == src_pattern[1] or src_pattern[1] in ["*", "?"]))
+        else [i for i in range(dst_cortical_boundary[1]) if i != src_coordinate[1]] if dst_pattern[1] == "!"
+        else [dst_pattern[1]] if (isinstance(dst_pattern[1], int) and
+                                  (src_pattern[1] == src_coordinate[1] or src_pattern[1] == "*" or
+                                   (src_pattern[1] == "?" and dst_pattern[1] == src_coordinate[1]))) else []
+    )
+
+    z_range = (
+        range(dst_cortical_boundary[2]) if dst_pattern[2] == "*"
+        else [src_coordinate[2]] if (dst_pattern[2] == "?" and src_coordinate[2] < dst_cortical_boundary[2] and
+                                     (src_coordinate[2] == src_pattern[2] or src_pattern[2] in ["*", "?"]))
+        else [i for i in range(dst_cortical_boundary[2]) if i != src_coordinate[2]] if dst_pattern[2] == "!"
+        else [dst_pattern[2]] if (isinstance(dst_pattern[2], int) and
+                                  (src_pattern[2] == src_coordinate[2] or src_pattern[2] == "*" or
+                                   (src_pattern[2] == "?" and dst_pattern[2] == src_coordinate[2]))) else []
+    )
+
+    # Use a generator expression to yield each matching destination coordinate
+    for x in x_range:
+        for y in y_range:
+            for z in z_range:
+                yield [x, y, z]
 
 
 def syn_expander_x(src_cortical_area, dst_cortical_area, src_neuron_id, src_subregion, dst_y_index=0, dst_z_index=0):
@@ -395,19 +475,97 @@ def syn_block_connection(src_cortical_area, dst_cortical_area, src_neuron_id, sr
     return [neuron_block_index_x // s, neuron_block_index_y, neuron_block_index_z]
 
 
-def syn_projector(src_cortical_area, dst_cortical_area, src_neuron_id, src_subregion):
+def syn_projector(src_cortical_area, dst_cortical_area, src_neuron_id, src_subregion,
+                  transpose=None, project_last_layer_of=None):
+
+    src_dimensions = runtime_data.genome['blueprint'][src_cortical_area]["block_boundaries"]
+    src_shape = [0, 0, 0]
+    dst_shape = [0, 0, 0]
     candidate_list = list()
-    src_shape = [
-        src_subregion[1][0] - src_subregion[0][0],
-        src_subregion[1][1] - src_subregion[0][1],
-        src_subregion[1][2] - src_subregion[0][2],
-    ]
 
-    dst_shape = runtime_data.genome['blueprint'][dst_cortical_area]["block_boundaries"]
+    # Apply transpose to src_subregion and neuron_location
+    if transpose:
+        axis_map = {"x": 0, "y": 1, "z": 2}  # Mapping of axes to indices
+        transpose_indices = [axis_map[axis] for axis in transpose]  # Get new order indices
+
+        # Transpose the source subregion
+        src_subregion = [
+            [src_subregion[0][transpose_indices[0]],
+             src_subregion[0][transpose_indices[1]],
+             src_subregion[0][transpose_indices[2]]],
+            [src_subregion[1][transpose_indices[0]],
+             src_subregion[1][transpose_indices[1]],
+             src_subregion[1][transpose_indices[2]]],
+        ]
+
+        # Transpose the neuron location
+        neuron_location = [
+            runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][transpose_indices[0]],
+            runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][transpose_indices[1]],
+            runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][transpose_indices[2]],
+        ]
+    else:
+        # If no transpose, use the default order
+        neuron_location = [
+            runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][0],
+            runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][1],
+            runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][2],
+        ]
+
+    # If project_last_layer is enabled, handle that case
+    if project_last_layer_of:
+
+        if project_last_layer_of == "x":
+            # Compute shapes of the source subregion and destination block boundaries
+            src_shape = [
+                src_dimensions[0] - 1,
+                src_subregion[1][1] - src_subregion[0][1],
+                src_subregion[1][2] - src_subregion[0][2],
+            ]
+
+            dst_shape = [
+                1,
+                runtime_data.genome['blueprint'][dst_cortical_area]["block_boundaries"][1],
+                runtime_data.genome['blueprint'][dst_cortical_area]["block_boundaries"][2]
+            ]
+
+        if project_last_layer_of == "y":
+            # Compute shapes of the source subregion and destination block boundaries
+            src_shape = [
+                src_subregion[1][0] - src_subregion[0][0],
+                src_dimensions[1] - 1,
+                src_subregion[1][2] - src_subregion[0][2],
+            ]
+
+            dst_shape = [
+                runtime_data.genome['blueprint'][dst_cortical_area]["block_boundaries"][0],
+                1,
+                runtime_data.genome['blueprint'][dst_cortical_area]["block_boundaries"][2]
+            ]
+
+        if project_last_layer_of == "z":
+            # Compute shapes of the source subregion and destination block boundaries
+            src_shape = [
+                src_subregion[1][0] - src_subregion[0][0],
+                src_subregion[1][1] - src_subregion[0][1],
+                src_dimensions[2] - 1,
+            ]
+
+            dst_shape = [
+                runtime_data.genome['blueprint'][dst_cortical_area]["block_boundaries"][0],
+                runtime_data.genome['blueprint'][dst_cortical_area]["block_boundaries"][1],
+                1
+            ]
+
+    else:
+        # Compute shapes of the source subregion and destination block boundaries
+        src_shape = [
+            src_subregion[1][0] - src_subregion[0][0],
+            src_subregion[1][1] - src_subregion[0][1],
+            src_subregion[1][2] - src_subregion[0][2],
+        ]
 
-    neuron_location = [runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][0],
-                       runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][1],
-                       runtime_data.brain[src_cortical_area][src_neuron_id]['soma_location'][2]]
+        dst_shape = runtime_data.genome['blueprint'][dst_cortical_area]["block_boundaries"]
 
     dst_vox_dict = dict()
 
@@ -415,13 +573,18 @@ def syn_projector(src_cortical_area, dst_cortical_area, src_neuron_id, src_subre
         for i in range(3):
             dst_vox_dict[i] = set()
             if src_shape[i] > dst_shape[i]:
-                ratio = src_shape[i]/dst_shape[i]
-                target_vox = int((neuron_location[i] - src_subregion[0][i])/ratio)
+                ratio = src_shape[i] / dst_shape[i]
+                target_vox = int((neuron_location[i] - src_subregion[0][i]) / ratio)
+                if (project_last_layer_of == "x" and i == 0) or \
+                        (project_last_layer_of == "y" and i == 1) or \
+                        (project_last_layer_of == "z" and i == 2):
+                    target_vox -= 1
                 dst_vox_dict[i].add(target_vox)
+
             elif src_shape[i] < dst_shape[i]:
-                ratio = dst_shape[i]/src_shape[i]
+                ratio = dst_shape[i] / src_shape[i]
                 for vox in range(dst_shape[i]):
-                    if int(vox/ratio) == (neuron_location[i] - src_subregion[0][i]):
+                    if int(vox / ratio) == (neuron_location[i] - src_subregion[0][i]):
                         target_vox = vox
                         dst_vox_dict[i].add(target_vox)
             elif src_shape[i] == dst_shape[i]:
@@ -431,13 +594,13 @@ def syn_projector(src_cortical_area, dst_cortical_area, src_neuron_id, src_subre
                 pass
     except ZeroDivisionError:
         pass
+
     if dst_vox_dict[0] and dst_vox_dict[1] and dst_vox_dict[2]:
         for x in dst_vox_dict[0]:
             for y in dst_vox_dict[1]:
                 for z in dst_vox_dict[2]:
-                    candidate_list.append([
-                        x, y, z
-                    ])
+                    candidate_list.append([x, y, z])
+
     return candidate_list
 
 
@@ -445,3 +608,9 @@ def syn_memory(src_cortical_area, dst_cortical_area):
     if dst_cortical_area not in runtime_data.memory_register:
         runtime_data.memory_register[dst_cortical_area] = set()
     runtime_data.memory_register[dst_cortical_area].add(src_cortical_area)
+
+
+def last_to_first(src_cortical_area):
+    src_cortical_dim = runtime_data.genome['blueprint'][src_cortical_area]["block_boundaries"]
+    return [[src_cortical_dim[0] - 1, src_cortical_dim[1] - 1, src_cortical_dim[2] - 1]]
+
diff --git a/src/evo/templates.py b/src/evo/templates.py
index 0d2034bce..650956985 100644
--- a/src/evo/templates.py
+++ b/src/evo/templates.py
@@ -38,17 +38,17 @@
             },
             "idgpio": {
                 "enabled": True,
-                "cortical_name": "Digital GPIO input",
+                "cortical_name": "Digital input",
                 "structure": "asymmetric",
-                "resolution": [28, 1, 1],
-                "coordinate_3d": [20, 0, 0]
+                "resolution": [1, 1, 1],
+                "coordinate_3d": [35, 20, -70]
             },
             "iagpio": {
                 "enabled": True,
-                "cortical_name": "Analog GPIO input",
+                "cortical_name": "Analog input",
                 "structure": "asymmetric",
-                "resolution": [28, 1, 10],
-                "coordinate_3d": [20, 0, 0]
+                "resolution": [1, 1, 10],
+                "coordinate_3d": [35, 0, -70]
             },
             "i__pro": {
                 "enabled": True,
@@ -153,7 +153,7 @@
                 "cortical_name": "ID Trainer",
                 "structure": "asymmetric",
                 "resolution": [1, 10, 1],
-                "coordinate_3d": [20, 0, 0]
+                "coordinate_3d": [111, 91, 0]
             },
             "i_spos": {
                 "enabled": True,
@@ -183,6 +183,13 @@
                 "resolution": [1, 1, 1],
                 "coordinate_3d": [20, 0, 0]
             },
+            "i_pres": {
+                "enabled": True,
+                "cortical_name": "Pressure Sensor Input",
+                "structure": "asymmetric",
+                "resolution": [3, 1, 21],
+                "coordinate_3d": [60, 0, 0]
+            },
         },
         "name_to_id_mapping": {
             "infrared": [
@@ -231,7 +238,20 @@
             ],
             "servo_motion": [
                 "i_smot"
+            ],
+            "digital_input": [
+                "idgpio"
+            ],
+            "analog_input": [
+                "iagpio"
+            ],
+            "id_trainer": [
+                "i___id"
+            ],
+            "pressure": [
+                "i_pres"
             ]
+
         }
     },
     "OPU": {
@@ -239,15 +259,17 @@
         "supported_devices": {
             "o__mot": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Motor control",
                 "controller_id": "motor",
                 "structure": "asymmetric",
                 "resolution": [2, 1, 10],
-                "coordinate_3d": [-30, 0, -20]
+                "coordinate_3d": [-30, 0, -20],
             },
             "odgpio": {
                 "enabled": True,
-                "cortical_name": "Digital GPIO output",
+                "measurable": False,
+                "cortical_name": "Digital output",
                 "controller_id": "gpio",
                 "structure": "asymmetric",
                 "resolution": [28, 1, 1],
@@ -255,7 +277,8 @@
             },
             "oagpio": {
                 "enabled": True,
-                "cortical_name": "Analog GPIO output",
+                "measurable": True,
+                "cortical_name": "Analog output",
                 "controller_id": "gpio",
                 "structure": "asymmetric",
                 "resolution": [28, 1, 10],
@@ -263,6 +286,7 @@
             },
             "oogpio": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "GPIO output pin assignment",
                 "controller_id": "gpio",
                 "structure": "asymmetric",
@@ -271,6 +295,7 @@
             },
             "oigpio": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "GPIO input pin assignment",
                 "controller_id": "gpio_input",
                 "structure": "asymmetric",
@@ -279,6 +304,7 @@
             },
             "o__nav": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Navigation vector",
                 "controller_id": "navigation",
                 "structure": "asymmetric",
@@ -287,6 +313,7 @@
             },
             "o__spd": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Navigation speed",
                 "controller_id": "speed",
                 "structure": "asymmetric",
@@ -295,6 +322,7 @@
             },
             "o__bat": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Battery charger",
                 "controller_id": "battery",
                 "structure": "asymmetric",
@@ -303,6 +331,7 @@
             },
             "o_init": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "Position initializer",
                 "controller_id": "reset",
                 "structure": "asymmetric",
@@ -311,6 +340,7 @@
             },
             "o_stop": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "Emergency stop",
                 "controller_id": "emergency",
                 "structure": "asymmetric",
@@ -319,6 +349,7 @@
             },
             "o__ser": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Servo control",
                 "controller_id": "servo",
                 "structure": "asymmetric",
@@ -327,6 +358,7 @@
             },
             "o_spos": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Servo Position OPU",
                 "controller_id": "servo_position",
                 "structure": "asymmetric",
@@ -335,6 +367,7 @@
             },
             "o_blnk": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "Blink",
                 "controller_id": "blink",
                 "structure": "asymmetric",
@@ -343,22 +376,34 @@
             },
             "o___id": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "ID Recognition",
                 "controller_id": "id_recognition",
                 "structure": "asymmetric",
                 "resolution": [1, 10, 1],
-                "coordinate_3d": [20, 0, 0]
+                "coordinate_3d": [120, 91, 0]
+            },
+            "o__sid": {
+                "enabled": True,
+                "measurable": False,
+                "cortical_name": "Trainer Stimuli ID Selector",
+                "controller_id": "stimuli_id_selector",
+                "structure": "asymmetric",
+                "resolution": [1, 10, 1],
+                "coordinate_3d": [30, 0, 0]
             },
             "o__loc": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "Recognition Location",
                 "controller_id": "recognition_location",
                 "structure": "asymmetric",
                 "resolution": [32, 32, 1],
-                "coordinate_3d": [20, 0, 0]
+                "coordinate_3d": [110, 51, 0]
             },
             "o_misc": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "Miscellaneous",
                 "controller_id": "misc",
                 "structure": "asymmetric",
@@ -367,6 +412,7 @@
             },
             "o_mctl": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Motion control",
                 "controller_id": "motion_control",
                 "structure": "asymmetric",
@@ -375,6 +421,7 @@
             },
             "ovflph": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "Vision horizontal flip",
                 "controller_id": "horizontal_flip",
                 "structure": "asymmetric",
@@ -383,6 +430,7 @@
             },
             "ovflpv": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "Vision vertical flip",
                 "controller_id": "vertical_flip",
                 "structure": "asymmetric",
@@ -391,6 +439,7 @@
             },
             "ov_mod": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Central vision modulation",
                 "controller_id": "modulation_control",
                 "structure": "asymmetric",
@@ -399,6 +448,7 @@
             },
             "ov_ecc": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Central vision eccentricity",
                 "controller_id": "eccentricity_control",
                 "structure": "asymmetric",
@@ -407,6 +457,7 @@
             },
             "ov_enh": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Lighting enhancement",
                 "controller_id": "enhancement",
                 "structure": "asymmetric",
@@ -415,6 +466,7 @@
             },
             "ovtune": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "Lighting threshold",
                 "controller_id": "threshold",
                 "structure": "asymmetric",
@@ -423,6 +475,7 @@
             },
             "o__led": {
                 "enabled": True,
+                "measurable": True,
                 "cortical_name": "LED",
                 "controller_id": "led",
                 "structure": "asymmetric",
@@ -431,6 +484,7 @@
             },
             "ov_reg": {
                 "enabled": True,
+                "measurable": False,
                 "cortical_name": "Vision activation regions",
                 "controller_id": "activation_regions",
                 "structure": "asymmetric",
@@ -439,12 +493,6 @@
             }
         },
         "name_to_id_mapping": {
-            "gpio": [
-                "odgpio",
-                "oagpio",
-                "oogpio",
-                "oigpio",
-            ],
             "motor": [
                 "o__mot",
             ],
@@ -481,8 +529,16 @@
             "motion_control": [
                 "o_mctl"
             ],
-            "miscellaneous": [
+            "misc": [
                 "o_misc"
+            ],
+            "digital_output": [
+                "odgpio",
+                "oogpio",
+                "oigpio",
+            ],
+            "analog_output": [
+                "oagpio"
             ]
         }
     },
@@ -518,7 +574,7 @@
     "per_voxel_neuron_cnt": 1,
     "synapse_attractivity": 100,
     "degeneration": 0,
-    "psp_uniform_distribution": False,
+    "psp_uniform_distribution": True,
     "postsynaptic_current_max": 99999,
     "plasticity_constant": 1,
     "cortical_mapping_dst": {},
@@ -535,7 +591,7 @@
     "firing_threshold_increment_y": 0,
     "firing_threshold_increment_z": 0,
     "firing_threshold_limit": 0,
-    "mp_charge_accumulation": True,
+    "mp_charge_accumulation": False,
     "mp_driven_psp": False,
     "is_mem_type": False,
     "longterm_mem_threshold": 100,
@@ -564,6 +620,41 @@
         "type": "functions",
         "class": "core"
     },
+    "projector_xy": {
+        "parameters": {},
+        "type": "functions",
+        "class": "core"
+    },
+    "projector_xz": {
+        "parameters": {},
+        "type": "functions",
+        "class": "core"
+    },
+    "projector_yz": {
+        "parameters": {},
+        "type": "functions",
+        "class": "core"
+    },
+    "project_from_end_x": {
+        "parameters": {},
+        "type": "functions",
+        "class": "core"
+    },
+    "project_from_end_y": {
+        "parameters": {},
+        "type": "functions",
+        "class": "core"
+    },
+    "project_from_end_z": {
+        "parameters": {},
+        "type": "functions",
+        "class": "core"
+    },
+    "last_to_first": {
+        "parameters": {},
+        "type": "functions",
+        "class": "core"
+    },
     "memory": {
         "parameters": {},
         "type": "functions",
diff --git a/src/evo/voxels.py b/src/evo/voxels.py
index 7e4d0cb88..de794fa7d 100644
--- a/src/evo/voxels.py
+++ b/src/evo/voxels.py
@@ -34,7 +34,7 @@ def voxel_list_to_neuron_list(cortical_area, voxel_list):
     neuron_list = list()
 
     for voxel in voxel_list:
-        voxel_ref = block_reference_builder(voxel[0])
+        voxel_ref = voxel[0]
         neurons = neurons_in_the_block(cortical_area=cortical_area, block_ref=voxel_ref)
         for neuron in neurons:
             neuron_list.append([neuron, voxel[1]])
@@ -47,7 +47,7 @@ def block_size_checker(cortical_area, block):
     Tests if the given block fits inside the cortical area block boundary
     """
     block_boundary = runtime_data.genome["blueprint"][cortical_area]["block_boundaries"]
-    block_in_list = block_ref_2_id(block)
+    block_in_list = block
 
     for _ in range(3):
         if block_in_list[_] >= block_boundary[_]:
@@ -59,21 +59,21 @@ def block_trimmer(cortical_area, block):
     """
     limits the size of a block to stay within the block boundary of a cortical area
     """
-    trimmed_block = [None, None, None]
+    trimmed_block = (None, None, None)
     block_boundary = runtime_data.genome["blueprint"][cortical_area]["block_boundaries"]
     if isinstance(block, list):
         for _ in range(3):
             trimmed_block[_] = min(block_boundary[_] - 1, block[_])
         return trimmed_block
     else:
-        block_in_list = block_ref_2_id(block)
+        block_in_list = block
         for _ in range(3):
             trimmed_block[_] = min(block_boundary[_] - 1, block_in_list[_])
-        return block_reference_builder(trimmed_block)
+        return trimmed_block
 
 
-def block_reference_builder(block):
-    return str(block[0]) + '-' + str(block[1]) + '-' + str(block[2])
+# def block_reference_builder(block):
+#     return str(block[0]) + '-' + str(block[1]) + '-' + str(block[2])
 
 
 def block_id_gen(cortical_area, coordinate):
@@ -124,17 +124,18 @@ def block_z_offset(block_ref, offset):
     Returns: Adjusted block reference
 
     """
-    block_id = block_ref_2_id(block_ref)
+    # block_id = block_ref_2_id(block_ref)
+    block_id = block_ref
     block_id[2] += int(offset)
     if block_id[2] < 0:
         block_id[2] = 0
-    return block_reference_builder(block_id)
+    return block_id
 
 
-def block_ref_2_id(block_ref):
-    block_id_str = block_ref.split('-')
-    block_id = [int(x) for x in block_id_str]
-    return block_id
+# def block_ref_2_id(block_ref):
+#     block_id_str = block_ref.split('-')
+#     block_id = [int(x) for x in block_id_str]
+#     return block_id
 
 
 def neighboring_blocks(block_ref, kernel_size):
@@ -142,7 +143,7 @@ def neighboring_blocks(block_ref, kernel_size):
     Returns the list of block ids who are neighbor of the given one
     Block_id is in form of [x,y,z]
     """
-    block_id = block_ref_2_id(block_ref)
+    block_id = block_ref
 
     block_id_list = list()
 
@@ -172,7 +173,7 @@ def neurons_in_block_neighborhood(cortical_area, block_ref, kernel_size=3):
     for _ in block_list:
         trimmed_block = block_trimmer(cortical_area, _)
         neurons_in_block = \
-            neurons_in_the_block(cortical_area=cortical_area, block_ref=block_reference_builder(trimmed_block))
+            neurons_in_the_block(cortical_area=cortical_area, block_ref=trimmed_block)
         for __ in neurons_in_block:
             candidate_list.append(__)
     return candidate_list
@@ -187,7 +188,7 @@ def all_block_refs(cortical_area):
     for x in range(block_boundaries[0]):
         for y in range(block_boundaries[1]):
             for z in range(block_boundaries[2]):
-                block_ref_list.append(block_reference_builder([x, y, z]))
+                block_ref_list.append((x, y, z))
     return block_ref_list
 
 
@@ -198,7 +199,7 @@ def x_block_refs(cortical_area, y_ref, z_ref):
     block_ref_list = list()
     block_boundaries = runtime_data.genome['blueprint'][cortical_area]["block_boundaries"]
     for x in range(block_boundaries[0]):
-        block_ref_list.append(block_reference_builder([x, y_ref, z_ref]))
+        block_ref_list.append((x, y_ref, z_ref))
     return block_ref_list
 
 
@@ -209,7 +210,7 @@ def y_block_refs(cortical_area, x_ref, z_ref):
     block_ref_list = list()
     block_boundaries = runtime_data.genome['blueprint'][cortical_area]["block_boundaries"]
     for y in range(block_boundaries[1]):
-        block_ref_list.append(block_reference_builder([x_ref, y, z_ref]))
+        block_ref_list.append((x_ref, y, z_ref))
     return block_ref_list
 
 
@@ -220,7 +221,7 @@ def z_block_refs(cortical_area, x_ref, y_ref):
     block_ref_list = list()
     block_boundaries = runtime_data.genome['blueprint'][cortical_area]["block_boundaries"]
     for z in range(block_boundaries[2]):
-        block_ref_list.append(block_reference_builder([x_ref, y_ref, z]))
+        block_ref_list.append((x_ref, y_ref, z))
     return block_ref_list
 
 
@@ -276,9 +277,8 @@ def active_neurons_in_blocks(cortical_area, current_fcl=True, include_neurons=Fa
 
     blocks_with_active_neurons = {}
     for neuron in fcl[cortical_area]:
-        neuron_block_ref = block_reference_builder(
-            runtime_data.brain[cortical_area][neuron]['soma_location']
-        )
+        neuron_block_ref = runtime_data.brain[cortical_area][neuron]['soma_location']
+
         if include_neurons:
             if neuron_block_ref in blocks_with_active_neurons:
                 blocks_with_active_neurons[neuron_block_ref].append(neuron)
@@ -318,7 +318,7 @@ def subregion_neurons(src_cortical_area, region_definition):
     try:
         for voxel in voxels:
             voxel_neurons = neurons_in_the_block(cortical_area=src_cortical_area,
-                                                 block_ref=block_reference_builder(list(voxel)))
+                                                 block_ref=tuple(voxel))
             for neuron in voxel_neurons:
                 neurons.add(neuron)
     except Exception as e:
diff --git a/src/evo/x_genesis.py b/src/evo/x_genesis.py
index 060ebb7df..d8177e543 100644
--- a/src/evo/x_genesis.py
+++ b/src/evo/x_genesis.py
@@ -602,6 +602,9 @@ def cortical_removal(cortical_area, genome_scrub=False):
         if cortical_area in runtime_data.memory_register:
             runtime_data.memory_register.pop(cortical_area)
 
+        # Remove area from brain region registry
+        eject_area_from_regions(cortical_area=cortical_area)
+
         # Optional genome scrub
         if genome_scrub:
             if cortical_area in runtime_data.genome['blueprint']:
@@ -620,12 +623,17 @@ def cortical_removal(cortical_area, genome_scrub=False):
                     file_name=runtime_data.connectome_path + "genome.json")
 
 
+def eject_area_from_regions(cortical_area):
+    for region in runtime_data.genome["brain_regions"]:
+        if cortical_area in runtime_data.genome["brain_regions"][region]["areas"]:
+            runtime_data.genome["brain_regions"][region]["areas"].remove(cortical_area)
+
+
 def prune_cortical_synapses(cortical_area):
     upstream_cortical_areas, downstream_cortical_areas = \
         neighboring_cortical_areas(cortical_area, blueprint=runtime_data.genome["blueprint"])
 
     for src_cortical_area in upstream_cortical_areas:
-        print("++++++ 2")
         runtime_data.brain = synaptic_pruner(src_cortical_area=src_cortical_area,
                                              dst_cortical_area=cortical_area)
 
@@ -973,7 +981,7 @@ def append_circuit(source_genome, circuit_origin, parent_brain_region, rewire_mo
                           f"id:{new_cortical_area_id} name:{new_cortical_name}")
                 else:
                     if cortical_area_id not in dst_blueprint:
-                        add_core_cortical_area(cortical_properties={
+                        added_id = add_core_cortical_area(cortical_properties={
                             "cortical_id": cortical_area_id,
                             "cortical_type": src_blueprint[cortical_area_id]['group_id'],
                             "cortical_name": src_blueprint[cortical_area_id]['cortical_name'],
@@ -981,8 +989,11 @@ def append_circuit(source_genome, circuit_origin, parent_brain_region, rewire_mo
                             "dev_count": 1,
                             "coordinates_2d": [0, 0]
                         })
-                        appended_cortical_areas.add(cortical_area_id)
-                        print(f"---------------Successfully imported a built-in cortical area. id:{cortical_area_id}")
+                        if cortical_area_id == added_id:
+                            appended_cortical_areas.add(cortical_area_id)
+                            print(f"-------------Successfully imported a built-in cortical area. id:{cortical_area_id}")
+                        else:
+                            print(f"!!!! Could not import {cortical_area_id}")
             except Exception as e:
                 print("Exception during cortical import", e, traceback.print_exc())
         # Amalgamate Brain Regions
diff --git a/src/inf/initialize.py b/src/inf/initialize.py
index 6f93ff989..b485e8c3c 100644
--- a/src/inf/initialize.py
+++ b/src/inf/initialize.py
@@ -165,6 +165,9 @@ def init_brain_regions():
     if "brain_regions" not in runtime_data.genome:
         runtime_data.genome["brain_regions"] = {}
 
+    if not runtime_data.genome["brain_regions"]:
+        runtime_data.genome["brain_regions"] = {}
+
     if "root" not in runtime_data.genome["brain_regions"]:
         runtime_data.genome["brain_regions"]["root"] = {}
         runtime_data.genome["brain_regions"]["root"]["title"] = "Genome's root brain region"
diff --git a/src/inf/runtime_data.py b/src/inf/runtime_data.py
index fe3fe3f01..5e0446a82 100644
--- a/src/inf/runtime_data.py
+++ b/src/inf/runtime_data.py
@@ -111,12 +111,15 @@
 prunning_candidates = set()
 plasticity_queue_candidates = dict()
 upcoming_lifesnap_mgmt = 0
+fcl_manager = None
 
 # Stats Collection
 neuron_mp_collection_scope = {}
 neuron_psp_collection_scope = {}
 training_stats = {}
-fitness_stats = {}
+fitness_stats = []
+fitness_score = 1
+fitness_criteria = {}
 brain_stats = {
     "neuron_count": 0,
     "synapse_count": 0
diff --git a/src/mem/memory.py b/src/mem/memory.py
index e8c6ddcca..96203345f 100644
--- a/src/mem/memory.py
+++ b/src/mem/memory.py
@@ -177,9 +177,9 @@ def long_short_term_memory():
                 mem_neuron_id = convert_hash_to_neuron_id(cortical_area=memory_cortical_area, memory_hash=memory_hash)
                 if mem_neuron_id not in runtime_data.brain[memory_cortical_area] and memory_hash != "0x0":
                     neuron_id = init_neuron(cortical_area=memory_cortical_area,
-                                            soma_location=[0, 0, 0],
+                                            soma_location=(0, 0, 0),
                                             mem_neuron_id=memory_hash)
-                    runtime_data.voxel_dict[memory_cortical_area]["0-0-0"].add(neuron_id)
+                    runtime_data.voxel_dict[memory_cortical_area][(0, 0, 0)].add(neuron_id)
                     synapse_count = synapse_memory_neuron(neuron_id=neuron_id)
                 else:
                     increase_neuron_lifespan(cortical_area=memory_cortical_area, neuron_id=mem_neuron_id)
diff --git a/src/npu/burst_engine.py b/src/npu/burst_engine.py
index d9c106f25..112674994 100644
--- a/src/npu/burst_engine.py
+++ b/src/npu/burst_engine.py
@@ -145,12 +145,6 @@ def capture_cortical_activity_stats():
                           + settings.Bcolors.ENDC)
 
     def burst_stats(burst_start_time):
-        if not runtime_data.brain:
-            print("\n !! Brain not found !!")
-        if not runtime_data.cortical_list:
-            print("\n !! Cortical list not found !!")
-        if not runtime_data.genome:
-            print("\n !! Genome not found !!")
 
         if runtime_data.parameters["Logs"]["print_burst_info"] and runtime_data.burst_timer > 0.1:
             runtime_data.burst_duration = datetime.now() - burst_start_time
@@ -458,6 +452,7 @@ def pns_manager():
                         # Dynamically adjusting burst duration based on Controller needs
                         runtime_data.burst_timer = burst_duration_calculator(embodiment_data)
                         if embodiment_data:
+                            # print("embodiment_data:", embodiment_data)
                             stimuli_router(embodiment_data)
 
             except Exception as e:
@@ -468,6 +463,7 @@ def pns_manager():
         if runtime_data.stimulation_script is not None:
             virtual_data = stimulator.stimulate()
             if virtual_data:
+                # print("virtual_data:", virtual_data)
                 stimuli_router({"data": {"direct_stimulation": virtual_data}})
 
         # Evaluated multiple scenarios and administers shock as needed
@@ -694,18 +690,18 @@ def burst():
         prune_all_candidates()
 
         # Burst stats
-        burst_stats(burst_start_time)
+        # burst_stats(burst_start_time)
 
         # Manage Threads
         # For performance reasons, running this function not on every single burst
-        if runtime_data.burst_count % 10 == 0:
-            try:
-                # consciousness_manager()
-                death_manager()
-                if runtime_data.feagi_state["state"] == "idle" and runtime_data.autopilot:
-                    load_new_genome()
-            except Exception as e:
-                print(f"consciousness_manager encountered an error!! {e}")
+        # if runtime_data.burst_count % 10 == 0:
+        #     try:
+        #         # consciousness_manager()
+        #         death_manager()
+        #         if runtime_data.feagi_state["state"] == "idle" and runtime_data.autopilot:
+        #             load_new_genome()
+        #     except Exception as e:
+        #         print(f"consciousness_manager encountered an error!! {e}")
 
         if not runtime_data.controller_config and runtime_data.burst_publisher:
             controller_handshake()
diff --git a/src/npu/physiology.py b/src/npu/physiology.py
index f072129c1..39bd3030f 100644
--- a/src/npu/physiology.py
+++ b/src/npu/physiology.py
@@ -121,6 +121,7 @@ def add_neuron_to_fcl(cortical_area, neuron_id, pre_fire_mp):
     if cortical_area not in runtime_data.future_fcl:
         runtime_data.future_fcl[cortical_area] = set()
     runtime_data.future_fcl[cortical_area].add(neuron_id)
+
     runtime_data.brain[cortical_area][neuron_id]["pre_fire_mp"] = pre_fire_mp
 
 
diff --git a/src/pns/pns_router.py b/src/pns/pns_router.py
index fcb035b5a..3df49e602 100644
--- a/src/pns/pns_router.py
+++ b/src/pns/pns_router.py
@@ -171,7 +171,7 @@ def opu_router():
     Relays neuronal activities to the controller.
     Sample data format for runtime_data.opu_data:
 
-    {'o__bat': {}, 'o__mot': {'0-0-0': 47, '0-0-5': 48, '0-0-15': 50, '0-0-1': 45}}
+    {'o__bat': {}, 'o__mot': {(0, 0, 0): 47, (0, 0, 5): 48, (0, 0, 15): 50, (0, 0, 1): 45}}
 
     """
     for cortical_area in runtime_data.fire_candidate_list.copy():
@@ -180,7 +180,6 @@ def opu_router():
                 runtime_data.opu_data[cortical_area] = {}
             runtime_data.opu_data[cortical_area] = opu_percentage_report(cortical_area=cortical_area)
 
-
 #
 # def action_router():
 #     """
diff --git a/src/pns/stimuli_processor.py b/src/pns/stimuli_processor.py
index b4551f6c2..a6ecbabdc 100644
--- a/src/pns/stimuli_processor.py
+++ b/src/pns/stimuli_processor.py
@@ -301,7 +301,7 @@ def coords_to_neuron_ids(detection_locations, cortical_area):
 
     if detection_locations is not None:
         for location in detection_locations:
-            block_ref = block_reference_builder(location)
+            block_ref = location
             block_neurons = neurons_in_the_block(cortical_area, block_ref)
             neuron_ids.update(neuron for neuron in block_neurons if neuron is not None)
 
diff --git a/src/pns/stimuli_translator.py b/src/pns/stimuli_translator.py
index 034876a46..9b9c29f97 100644
--- a/src/pns/stimuli_translator.py
+++ b/src/pns/stimuli_translator.py
@@ -22,6 +22,8 @@
 from src.pns import stimuli_processor
 from src.npu.physiology import update_membrane_potential_fire_queue
 
+from src.evo.genome_processor import is_memory_cortical_area
+
 logger = logging.getLogger(__name__)
 
 """
@@ -41,6 +43,15 @@
 """
 
 
+def stimulation_validator(stimulation):
+    # Removes stimulation that are not part of genome
+    for cortical_area in stimulation.copy():
+        if cortical_area not in runtime_data.cortical_list:
+            del stimulation[cortical_area]
+            print(f"!! Manual stimulation container {cortical_area} which was not part of genome !!")
+    return stimulation
+
+
 def induce_manual_stimulation(stimulation):
     """
     Stimulation data received will have the following data structure:
@@ -52,22 +63,24 @@ def induce_manual_stimulation(stimulation):
         }
     }
     """
-    stimulation = convert_stimulation_to_dashed_format(stimulation_data=stimulation)
+    stimulation = stimulation_validator(stimulation=stimulation)
+    # stimulation = convert_stimulation_to_dashed_format(stimulation_data=stimulation)
     stimulation_injector(stimulation_data=stimulation)
 
 
-def convert_stimulation_to_dashed_format(stimulation_data):
-    """
-    Converts stimulation from list format to dashed format
-    # todo: revisit the value of having dashed format in the first place and get rid of it
-    """
-
-    dashed_stimulation = {}
-    for cortical_area in stimulation_data:
-        dashed_stimulation[cortical_area] = list()
-        for neuron_block in stimulation_data[cortical_area]:
-            dashed_stimulation[cortical_area].append(block_reference_builder(neuron_block))
-    return dashed_stimulation
+# def convert_stimulation_to_dashed_format(stimulation_data):
+#     """
+#     Converts stimulation from list format to dashed format
+#     # todo: revisit the value of having dashed format in the first place and get rid of it
+#     """
+#
+#     dashed_stimulation = {}
+#     for cortical_area in stimulation_data:
+#         if not is_memory_cortical_area(cortical_area=cortical_area):
+#             dashed_stimulation[cortical_area] = list()
+#             for neuron_block in stimulation_data[cortical_area]:
+#                 dashed_stimulation[cortical_area].append(neuron_block)
+#     return dashed_stimulation
 
 
 def stimuli_generator(input_instruction, burst_count):
@@ -107,6 +120,7 @@ def stimuli_generator(input_instruction, burst_count):
             runtime_data.logs["CNS"].add(f"Warning: Cortical area %s not found within the voxel_dict {cortical_area_}")
 
 
+# todo: has overlap with function called generic_ipu_translator in this module
 def stimulation_injector(stimulation_data):
     """
     TODO: define the stimulation_data format here
@@ -114,18 +128,19 @@ def stimulation_injector(stimulation_data):
     """
 
     for cortical_area in stimulation_data:
-        if stimulation_data[cortical_area]:
-            neuron_list = set()
-            for voxel in stimulation_data[cortical_area]:
-                if type(voxel) is list:
-                    voxel = block_reference_builder(voxel)
-                in_the_block = neurons_in_the_block(cortical_area=cortical_area, block_ref=voxel)
-                for neuron in in_the_block:
-                    neuron_list.add(neuron)
-            for _ in neuron_list:
-                if cortical_area not in runtime_data.fire_candidate_list:
-                    runtime_data.fire_candidate_list[cortical_area] = set()
-                runtime_data.fire_candidate_list[cortical_area].add(_)
+        if not is_memory_cortical_area(cortical_area=cortical_area):
+            if stimulation_data[cortical_area]:
+                neuron_list = set()
+                for voxel in stimulation_data[cortical_area]:
+                    if type(voxel) is list:
+                        voxel = tuple(voxel)
+                    in_the_block = neurons_in_the_block(cortical_area=cortical_area, block_ref=voxel)
+                    for neuron in in_the_block:
+                        neuron_list.add(neuron)
+                for _ in neuron_list:
+                    if cortical_area not in runtime_data.fire_candidate_list:
+                        runtime_data.fire_candidate_list[cortical_area] = set()
+                    runtime_data.fire_candidate_list[cortical_area].add(_)
 
 
 # @staticmethod
@@ -494,4 +509,5 @@ def vision_translator(vision_data):
 def generic_ipu_translator(ipu_data):
     if ipu_data is not None:
         for cortical_area in ipu_data:
-            inject_stimuli_to_fcl(cortical_area=cortical_area, stimulation=ipu_data[cortical_area])
+            if not is_memory_cortical_area(cortical_area=cortical_area):
+                inject_stimuli_to_fcl(cortical_area=cortical_area, stimulation=ipu_data[cortical_area])
diff --git a/src/version.py b/src/version.py
index 003e89c8b..246c3a3df 100644
--- a/src/version.py
+++ b/src/version.py
@@ -1,2 +1,2 @@
-__version__ = 'v1.3.1'
+__version__ = 'v1.3.0'
 


Test patch:
diff --git a/.github/workflows/docker-update-latest.yml b/.github/workflows/docker-update-latest.yml
new file mode 100644
index 000000000..55ff41350
--- /dev/null
+++ b/.github/workflows/docker-update-latest.yml
@@ -0,0 +1,35 @@
+name: Update latest FEAGI on Docker Hub
+
+on:
+  push:
+    branches:
+      - "staging"
+    paths:
+      - 'src/**'
+      - 'generate_version.sh'
+
+jobs:
+  docker:
+    runs-on: ubuntu-latest
+    if: github.repository == 'feagi/feagi'
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+      - name: Set up QEMU
+        uses: docker/setup-qemu-action@v3
+      - name: Set up Docker Buildx
+        uses: docker/setup-buildx-action@v3
+      - name: Login to Docker Hub
+        uses: docker/login-action@v3
+        with:
+          username: ${{ secrets.DOCKERHUB_USERNAME }}
+          password: ${{ secrets.DOCKERHUB_TOKEN }}
+      - name: Build and push
+        uses: docker/build-push-action@v5
+        with:
+          context: docker/
+          platforms: linux/amd64,linux/arm64
+          push: true
+          tags: neuraville/feagi:latest
+          build-args: |
+            BRANCH=staging
diff --git a/.github/workflows/performance_test.yml b/.github/workflows/performance_test.yml
new file mode 100644
index 000000000..435a0fa81
--- /dev/null
+++ b/.github/workflows/performance_test.yml
@@ -0,0 +1,48 @@
+name: Run timer on FEAGI
+
+on:
+  workflow_dispatch:
+  push:
+    branches:
+      - "staging"
+
+permissions:
+  contents: read
+
+jobs:
+  deploy:
+
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v3
+    - name: Set up Python
+      uses: actions/setup-python@v3
+      with:
+        python-version: '3.9'
+
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip
+        pip install build setuptools
+        ls -a
+
+    - name: Install Root Requirements
+      run: pip3 install -r requirements.txt
+
+    - name: Run Main Python Script in src
+      run: |
+        ls
+        cd src/
+        python3 main.py &
+      
+    - name: Work with Controller
+      run: |
+        cd tests/timer
+        pip3 install -r requirements.txt
+        python3 controller.py
+
+    - name: Exit Container
+      if: ${{ success() }}
+      run: |
+        echo "No error"
+        exit 0
diff --git a/tests/test_skeleton.py b/tests/test_skeleton.py
index f840ff589..211e39d93 100644
--- a/tests/test_skeleton.py
+++ b/tests/test_skeleton.py
@@ -1,5 +1,4 @@
 # -*- coding: utf-8 -*-
-
 ##
 # Copyright 2016-Present Neuraville Inc. All Rights Reserved.
 #
diff --git a/tests/timer/capabilities.json b/tests/timer/capabilities.json
new file mode 100644
index 000000000..fd00ba779
--- /dev/null
+++ b/tests/timer/capabilities.json
@@ -0,0 +1,25 @@
+{
+    "capabilities": {
+		"output": {
+			"misc": {
+				"0": {
+					"custom_name": "",
+					"disabled": false,
+					"feagi_index": 0
+				}
+			}
+		},
+        "input": {
+            "misc": {
+                "0": {
+                    "disable": false,
+                    "feagi_index": 0,
+                    "minimum_value": 0,
+                    "maximum_value": 100,
+                    "cortical_id": "i_misc",
+                    "custom_name": "misc_0"
+                }
+            }
+        }
+    }
+}
diff --git a/tests/timer/controller.py b/tests/timer/controller.py
new file mode 100644
index 000000000..8452459a0
--- /dev/null
+++ b/tests/timer/controller.py
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+"""
+Copyright 2016-present Neuraville Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================
+"""
+import time
+import psutil
+import argparse
+import requests
+import traceback
+from time import sleep
+from version import __version__
+from feagi_connector import sensors
+from feagi_connector import pns_gateway as pns
+from feagi_connector import feagi_interface as FEAGI
+
+runtime_data = {}
+previous_frame_data = {}
+FEAGI.validate_requirements('requirements.txt')  # you should get it from the boilerplate generator
+
+
+def current_milli_time():
+    return time.time() * 1000
+
+
+def prepare_the_genome_of_timer(args):
+    # Prepare the file to be uploaded
+    print("Loading genome now...")
+    with open('test_timer.json', 'rb') as f:
+        files = {'file': f}
+
+        # Send the POST request with the file
+        url = api_address + '/v1/genome/upload/file'
+        response = requests.post(url, files=files)
+
+    flag = True
+    # print(response.status_code)
+    while flag:
+        # Print the response
+        if response.status_code == 200:
+            # print("genome loaded")
+            flag = False
+        else:
+            # print("failed. type: ", type(response.status_code)," and status: ", response.status_code)
+            sleep(1)
+
+    json_data = {"cortical_id": "CM0Tim", "cortical_name": "Timer",
+                 "cortical_dimensions": [int(args['number']), 100, 1]}
+    url = api_address + '/v1/cortical_area/cortical_area'
+    response = requests.put(url, json=json_data)
+    flag = True
+    while flag:
+        # Print the response
+        if response.status_code == 200:
+            # print("updated timer cortical")
+            flag = False
+        else:
+            # print("failed. type: ", type(response.status_code)," and status: ", response.status_code)
+            response = requests.put(url, json=json_data)
+            sleep(3)
+
+    json_data = {"cortical_id": "o_misc", "cortical_name": "Miscellaneous",
+                 "cortical_dimensions_per_device": [int(args['number']), 1, 1]}
+    url = api_address + '/v1/cortical_area/cortical_area'
+    response = requests.put(url, json=json_data)
+    flag = True
+    while flag:
+        # Print the response
+        if response.status_code == 200:
+            # print("updated misc cortical")
+            flag = False
+        else:
+            # print("failed. type: ", type(response.status_code)," and status: ", response.status_code)
+            response = requests.put(url, json=json_data)
+            sleep(3)
+    print("genome is completed")
+
+
+if __name__ == '__main__':
+    config = FEAGI.build_up_from_configuration()
+    feagi_settings = config['feagi_settings'].copy()
+    agent_settings = config['agent_settings'].copy()
+    default_capabilities = config['default_capabilities'].copy()
+    message_to_feagi = config['message_to_feagi'].copy()
+    capabilities = config['capabilities'].copy()
+
+    message_to_feagi = {}
+    parser = argparse.ArgumentParser(description='Number to update width')
+    parser.add_argument('-number', '--number', help='for the number', default=10, required=False)
+
+    # # # FEAGI registration # # # - - - - - - - - - - - - - - - - - - - - -
+    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
+    feagi_settings, runtime_data, api_address, feagi_ipu_channel, feagi_opu_channel = \
+        FEAGI.connect_to_feagi(feagi_settings, runtime_data, agent_settings,
+                               capabilities, __version__)
+    # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    # - - - - - - - - - - -
+    args = vars(parser.parse_args())
+    prepare_the_genome_of_timer(args)
+    message_to_feagi = sensors.add_generic_input_to_feagi_data(
+        {'i_misc': {(0, 0, 0): 100}}, message_to_feagi)
+    pns.signals_to_feagi(message_to_feagi, feagi_ipu_channel, agent_settings,
+                         feagi_settings)
+
+    start_time = current_milli_time()
+    previous_total_time = start_time
+    iteration_list = []
+    flag = False
+    while True:
+        try:
+            message_from_feagi = pns.message_from_feagi
+            if message_from_feagi:
+                obtained_signals = pns.obtain_opu_data(message_from_feagi)
+                pns.check_genome_status_no_vision(message_from_feagi)
+                if 'misc' in obtained_signals:
+                    # print(obtained_signals['misc'])
+                    for x in obtained_signals['misc']:
+                        iteration = int(x) + 1
+                        if iteration not in iteration_list:
+                            total_numbers = iteration * 100
+                            total_time = current_milli_time() - start_time  # unix time - unix time
+                            time_delta = current_milli_time() - previous_total_time  # unix - (seconds)
+                            time_per_neuron = time_delta / (100 * iteration)
+                            cpu = psutil.cpu_percent(interval=1)
+                            memory = psutil.virtual_memory().percent
+                            print(f"iteration = {iteration}, total_numbers = {total_numbers}, "
+                                  f"total_time = {total_time}, time_delta = {time_delta}, "
+                                  f"time_per_neuron = {time_per_neuron}, cpu utilization = {cpu}, "
+                                  f"memory_usuage={memory}")
+                            # previous_total_time = total_time
+                            iteration_list.append(iteration)
+                            previous_total_time = current_milli_time()
+                if len(iteration_list) == int(args['number']):
+                    print("number reached!")
+                    start_time = current_milli_time()
+                    previous_total_time = start_time
+                    iteration_list = []
+                    if flag:
+                        break
+                    prepare_the_genome_of_timer(args)
+                    json_data = {"global_visualization": False}
+                    url = api_address + '/v1/system/global_activity_visualization'
+                    response = requests.put(url, json=json_data)
+                    print("! ! " * 10, "VISUALIZATION TOGGLED TO FALSE", " ! !" * 10)
+                    flag = True
+            if current_milli_time() - start_time >= 2000.0 and not iteration_list:
+                # print("missed, trying again...")
+                message_to_feagi = sensors.add_generic_input_to_feagi_data({'i_misc': {(0, 0, 0): 100}},
+                                                                           message_to_feagi)
+                start_time = current_milli_time()
+                previous_total_time = start_time
+
+            sleep(feagi_settings['feagi_burst_speed'])  # bottleneck
+            pns.signals_to_feagi(message_to_feagi, feagi_ipu_channel,
+                                 agent_settings, feagi_settings)
+            message_to_feagi.clear()
+        except Exception as e:
+            print("ERROR IN TIMER MAIN CODE: ", e)
+            traceback.print_exc()
+            break
diff --git a/tests/timer/networking.json b/tests/timer/networking.json
new file mode 100644
index 000000000..a7b4fca9e
--- /dev/null
+++ b/tests/timer/networking.json
@@ -0,0 +1,14 @@
+{    "description": "timer",
+    "version": "v0.0.0",
+    "feagi_settings": {
+        "feagi_url": "http://127.0.0.1",
+        "feagi_api_port": 8000,
+        "magic_link": "null"
+  },
+    "agent_settings": {
+        "agent_data_port": 10006,
+        "agent_id": "timer",
+        "agent_type": "embodiment",
+        "compression": true
+    }
+}
\ No newline at end of file
diff --git a/tests/timer/requirements.txt b/tests/timer/requirements.txt
new file mode 100644
index 000000000..246325a7c
--- /dev/null
+++ b/tests/timer/requirements.txt
@@ -0,0 +1,2 @@
+feagi-connector>=0.0.17
+psutil==5.8.0
diff --git a/tests/timer/test_timer.json b/tests/timer/test_timer.json
new file mode 100644
index 000000000..e2ae2ac5d
--- /dev/null
+++ b/tests/timer/test_timer.json
@@ -0,0 +1,1875 @@
+{
+   "genome_id": "2022-07-10_21:53:10_961677_111111_G",
+   "genome_title": "Performance Test Genome",
+   "genome_description": "This genome will enable testing neuron activation time on FEAGI while number of activated neurons progressively increase",
+   "version": "2.0",
+   "neuron_morphologies": {
+      "decrease_filter_diagonal": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  1,
+                  1
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "custom"
+      },
+      "decrease_filter_diagonal2": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  2,
+                  1
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "custom"
+      },
+      "increase_filter_diagonal": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  1,
+                  -1
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "custom",
+         "morphology_name": "increase_filter_diagonal"
+      },
+      "increase_filter_diagonal2": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  2,
+                  -1
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "custom"
+      },
+      "to_block_[5, 7, 4]": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     "*",
+                     "*",
+                     "*"
+                  ],
+                  [
+                     5,
+                     7,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_left_level_one": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     3
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     3
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_left_level_two": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     1,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     2
+                  ]
+               ],
+               [
+                  [
+                     1,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     1,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     2
+                  ]
+               ],
+               [
+                  [
+                     1,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_left_level_three": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     2,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     1
+                  ]
+               ],
+               [
+                  [
+                     2,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     2,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     1
+                  ]
+               ],
+               [
+                  [
+                     2,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_left_level_four": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     3,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     2
+                  ]
+               ],
+               [
+                  [
+                     3,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     3,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     2
+                  ]
+               ],
+               [
+                  [
+                     3,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_left_level_five": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     4,
+                     0,
+                     0
+                  ],
+                  [
+                     1,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     4,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     4,
+                     0,
+                     0
+                  ],
+                  [
+                     5,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     4,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_right_level_one": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     3
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     3
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_right_level_two": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     1,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     1,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     2
+                  ]
+               ],
+               [
+                  [
+                     1,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     1,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     2
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_right_level_three": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     2,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     2,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     1
+                  ]
+               ],
+               [
+                  [
+                     2,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     2,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     1
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_right_level_four": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     3,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     3,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     2
+                  ]
+               ],
+               [
+                  [
+                     3,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     3,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     2
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "turn_right_level_five": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     4,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     4,
+                     0,
+                     0
+                  ],
+                  [
+                     3,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     4,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     4,
+                     0,
+                     0
+                  ],
+                  [
+                     7,
+                     0,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "motor_forward": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "motor_backward": {
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     1,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     3,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     5,
+                     0,
+                     4
+                  ]
+               ],
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     7,
+                     0,
+                     4
+                  ]
+               ]
+            ]
+         },
+         "type": "patterns",
+         "class": "custom"
+      },
+      "y_consolidator": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     "*",
+                     "*",
+                     "*"
+                  ],
+                  [
+                     "*",
+                     "?",
+                     "*"
+                  ]
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "intensity": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     "*",
+                     "*",
+                     "*"
+                  ],
+                  [
+                     0,
+                     0,
+                     "*"
+                  ]
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "APT_low": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     7
+                  ],
+                  [
+                     0,
+                     0,
+                     8
+                  ]
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "apt_high": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     2
+                  ],
+                  [
+                     0,
+                     0,
+                     2
+                  ]
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "diagonal_proprio": {
+         "type": "vectors",
+         "parameters": {
+            "vectors": [
+               [
+                  1,
+                  1,
+                  0
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "right_detect": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     7,
+                     "*",
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "left_detect": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     "*",
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "bbb3": {
+         "type": "vectors",
+         "parameters": {
+            "vectors": [
+               [
+                  -1,
+                  1,
+                  0
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "ori_135_deg": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  0
+               ],
+               [
+                  1,
+                  -1,
+                  0
+               ],
+               [
+                  2,
+                  -2,
+                  0
+               ],
+               [
+                  3,
+                  -3,
+                  0
+               ],
+               [
+                  4,
+                  -4,
+                  0
+               ],
+               [
+                  5,
+                  -5,
+                  0
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "custom"
+      },
+      "ori_115": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  0
+               ],
+               [
+                  1,
+                  -2,
+                  0
+               ],
+               [
+                  2,
+                  -4,
+                  0
+               ],
+               [
+                  3,
+                  -6,
+                  0
+               ],
+               [
+                  4,
+                  -9,
+                  0
+               ],
+               [
+                  5,
+                  -11,
+                  0
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "custom"
+      },
+      "ori_0_deg": {
+         "type": "vectors",
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  0
+               ],
+               [
+                  1,
+                  0,
+                  0
+               ],
+               [
+                  2,
+                  0,
+                  0
+               ],
+               [
+                  3,
+                  0,
+                  0
+               ],
+               [
+                  4,
+                  0,
+                  0
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "ori_90_deg": {
+         "type": "vectors",
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  0
+               ],
+               [
+                  0,
+                  1,
+                  0
+               ],
+               [
+                  0,
+                  2,
+                  0
+               ],
+               [
+                  0,
+                  3,
+                  0
+               ],
+               [
+                  0,
+                  4,
+                  0
+               ],
+               [
+                  0,
+                  5,
+                  0
+               ],
+               [
+                  0,
+                  6,
+                  0
+               ],
+               [
+                  0,
+                  7,
+                  0
+               ],
+               [
+                  0,
+                  8,
+                  0
+               ],
+               [
+                  0,
+                  9,
+                  0
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "ori_45_deg": {
+         "type": "vectors",
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  0
+               ],
+               [
+                  1,
+                  1,
+                  0
+               ],
+               [
+                  2,
+                  2,
+                  0
+               ],
+               [
+                  3,
+                  3,
+                  0
+               ],
+               [
+                  4,
+                  4,
+                  0
+               ],
+               [
+                  5,
+                  5,
+                  0
+               ],
+               [
+                  6,
+                  6,
+                  0
+               ],
+               [
+                  7,
+                  7,
+                  0
+               ],
+               [
+                  8,
+                  8,
+                  0
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "ori_60_deg": {
+         "type": "vectors",
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  0
+               ],
+               [
+                  1,
+                  1,
+                  0
+               ],
+               [
+                  1,
+                  2,
+                  0
+               ],
+               [
+                  2,
+                  3,
+                  0
+               ],
+               [
+                  2,
+                  4,
+                  0
+               ],
+               [
+                  3,
+                  5,
+                  0
+               ],
+               [
+                  3,
+                  6,
+                  0
+               ],
+               [
+                  4,
+                  7,
+                  0
+               ]
+            ]
+         },
+         "class": "custom"
+      },
+      "block_to_block": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  0
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "core"
+      },
+      "projector": {
+         "parameters": {},
+         "type": "functions",
+         "class": "core"
+      },
+      "memory": {
+         "parameters": {},
+         "type": "functions",
+         "class": "core"
+      },
+      "0-0-0_to_all": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     "*",
+                     "*",
+                     "*"
+                  ]
+               ]
+            ]
+         },
+         "class": "core"
+      },
+      "all_to_0-0-0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     "*",
+                     "*",
+                     "*"
+                  ],
+                  [
+                     0,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "class": "core"
+      },
+      "all_to_all": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     "?",
+                     "?",
+                     "?"
+                  ],
+                  [
+                     "*",
+                     "*",
+                     "*"
+                  ]
+               ]
+            ]
+         },
+         "class": "core"
+      },
+      "lateral_+x": {
+         "parameters": {
+            "vectors": [
+               [
+                  1,
+                  0,
+                  0
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "core"
+      },
+      "lateral_-x": {
+         "parameters": {
+            "vectors": [
+               [
+                  -1,
+                  0,
+                  0
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "core"
+      },
+      "lateral_+y": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  1,
+                  0
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "core"
+      },
+      "lateral_-y": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  -1,
+                  0
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "core"
+      },
+      "lateral_+z": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  1
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "core"
+      },
+      "lateral_-z": {
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  0,
+                  -1
+               ]
+            ]
+         },
+         "type": "vectors",
+         "class": "core"
+      },
+      "randomizer": {
+         "parameters": {},
+         "type": "functions",
+         "class": "core"
+      },
+      "expander_x": {
+         "parameters": {},
+         "type": "functions",
+         "class": "core"
+      },
+      "reducer_x": {
+         "parameters": {},
+         "type": "functions",
+         "class": "core"
+      },
+      "lateral_pairs_x": {
+         "parameters": {},
+         "type": "functions",
+         "class": "core"
+      },
+      "tile": {
+         "parameters": {
+            "src_seed": [
+               16,
+               16,
+               1
+            ],
+            "src_pattern": [
+               [
+                  1,
+                  0
+               ],
+               [
+                  1,
+                  0
+               ],
+               [
+                  1,
+                  0
+               ]
+            ],
+            "mapper_morphology": "projector"
+         },
+         "type": "composite",
+         "class": "core"
+      },
+      "0_0_0-_0_0_0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     0,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "morphology_name": "0_0_0-_0_0_0",
+         "class": "custom"
+      },
+      "0_0_0-1_0_0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     1,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "morphology_name": "0_0_0-1_0_0",
+         "class": "custom"
+      },
+      "0_0_0-2_0_0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     2,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "morphology_name": "0_0_0-2_0_0",
+         "class": "custom"
+      },
+      "0_0_0-3_0_0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     3,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "morphology_name": "0_0_0-3_0_0",
+         "class": "custom"
+      },
+      "0_0_0-4_0_0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     4,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "morphology_name": "0_0_0-4_0_0",
+         "class": "custom"
+      },
+      "0_0_0-5_0_0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     5,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "morphology_name": "0_0_0-5_0_0",
+         "class": "custom"
+      },
+      "0_0_0-6_0_0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     6,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "morphology_name": "0_0_0-6_0_0",
+         "class": "custom"
+      },
+      "0_0_0-7_0_0": {
+         "type": "patterns",
+         "parameters": {
+            "patterns": [
+               [
+                  [
+                     0,
+                     0,
+                     0
+                  ],
+                  [
+                     7,
+                     0,
+                     0
+                  ]
+               ]
+            ]
+         },
+         "morphology_name": "0_0_0-7_0_0",
+         "class": "custom"
+      },
+      "go next to column": {
+         "type": "vectors",
+         "class": "custom",
+         "parameters": {
+            "vectors": [
+               [
+                  0,
+                  -99,
+                  0
+               ]
+            ]
+         },
+         "morphology_name": "go next to column"
+      },
+      "go next column": {
+         "type": "vectors",
+         "class": "custom",
+         "parameters": {
+            "vectors": [
+               [
+                  1,
+                  -99,
+                  0
+               ]
+            ]
+         },
+         "morphology_name": "go next column"
+      }
+   },
+   "hosts": {},
+   "physiology": {
+      "burst_delay": 0.01,
+      "max_age": 10000000,
+      "evolution_burst_count": 50,
+      "ipu_idle_threshold": 1000,
+      "plasticity_queue_depth": 3,
+      "lifespan_mgmt_interval": 10
+   },
+   "stats": {
+      "innate_cortical_area_count": 5,
+      "innate_neuron_count": 104,
+      "innate_synapse_count": 102
+   },
+   "signatures": {
+      "genome": "b18c143294a02f56",
+      "blueprint": "aa42bf9057dc9219",
+      "physiology": "205db8ae103573bd"
+   },
+   "timestamp": 1724162241.382782,
+   "brain_regions": {
+      "root": {
+         "title": "Genome's root brain region",
+         "description": null,
+         "parent_region_id": null,
+         "coordinate_2d": [
+            0,
+            0
+         ],
+         "coordinate_3d": [
+            0,
+            0,
+            0
+         ],
+         "areas": [
+            "___pwr",
+            "_death",
+            "i_misc",
+            "o_misc",
+            "CM0Tim"
+         ],
+         "regions": [],
+         "inputs": [],
+         "outputs": []
+      }
+   },
+   "blueprint": {
+      "_____10c-___pwr-cx-subgrp-t": "",
+      "_____10c-___pwr-cx-_n_cnt-i": 1,
+      "_____10c-___pwr-cx-synatt-f": 100,
+      "_____10c-___pwr-cx-de_gen-f": 0,
+      "_____10c-___pwr-cx-pspuni-b": false,
+      "_____10c-___pwr-nx-pstcrm-f": 35,
+      "_____10c-___pwr-cx-dstmap-d": {},
+      "_____10c-___pwr-cx-___bbx-i": 1,
+      "_____10c-___pwr-cx-___bby-i": 1,
+      "_____10c-___pwr-cx-___bbz-i": 1,
+      "_____10c-___pwr-cx-rcordx-i": 10,
+      "_____10c-___pwr-cx-rcordy-i": 0,
+      "_____10c-___pwr-cx-rcordz-i": -20,
+      "_____10c-___pwr-cx-2dcorx-i": -125,
+      "_____10c-___pwr-cx-2dcory-i": -2,
+      "_____10c-___pwr-cx-gd_vis-b": true,
+      "_____10c-___pwr-nx-pstcr_-f": 500,
+      "_____10c-___pwr-nx-fire_t-f": 1,
+      "_____10c-___pwr-nx-refrac-i": 0,
+      "_____10c-___pwr-nx-leak_c-f": 10,
+      "_____10c-___pwr-nx-leak_v-f": 0,
+      "_____10c-___pwr-nx-c_fr_c-i": 3,
+      "_____10c-___pwr-nx-snooze-f": 0,
+      "_____10c-___pwr-nx-ftincx-f": 0,
+      "_____10c-___pwr-nx-ftincy-f": 0,
+      "_____10c-___pwr-nx-ftincz-f": 0,
+      "_____10c-___pwr-nx-fthlim-f": 0,
+      "_____10c-___pwr-nx-mp_acc-b": true,
+      "_____10c-___pwr-nx-mp_psp-b": false,
+      "_____10c-___pwr-cx-memory-b": false,
+      "_____10c-___pwr-cx-mem__t-i": 100,
+      "_____10c-___pwr-cx-mem_gr-i": 1,
+      "_____10c-___pwr-cx-mem_ls-i": 9,
+      "_____10c-___pwr-nx-excite-f": 100,
+      "_____10c-___pwr-cx-__name-t": "Brain_Power",
+      "_____10c-___pwr-cx-_group-t": "CORE",
+      "_____10c-_death-cx-subgrp-t": "",
+      "_____10c-_death-cx-_n_cnt-i": 1,
+      "_____10c-_death-cx-synatt-f": 100,
+      "_____10c-_death-cx-de_gen-f": 0,
+      "_____10c-_death-cx-pspuni-b": false,
+      "_____10c-_death-nx-pstcrm-f": 35,
+      "_____10c-_death-cx-dstmap-d": {},
+      "_____10c-_death-cx-___bbx-i": 1,
+      "_____10c-_death-cx-___bby-i": 1,
+      "_____10c-_death-cx-___bbz-i": 1,
+      "_____10c-_death-cx-rcordx-i": 10,
+      "_____10c-_death-cx-rcordy-i": 0,
+      "_____10c-_death-cx-rcordz-i": -30,
+      "_____10c-_death-cx-2dcorx-i": -125,
+      "_____10c-_death-cx-2dcory-i": -145,
+      "_____10c-_death-cx-gd_vis-b": true,
+      "_____10c-_death-nx-pstcr_-f": 5,
+      "_____10c-_death-nx-fire_t-f": 1,
+      "_____10c-_death-nx-refrac-i": 0,
+      "_____10c-_death-nx-leak_c-f": 10,
+      "_____10c-_death-nx-leak_v-f": 0,
+      "_____10c-_death-nx-c_fr_c-i": 3,
+      "_____10c-_death-nx-snooze-f": 0,
+      "_____10c-_death-nx-ftincx-f": 0,
+      "_____10c-_death-nx-ftincy-f": 0,
+      "_____10c-_death-nx-ftincz-f": 0,
+      "_____10c-_death-nx-fthlim-f": 0,
+      "_____10c-_death-nx-mp_acc-b": false,
+      "_____10c-_death-nx-mp_psp-b": false,
+      "_____10c-_death-cx-memory-b": false,
+      "_____10c-_death-cx-mem__t-i": 100,
+      "_____10c-_death-cx-mem_gr-i": 1,
+      "_____10c-_death-cx-mem_ls-i": 9,
+      "_____10c-_death-nx-excite-f": 100,
+      "_____10c-_death-cx-__name-t": "Brain_Death",
+      "_____10c-_death-cx-_group-t": "CORE",
+      "_____10c-i_misc-cx-subgrp-t": "",
+      "_____10c-i_misc-cx-_n_cnt-i": 1,
+      "_____10c-i_misc-cx-synatt-f": 100,
+      "_____10c-i_misc-cx-de_gen-f": 0,
+      "_____10c-i_misc-cx-pspuni-b": true,
+      "_____10c-i_misc-nx-pstcrm-f": 99999,
+      "_____10c-i_misc-cx-dstmap-d": {
+         "CM0Tim": [
+            [
+               "block_to_block",
+               [
+                  1,
+                  1,
+                  1
+               ],
+               1,
+               false,
+               1,
+               1,
+               1
+            ]
+         ],
+         "i_misc": [
+            [
+               "block_to_block",
+               [
+                  1,
+                  1,
+                  1
+               ],
+               1,
+               false,
+               1,
+               1,
+               1
+            ]
+         ]
+      },
+      "_____10c-i_misc-cx-___bbx-i": 1,
+      "_____10c-i_misc-cx-___bby-i": 1,
+      "_____10c-i_misc-cx-___bbz-i": 1,
+      "_____10c-i_misc-cx-rcordx-i": 40,
+      "_____10c-i_misc-cx-rcordy-i": 0,
+      "_____10c-i_misc-cx-rcordz-i": 0,
+      "_____10c-i_misc-cx-2dcorx-i": 486,
+      "_____10c-i_misc-cx-2dcory-i": -160,
+      "_____10c-i_misc-cx-gd_vis-b": true,
+      "_____10c-i_misc-nx-pstcr_-f": 1,
+      "_____10c-i_misc-nx-fire_t-f": 1,
+      "_____10c-i_misc-nx-refrac-i": 0,
+      "_____10c-i_misc-nx-leak_c-f": 0,
+      "_____10c-i_misc-nx-leak_v-f": 0,
+      "_____10c-i_misc-nx-c_fr_c-i": 0,
+      "_____10c-i_misc-nx-snooze-f": 0,
+      "_____10c-i_misc-nx-ftincx-f": 0,
+      "_____10c-i_misc-nx-ftincy-f": 0,
+      "_____10c-i_misc-nx-ftincz-f": 0,
+      "_____10c-i_misc-nx-fthlim-f": 0,
+      "_____10c-i_misc-nx-mp_acc-b": false,
+      "_____10c-i_misc-nx-mp_psp-b": false,
+      "_____10c-i_misc-cx-memory-b": false,
+      "_____10c-i_misc-cx-mem__t-i": 100,
+      "_____10c-i_misc-cx-mem_gr-i": 1,
+      "_____10c-i_misc-cx-mem_ls-i": 9,
+      "_____10c-i_misc-nx-excite-f": 100,
+      "_____10c-i_misc-cx-__name-t": "Miscellaneous Input",
+      "_____10c-i_misc-cx-_group-t": "IPU",
+      "_____10c-i_misc-cx-devcnt-i": 1,
+      "_____10c-o_misc-cx-subgrp-t": "",
+      "_____10c-o_misc-cx-_n_cnt-i": 1,
+      "_____10c-o_misc-cx-synatt-f": 100,
+      "_____10c-o_misc-cx-de_gen-f": 0,
+      "_____10c-o_misc-cx-pspuni-b": false,
+      "_____10c-o_misc-nx-pstcrm-f": 99999,
+      "_____10c-o_misc-cx-dstmap-d": {},
+      "_____10c-o_misc-cx-___bbx-i": 1,
+      "_____10c-o_misc-cx-___bby-i": 1,
+      "_____10c-o_misc-cx-___bbz-i": 1,
+      "_____10c-o_misc-cx-rcordx-i": 65,
+      "_____10c-o_misc-cx-rcordy-i": 0,
+      "_____10c-o_misc-cx-rcordz-i": -26,
+      "_____10c-o_misc-cx-2dcorx-i": 1428,
+      "_____10c-o_misc-cx-2dcory-i": -122,
+      "_____10c-o_misc-cx-gd_vis-b": true,
+      "_____10c-o_misc-nx-pstcr_-f": 1,
+      "_____10c-o_misc-nx-fire_t-f": 1,
+      "_____10c-o_misc-nx-refrac-i": 0,
+      "_____10c-o_misc-nx-leak_c-f": 0,
+      "_____10c-o_misc-nx-leak_v-f": 0,
+      "_____10c-o_misc-nx-c_fr_c-i": 0,
+      "_____10c-o_misc-nx-snooze-f": 0,
+      "_____10c-o_misc-nx-ftincx-f": 0,
+      "_____10c-o_misc-nx-ftincy-f": 0,
+      "_____10c-o_misc-nx-ftincz-f": 0,
+      "_____10c-o_misc-nx-fthlim-f": 0,
+      "_____10c-o_misc-nx-mp_acc-b": true,
+      "_____10c-o_misc-nx-mp_psp-b": false,
+      "_____10c-o_misc-cx-memory-b": false,
+      "_____10c-o_misc-cx-mem__t-i": 100,
+      "_____10c-o_misc-cx-mem_gr-i": 1,
+      "_____10c-o_misc-cx-mem_ls-i": 9,
+      "_____10c-o_misc-nx-excite-f": 100,
+      "_____10c-o_misc-cx-__name-t": "Miscellaneous",
+      "_____10c-o_misc-cx-_group-t": "OPU",
+      "_____10c-o_misc-cx-devcnt-i": 1,
+      "_____10c-CM0Tim-cx-subgrp-t": "",
+      "_____10c-CM0Tim-cx-_n_cnt-i": 1,
+      "_____10c-CM0Tim-cx-synatt-f": 100,
+      "_____10c-CM0Tim-cx-de_gen-f": 0,
+      "_____10c-CM0Tim-cx-pspuni-b": true,
+      "_____10c-CM0Tim-nx-pstcrm-f": 99999,
+      "_____10c-CM0Tim-cx-dstmap-d": {
+         "o_misc": [
+            [
+               "block_to_block",
+               [
+                  1,
+                  1,
+                  1
+               ],
+               1,
+               false,
+               1,
+               1,
+               1
+            ]
+         ],
+         "CM0Tim": [
+            [
+               "lateral_+y",
+               [
+                  1,
+                  1,
+                  1
+               ],
+               1,
+               false,
+               1,
+               1,
+               1
+            ],
+            [
+               "go next column",
+               [
+                  1,
+                  1,
+                  1
+               ],
+               1,
+               false,
+               1,
+               1,
+               1
+            ]
+         ]
+      },
+      "_____10c-CM0Tim-cx-___bbx-i": 1,
+      "_____10c-CM0Tim-cx-___bby-i": 100,
+      "_____10c-CM0Tim-cx-___bbz-i": 1,
+      "_____10c-CM0Tim-cx-rcordx-i": 116,
+      "_____10c-CM0Tim-cx-rcordy-i": 0,
+      "_____10c-CM0Tim-cx-rcordz-i": 0,
+      "_____10c-CM0Tim-cx-2dcorx-i": 1012,
+      "_____10c-CM0Tim-cx-2dcory-i": -152,
+      "_____10c-CM0Tim-cx-gd_vis-b": true,
+      "_____10c-CM0Tim-nx-pstcr_-f": 1,
+      "_____10c-CM0Tim-nx-fire_t-f": 1,
+      "_____10c-CM0Tim-nx-refrac-i": 0,
+      "_____10c-CM0Tim-nx-leak_c-f": 0,
+      "_____10c-CM0Tim-nx-leak_v-f": 0,
+      "_____10c-CM0Tim-nx-c_fr_c-i": 0,
+      "_____10c-CM0Tim-nx-snooze-f": 0,
+      "_____10c-CM0Tim-nx-ftincx-f": 0,
+      "_____10c-CM0Tim-nx-ftincy-f": 0,
+      "_____10c-CM0Tim-nx-ftincz-f": 0,
+      "_____10c-CM0Tim-nx-fthlim-f": 0,
+      "_____10c-CM0Tim-nx-mp_acc-b": false,
+      "_____10c-CM0Tim-nx-mp_psp-b": false,
+      "_____10c-CM0Tim-cx-memory-b": false,
+      "_____10c-CM0Tim-cx-mem__t-i": 100,
+      "_____10c-CM0Tim-cx-mem_gr-i": 1,
+      "_____10c-CM0Tim-cx-mem_ls-i": 9,
+      "_____10c-CM0Tim-nx-excite-f": 100,
+      "_____10c-CM0Tim-cx-__name-t": "Timer",
+      "_____10c-CM0Tim-cx-_group-t": "CUSTOM"
+   }
+}
\ No newline at end of file
diff --git a/tests/timer/version.py b/tests/timer/version.py
new file mode 100644
index 000000000..dca5ae303
--- /dev/null
+++ b/tests/timer/version.py
@@ -0,0 +1,1 @@
+__version__ = '1696966727'