"""
Classes representing common objects in the UMLS
"""

semantic_mappings = {
    "Acquired Abnormality": {
        "groups": [("DISO", "Disorders")],
        "long": "Acquired Abnormality",
        "short": "acab",
        "tui": "T020",
    },
    "Activity": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Activity",
        "short": "acty",
        "tui": "T052",
    },
    "Age Group": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Age Group",
        "short": "aggp",
        "tui": "T100",
    },
    "Amino Acid Sequence": {
        "groups": [("GENE", "Genes & Molecular Sequences")],
        "long": "Amino Acid Sequence",
        "short": "amas",
        "tui": "T087",
    },
    "Amino Acid, Peptide, or Protein": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Amino Acid, Peptide, or Protein",
        "short": "aapp",
        "tui": "T116",
    },
    "Amphibian": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Amphibian",
        "short": "amph",
        "tui": "T011",
    },
    "Anatomical Abnormality": {
        "groups": [("DISO", "Disorders")],
        "long": "Anatomical Abnormality",
        "short": "anab",
        "tui": "T190",
    },
    "Anatomical Structure": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Anatomical Structure",
        "short": "anst",
        "tui": "T017",
    },
    "Animal": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Animal",
        "short": "anim",
        "tui": "T008",
    },
    "Antibiotic": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Antibiotic",
        "short": "antb",
        "tui": "T195",
    },
    "Archaeon": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Archaeon",
        "short": "arch",
        "tui": "T194",
    },
    "Bacterium": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Bacterium",
        "short": "bact",
        "tui": "T007",
    },
    "Behavior": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Behavior",
        "short": "bhvr",
        "tui": "T053",
    },
    "Biologic Function": {
        "groups": [("PHEN", "Phenomena")],
        "long": "Biologic Function",
        "short": "biof",
        "tui": "T038",
    },
    "Biologically Active Substance": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Biologically Active Substance",
        "short": "bacs",
        "tui": "T123",
    },
    "Biomedical Occupation or Discipline": {
        "groups": [("OCCU", "Occupations")],
        "long": "Biomedical Occupation or Discipline",
        "short": "bmod",
        "tui": "T091",
    },
    "Biomedical or Dental Material": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Biomedical or Dental Material",
        "short": "bodm",
        "tui": "T122",
    },
    "Bird": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Bird",
        "short": "bird",
        "tui": "T012",
    },
    "Body Location or Region": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Body Location or Region",
        "short": "blor",
        "tui": "T029",
    },
    "Body Part, Organ, or Organ Component": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Body Part, Organ, or Organ Component",
        "short": "bpoc",
        "tui": "T023",
    },
    "Body Space or Junction": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Body Space or Junction",
        "short": "bsoj",
        "tui": "T030",
    },
    "Body Substance": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Body Substance",
        "short": "bdsu",
        "tui": "T031",
    },
    "Body System": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Body System",
        "short": "bdsy",
        "tui": "T022",
    },
    "Carbohydrate": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Carbohydrate",
        "short": "carb",
        "tui": "T118",
    },
    "Carbohydrate Sequence": {
        "groups": [("GENE", "Genes & Molecular Sequences")],
        "long": "Carbohydrate Sequence",
        "short": "crbs",
        "tui": "T088",
    },
    "Cell": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Cell",
        "short": "cell",
        "tui": "T025",
    },
    "Cell Component": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Cell Component",
        "short": "celc",
        "tui": "T026",
    },
    "Cell Function": {
        "groups": [("PHYS", "Physiology")],
        "long": "Cell Function",
        "short": "celf",
        "tui": "T043",
    },
    "Cell or Molecular Dysfunction": {
        "groups": [("DISO", "Disorders")],
        "long": "Cell or Molecular Dysfunction",
        "short": "comd",
        "tui": "T049",
    },
    "Chemical": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Chemical",
        "short": "chem",
        "tui": "T103",
    },
    "Chemical Viewed Functionally": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Chemical Viewed Functionally",
        "short": "chvf",
        "tui": "T120",
    },
    "Chemical Viewed Structurally": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Chemical Viewed Structurally",
        "short": "chvs",
        "tui": "T104",
    },
    "Classification": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Classification",
        "short": "clas",
        "tui": "T185",
    },
    "Clinical Attribute": {
        "groups": [("PHYS", "Physiology")],
        "long": "Clinical Attribute",
        "short": "clna",
        "tui": "T201",
    },
    "Clinical Drug": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Clinical Drug",
        "short": "clnd",
        "tui": "T200",
    },
    "Conceptual Entity": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Conceptual Entity",
        "short": "cnce",
        "tui": "T077",
    },
    "Congenital Abnormality": {
        "groups": [("DISO", "Disorders")],
        "long": "Congenital Abnormality",
        "short": "cgab",
        "tui": "T019",
    },
    "Daily or Recreational Activity": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Daily or Recreational Activity",
        "short": "dora",
        "tui": "T056",
    },
    "Diagnostic Procedure": {
        "groups": [("PROC", "Procedures")],
        "long": "Diagnostic Procedure",
        "short": "diap",
        "tui": "T060",
    },
    "Disease or Syndrome": {
        "groups": [("DISO", "Disorders")],
        "long": "Disease or Syndrome",
        "short": "dsyn",
        "tui": "T047",
    },
    "Drug Delivery Device": {
        "groups": [("DEVI", "Devices")],
        "long": "Drug Delivery Device",
        "short": "drdd",
        "tui": "T203",
    },
    "Educational Activity": {
        "groups": [("PROC", "Procedures")],
        "long": "Educational Activity",
        "short": "edac",
        "tui": "T065",
    },
    "Eicosanoid": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Eicosanoid",
        "short": "eico",
        "tui": "T111",
    },
    "Element, Ion, or Isotope": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Element, Ion, or Isotope",
        "short": "elii",
        "tui": "T196",
    },
    "Embryonic Structure": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Embryonic Structure",
        "short": "emst",
        "tui": "T018",
    },
    "Entity": {
        "groups": [("OBJC", "Objects")],
        "long": "Entity",
        "short": "enty",
        "tui": "T071",
    },
    "Environmental Effect of Humans": {
        "groups": [("PHEN", "Phenomena")],
        "long": "Environmental Effect of Humans",
        "short": "eehu",
        "tui": "T069",
    },
    "Enzyme": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Enzyme",
        "short": "enzy",
        "tui": "T126",
    },
    "Eukaryote": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Eukaryote",
        "short": "euka",
        "tui": "T204",
    },
    "Event": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Event",
        "short": "evnt",
        "tui": "T051",
    },
    "Experimental Model of Disease": {
        "groups": [("DISO", "Disorders")],
        "long": "Experimental Model of Disease",
        "short": "emod",
        "tui": "T050",
    },
    "Family Group": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Family Group",
        "short": "famg",
        "tui": "T099",
    },
    "Finding": {
        "groups": [("DISO", "Disorders")],
        "long": "Finding",
        "short": "fndg",
        "tui": "T033",
    },
    "Fish": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Fish",
        "short": "fish",
        "tui": "T013",
    },
    "Food": {
        "groups": [("OBJC", "Objects")],
        "long": "Food",
        "short": "food",
        "tui": "T168",
    },
    "Fully Formed Anatomical Structure": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Fully Formed Anatomical Structure",
        "short": "ffas",
        "tui": "T021",
    },
    "Functional Concept": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Functional Concept",
        "short": "ftcn",
        "tui": "T169",
    },
    "Fungus": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Fungus",
        "short": "fngs",
        "tui": "T004",
    },
    "Gene or Genome": {
        "groups": [("GENE", "Genes & Molecular Sequences")],
        "long": "Gene or Genome",
        "short": "gngm",
        "tui": "T028",
    },
    "Genetic Function": {
        "groups": [("PHYS", "Physiology")],
        "long": "Genetic Function",
        "short": "genf",
        "tui": "T045",
    },
    "Geographic Area": {
        "groups": [("GEOG", "Geographic Areas")],
        "long": "Geographic Area",
        "short": "geoa",
        "tui": "T083",
    },
    "Governmental or Regulatory Activity": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Governmental or Regulatory Activity",
        "short": "gora",
        "tui": "T064",
    },
    "Group": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Group",
        "short": "grup",
        "tui": "T096",
    },
    "Group Attribute": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Group Attribute",
        "short": "grpa",
        "tui": "T102",
    },
    "Hazardous or Poisonous Substance": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Hazardous or Poisonous Substance",
        "short": "hops",
        "tui": "T131",
    },
    "Health Care Activity": {
        "groups": [("PROC", "Procedures")],
        "long": "Health Care Activity",
        "short": "hlca",
        "tui": "T058",
    },
    "Health Care Related Organization": {
        "groups": [("ORGA", "Organizations")],
        "long": "Health Care Related Organization",
        "short": "hcro",
        "tui": "T093",
    },
    "Hormone": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Hormone",
        "short": "horm",
        "tui": "T125",
    },
    "Human": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Human",
        "short": "humn",
        "tui": "T016",
    },
    "Human-caused Phenomenon or Process": {
        "groups": [("PHEN", "Phenomena")],
        "long": "Human-caused Phenomenon or Process",
        "short": "hcpp",
        "tui": "T068",
    },
    "Idea or Concept": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Idea or Concept",
        "short": "idcn",
        "tui": "T078",
    },
    "Immunologic Factor": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Immunologic Factor",
        "short": "imft",
        "tui": "T129",
    },
    "Indicator, Reagent, or Diagnostic Aid": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Indicator, Reagent, or Diagnostic Aid",
        "short": "irda",
        "tui": "T130",
    },
    "Individual Behavior": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Individual Behavior",
        "short": "inbe",
        "tui": "T055",
    },
    "Injury or Poisoning": {
        "groups": [("DISO", "Disorders")],
        "long": "Injury or Poisoning",
        "short": "inpo",
        "tui": "T037",
    },
    "Inorganic Chemical": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Inorganic Chemical",
        "short": "inch",
        "tui": "T197",
    },
    "Intellectual Product": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Intellectual Product",
        "short": "inpr",
        "tui": "T170",
    },
    "Laboratory Procedure": {
        "groups": [("PROC", "Procedures")],
        "long": "Laboratory Procedure",
        "short": "lbpr",
        "tui": "T059",
    },
    "Laboratory or Test Result": {
        "groups": [("PHEN", "Phenomena")],
        "long": "Laboratory or Test Result",
        "short": "lbtr",
        "tui": "T034",
    },
    "Language": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Language",
        "short": "lang",
        "tui": "T171",
    },
    "Lipid": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Lipid",
        "short": "lipd",
        "tui": "T119",
    },
    "Machine Activity": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Machine Activity",
        "short": "mcha",
        "tui": "T066",
    },
    "Mammal": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Mammal",
        "short": "mamm",
        "tui": "T015",
    },
    "Manufactured Object": {
        "groups": [("OBJC", "Objects")],
        "long": "Manufactured Object",
        "short": "mnob",
        "tui": "T073",
    },
    "Medical Device": {
        "groups": [("DEVI", "Devices")],
        "long": "Medical Device",
        "short": "medd",
        "tui": "T074",
    },
    "Mental Process": {
        "groups": [("PHYS", "Physiology")],
        "long": "Mental Process",
        "short": "menp",
        "tui": "T041",
    },
    "Mental or Behavioral Dysfunction": {
        "groups": [("DISO", "Disorders")],
        "long": "Mental or Behavioral Dysfunction",
        "short": "mobd",
        "tui": "T048",
    },
    "Molecular Biology Research Technique": {
        "groups": [("PROC", "Procedures")],
        "long": "Molecular Biology Research Technique",
        "short": "mbrt",
        "tui": "T063",
    },
    "Molecular Function": {
        "groups": [("PHYS", "Physiology")],
        "long": "Molecular Function",
        "short": "moft",
        "tui": "T044",
    },
    "Molecular Sequence": {
        "groups": [("GENE", "Genes & Molecular Sequences")],
        "long": "Molecular Sequence",
        "short": "mosq",
        "tui": "T085",
    },
    "Natural Phenomenon or Process": {
        "groups": [("PHEN", "Phenomena")],
        "long": "Natural Phenomenon or Process",
        "short": "npop",
        "tui": "T070",
    },
    "Neoplastic Process": {
        "groups": [("DISO", "Disorders")],
        "long": "Neoplastic Process",
        "short": "neop",
        "tui": "T191",
    },
    "Neuroreactive Substance or Biogenic Amine": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Neuroreactive Substance or Biogenic Amine",
        "short": "nsba",
        "tui": "T124",
    },
    "Nucleic Acid, Nucleoside, or Nucleotide": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Nucleic Acid, Nucleoside, or Nucleotide",
        "short": "nnon",
        "tui": "T114",
    },
    "Nucleotide Sequence": {
        "groups": [("GENE", "Genes & Molecular Sequences")],
        "long": "Nucleotide Sequence",
        "short": "nusq",
        "tui": "T086",
    },
    "Occupation or Discipline": {
        "groups": [("OCCU", "Occupations")],
        "long": "Occupation or Discipline",
        "short": "ocdi",
        "tui": "T090",
    },
    "Occupational Activity": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Occupational Activity",
        "short": "ocac",
        "tui": "T057",
    },
    "Organ or Tissue Function": {
        "groups": [("PHYS", "Physiology")],
        "long": "Organ or Tissue Function",
        "short": "ortf",
        "tui": "T042",
    },
    "Organic Chemical": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Organic Chemical",
        "short": "orch",
        "tui": "T109",
    },
    "Organism": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Organism",
        "short": "orgm",
        "tui": "T001",
    },
    "Organism Attribute": {
        "groups": [("PHYS", "Physiology")],
        "long": "Organism Attribute",
        "short": "orga",
        "tui": "T032",
    },
    "Organism Function": {
        "groups": [("PHYS", "Physiology")],
        "long": "Organism Function",
        "short": "orgf",
        "tui": "T040",
    },
    "Organization": {
        "groups": [("ORGA", "Organizations")],
        "long": "Organization",
        "short": "orgt",
        "tui": "T092",
    },
    "Organophosphorus Compound": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Organophosphorus Compound",
        "short": "opco",
        "tui": "T115",
    },
    "Pathologic Function": {
        "groups": [("DISO", "Disorders")],
        "long": "Pathologic Function",
        "short": "patf",
        "tui": "T046",
    },
    "Patient or Disabled Group": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Patient or Disabled Group",
        "short": "podg",
        "tui": "T101",
    },
    "Pharmacologic Substance": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Pharmacologic Substance",
        "short": "phsu",
        "tui": "T121",
    },
    "Phenomenon or Process": {
        "groups": [("PHEN", "Phenomena")],
        "long": "Phenomenon or Process",
        "short": "phpr",
        "tui": "T067",
    },
    "Physical Object": {
        "groups": [("OBJC", "Objects")],
        "long": "Physical Object",
        "short": "phob",
        "tui": "T072",
    },
    "Physiologic Function": {
        "groups": [("PHYS", "Physiology")],
        "long": "Physiologic Function",
        "short": "phsf",
        "tui": "T039",
    },
    "Plant": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Plant",
        "short": "plnt",
        "tui": "T002",
    },
    "Population Group": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Population Group",
        "short": "popg",
        "tui": "T098",
    },
    "Professional Society": {
        "groups": [("ORGA", "Organizations")],
        "long": "Professional Society",
        "short": "pros",
        "tui": "T094",
    },
    "Professional or Occupational Group": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Professional or Occupational Group",
        "short": "prog",
        "tui": "T097",
    },
    "Qualitative Concept": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Qualitative Concept",
        "short": "qlco",
        "tui": "T080",
    },
    "Quantitative Concept": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Quantitative Concept",
        "short": "qnco",
        "tui": "T081",
    },
    "Receptor": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Receptor",
        "short": "rcpt",
        "tui": "T192",
    },
    "Regulation or Law": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Regulation or Law",
        "short": "rnlw",
        "tui": "T089",
    },
    "Reptile": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Reptile",
        "short": "rept",
        "tui": "T014",
    },
    "Research Activity": {
        "groups": [("PROC", "Procedures")],
        "long": "Research Activity",
        "short": "resa",
        "tui": "T062",
    },
    "Research Device": {
        "groups": [("DEVI", "Devices")],
        "long": "Research Device",
        "short": "resd",
        "tui": "T075",
    },
    "Self-help or Relief Organization": {
        "groups": [("ORGA", "Organizations")],
        "long": "Self-help or Relief Organization",
        "short": "shro",
        "tui": "T095",
    },
    "Sign or Symptom": {
        "groups": [("DISO", "Disorders")],
        "long": "Sign or Symptom",
        "short": "sosy",
        "tui": "T184",
    },
    "Social Behavior": {
        "groups": [("ACTI", "Activities & Behaviors")],
        "long": "Social Behavior",
        "short": "socb",
        "tui": "T054",
    },
    "Spatial Concept": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Spatial Concept",
        "short": "spco",
        "tui": "T082",
    },
    "Steroid": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Steroid",
        "short": "strd",
        "tui": "T110",
    },
    "Substance": {
        "groups": [("OBJC", "Objects")],
        "long": "Substance",
        "short": "sbst",
        "tui": "T167",
    },
    "Temporal Concept": {
        "groups": [("CONC", "Concepts & Ideas")],
        "long": "Temporal Concept",
        "short": "tmco",
        "tui": "T079",
    },
    "Therapeutic or Preventive Procedure": {
        "groups": [("PROC", "Procedures")],
        "long": "Therapeutic or Preventive Procedure",
        "short": "topp",
        "tui": "T061",
    },
    "Tissue": {
        "groups": [("ANAT", "Anatomy")],
        "long": "Tissue",
        "short": "tisu",
        "tui": "T024",
    },
    "Vertebrate": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Vertebrate",
        "short": "vtbt",
        "tui": "T010",
    },
    "Virus": {
        "groups": [("LIVB", "Living Beings")],
        "long": "Virus",
        "short": "virs",
        "tui": "T005",
    },
    "Vitamin": {
        "groups": [("CHEM", "Chemicals & Drugs")],
        "long": "Vitamin",
        "short": "vita",
        "tui": "T127",
    },
}

