Source code for atlannot.merge_original.coarse

# Copyright 2021, Blue Brain Project, EPFL
#
# 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.
"""The coarse merging of the annotation atlases."""
import numpy as np

from .JSONread import RegionData


[docs]def coarse_merge(annotation, annotation2, brain_regions): """Perform the coarse atlas merging. Parameters ---------- annotation : np.ndarray The first atlas to merge, usually CCFv2. annotation2 : np.ndarray The second atlas to merge, usually CCFv3. brain_regions : dict The brain regions dictionary. Can be obtained from the "msg" key of the `brain_regions.json` (`1.json`) file. Returns ------- ccfv2_corrected : np.ndarray The merged CCFv2 atlas. ccfv3_corrected : np.ndarray The merged CCFv3 atlas. """ region_data = RegionData(brain_regions) uniques = region_data.find_unique_regions(annotation, top_region_name="root") children, _ = region_data.find_children(uniques) uniques2 = region_data.find_unique_regions(annotation2, top_region_name="root") children2, _ = region_data.find_children(uniques2) ccfv2_corrected = np.copy(annotation) ccfv3_corrected = np.copy(annotation2) ids = np.unique(ccfv2_corrected) ids2 = np.unique(ccfv3_corrected) ids_to_correct = ids[np.in1d(ids, ids2, invert=True)] for id_reg in ids_to_correct: allname = region_data.id_to_region_dictionary_ALLNAME[id_reg] if ( region_data.is_leaf[allname] and id_reg not in ids2 and region_data.region_dictionary_to_id[ region_data.region_dictionary_to_id_parent[ region_data.id_to_region_dictionary[id_reg] ] ] in ids2 ): ccfv2_corrected[ ccfv2_corrected == id_reg ] = region_data.region_dictionary_to_id[ region_data.region_dictionary_to_id_parent[ region_data.id_to_region_dictionary[id_reg] ] ] elif region_data.is_leaf[allname] and ( "Medial amygdalar nucleus" in allname or "Subiculum" in allname or "Bed nuclei of the stria terminalis" in allname ): ccfv2_corrected[ ccfv2_corrected == id_reg ] = region_data.region_dictionary_to_id[ region_data.region_dictionary_to_id_parent[ region_data.region_dictionary_to_id_parent[ region_data.id_to_region_dictionary[id_reg] ] ] ] elif "Paraventricular hypothalamic nucleus" in allname: ccfv2_corrected[ccfv2_corrected == id_reg] = 38 # Entorhinal area, lateral part ccfv2_corrected[np.where(ccfv2_corrected == 60)] = 28 # L6b -> L6a ccfv2_corrected[np.where(ccfv2_corrected == 999)] = 20 # L2/3 -> L2 # double check? ccfv2_corrected[np.where(ccfv2_corrected == 715)] = 20 # L2a -> L2 ccfv2_corrected[np.where(ccfv2_corrected == 764)] = 20 # L2b -> L2 ccfv2_corrected[np.where(ccfv2_corrected == 92)] = 139 # L4 -> L5 ccfv2_corrected[np.where(ccfv2_corrected == 312)] = 139 # L4/5 -> L5 # Entorhinal area, medial part, dorsal zone ccfv2_corrected[np.where(ccfv2_corrected == 468)] = 543 # L2a -> L2 ccfv2_corrected[np.where(ccfv2_corrected == 508)] = 543 # L2b -> L2 ccfv2_corrected[np.where(ccfv2_corrected == 712)] = 727 # L4 -> L5 # double check? ccfv2_corrected[np.where(ccfv2_corrected == 195)] = 304 # L2 -> L2/3 ccfv2_corrected[np.where(ccfv2_corrected == 524)] = 582 # L2 -> L2/3 ccfv2_corrected[np.where(ccfv2_corrected == 606)] = 430 # L2 -> L2/3 ccfv2_corrected[np.where(ccfv2_corrected == 747)] = 556 # L2 -> L2/3 # subreg of Cochlear nuclei -> Cochlear nuclei ccfv2_corrected[np.where(ccfv2_corrected == 96)] = 607 ccfv2_corrected[np.where(ccfv2_corrected == 101)] = 607 ccfv2_corrected[np.where(ccfv2_corrected == 112)] = 607 ccfv2_corrected[np.where(ccfv2_corrected == 560)] = 607 ccfv3_corrected[np.where(ccfv3_corrected == 96)] = 607 ccfv3_corrected[np.where(ccfv3_corrected == 101)] = 607 # subreg of Nucleus ambiguus -> Nucleus ambiguus ccfv2_corrected[np.where(ccfv2_corrected == 143)] = 135 ccfv2_corrected[np.where(ccfv2_corrected == 939)] = 135 ccfv3_corrected[np.where(ccfv3_corrected == 143)] = 135 ccfv3_corrected[np.where(ccfv3_corrected == 939)] = 135 # subreg of Accessory olfactory bulb -> Accessory olfactory bulb ccfv2_corrected[np.where(ccfv2_corrected == 188)] = 151 ccfv2_corrected[np.where(ccfv2_corrected == 196)] = 151 ccfv2_corrected[np.where(ccfv2_corrected == 204)] = 151 ccfv3_corrected[np.where(ccfv3_corrected == 188)] = 151 ccfv3_corrected[np.where(ccfv3_corrected == 196)] = 151 ccfv3_corrected[np.where(ccfv3_corrected == 204)] = 151 # subreg of Medial mammillary nucleus -> Medial mammillary nucleus ccfv2_corrected[np.where(ccfv2_corrected == 798)] = 491 ccfv3_corrected[np.where(ccfv3_corrected == 798)] = 491 ccfv3_corrected[np.where(ccfv3_corrected == 606826647)] = 491 ccfv3_corrected[np.where(ccfv3_corrected == 606826651)] = 491 ccfv3_corrected[np.where(ccfv3_corrected == 606826655)] = 491 ccfv3_corrected[np.where(ccfv3_corrected == 606826659)] = 491 # Subreg to Dorsal part of the lateral geniculate complex ccfv3_corrected[np.where(ccfv3_corrected == 496345664)] = 170 ccfv3_corrected[np.where(ccfv3_corrected == 496345668)] = 170 ccfv3_corrected[np.where(ccfv3_corrected == 496345672)] = 170 # Subreg to Lateral reticular nucleus ccfv2_corrected[np.where(ccfv2_corrected == 955)] = 235 ccfv2_corrected[np.where(ccfv2_corrected == 963)] = 235 ccfv3_corrected[np.where(ccfv3_corrected == 955)] = 235 ccfv3_corrected[np.where(ccfv3_corrected == 963)] = 235 # subreg of Posterior parietal association areas combined layer by layer ccfv3_corrected[np.where(ccfv3_corrected == 312782550)] = 532 ccfv3_corrected[np.where(ccfv3_corrected == 312782604)] = 532 ccfv3_corrected[np.where(ccfv3_corrected == 312782554)] = 241 ccfv3_corrected[np.where(ccfv3_corrected == 312782608)] = 241 ccfv3_corrected[np.where(ccfv3_corrected == 312782558)] = 635 ccfv3_corrected[np.where(ccfv3_corrected == 312782612)] = 635 ccfv3_corrected[np.where(ccfv3_corrected == 312782562)] = 683 ccfv3_corrected[np.where(ccfv3_corrected == 312782616)] = 683 ccfv3_corrected[np.where(ccfv3_corrected == 312782566)] = 308 ccfv3_corrected[np.where(ccfv3_corrected == 312782620)] = 308 ccfv3_corrected[np.where(ccfv3_corrected == 312782570)] = 340 ccfv3_corrected[np.where(ccfv3_corrected == 312782624)] = 340 # subreg to Parabrachial nucleus ccfv2_corrected[np.where(ccfv2_corrected == 123)] = 867 ccfv2_corrected[np.where(ccfv2_corrected == 860)] = 867 ccfv2_corrected[np.where(ccfv2_corrected == 868)] = 867 ccfv2_corrected[np.where(ccfv2_corrected == 875)] = 867 ccfv2_corrected[np.where(ccfv2_corrected == 883)] = 867 ccfv2_corrected[np.where(ccfv2_corrected == 891)] = 867 ccfv2_corrected[np.where(ccfv2_corrected == 899)] = 867 ccfv2_corrected[np.where(ccfv2_corrected == 915)] = 867 ccfv3_corrected[np.where(ccfv3_corrected == 123)] = 867 for id_reg in np.unique(np.concatenate((ids, ids2)))[1:]: allname = region_data.id_to_region_dictionary_ALLNAME[id_reg] if "Visual areas" in allname: if "ayer 1" in allname: ccfv3_corrected[np.where(ccfv3_corrected == id_reg)] = 801 ccfv2_corrected[np.where(ccfv2_corrected == id_reg)] = 801 elif "ayer 2/3" in allname: ccfv3_corrected[np.where(ccfv3_corrected == id_reg)] = 561 ccfv2_corrected[np.where(ccfv2_corrected == id_reg)] = 561 elif "ayer 4" in allname: ccfv3_corrected[np.where(ccfv3_corrected == id_reg)] = 913 ccfv2_corrected[np.where(ccfv2_corrected == id_reg)] = 913 elif "ayer 5" in allname: ccfv3_corrected[np.where(ccfv3_corrected == id_reg)] = 937 ccfv2_corrected[np.where(ccfv2_corrected == id_reg)] = 937 elif "ayer 6a" in allname: ccfv3_corrected[np.where(ccfv3_corrected == id_reg)] = 457 ccfv2_corrected[np.where(ccfv2_corrected == id_reg)] = 457 elif "ayer 6b" in allname: ccfv3_corrected[np.where(ccfv3_corrected == id_reg)] = 497 ccfv2_corrected[np.where(ccfv2_corrected == id_reg)] = 497 # subreg of Prosubiculum to subiculum ccfv3_corrected[np.where(ccfv3_corrected == 484682470)] = 502 # Orbital area, medial part, layer 6b -> 6a ccfv3_corrected[np.where(ccfv3_corrected == 527696977)] = 910 ccfv3_corrected[np.where(ccfv3_corrected == 355)] = 314 for id_reg in ids2[1:]: if ( ( "fiber tracts" in region_data.id_to_region_dictionary_ALLNAME[id_reg] or "Interpeduncular nucleus" in region_data.id_to_region_dictionary_ALLNAME[id_reg] ) and id_reg not in ids and region_data.region_dictionary_to_id[ region_data.region_dictionary_to_id_parent[ region_data.id_to_region_dictionary[id_reg] ] ] in ids ): ccfv3_corrected[ np.where(ccfv3_corrected == id_reg) ] = region_data.region_dictionary_to_id[ region_data.region_dictionary_to_id_parent[ region_data.id_to_region_dictionary[id_reg] ] ] if ( "Frontal pole, cerebral cortex" in region_data.id_to_region_dictionary_ALLNAME[id_reg] ): ccfv3_corrected[np.where(ccfv3_corrected == id_reg)] = 184 ccfv2_corrected[np.where(ccfv2_corrected == id_reg)] = 184 ids = np.unique(ccfv2_corrected) ids2 = np.unique(ccfv3_corrected) ids_to_correct = ids[np.in1d(ids, ids2, invert=True)] ids_to_correct = ids2[np.in1d(ids2, ids, invert=True)] ids_to_correct = ids_to_correct[ids_to_correct != 997] ids_to_correct = ids_to_correct[ids_to_correct != 8] while len(ids_to_correct) > 0: parent = ids_to_correct[0] while parent not in uniques: parent = region_data.region_dictionary_to_id[ region_data.region_dictionary_to_id_parent[ region_data.id_to_region_dictionary[parent] ] ] for child in children2[region_data.id_to_region_dictionary_ALLNAME[parent]]: ccfv3_corrected[np.where(ccfv3_corrected == child)] = parent for child in children[region_data.id_to_region_dictionary_ALLNAME[parent]]: ccfv2_corrected[np.where(ccfv2_corrected == child)] = parent ids = np.unique(ccfv2_corrected) ids2 = np.unique(ccfv3_corrected) ids_to_correct = ids2[np.in1d(ids2, ids, invert=True)] ids_to_correct = ids_to_correct[ids_to_correct != 997] ids_to_correct = ids_to_correct[ids_to_correct != 8] ids_to_correct = ids[np.in1d(ids, ids2, invert=True)] ids_to_correct = ids_to_correct[ids_to_correct != 997] ids_to_correct = ids_to_correct[ids_to_correct != 8] while len(ids_to_correct) > 0: parent = ids_to_correct[0] while parent not in uniques2: parent = region_data.region_dictionary_to_id[ region_data.region_dictionary_to_id_parent[ region_data.id_to_region_dictionary[parent] ] ] for child in children2[region_data.id_to_region_dictionary_ALLNAME[parent]]: ccfv3_corrected[np.where(ccfv3_corrected == child)] = parent for child in children[region_data.id_to_region_dictionary_ALLNAME[parent]]: ccfv2_corrected[np.where(ccfv2_corrected == child)] = parent ids = np.unique(ccfv2_corrected) ids2 = np.unique(ccfv3_corrected) ids_to_correct = ids[np.in1d(ids, ids2, invert=True)] ids_to_correct = ids_to_correct[ids_to_correct != 997] ids_to_correct = ids_to_correct[ids_to_correct != 8] return ccfv2_corrected, ccfv3_corrected