Merge branch '19868-pca-in-ml' into main
[lightning.git] / manhattan.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 manhattanPlot struct{}
19
20 //go:embed manhattan.py
21 var manhattanPy string
22
23 func (cmd *manhattanPlot) 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         inputDirectory := flags.String("i", "-", "input `directory` (output of slice-numpy -single-onehot)")
34         outputFilename := flags.String("o", "", "output `filename` (e.g., './plot.png')")
35         csvOutputFilename := flags.String("csv-output", "", "csv output `filename` (e.g., './tile-locations-pvalues.csv')")
36         csvOutputThreshold := flags.Float64("csv-output-threshold", 0, "logpvalue threshold for csv output (0 for none)")
37         priority := flags.Int("priority", 500, "container request priority")
38         runlocal := flags.Bool("local", false, "run on local host (default: run in an arvados container)")
39         err = flags.Parse(args)
40         if err == flag.ErrHelp {
41                 err = nil
42                 return 0
43         } else if err != nil {
44                 return 2
45         } else if flags.NArg() > 0 {
46                 err = fmt.Errorf("errant command line arguments after parsed flags: %v", flags.Args())
47                 return 2
48         }
49
50         runner := arvadosContainerRunner{
51                 Name:        "lightning manhattan",
52                 Client:      arvados.NewClientFromEnv(),
53                 ProjectUUID: *projectUUID,
54                 RAM:         4 << 30,
55                 VCPUs:       1,
56                 Priority:    *priority,
57                 Mounts: map[string]map[string]interface{}{
58                         "/manhattan.py": map[string]interface{}{
59                                 "kind":    "text",
60                                 "content": manhattanPy,
61                         },
62                 },
63         }
64         if !*runlocal {
65                 err = runner.TranslatePaths(inputDirectory)
66                 if err != nil {
67                         return 1
68                 }
69                 *outputFilename = "/mnt/output/plot.png"
70                 *csvOutputFilename = "/mnt/output/tile-locations-pvalues.csv"
71         }
72         args = []string{
73                 *inputDirectory,
74                 *outputFilename,
75                 fmt.Sprintf("%g", *csvOutputThreshold),
76                 *csvOutputFilename,
77         }
78         if *runlocal {
79                 if *outputFilename == "" {
80                         fmt.Fprintln(stderr, "error: must specify -o filename.png in local mode (or try -help)")
81                         return 1
82                 }
83                 cmd := exec.Command("python3", append([]string{"-"}, args...)...)
84                 cmd.Stdin = strings.NewReader(manhattanPy)
85                 cmd.Stdout = stdout
86                 cmd.Stderr = stderr
87                 err = cmd.Run()
88                 if err != nil {
89                         return 1
90                 }
91                 return 0
92         }
93         runner.Prog = "python3"
94         runner.Args = append([]string{"/manhattan.py"}, args...)
95         var output string
96         output, err = runner.Run()
97         if err != nil {
98                 return 1
99         }
100         fmt.Fprintln(stdout, output+"/plot.png")
101         return 0
102 }