1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
// Copyright ©2011-2012 The bíogo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package alphabet
import (
"fmt"
"math"
"gopkg.in/check.v1"
)
type approxChecker struct {
*check.CheckerInfo
}
var approx check.Checker = &approxChecker{
&check.CheckerInfo{Name: "Approx", Params: []string{"obtained", "expected", "epsilon"}},
}
func (checker *approxChecker) Check(params []interface{}, names []string) (result bool, error string) {
defer func() {
if v := recover(); v != nil {
result = false
error = fmt.Sprint(v)
}
}()
return math.Abs(params[0].(float64)-params[1].(float64)) <= params[2].(float64)*params[1].(float64), ""
}
// Tests
func (s *S) TestPhred(c *check.C) {
// Confirm landmarks.
for _, t := range []struct {
E float64
Q Qphred
}{
{E: 1e-1, Q: 10},
{E: 1e-2, Q: 20},
{E: 1e-3, Q: 30},
{E: 1e-4, Q: 40},
{E: 1e-5, Q: 50},
} {
c.Check(Ephred(t.E), check.Equals, t.Q)
c.Check(t.Q.ProbE(), check.Equals, t.E)
}
for q := Qphred(0); q < 254; q++ {
c.Check(q.ProbE(), check.Equals, math.Pow(10, -(float64(q)/10)))
c.Check(Ephred(q.ProbE()), check.Equals, q)
}
c.Check(Qphred(254).ProbE(), check.Equals, 0.)
c.Check(math.IsNaN(Qphred(255).ProbE()), check.Equals, true)
}
func (s *S) TestSolexa(c *check.C) {
// Confirm landmarks.
for _, t := range []struct {
E float64
Q Qsolexa
}{
{E: 1e-1 / (1 + 1e-1), Q: 10},
{E: 1e-2 / (1 + 1e-2), Q: 20},
{E: 1e-3 / (1 + 1e-3), Q: 30},
{E: 1e-4 / (1 + 1e-4), Q: 40},
{E: 1e-5 / (1 + 1e-5), Q: 50},
} {
c.Check(Esolexa(t.E), check.Equals, t.Q)
c.Check(t.Q.ProbE(), approx, t.E, 1e-15)
}
c.Check(math.IsNaN(Qsolexa(-128).ProbE()), check.Equals, true)
for q := -127; q < 127; q++ {
pq := math.Pow(10, -(float64(q) / 10))
pq /= (1 + pq)
c.Check(Qsolexa(q).ProbE(), check.Equals, pq)
c.Check(Esolexa(Qsolexa(q).ProbE()), check.Equals, Qsolexa(q))
}
c.Check(Qsolexa(127).ProbE(), check.Equals, 0.)
}
func (s *S) TestInterconversion(c *check.C) {
for q := 0; q < 127; q++ {
if 10 <= q && q < 127 {
c.Check(Qphred(q).Qsolexa().Qphred(), check.Equals, Qphred(q))
c.Check(Qsolexa(q).Qphred().Qsolexa(), check.Equals, Qsolexa(q))
}
c.Check(Qphred(q).Qsolexa().ProbE(), approx, Qphred(q).ProbE(), math.Pow(10, 1e-4-float64(q)/10),
check.Commentf("Test %d at E = %e", q, Qphred(q).ProbE()))
c.Check(Qsolexa(q).Qphred().ProbE(), approx, Qsolexa(q).ProbE(), math.Pow(10, 1e-4-float64(q)/10),
check.Commentf("Test %d at E = %e", q, Qsolexa(q).ProbE()))
}
}
|