Beispiel #1
0
class DKTLabels(LabelsBase):
    """ Labels from the Desikan-Killiany-Tourville human brain labeling protocol. """

    filename = 'dkt-labels'
    name = 'Desikan-Killiany-Tourville Parcellation Labels'
    shortname = 'dkt'
    namespace = DKT
    prefixes = {'DKTr':str(DKTr), 'DKTs':str(DKTs), **LabelsBase.prefixes}
    imports = parcCore,
    sources = DKTSrc,
    root = LabelRoot(iri=nsExact(namespace),  # ilxtr.hcpmmproot,
                     label='DKT label root',
                     shortname=shortname,
                     definingArtifacts=(s.artifact.iri for s in sources),
    )

    def _triples(self):
        for source in self.sources:
            for namespace, index, label in source:
                iri = namespace[str(index)]
                yield from Label(labelRoot=self.root,
                                 label=label,
                                 iri=iri)

            yield from source.isVersionOf
Beispiel #2
0
class SwansonLabels(ParcOnt):  # FIXME not labels...
    filename = 'swanson'
    name = 'Swanson 2014 partonomies'
    shortname = 'swannt'
    imports = parcCore,
    prefixes = {**makePrefixes('NIFRID', 'ilxtr', 'prov'),
                'swanr':interlex_namespace('swanson/uris/readable/'),
                'SWAN':interlex_namespace('swanson/uris/neuroanatomical-terminology/terms/'),
                'SWAA':interlex_namespace('swanson/uris/neuroanatomical-terminology/appendix/'),}
    sources = SwansonAppendix,
    namespace = prefixes['SWAN']
    root = LabelRoot(iri=nsExact(namespace),  # FIXME this is not really a label in the strict sense
                     label='Swanson label root',
                     shortname=shortname,
                     definingArtifacts=(s.artifact.iri for s in sources),)

    def _triples(self):
        for s, p, o in swanson().g:
            #if p != rdf.type and o != owl.Ontology:
            if s != rdflib.URIRef('http://ontology.neuinfo.org/NIF/ttl/generated/swanson_hierarchies.ttl'):

                if p == rdfs.subClassOf and o == ilxtr.swansonBrainRegionConcept:
                    yield s, p, self.root.iri
                elif p == rdfs.label:
                    yield s, p, Label(label=o, labelRoot=self.root).rdfs_label
                    yield s, skos.prefLabel, o
                else:
                    yield s, p, o
Beispiel #3
0
class MNDBGLLabels():
    """ DEPRECATED use FreeSurfer """
    filename = 'mndbgl-labels'
    name = 'Mindboggle Parcellation Labels'
    shortname = 'mndbgl'
    namespace = MNDBGL
    imports = parcCore,
    sources = MNDBGLSrc,
    root = LabelRoot(iri=nsExact(namespace),  # ilxtr.hcpmmproot,
                     label='Mindboggle label root',
                     shortname=shortname,
                     comment=('The local integer identifiers in the MNDBGL namespace '
                              'correspond to numbers from FreeSurferColorLUT.txt.'),
                     #definingArtifacts=(s.artifact.iri for s in sources),
                    )

    def _triples(self):
        for source in self.sources:
            for index, label in source:
                iri = self.namespace[str(index)]
                yield from Label(labelRoot=self.root,
                                 label=label,
                                 iri=iri)

            yield from source.isVersionOf