# Create a short form mapping dict from the long forms
short_semantic_mappings = {}
for k, v in semantic_mappings.items():
    short_semantic_mappings[v["short"]] = v


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def get_sty_from_short(short):
    """
    Helper function to return a Sty object from a short form
    """
    data = short_semantic_mappings[short]

    return Sty(
        data["tui"],
        term=data["long"],
        short=data["short"],
        groups=data["groups"],
    )


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def get_sty_from_long(long):
    """
    Helper function to return a Sty object from a long form
    """
    data = semantic_mappings[long]

    return Sty(
        data["tui"],
        term=data["long"],
        short=data["short"],
        groups=data["groups"],
    )


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class Sty(object):
    """
    A class representing a semantic type
    """

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __init__(self, tui, term="", short="", groups=None):
        """Initialise a semantic type object.

        Parameters
        ----------
        tui : `str`
            The UMLS semantic type identifier.
        term : `str`, optional, default: ``""``
            The semantic type long description.
        short : `str`, optional, default: ``""``
            The semantic type short code.
        groups : `list` or `NoneType`, optional, default: `NoneType`
            Semantic groups associated with this semantic type.
        """
        if groups is None:
            groups = []

        self.tui = tui
        self.term = term
        self.short = short
        self.groups = groups

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __eq__(self, other):
        """Compare semantic type identity by ``tui``.

        Parameters
        ----------
        other : `object`
            Object to compare with this instance.

        Returns
        -------
        result : `bool` or `NotImplementedType`
            ``True`` when both instances share the same ``tui``. Returns
            ``NotImplemented`` for non-``Sty`` objects.
        """
        if not isinstance(other, Sty):
            return NotImplemented
        return self.tui == other.tui

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __hash__(self):
        """Hash semantic type identity.

        Returns
        -------
        value : `int`
            Hash based on the immutable ``tui`` identity used by ``__eq__``.
        """
        return hash(self.tui)

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return (
            "<{0}(tui='{1}',term='{2}',short='{3}', "
            "no_of_groups='{4}')>".format(
                self.__class__.__name__,
                self.tui,
                self.term,
                self.short,
                len(self.groups),
            )
        )


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class Cui(object):
    """
    A class representing a CUI from UMLS, i.e. an Entry in MRCONSO
    """

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __init__(
        self,
        cui,
        term="",
        pref_term=None,
        sabs=None,
        tty="",
        suppress="",
        stys=None,
    ):
        """Initialise a UMLS concept identifier object.

        Parameters
        ----------
        cui : `str`
            The UMLS concept identifier.
        term : `str`, optional, default: ``""``
            The concept term.
        pref_term : `str` or `NoneType`, optional, default: `NoneType`
            Preferred concept term. When ``None``, falls back to ``term``.
        sabs : `list` or `NoneType`, optional, default: `NoneType`
            Source vocabularies for this concept.
        tty : `str`, optional, default: ``""``
            Term type.
        suppress : `str`, optional, default: ``""``
            Suppression flag.
        stys : `list` or `NoneType`, optional, default: `NoneType`
            Semantic types linked to the concept.
        """
        if sabs is None:
            sabs = []
        if stys is None:
            stys = []

        self.cui = cui
        self.term = term
        self.pref_term = pref_term or self.term
        self.sabs = sabs
        self.tty = tty
        self.suppress = suppress
        self.stys = stys

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __eq__(self, other):
        """Compare CUI identity by ``cui``.

        Parameters
        ----------
        other : `object`
            Object to compare with this instance.

        Returns
        -------
        result : `bool` or `NotImplementedType`
            ``True`` when both instances share the same ``cui``. Returns
            ``NotImplemented`` for non-``Cui`` objects.
        """
        if not isinstance(other, Cui):
            return NotImplemented
        return self.cui == other.cui

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __hash__(self):
        """Hash concept identity.

        Returns
        -------
        value : `int`
            Hash based on the immutable ``cui`` identity used by ``__eq__``.
        """
        return hash(self.cui)

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return (
            "<{0}(cui='{1}',term='{2}',pref_term='{3}', tty='{4}',"
            " suppress='{5}', no_of_sabs='{6}',"
            " no_of_stys='{7}')>".format(
                self.__class__.__name__,
                self.cui,
                self.term,
                self.pref_term,
                self.tty,
                self.suppress,
                len(self.sabs),
                len(self.stys),
            )
        )


# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
class Sab(object):
    """
    A class representing an SAB from UMLS
    """

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __init__(self, sab):
        self.sab = sab

        # Will eventually get the long format

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __eq__(self, other):
        """Compare source vocabulary identity by ``sab``.

        Parameters
        ----------
        other : `object`
            Object to compare with this instance.

        Returns
        -------
        result : `bool` or `NotImplementedType`
            ``True`` when both instances share the same ``sab``. Returns
            ``NotImplemented`` for non-``Sab`` objects.
        """
        if not isinstance(other, Sab):
            return NotImplemented
        return self.sab == other.sab

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __hash__(self):
        """Hash source vocabulary identity.

        Returns
        -------
        value : `int`
            Hash based on the immutable ``sab`` identity used by ``__eq__``.
        """
        return hash(self.sab)

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def __repr__(self):
        return "<{0}(sab='{1}')>".format(self.__class__.__name__, self.sab)
