Merge branch '20753-fix-missing-columns'
[lightning.git] / pipeline_test.go
1 // Copyright (C) The Lightning Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package lightning
6
7 import (
8         "bytes"
9         "fmt"
10         "io"
11         "io/ioutil"
12         "os"
13         "sort"
14         "strings"
15         "sync"
16
17         "gopkg.in/check.v1"
18 )
19
20 type pipelineSuite struct{}
21
22 var _ = check.Suite(&pipelineSuite{})
23
24 func (s *pipelineSuite) TestImport(c *check.C) {
25         for _, infile := range []string{
26                 "testdata/pipeline1/",
27                 "testdata/ref.fasta",
28         } {
29                 c.Logf("TestImport: %s", infile)
30                 var wg sync.WaitGroup
31
32                 statsin, importout := io.Pipe()
33                 wg.Add(1)
34                 go func() {
35                         defer wg.Done()
36                         code := (&importer{}).RunCommand("lightning import", []string{"-local=true", "-skip-ooo=true", "-output-tiles", "-tag-library", "testdata/tags", infile}, bytes.NewReader(nil), importout, os.Stderr)
37                         c.Check(code, check.Equals, 0)
38                         importout.Close()
39                 }()
40                 statsout := &bytes.Buffer{}
41                 wg.Add(1)
42                 go func() {
43                         defer wg.Done()
44                         code := (&statscmd{}).RunCommand("lightning stats", []string{"-local"}, statsin, statsout, os.Stderr)
45                         c.Check(code, check.Equals, 0)
46                 }()
47                 wg.Wait()
48                 c.Logf("%s", statsout.String())
49         }
50 }
51
52 func (s *pipelineSuite) TestImportMerge(c *check.C) {
53         libfile := make([]string, 2)
54         tmpdir := c.MkDir()
55
56         var wg sync.WaitGroup
57         for i, infile := range []string{
58                 "testdata/ref.fasta",
59                 "testdata/pipeline1/",
60         } {
61                 i, infile := i, infile
62                 c.Logf("TestImportMerge: %s", infile)
63                 libfile[i] = fmt.Sprintf("%s/%d.gob", tmpdir, i)
64                 wg.Add(1)
65                 go func() {
66                         defer wg.Done()
67                         args := []string{"-local=true", "-o=" + libfile[i], "-skip-ooo=true", "-output-tiles", "-tag-library", "testdata/tags"}
68                         if i == 0 {
69                                 // ref only
70                                 args = append(args, "-save-incomplete-tiles")
71                         }
72                         args = append(args, infile)
73                         code := (&importer{}).RunCommand("lightning import", args, bytes.NewReader(nil), &bytes.Buffer{}, os.Stderr)
74                         c.Check(code, check.Equals, 0)
75                 }()
76         }
77         wg.Wait()
78
79         merged := &bytes.Buffer{}
80         code := (&merger{}).RunCommand("lightning merge", []string{"-local", libfile[0], libfile[1]}, bytes.NewReader(nil), merged, os.Stderr)
81         c.Check(code, check.Equals, 0)
82         c.Logf("len(merged) %d", merged.Len())
83
84         statsout := &bytes.Buffer{}
85         code = (&statscmd{}).RunCommand("lightning stats", []string{"-local"}, bytes.NewReader(merged.Bytes()), statsout, os.Stderr)
86         c.Check(code, check.Equals, 0)
87         c.Check(statsout.Len() > 0, check.Equals, true)
88         c.Logf("%s", statsout.String())
89
90         err := os.Mkdir(tmpdir+"/merged", 0777)
91         c.Assert(err, check.IsNil)
92         c.Check(ioutil.WriteFile(tmpdir+"/merged/library.gob", merged.Bytes(), 0666), check.IsNil)
93
94         code = (&exporter{}).RunCommand("lightning export", []string{"-local", "-ref", "testdata/ref.fasta", "-output-format", "hgvs", "-input-dir", tmpdir + "/merged", "-output-dir", tmpdir, "-output-per-chromosome=false"}, bytes.NewReader(nil), os.Stderr, os.Stderr)
95         c.Check(code, check.Equals, 0)
96         hgvsout, err := ioutil.ReadFile(tmpdir + "/out.tsv")
97         c.Check(err, check.IsNil)
98         c.Check(sortLines(string(hgvsout)), check.Equals, sortLines(`chr1:g.1_3delinsGGC        N
99 chr1:g.[41T>A];[41=]    N
100 chr1:g.[42T>A];[42=]    N
101 chr1:g.[161=];[161A>T]  N
102 chr1:g.[178=];[178A>T]  N
103 chr1:g.222_224del       N
104 chr1:g.[302=];[302_305delinsAAAA]       .
105 .       chr2:g.[1=];[1_3delinsAAA]
106 .       chr2:g.125_127delinsAAA
107 chr2:g.[241_254del];[241=]      .
108 chr2:g.[258_269delinsAA];[258=] .
109 chr2:g.[315C>A];[315=]  .
110 chr2:g.[470_472del];[470=]      .
111 chr2:g.[471=];[471G>A]  .
112 chr2:g.[472=];[472G>A]  .
113 `))
114
115         code = (&exporter{}).RunCommand("lightning export", []string{"-local", "-ref", "testdata/ref.fasta", "-output-dir", tmpdir, "-output-format", "pvcf", "-input-dir", tmpdir + "/merged", "-output-bed", tmpdir + "/export.bed", "-output-per-chromosome=false"}, bytes.NewReader(nil), os.Stderr, os.Stderr)
116         c.Check(code, check.Equals, 0)
117         vcfout, err := ioutil.ReadFile(tmpdir + "/out.vcf")
118         c.Check(err, check.IsNil)
119         c.Check(sortLines(string(vcfout)), check.Equals, sortLines(`##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">
120 #CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT  testdata/pipeline1/input1.1.fasta       testdata/pipeline1/input2.1.fasta
121 chr1    1       .       NNN     GGC     .       .       .       GT      1/1     0/0
122 chr1    41      .       T       A       .       .       .       GT      1/0     0/0
123 chr1    42      .       T       A       .       .       .       GT      1/0     0/0
124 chr1    161     .       A       T       .       .       .       GT      0/1     0/0
125 chr1    178     .       A       T       .       .       .       GT      0/1     0/0
126 chr1    221     .       TCCA    T       .       .       .       GT      1/1     0/0
127 chr1    302     .       TTTT    AAAA    .       .       .       GT      0/1     0/0
128 chr2    1       .       TTT     AAA     .       .       .       GT      0/0     0/1
129 chr2    125     .       CTT     AAA     .       .       .       GT      0/0     1/1
130 chr2    240     .       ATTTTTCTTGCTCTC A       .       .       .       GT      1/0     0/0
131 chr2    258     .       CCTTGTATTTTT    AA      .       .       .       GT      1/0     0/0
132 chr2    315     .       C       A       .       .       .       GT      1/0     0/0
133 chr2    469     .       GTGG    G       .       .       .       GT      1/0     0/0
134 chr2    471     .       G       A       .       .       .       GT      0/1     0/0
135 chr2    472     .       G       A       .       .       .       GT      0/1     0/0
136 `))
137         bedout, err := ioutil.ReadFile(tmpdir + "/export.bed")
138         c.Check(err, check.IsNil)
139         c.Logf("%s", string(bedout))
140         c.Check(sortLines(string(bedout)), check.Equals, sortLines(`chr1 0 248 0 1000 . 0 224
141 chr1 224 372 1 1000 . 248 348
142 chr1 348 496 2 1000 . 372 472
143 chr1 472 572 3 1000 . 496 572
144 chr2 0 248 4 1000 . 0 224
145 chr2 224 372 5 750 . 248 348
146 chr2 348 496 6 1000 . 372 472
147 chr2 472 572 7 1000 . 496 572
148 `))
149
150         annotateout := &bytes.Buffer{}
151         code = (&annotatecmd{}).RunCommand("lightning annotate", []string{"-local", "-variant-hash=true", "-i", tmpdir + "/merged/library.gob"}, bytes.NewReader(nil), annotateout, os.Stderr)
152         c.Check(code, check.Equals, 0)
153         c.Check(annotateout.Len() > 0, check.Equals, true)
154         sorted := sortLines(annotateout.String())
155         c.Logf("%s", sorted)
156         c.Check(sorted, check.Equals, sortLines(`0,0,8d4fe9a63921b,chr1:g.161A>T
157 0,0,8d4fe9a63921b,chr1:g.178A>T
158 0,0,8d4fe9a63921b,chr1:g.1_3delinsGGC
159 0,0,8d4fe9a63921b,chr1:g.222_224del
160 0,0,ba4263ca4199c,chr1:g.1_3delinsGGC
161 0,0,ba4263ca4199c,chr1:g.222_224del
162 0,0,ba4263ca4199c,chr1:g.41T>A
163 0,0,ba4263ca4199c,chr1:g.42T>A
164 1,1,139890345dbb8,chr1:g.302_305delinsAAAA
165 4,4,cbfca15d241d3,chr2:g.125_127delinsAAA
166 4,4,cbfca15d241d3,chr2:g.1_3delinsAAA
167 4,4,f5fafe9450b02,chr2:g.241_245delinsAAAAA
168 4,4,f5fafe9450b02,chr2:g.291C>A
169 4,4,fe9a71a42adb4,chr2:g.125_127delinsAAA
170 6,6,e36dce85efbef,chr2:g.471G>A
171 6,6,e36dce85efbef,chr2:g.472G>A
172 6,6,f81388b184f4a,chr2:g.470_472del
173 `))
174 }
175
176 func sortLines(txt string) string {
177         lines := strings.Split(strings.TrimRightFunc(txt, func(c rune) bool { return c == '\n' }), "\n")
178         sort.Strings(lines)
179         return strings.Join(lines, "\n") + "\n"
180 }