Beispiel #4
0
class PaxMouseLabels(PaxLabels):
    """ Compilation of all labels used to name mouse brain regions
        in atlases created using Paxinos and Franklin\'s methodology."""

    # TODO FIXME align indexes where possible to paxrat???

    filename = 'paxinos-mus-labels'
    name = 'Paxinos & Franklin Mouse Parcellation Labels'
    shortname = 'paxmus'
    namespace = PAXMUS

    prefixes = {
        **makePrefixes('NIFRID', 'ilxtr', 'prov', 'dcterms'),
        'PAXMUS': str(PAXMUS),
        'paxmusver': str(paxmusver),
    }
    sources = PaxMFix, PaxMSrAr_2, PaxMSrAr_3
    root = LabelRoot(
        iri=nsExact(namespace),  # PAXMUS['0'],
        label='Paxinos mouse parcellation label root',
        shortname=shortname,
        definingArtifactsS=(Artifacts.PaxMouseAt.iri, ),
    )

    _merge = {
        '4/5Cb': '4&5Cb',
        '5N': 'Mo5',
        '12N': '12',
        'AngT': 'Ang',
        'ANS': 'Acc',
        'ASt': 'AStr',
        'hif': 'hf',
        'MnM': 'MMn',
        'MoDG': 'Mol',
        'och': 'ox',
        'PHA': 'PH',  # FIXME PH is reused in 3rd
        'ST': 'BST',
        'STIA': 'BSTIA',
        'STLD': 'BSTLD',
        'STLI': 'BSTLI',
        'STLJ': 'BSTLJ',
        'STLP': 'BSTLP',
        'STLV': 'BSTLV',
        'STMA': 'BSTMA',
        'STMP': 'BSTMP',
        'STMPI': 'BSTMPI',
        'STMPL': 'BSTMPL',
        'STMPM': 'BSTMPM',
        'STMV': 'BSTMV',
        'STS': 'BSTS',
    }
Beispiel #5
0
class BermanLabels(LabelsBase):
    """ Berman Cat labels """
    # sort by label/structure not by abbrev
    filename = 'berman-cat-labels'
    name = 'Berman 1968 cat brain stem labels'
    shortname = 'bercat'
    imports = parcCore,
    prefixes = {
        **makePrefixes('NIFRID', 'ilxtr', 'prov'), 'BERCAT': str(BERCAT)
    }
    sources = BermanSrc,
    namespace = BERCAT
    root = LabelRoot(
        iri=nsExact(namespace),
        label='Berman 1968 cat label root',
        shortname=shortname,
        definingArtifacts=(s.artifact.iri for s in sources),
    )

    def _triples(self):
        for source in self.sources:
            for i, (label, paren_thing, abbrev, index) in enumerate(source):
                local_identifier = str(i + 1)
                iri = self.namespace[
                    local_identifier]  # TODO load from existing
                yield from Label(
                    labelRoot=self.root,
                    label=label,
                    #altLabel=None,
                    #synonyms=extras,
                    abbrevs=(abbrev, ),
                    iri=iri,
                )
                if paren_thing:
                    yield iri, ilx[
                        'berman/uris/readable/hasWeirdParenValue'], rdflib.Literal(
                            paren_thing)

                continue
                # FIXME different file ...
                region_iri = ilx['berman/uris/cat/regions/' + local_identifier]
                # FIXME incorporate version in tree or no?
                # just have it be consecutive? HRM
                yield region_iri, rdf.type, owl.Class
                yield region_iri, ilxtr.hasParcellationLabel, iri  # FIXME predicate choice ...
                yield region_iri, ilxtr.isDefinedBy, BermanSrc.artifact.iri  # FIXME
                for plate_num in index:
                    yield region_iri, ilxtr.appearsOnPlateNumber, rdflib.Literal(
                        plate_num)  # FIXME generalize ...
Beispiel #6
0
class WHSSDLabels(LabelsBase):
    filename = 'waxholm-rat-labels'
    name = 'Waxholm Sprague Dawley Atlas Labels'
    shortname = 'whssd'
    imports = parcCore,
    prefixes = {
        **makePrefixes('NIFRID', 'ilxtr', 'prov', 'dcterms'), 'WHSSD':
        str(WHSSD)
    }
    sources = WHSSDSrc2, WHSSDilfSrc2, WHSSDSrc1, WHSSDilfSrc1
    namespace = WHSSD
    root = LabelRoot(
        iri=nsExact(namespace),  # ilxtr.whssdroot,
        label='Waxholm Space Sprague Dawley parcellation label root',
        shortname=shortname,
        definingArtifacts=(s.artifact.iri for s in sources),
    )

    def _triples(self):
        for source in self.sources:
            preds = False
            for index, label, *rest in source:
                abbrev, parent = rest if rest else (
                    False, False)  # a tricky one if you miss the parens
                abbrevs = (abbrev, ) if abbrev and abbrev != label else tuple()
                if int(index
                       ) >= 1000:  # FIXME this is the WRONG way to do this
                    # FIXME parentless structures in the ilf files?
                    label += ' (structure)'
                iri = WHSSD[str(index)]
                yield from Label(
                    labelRoot=self.root,
                    label=label,
                    abbrevs=abbrevs,
                    iri=iri,
                )
                if parent:
                    preds = True
                    parent = WHSSD[str(parent)]
                    yield from restriction.serialize(
                        iri, source.predicates[ilxtr.labelPartOf], parent)

            yield from source.isVersionOf
            if preds:
                for parent, child in source.predicates.items(
                ):  # FIXME annotationProperty vs objectProperty
                    yield child, rdfs.subPropertyOf, parent
