def adiponectin_levels(genome): """Adiponectin levels.""" if genome.ethnicity == "asian": r = unphased_match( genome.rs1851665, { "AA": "Slightly lower, which may be bad (rs1851665)\n", "AG": "Typical (rs1851665)\n", "GG": "Slightly higher, which is good (rs1851665)\n", None: "Unable to determine for rs1851665\n" }) r += unphased_match( genome.rs7193788, { "AA": "Slightly higher, which is good (rs7193788)", "AG": "Typical (rs7193788)", "GG": "Slightly lower, which may be bad (rs7193788)", None: "Unable to determine for rs7193788" }) return r elif genome.ethnicity in [None, "european"]: return unphased_match( genome.rs6444175, { "AA": "Lower, which may be bad", "AG": "Slightly lower, which may be bad", "GG": "Typical levels", None: "Unable to determine" })
def adiponectin_levels(genome): """Adiponectin levels.""" if genome.ethnicity == "asian": r = unphased_match( genome.rs1851665, { "AA": "Slightly lower, which may be bad (rs1851665)\n", "AG": "Typical (rs1851665)\n", "GG": "Slightly higher, which is good (rs1851665)\n", None: "Unable to determine for rs1851665\n", }, ) r += unphased_match( genome.rs7193788, { "AA": "Slightly higher, which is good (rs7193788)", "AG": "Typical (rs7193788)", "GG": "Slightly lower, which may be bad (rs7193788)", None: "Unable to determine for rs7193788", }, ) return r elif genome.ethnicity in [None, "european"]: return unphased_match( genome.rs6444175, { "AA": "Lower, which may be bad", "AG": "Slightly lower, which may be bad", "GG": "Typical levels", None: "Unable to determine", }, )
def exfoliation_glaucoma(genome): """Exfoliation glaucoma.""" assert_european(genome) OR = unphased_match(genome.rs2165241, { "CT": 0.79, }) raise NotImplementedError()
def stroke(genome): """Stroke.""" return unphased_match(genome.rs12425791, { "AA": "Moderately increased risk of having a stroke", "AG": "Slightly increased risk of having a stroke", "GG": "Typical risk of having a stroke", None: "Unable to determine"})
def caffeine_metabolism(genome): """Caffeine metabolism.""" assert_european(genome) return unphased_match( genome.rs762551, {"AA": "Fast metabolizer", "AC": "Slow metabolizer", "CC": "Slow metabolizer", None: "Unable to determine"}, )
def biological_age(genome): """Biological aging (telomere lengths).""" assert_european(genome) ages = { "rs10936599": {"TT": 7.82, "CT": 3.91, "CC": 0, None: 0}, "rs2736100": {"AA": 3.14, "AC": 0, "CC": -3.14, None: 0}, "rs9420907": {"AA": 0, "AC": -2.76, "CC": -5.52, None: 0}, "rs755017": {"AA": 0, "AG": -2.47, "GG": -4.94, None: 0}, "rs11100479": {"CC": 5.98, "CT": -2.99, "TT": 0, None: 0}, "rs10165485": {"TT": 0, "CT": -2.23, "CC": -4.46, None: 0}, } age = [unphased_match(genome[rsid], t) for (rsid, t) in ages.items()] def qual(age): if age <= 0: return "younger" elif age > 0: return "older" msg = "From %.1f years %s to %.1f years %s than actual age\n" % ( abs(min(age)), qual(min(age)), abs(max(age)), qual(max(age)), ) msg += "The sum is %.1f years %s, compared to actual age" % (abs(sum(age)), qual(sum(age))) return msg
def hiv_aids_resistance(genome): """Resistance to HIV/AIDS.""" return unphased_match( genome.i3003626, { "DD": "Some resistance to most common strain of HIV", "DI": "Not resistant, but may have slower disease progression", "II": "Not resistant" })
def hair_curl(genome): assert_european(genome) return unphased_match( genome.rs17646946, { "AA": "Straighter hair on average", "AG": "Straighter hair on average", "GG": "Slightly curlier hair on average" })
def pain_sensitivity(genome): """Pain sensitivity.""" return unphased_match( genome.rs6269, { "AA": "Increased sensitivity to pain", "AG": "Typical sensitivity to pain", "GG": "Less sensitive to pain", None: "Unable to determine" })
def blond_vs_brown_hair(genome): """Hair color; blond versus brown.""" return unphased_match( genome.rs1667394, { "CC": "Greatly decreased odds of having blond hair vs. brown", "CT": "Decreased odds of having blond hair vs. brown", "TT": "Typical odds of having blond hair vs. brown hair", None: "Unable to determine" })
def red_hair(genome): """Hair color; odds for red hair.""" return unphased_match( genome.rs1805007, { "CC": "Typical odds for red hair", "CT": "Substantially increased odds for red hair", "TT": "Greatly increased odds for red hair", None: "Unable to determine" })
def bitter_taste(genome): "Bitter taste perception." return unphased_match( genome.rs713598, { "CC": "Probably can't taste certain bitter flavours", "CG": "Can taste bitter flavours that others can't", "GG": "Can taste bitter flavours that others can't", None: "Unable to determine" })
def earwax_type(genome): "Earwax type." return unphased_match( genome.rs17822931, { "CC": "Wet earwax (sticky, honey-colored)", "CT": "Wet earwax (sticky, honey-colored)", "TT": "Dry earwax (flaky, pale)", None: "Unable to determine" })
def malaria_resistance(genome): "Malaria resistance (Duffy antigen)." return unphased_match( genome.rs2814778, { "CC": "Likely resistant to P. vivax", "CT": "Likely to have some resistance to P. vivax", "TT": "Likely not resistant to P. vivax", None: "Unable to determine" })
def alcohol_flush_reaction(genome): "Alcohol flush reaction." return unphased_match( genome.rs671, { "AA": "Extreme reaction (no copies of the ALDH2 gene)", "AG": "Moderate reaction (one copy of the ALDH2 gene)", "GG": "Little to no reaction (two copies of the ALDH2 gene)", None: "Unable to determine" })
def lactose_intolerance(genome): "Lactose intolerance." return unphased_match( genome.rs4988235, { "AA": "Likely lactose tolerant", "AG": "Likely lactose tolerant", "GG": "Likely lactose intolerant", None: "Unable to determine" })
def birth_weight(genome): """Birth weight.""" assert_european(genome) weights = { "rs7903146": {"TT": 0, "CT": -30, "CC": -60, None: 0}, "rs1799884": {"TT": +54, "CT": +27, "CC": 0, None: 0}, } weight = [unphased_match(genome[rsid], w) for (rsid, w) in weights.items()] return "From %.1fg to %.1fg (sum: %.1fg) compared to typical weight" % (min(weight), max(weight), sum(weight))
def norovirus_resistance(genome): """Norovirus resistance (most common strain).""" return unphased_match( genome.rs601338, { "AA": "Resistant to most common strain", "AG": "Likely not resistant to most common strain", "GG": "Likely not resistant to most common strain", None: "Unable to determine" })
def biological_age(genome): """Biological aging (telomere lengths).""" assert_european(genome) ages = { "rs10936599": { "TT": 7.82, "CT": 3.91, "CC": 0, None: 0 }, "rs2736100": { "AA": 3.14, "AC": 0, "CC": -3.14, None: 0 }, "rs9420907": { "AA": 0, "AC": -2.76, "CC": -5.52, None: 0 }, "rs755017": { "AA": 0, "AG": -2.47, "GG": -4.94, None: 0 }, "rs11100479": { "CC": 5.98, "CT": -2.99, "TT": 0, None: 0 }, "rs10165485": { "TT": 0, "CT": -2.23, "CC": -4.46, None: 0 }, } age = [unphased_match(genome[rsid], t) for (rsid, t) in ages.items()] def qual(age): if age <= 0: return "younger" elif age > 0: return "older" msg = "From %.1f years %s to %.1f years %s than actual age\n" % (abs( min(age)), qual(min(age)), abs(max(age)), qual(max(age))) msg += "The sum is %.1f years %s, compared to actual age" % (abs( sum(age)), qual(sum(age))) return msg
def smoking_behaviour(genome): """Smoking behaviour.""" assert_european(genome) return unphased_match( genome.rs1051730, { "AA": "Likely to smoke more than average", "AG": "Likely to smoke a little bit more than average", "GG": "Likely to smoke typical amount of cigarettes per day", None: "Unable to determine" })
def muscle_performance(genome): """Muscle performance.""" return unphased_match( genome.rs1815739, { "CC": "Likely sprinter, perhaps endurance athlete (two copies)", "CT": "Likely sprinter, perhaps endurance athlete (one copy)", "TT": "Unlikely sprinter, but likely endurance athlete (no copies)", None: "Unable to determine" })
def hair_curl(genome): assert_european(genome) return unphased_match( genome.rs17646946, { "AA": "Straighter hair on average", "AG": "Straighter hair on average", "GG": "Slightly curlier hair on average", }, )
def hiv_aids_resistance(genome): """Resistance to HIV/AIDS.""" return unphased_match( genome.i3003626, { "DD": "Some resistance to most common strain of HIV", "DI": "Not resistant, but may have slower disease progression", "II": "Not resistant", }, )
def caffeine_metabolism(genome): """Caffeine metabolism.""" assert_european(genome) return unphased_match( genome.rs762551, { "AA": "Fast metabolizer", "AC": "Slow metabolizer", "CC": "Slow metabolizer", None: "Unable to determine" })
def blood_glucose(genome): """Blood glucose.""" assert_european(genome) return unphased_match( genome.rs560887, { "CC": "Average fasting plasma glucose levels of 5.18mmol/L", "CT": "Average fasting plasma glucose levels of 5.12mmol/L", "TT": "Average fasting plasma glucose levels of 5.06mmol/L", None: "Unable to determine" })
def aspargus_detection(genome): """Aspargus metabolite detection.""" assert_european(genome) return unphased_match( genome.rs4481887, { "AA": "Higher odds of smelling aspargus in urine", "AG": "Medium odds of smelling aspargus in urine", "GG": "Typical odds of smelling aspargus in urine", None: "Unable to determine" })
def heroin_addiction(genome): """Heroin addiction.""" assert_european(genome) return unphased_match( genome.rs1799971, { "AA": "Typical odds of addiction", "AG": "Higher odds of addiction", "GG": "Higher odds of addiction", None: "Unable to determine" })
def eye_color(genome): "Eye color." assert_european(genome) return unphased_match( genome.rs12913832, { "AA": "Brown eyes, although 14% have green and 1% have blue", "AG": "Most likely brown or green, but 7% have blue", "GG": "Most likely blue, but 30% have green and 1% brown", None: "Unable to determine" })
def pain_sensitivity(genome): """Pain sensitivity.""" return unphased_match( genome.rs6269, { "AA": "Increased sensitivity to pain", "AG": "Typical sensitivity to pain", "GG": "Less sensitive to pain", None: "Unable to determine", }, )
def blond_vs_brown_hair(genome): """Hair color; blond versus brown.""" return unphased_match( genome.rs1667394, { "CC": "Greatly decreased odds of having blond hair vs. brown", "CT": "Decreased odds of having blond hair vs. brown", "TT": "Typical odds of having blond hair vs. brown hair", None: "Unable to determine", }, )
def bitter_taste(genome): "Bitter taste perception." return unphased_match( genome.rs713598, { "CC": "Probably can't taste certain bitter flavours", "CG": "Can taste bitter flavours that others can't", "GG": "Can taste bitter flavours that others can't", None: "Unable to determine", }, )
def red_hair(genome): """Hair color; odds for red hair.""" return unphased_match( genome.rs1805007, { "CC": "Typical odds for red hair", "CT": "Substantially increased odds for red hair", "TT": "Greatly increased odds for red hair", None: "Unable to determine", }, )
def muscle_performance(genome): """Muscle performance.""" return unphased_match( genome.rs1815739, { "CC": "Likely sprinter, perhaps endurance athlete (two copies)", "CT": "Likely sprinter, perhaps endurance athlete (one copy)", "TT": "Unlikely sprinter, but likely endurance athlete (no copies)", None: "Unable to determine", }, )
def alcohol_flush_reaction(genome): "Alcohol flush reaction." return unphased_match( genome.rs671, { "AA": "Extreme reaction (no copies of the ALDH2 gene)", "AG": "Moderate reaction (one copy of the ALDH2 gene)", "GG": "Little to no reaction (two copies of the ALDH2 gene)", None: "Unable to determine", }, )
def malaria_resistance(genome): "Malaria resistance (Duffy antigen)." return unphased_match( genome.rs2814778, { "CC": "Likely resistant to P. vivax", "CT": "Likely to have some resistance to P. vivax", "TT": "Likely not resistant to P. vivax", None: "Unable to determine", }, )
def lactose_intolerance(genome): "Lactose intolerance." return unphased_match( genome.rs4988235, { "AA": "Likely lactose tolerant", "AG": "Likely lactose tolerant", "GG": "Likely lactose intolerant", None: "Unable to determine", }, )
def norovirus_resistance(genome): """Norovirus resistance (most common strain).""" return unphased_match( genome.rs601338, { "AA": "Resistant to most common strain", "AG": "Likely not resistant to most common strain", "GG": "Likely not resistant to most common strain", None: "Unable to determine", }, )
def earwax_type(genome): "Earwax type." return unphased_match( genome.rs17822931, { "CC": "Wet earwax (sticky, honey-colored)", "CT": "Wet earwax (sticky, honey-colored)", "TT": "Dry earwax (flaky, pale)", None: "Unable to determine", }, )
def eye_color(genome): "Eye color." assert_european(genome) return unphased_match( genome.rs12913832, { "AA": "Brown eyes, although 14% have green and 1% have blue", "AG": "Most likely brown or green, but 7% have blue", "GG": "Most likely blue, but 30% have green and 1% brown", None: "Unable to determine", }, )
def blood_glucose(genome): """Blood glucose.""" assert_european(genome) return unphased_match( genome.rs560887, { "CC": "Average fasting plasma glucose levels of 5.18mmol/L", "CT": "Average fasting plasma glucose levels of 5.12mmol/L", "TT": "Average fasting plasma glucose levels of 5.06mmol/L", None: "Unable to determine", }, )
def heroin_addiction(genome): """Heroin addiction.""" assert_european(genome) return unphased_match( genome.rs1799971, { "AA": "Typical odds of addiction", "AG": "Higher odds of addiction", "GG": "Higher odds of addiction", None: "Unable to determine", }, )
def aspargus_detection(genome): """Aspargus metabolite detection.""" assert_european(genome) return unphased_match( genome.rs4481887, { "AA": "Higher odds of smelling aspargus in urine", "AG": "Medium odds of smelling aspargus in urine", "GG": "Typical odds of smelling aspargus in urine", None: "Unable to determine", }, )
def breast_cancer(genome): """Breast cancer.""" if not genome.female: raise ValueError("Only applicable for females") s = [] s.append(unphased_match(genome.rs1219648, { "AA": "Typical odds", "AG": "Slightly higher odds", "GG": "Moderately higher odds", None: "Unable to determine (see rs2420946 instead)"})) s.append(unphased_match(genome.rs3803662, { "AA": "Moderately increased odds", "AG": "?", "GG": "Typical odds", None: "Unable to determine"})) s.append("Note: There are MANY more SNPs to test here...") # TODO: Add remaining SNPs return "\n".join(s)
def smoking_behaviour(genome): """Smoking behaviour.""" assert_european(genome) return unphased_match( genome.rs1051730, { "AA": "Likely to smoke more than average", "AG": "Likely to smoke a little bit more than average", "GG": "Likely to smoke typical amount of cigarettes per day", None: "Unable to determine", }, )
def migraines(genome): """Migranes.""" assert_european(genome) s = [] s.append(unphased_match(genome.rs2651899, { "CC": "Slightly higher odds of migraines", "CT": "Typical odds of migraines", "TT": "Slightly lower odds of migraines", None: "Unable to determine"})) s.append(unphased_match(genome.rs10166942, { "TT": "Typical odds of migraines", "CT": "Slightly lower odds of migraines", "CC": "Slightly lower odds of migraines", None: "Unable to determine"})) s.append(unphased_match(genome.rs11172113, { "TT": "Slightly higher odds of migraines", "CT": "Typical odds of migraines", "CC": "Slightly lower odds of migraines", None: "Unable to determine"})) return "\n".join(s)
def birth_weight(genome): """Birth weight.""" assert_european(genome) weights = { "rs7903146": { "TT": 0, "CT": -30, "CC": -60, None: 0 }, "rs1799884": { "TT": +54, "CT": +27, "CC": 0, None: 0 }, } weight = [unphased_match(genome[rsid], w) for (rsid, w) in weights.items()] return "From %.1fg to %.1fg (sum: %.1fg) compared to typical weight" % ( min(weight), max(weight), sum(weight))
def hypothyroidism(genome): """Hypothyroidism. Studies: http://dx.doi.org/10.1371/journal.pone.0034442 """ if genome.ethnicity is not None and genome.ethnicity != "european": raise ValueError("Only applicable to Europeans") # TODO: Use a better score metric and use weighting and ORs. # TODO: Try to use interval arithmetic as well, for fun. scores = { "rs7850258": {"GG": 0.5, "AG": 0, "AA": -0.5, None: 0}, "rs2476601": {"GG": 1, "AG": 0.5, "AA": 0, None: 0}, "rs3184504": {"TT": 0.5, "CT": 0, "CC": -0.5, None: 0}, "rs4915077": {"CC": 1, "CT": 0.5, "TT": 0, None: 0}, "rs2517532": {"GG": 0.5, "AG": 0, "AA": -0.5, None: 0}, } hi = sum(map(lambda l: max(l.values()), scores.values())) lo = sum(map(lambda l: min(l.values()), scores.values())) score = 0.0 for rsid, genotypes in scores.items(): score += unphased_match(genome[rsid], genotypes) if score > 0: s = "About %.1f%% higher risk than baseline\n" % (100.0*score/hi) s += "(%.1f vs %.1f of %.1f points)\n" % (score, lo, hi) s += "Test is unweighted, see 23andMe for more info" return s elif score < 0: s = "About %.1f%% lower risk than baseline\n" % 100.0*score/lo s += "(%.1f vs %.1f of %.1f points)\n" % (score, lo, hi) s += "Test is unweighted, see 23andMe for more info" return s else: return "Typical risk"