Use new Arvados logs API.
[lightning.git] / pca_plot.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         _ "embed"
9         "flag"
10         "fmt"
11         "io"
12         "os/exec"
13         "strings"
14
15         "git.arvados.org/arvados.git/sdk/go/arvados"
16 )
17
18 type pythonPlot struct{}
19
20 //go:embed pca_plot.py
21 var pcaPlotPy string
22
23 func (cmd *pythonPlot) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
24         var err error
25         defer func() {
26                 if err != nil {
27                         fmt.Fprintf(stderr, "%s\n", err)
28                 }
29         }()
30         flags := flag.NewFlagSet("", flag.ContinueOnError)
31         flags.SetOutput(stderr)
32         projectUUID := flags.String("project", "", "project `UUID` for output data")
33         inputFilename := flags.String("i", "-", "input `file`")
34         outputFilename := flags.String("o", "", "output `filename` (e.g., './plot.png')")
35         sampleListFilename := flags.String("samples", "", "use second column of `samples.csv` as complete list of sample IDs")
36         phenotypeFilename := flags.String("phenotype", "", "use `phenotype.csv` as id->phenotype mapping (column 0 is sample id)")
37         cat1Column := flags.Int("phenotype-cat1-column", 1, "0-based column `index` of 1st category in phenotype.csv file")
38         cat2Column := flags.Int("phenotype-cat2-column", -1, "0-based column `index` of 2nd category in phenotype.csv file")
39         xComponent := flags.Int("x", 1, "1-based PCA component to plot on x axis")
40         yComponent := flags.Int("y", 2, "1-based PCA component to plot on y axis")
41         priority := flags.Int("priority", 500, "container request priority")
42         runlocal := flags.Bool("local", false, "run on local host (default: run in an arvados container)")
43         err = flags.Parse(args)
44         if err == flag.ErrHelp {
45                 err = nil
46                 return 0
47         } else if err != nil {
48                 return 2
49         } else if flags.NArg() > 0 {
50                 err = fmt.Errorf("errant command line arguments after parsed flags: %v", flags.Args())
51                 return 2
52         }
53
54         runner := arvadosContainerRunner{
55                 Name:        "lightning pca-plot",
56                 Client:      arvados.NewClientFromEnv(),
57                 ProjectUUID: *projectUUID,
58                 RAM:         4 << 30,
59                 VCPUs:       1,
60                 Priority:    *priority,
61                 Mounts: map[string]map[string]interface{}{
62                         "/pca_plot.py": map[string]interface{}{
63                                 "kind":    "text",
64                                 "content": pcaPlotPy,
65                         },
66                 },
67         }
68         if !*runlocal {
69                 err = runner.TranslatePaths(inputFilename, sampleListFilename, phenotypeFilename)
70                 if err != nil {
71                         return 1
72                 }
73                 *outputFilename = "/mnt/output/plot.png"
74         }
75         args = []string{
76                 *inputFilename,
77                 fmt.Sprintf("%d", *xComponent),
78                 fmt.Sprintf("%d", *yComponent),
79                 *sampleListFilename,
80                 *phenotypeFilename,
81                 fmt.Sprintf("%d", *cat1Column),
82                 fmt.Sprintf("%d", *cat2Column),
83                 *outputFilename,
84         }
85         if *runlocal {
86                 if *outputFilename == "" {
87                         fmt.Fprintln(stderr, "error: must specify -o filename.png in local mode (or try -help)")
88                         return 1
89                 }
90                 cmd := exec.Command("python3", append([]string{"-"}, args...)...)
91                 cmd.Stdin = strings.NewReader(pcaPlotPy)
92                 cmd.Stdout = stdout
93                 cmd.Stderr = stderr
94                 err = cmd.Run()
95                 if err != nil {
96                         return 1
97                 }
98                 return 0
99         }
100         runner.Prog = "python3"
101         runner.Args = append([]string{"/pca_plot.py"}, args...)
102         var output string
103         output, err = runner.Run()
104         if err != nil {
105                 return 1
106         }
107         fmt.Fprintln(stdout, output+"/plot.png")
108         return 0
109 }