Beispiel #7
0
class HCPMMPLabels(LabelsBase):
    filename = 'hcpmmp'
    name = 'Human Connectome Project Multi-Modal human cortical parcellation'
    shortname = 'hcpmmp'
    imports = parcCore,
    prefixes = {
        **makePrefixes('NIFRID', 'ilxtr', 'prov'), 'HCPMMP': str(HCPMMP)
    }
    sources = HCPMMPSrc,
    namespace = HCPMMP
    root = LabelRoot(
        iri=nsExact(namespace),  # ilxtr.hcpmmproot,
        label='HCPMMP label root',
        shortname=shortname,
        definingArtifacts=(s.artifact.iri for s in sources),
    )

    def _triples(self):
        for source in self.sources:
            for record in source:
                (Parcellation_Index, Area_Name, Area_Description,
                 Newly_Described, Results_Section, Other_Names,
                 Key_Studies) = [r.strip() for r in record]
                iri = HCPMMP[str(Parcellation_Index)]
                onames = [
                    n.strip() for n in Other_Names.split(',') if n.strip()
                ]
                syns = (n for n in onames if len(n) > 3)
                abvs = tuple(n for n in onames if len(n) <= 3)
                cites = tuple(s.strip() for s in Key_Studies.split(','))
                if Newly_Described in ('Yes*', 'Yes'):
                    cites = cites + ('Glasser and Van Essen 2016', )

                yield from Label(
                    labelRoot=self.root,
                    label=Area_Description,
                    altLabel=Area_Name,
                    synonyms=syns,
                    abbrevs=abvs,
                    #bibliographicCitation=  # XXX vs definingCitation
                    definingCitations=cites,
                    iri=iri)
Beispiel #8
0
class FreeSurferLabels(LabelsBase):
    filename = 'freesurfer-labels'
    name = 'FreeSurfer color LUT Parcellation Labels'
    shortname = 'fscl'  # can't use fsl because that is already in use by another fMRI package...
    namespace = FSCL
    prefixes = {**LabelsBase.prefixes}  # FIXME it would be nice to be able to automate this...
    imports = parcCore,
    sources = FreeSurferSrc,
    root = LabelRoot(iri=nsExact(namespace),  # ilxtr.hcpmmproot,
                     label='FreeSurfer Color LUT label root',
                     shortname=shortname,
                     definingArtifacts=(s.artifact.iri for s in sources),)

    def _triples(self):
        for source in self.sources:
            for index, label in source:
                iri = self.namespace[str(index)]
                yield from Label(labelRoot=self.root,
                                 label=label,
                                 iri=iri)

            yield from source.isVersionOf
