コード例 #1
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
            })
コード例 #2
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
            },
        )
コード例 #3
0
ファイル: health.py プロジェクト: WeHaveNoLife/dna-traits
def exfoliation_glaucoma(genome):
    """Exfoliation glaucoma."""
    assert_european(genome)
    OR = unphased_match(genome.rs2165241, {
        "CT": 0.79,
        })
    raise NotImplementedError()
コード例 #4
0
ファイル: health.py プロジェクト: WeHaveNoLife/dna-traits
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"})
コード例 #5
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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"},
    )
コード例 #6
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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
コード例 #7
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #8
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #9
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #10
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #11
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #12
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #13
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #14
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #15
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #16
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #17
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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))
コード例 #18
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #19
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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
コード例 #20
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #21
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #22
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #23
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #24
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #25
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #26
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #27
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #28
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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"
        })
コード例 #29
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #30
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #31
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #32
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #33
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #34
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #35
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #36
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #37
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #38
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #39
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #40
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #41
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #42
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #43
0
ファイル: health.py プロジェクト: WeHaveNoLife/dna-traits
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)
コード例 #44
0
ファイル: traits.py プロジェクト: WeHaveNoLife/dna-traits
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",
        },
    )
コード例 #45
0
ファイル: health.py プロジェクト: WeHaveNoLife/dna-traits
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)
コード例 #46
0
ファイル: traits.py プロジェクト: OasisYE/dna-traits
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))
コード例 #47
0
ファイル: health.py プロジェクト: WeHaveNoLife/dna-traits
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"