Beispiel #9
0
    def prepare(cls):
        ATLAS_PATH = '/usr/share/fsl/data/atlases/'

        shortnames = {
            'JHU White-Matter Tractography Atlas': 'JHU WM',
            'Oxford-Imanova Striatal Structural Atlas': 'OISS',
            'Talairach Daemon Labels': 'Talairach',
            'Subthalamic Nucleus Atlas': 'SNA',
            'JHU ICBM-DTI-81 White-Matter Labels': 'JHU ICBM WM',
            'Juelich Histological Atlas': 'Juelich',
            'MNI Structural Atlas': 'MNI Struct',
        }

        prefixes = {
            'Cerebellar Atlas in MNI152 space after normalization with FLIRT':
            'CMNIfl',
            'Cerebellar Atlas in MNI152 space after normalization with FNIRT':
            'CMNIfn',
            'Sallet Dorsal Frontal connectivity-based parcellation': 'DFCBP',
            'Neubert Ventral Frontal connectivity-based parcellation': 'VFCBP',
            'Mars Parietal connectivity-based parcellation': 'PCBP',
        }

        for xmlfile in glob.glob(ATLAS_PATH + '*.xml'):
            filename = os.path.splitext(os.path.basename(xmlfile))[0]

            tree = etree.parse(xmlfile)
            parcellation_name = tree.xpath('header//name')[0].text

            # namespace
            namespace = rdflib.Namespace(FSLATS[filename + '/labels/'])

            # shortname
            shortname = tree.xpath('header//shortname')
            if shortname:
                shortname = shortname[0].text
            else:
                shortname = shortnames[parcellation_name]

            artifact_shortname = shortname
            shortname = shortname.replace(' ', '')

            # Artifact
            artifact = Terminology(
                iri=FSLATS[filename],
                label=parcellation_name,
                docUri='http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/Atlases',
                species=NCBITaxon['9606'],
                devstage=UBERON[
                    '0000113'],  # FIXME mature vs adult vs when they actually did it...
                region=UBERON['0000955'],
                shortname=artifact_shortname)
            setattr(cls.Artifacts, shortname, artifact)

            # LabelRoot
            root = LabelRoot(iri=nsExact(namespace),
                             label=parcellation_name + ' label root',
                             shortname=shortname,
                             definingArtifacts=(artifact.iri, ))
            root.namespace = namespace
            cls.roots += root,

            # prefix
            if parcellation_name in prefixes:
                prefix = 'fsl' + prefixes[parcellation_name]
            else:
                prefix = 'fsl' + shortname

            cls.prefixes[prefix] = root.iri

            # Source
            @classmethod
            def loadData(cls, _tree=tree):
                out = []
                for node in _tree.xpath('data//label'):
                    index, label = node.get('index'), node.text
                    out.append((index, label))
                return out

            source = type(
                'FSLsource_' + shortname.replace(' ', '_'),
                (Source, ),
                dict(
                    iri=rdflib.URIRef('file://' + xmlfile),
                    source=xmlfile,
                    source_original=True,
                    artifact=artifact,
                    root=
                    root,  # used locally since we have more than one root per ontology here
                    loadData=loadData))
            cls.sources += source,

        super().prepare()
Beispiel #10
0
class PaxRatLabels(PaxLabels):
    """ Compilation of all labels used to name rat brain regions
        in atlases created using Paxinos and Watson\'s methodology."""

    filename = 'paxinos-rat-labels'
    name = 'Paxinos & Watson Rat Parcellation Labels'
    shortname = 'paxrat'
    namespace = PAXRAT

    prefixes = {
        **makePrefixes('NIFRID', 'ilxtr', 'prov', 'dcterms'),
        'PAXRAT': str(PAXRAT),
        'paxratver': str(paxratver),
    }
    # sources need to go in the order with which we want the labels to take precedence (ie in this case 6e > 4e)
    sources = PaxFix, PaxSrAr_6, PaxSr_6, PaxSrAr_4, PaxFix6, PaxFix4  #, PaxTree_6()  # tree has been successfully used for crossreferencing, additional terms need to be left out at the moment (see in_tree_not_in_six)
    root = LabelRoot(
        iri=nsExact(namespace),  # PAXRAT['0'],
        label='Paxinos rat parcellation label root',
        shortname=shortname,
        #definingArtifactsS=None,#Artifacts.PaxRatAt.iri,
        definingArtifactsS=(Artifacts.PaxRatAt.iri, ),
    )

    _fixes = []

    _dupes = {
        # for 4e the numbers in the index are to the cranial nerve nuclei entries
        '3N':
        DupeRecord(alt_abbrevs=['3'],
                   structures=['oculomotor nucleus'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '4N':
        DupeRecord(alt_abbrevs=['4'],
                   structures=['trochlear nucleus'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '6N':
        DupeRecord(alt_abbrevs=['6'],
                   structures=['abducens nucleus'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '7N':
        DupeRecord(alt_abbrevs=['7'],
                   structures=['facial nucleus'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '10N':
        DupeRecord(alt_abbrevs=['10'],
                   structures=['dorsal motor nucleus of vagus'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),

        # FIXME need comments about the index entries
        '1Cb':
        DupeRecord(alt_abbrevs=['1'],
                   structures=['cerebellar lobule 1'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '2Cb':
        DupeRecord(alt_abbrevs=['2'],
                   structures=['cerebellar lobule 2'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '2/3Cb':
        DupeRecord(alt_abbrevs=['2&3'],
                   structures=['cerebellar lobules 2&3'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '3Cb':
        DupeRecord(alt_abbrevs=['3'],
                   structures=['cerebellar lobule 3'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '4Cb':
        DupeRecord(alt_abbrevs=['4'],
                   structures=['cerebellar lobule 4'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '4/5Cb':
        DupeRecord(alt_abbrevs=['4&5'],
                   structures=['cerebellar lobules 4&5'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '5Cb':
        DupeRecord(alt_abbrevs=['5'],
                   structures=['cerebellar lobule 5'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '6Cb':
        DupeRecord(alt_abbrevs=['6'],
                   structures=['cerebellar lobule 6'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '6aCb':
        DupeRecord(alt_abbrevs=['6a'],
                   structures=['cerebellar lobule 6a'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '6bCb':
        DupeRecord(alt_abbrevs=['6b'],
                   structures=['cerebellar lobule 6b'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '6cCb':
        DupeRecord(alt_abbrevs=['6c'],
                   structures=['cerebellar lobule 6c'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '7Cb':
        DupeRecord(alt_abbrevs=['7'],
                   structures=['cerebellar lobule 7'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '8Cb':
        DupeRecord(alt_abbrevs=['8'],
                   structures=['cerebellar lobule 8'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '9Cb':
        DupeRecord(alt_abbrevs=['9'],
                   structures=['cerebellar lobule 9'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
        '10Cb':
        DupeRecord(alt_abbrevs=['10'],
                   structures=['cerebellar lobule 10'],
                   figures={},
                   artiris=[Artifacts.PaxRat4.iri]),
    }

    _merge = {  # abbrevs that have identical structure names
        '5N':'Mo5',
        '12N':'12',
        'ANS':'Acc',
        'ASt':'AStr',
        'AngT':'Ang',
        'MnM':'MMn',
        'MoDG':'Mol',
        'PDPO':'PDP',
        'PTg':'PPTg',
        'STIA':'BSTIA',
        'STL':'BSTL',
        'STLD':'BSTLD',
        'STLI':'BSTLI',
        'STLJ':'BSTLJ',
        'STLP':'BSTLP',
        'STLV':'BSTLV',
        'STM':'BSTM',
        'STMA':'BSTMA',
        'STMP':'BSTMP',
        'STMPI':'BSTMPI',
        'STMPL':'BSTMPL',
        'STMPM':'BSTMPM',
        'STMV':'BSTMV',
        'hif':'hf',
        'och':'ox',
    }

    def curate(self):
        fr, err4 = PaxSrAr_4()
        sx, err6 = PaxSrAr_6()
        sx2, _ = PaxSr_6()
        tr, err6t = PaxTree_6()

        sfr = set(fr)
        ssx = set(sx)
        ssx2 = set(sx2)
        str_ = set(tr)
        in_four_not_in_six = sfr - ssx
        in_six_not_in_four = ssx - sfr
        in_tree_not_in_six = str_ - ssx
        in_six_not_in_tree = ssx - str_
        in_six2_not_in_six = ssx2 - ssx
        in_six_not_in_six2 = ssx - ssx2

        print(
            len(in_four_not_in_six),
            len(in_six_not_in_four),
            len(in_tree_not_in_six),
            len(in_six_not_in_tree),
            len(in_six2_not_in_six),
            len(in_six_not_in_six2),
        )
        tr_struct_abrv = {}
        for abrv, ((struct, *extra), _, parent) in tr.items():
            tr_struct_abrv[struct] = abrv
            if abrv in sx:
                #print(abrv, struct, parent)
                if struct and struct not in sx[abrv][0]:
                    print(
                        f'Found new label from tr for {abrv}:\n{struct}\n{sx[abrv][0]}\n'
                    )

        # can't run these for tr yet
        #reduced = set(tr_struct_abrv.values())
        #print(sorted(_ for _ in tr if _ not in reduced))
        #assert len(tr_struct_abrv) == len(tr), 'mapping between abrvs and structs is not 1:1 for tr'

        sx2_struct_abrv = {}
        for abrv, ((struct, *extra), _) in sx2.items():
            sx2_struct_abrv[struct] = abrv
            if abrv in sx:
                if struct and struct not in sx[abrv][0]:
                    print(
                        f'Found new label from sx2 for {abrv}:\n{struct}\n{sx[abrv][0]}\n'
                    )

        reduced = set(sx2_struct_abrv.values())
        print(sorted(
            _ for _ in reduced
            if _ not in sx2))  # ah inconsistent scoping rules in class defs...
        assert len(sx2_struct_abrv) == len(sx2), 'there is a duplicate struct'

        sx_struct_abrv = {}
        for abrv, ((struct, *extra), _) in sx.items():
            sx_struct_abrv[struct] = abrv

        reduced = set(sx_struct_abrv.values())
        print(sorted(_ for _ in reduced if _ not in sx))
        assert len(sx_struct_abrv) == len(sx), 'there is a duplicate struct'

        # TODO test whether any of the tree members that were are going to exclude have children that we are going to include

        names_match_not_abbervs = {}

        tree_no_name = {
            _: tr[_]
            for _ in sorted(in_tree_not_in_six) if not tr[_][0][0]
        }
        tree_with_name = {
            _: tr[_]
            for _ in sorted(in_tree_not_in_six) if tr[_][0][0]
        }
        not_in_tree_with_figures = {
            _: sx[_]
            for _ in sorted(in_six_not_in_tree) if sx[_][-1]
        }
        a = f'{"abv":<25} | {"structure name":<60} | parent abv\n' + '\n'.join(
            f'{k:<25} | {v[0][0]:<60} | {v[-1]}'
            for k, v in tree_with_name.items())
        b = f'{"abv":<25} | {"structure name":<15} | parent abv\n' + '\n'.join(
            f'{k:<25} | {"":<15} | {v[-1]}' for k, v in tree_no_name.items())
        c = f'abv    | {"structure name":<60} | figures (figure ranges are tuples)\n' + '\n'.join(
            f'{k:<6} | {v[0][0]:<60} | {v[-1]}'
            for k, v in not_in_tree_with_figures.items())
        with open(
                os.path.expanduser(
                    '~/ni/dev/nifstd/paxinos/tree-with-name.txt'), 'wt') as f:
            f.write(a)
        with open(
                os.path.expanduser('~/ni/dev/nifstd/paxinos/tree-no-name.txt'),
                'wt') as f:
            f.write(b)
        with open(
                os.path.expanduser(
                    '~/ni/dev/nifstd/paxinos/not-in-tree-with-figures.txt'),
                'wt') as f:
            f.write(c)
        #match_name_not_abrev = set(v[0][0] for v in tree_with_name.values()) & set(v[0][0] for v in sx.values())

        _match_name_not_abrev = {}
        for a, (alts, (s, *extra), f,
                *_) in PaxRatLabels().records()[0].items():
            if s not in _match_name_not_abrev:
                _match_name_not_abrev[s] = [a]
            elif a not in _match_name_not_abrev[s]:
                _match_name_not_abrev[s].append(a)

        match_name_not_abrev = {
            k: v
            for k, v in _match_name_not_abrev.items() if len(v) > 1
        }

        abrv_match_not_name = {
            k: v[0]
            for k, v in PaxRatLabels().records()[0].items() if len(v[0]) > 1
        }
        _ = [
            print(k, *v[0]) for k, v in PaxRatLabels().records()[0].items()
            if len(v[0]) > 1
        ]
        breakpoint()