miga-base 0.7.9.0 → 0.7.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/miga/cli/action/browse.rb +213 -0
- data/lib/miga/cli/action/browse/about.html +31 -0
- data/lib/miga/cli/action/browse/dataset.html +5 -0
- data/lib/miga/cli/action/browse/dataset_menu_item.html +3 -0
- data/lib/miga/cli/action/browse/datasets.html +4 -0
- data/lib/miga/cli/action/browse/favicon-32.png +0 -0
- data/lib/miga/cli/action/browse/index.html +8 -0
- data/lib/miga/cli/action/browse/layout.html +57 -0
- data/lib/miga/cli/action/browse/redirect.html +11 -0
- data/lib/miga/cli/action/browse/style.css +97 -0
- data/lib/miga/cli/action/classify_wf.rb +3 -1
- data/lib/miga/cli/action/derep_wf.rb +4 -0
- data/lib/miga/cli/action/edit.rb +9 -6
- data/lib/miga/cli/action/quality_wf.rb +4 -1
- data/lib/miga/cli/action/stats.rb +1 -1
- data/lib/miga/cli/action/wf.rb +11 -3
- data/lib/miga/cli/base.rb +27 -26
- data/lib/miga/common/format.rb +26 -6
- data/lib/miga/daemon.rb +6 -4
- data/lib/miga/dataset.rb +5 -1
- data/lib/miga/dataset/base.rb +3 -3
- data/lib/miga/dataset/hooks.rb +4 -4
- data/lib/miga/dataset/result.rb +18 -14
- data/lib/miga/lair.rb +1 -1
- data/lib/miga/project/dataset.rb +3 -5
- data/lib/miga/project/hooks.rb +4 -3
- data/lib/miga/remote_dataset/download.rb +2 -1
- data/lib/miga/result.rb +3 -1
- data/lib/miga/result/stats.rb +55 -23
- data/lib/miga/version.rb +2 -2
- data/scripts/cds.bash +0 -1
- data/scripts/distances.bash +6 -1
- data/test/daemon_test.rb +1 -1
- data/test/dataset_test.rb +3 -1
- data/test/project_test.rb +1 -1
- data/test/remote_dataset_test.rb +1 -1
- metadata +16 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 881c30021a8c7e8219dd2fad710bc3049eb56ce1307c0507607b3dd2c83ab296
|
4
|
+
data.tar.gz: 34b47f66564a02413b79e12fa19cf181c639c50ae28030cef624634485c8af9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb36047b431765f2227e991d7adb5a2899801018a067227e581d8e0b63999082099c8f41138395ce83c86e7664284a9cb9267c280138d62656a8b671ffda2bee
|
7
|
+
data.tar.gz: ec59a539424db91f6744799ea022c1aa56c39123b4c43e19f1ce20b01954c16c90e481a4e062d3ed01d912f57eda4c29123047399041889ba1997a4eb839f94d
|
data/README.md
CHANGED
@@ -41,6 +41,7 @@ Developed and maintained by [Luis M. Rodriguez-R][lrr]. MiGA is the result of a
|
|
41
41
|
collaboration between [Kostas Lab][kostas] at the Georgia Institute of
|
42
42
|
Technology and [RDP][rdp] at Michigan State University.
|
43
43
|
|
44
|
+
See also the [complete list of contributors](manual/part1/contributors.md).
|
44
45
|
|
45
46
|
# License
|
46
47
|
|
@@ -0,0 +1,213 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'miga/cli/action'
|
4
|
+
|
5
|
+
# Action: miga browse
|
6
|
+
class MiGA::Cli::Action::Browse < MiGA::Cli::Action
|
7
|
+
def parse_cli
|
8
|
+
cli.parse do |opt|
|
9
|
+
cli.defaults = { open: true }
|
10
|
+
cli.opt_object(opt, [:project])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform
|
15
|
+
p = cli.load_project
|
16
|
+
create_empty_page(p)
|
17
|
+
generate_project_page(p)
|
18
|
+
say 'Creating dataset pages'
|
19
|
+
cli.load_project.each_dataset do |d|
|
20
|
+
generate_dataset_page(p, d)
|
21
|
+
end
|
22
|
+
generate_datasets_index(p)
|
23
|
+
say "Open in your browser: #{File.join(p.path, 'index.html')}"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
##
|
29
|
+
# Create an empty page with necessary assets for project +p+
|
30
|
+
def create_empty_page(p)
|
31
|
+
say 'Creating project page'
|
32
|
+
FileUtils.mkdir_p(browse_file(p, '.'))
|
33
|
+
%w[favicon-32.png style.css].each do |i|
|
34
|
+
FileUtils.cp(template_file(i), browse_file(p, i))
|
35
|
+
end
|
36
|
+
write_file(p, 'about.html') do
|
37
|
+
build_from_template('about.html', citation: MiGA::MiGA.CITATION)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Create landing page for project +p+
|
43
|
+
def generate_project_page(p)
|
44
|
+
# Redirect page
|
45
|
+
write_file(p, '../index.html') { build_from_template('redirect.html') }
|
46
|
+
|
47
|
+
# Summaries
|
48
|
+
summaries = Dir["#{p.path}/*.tsv"].map do |i|
|
49
|
+
"<li><a href='file://#{i}'>#{File.basename(i)}</a></li>"
|
50
|
+
end.join('')
|
51
|
+
|
52
|
+
# Project index page
|
53
|
+
data = {
|
54
|
+
project_active: 'active',
|
55
|
+
information: format_metadata(p),
|
56
|
+
summaries: summaries.empty? ? 'None' : "<ul>#{summaries}</ul>",
|
57
|
+
results: format_results(p)
|
58
|
+
}
|
59
|
+
write_file(p, 'index.html') { build_from_template('index.html', data) }
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Create page for dataset +d+ within project +p+
|
64
|
+
def generate_dataset_page(p, d)
|
65
|
+
data = {
|
66
|
+
unmiga_name: d.name.unmiga_name,
|
67
|
+
information: format_metadata(d),
|
68
|
+
results: format_results(d)
|
69
|
+
}
|
70
|
+
write_file(p, "d_#{d.name}.html") do
|
71
|
+
build_from_template('dataset.html', data)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Create pages for reference and query dataset indexes
|
77
|
+
def generate_datasets_index(p)
|
78
|
+
say 'Creating index pages'
|
79
|
+
data = format_dataset_index(p)
|
80
|
+
data.each do |k, v|
|
81
|
+
write_file(p, "#{k}_datasets.html") do
|
82
|
+
v[:list] = 'None' if v[:list] == ''
|
83
|
+
build_from_template(
|
84
|
+
'datasets.html',
|
85
|
+
v.merge(:"#{k}_datasets_active" => 'active')
|
86
|
+
)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def format_dataset_index(p)
|
92
|
+
data = {
|
93
|
+
ref: { type_name: 'Reference', list: '' },
|
94
|
+
qry: { type_name: 'Query', list: '' }
|
95
|
+
}
|
96
|
+
p.each_dataset do |d|
|
97
|
+
data[d.ref? ? :ref : :qry][:list] +=
|
98
|
+
"<li><a href='d_#{d.name}.html'>#{d.name.unmiga_name}</a></li>"
|
99
|
+
end
|
100
|
+
data
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Format +obj+ metadata as a table
|
105
|
+
def format_metadata(obj)
|
106
|
+
'<table class="table table-sm table-responsive">' +
|
107
|
+
obj.metadata.data.map do |k, v|
|
108
|
+
case k
|
109
|
+
when /^run_/, :plugins, :user
|
110
|
+
next
|
111
|
+
when :web_assembly_gz
|
112
|
+
v = "<a href='#{v}'>#{v[0..50]}...</a>"
|
113
|
+
when :datasets
|
114
|
+
v = v.size
|
115
|
+
end
|
116
|
+
"<tr><td class='text-right pr-4'><b>#{format_name(k)}</b></td>" \
|
117
|
+
"<td>#{v}</td></tr>"
|
118
|
+
end.compact.join('') +
|
119
|
+
'</table>'
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Format +obj+ results as cards
|
124
|
+
def format_results(obj)
|
125
|
+
o = ''
|
126
|
+
obj.each_result do |key, res|
|
127
|
+
links = format_result_links(res)
|
128
|
+
stats = format_result_stats(res)
|
129
|
+
next unless links || stats
|
130
|
+
name = format_name(key)
|
131
|
+
url_doc =
|
132
|
+
'http://manual.microbial-genomes.org/part5/workflow#' +
|
133
|
+
key.to_s.tr('_', '-')
|
134
|
+
o += <<~CARD
|
135
|
+
<div class="col-md-6 mb-4">
|
136
|
+
<h3>#{name}</h3>
|
137
|
+
<div class='border-left p-3'>
|
138
|
+
#{stats}
|
139
|
+
#{links}
|
140
|
+
</div>
|
141
|
+
<div class='border-top p-2 bg-light'>
|
142
|
+
<a target=_blank href="#{url_doc}" class='p-2'>Learn more</a>
|
143
|
+
</div>
|
144
|
+
</div>
|
145
|
+
CARD
|
146
|
+
end
|
147
|
+
"<div class='row'>#{o}</div>"
|
148
|
+
end
|
149
|
+
|
150
|
+
def format_name(str)
|
151
|
+
str
|
152
|
+
.to_s.unmiga_name
|
153
|
+
.sub(/^./, &:upcase)
|
154
|
+
.gsub(/(Aai|Ani|Ogs|Cds|Ssu| db$| ssu )/, &:upcase)
|
155
|
+
.sub(/Haai/, 'hAAI')
|
156
|
+
.sub(/Mytaxa/, 'MyTaxa')
|
157
|
+
.sub(/ pvalue$/, ' p-value')
|
158
|
+
.sub(/contigs$/, 'Contigs')
|
159
|
+
end
|
160
|
+
|
161
|
+
def format_result_links(res)
|
162
|
+
links = []
|
163
|
+
res.each_file do |key, _|
|
164
|
+
name = format_name(key)
|
165
|
+
links << "<a href='file://#{res.file_path(key)}'>#{name}</a><br/>"
|
166
|
+
end
|
167
|
+
links.empty? ? nil : links.join('')
|
168
|
+
end
|
169
|
+
|
170
|
+
def format_result_stats(res)
|
171
|
+
res.stats.map do |k, v|
|
172
|
+
v = [v, ''] unless v.is_a? Array
|
173
|
+
v[0] = ('%.3g' % v[0]) if v[0].is_a? Float
|
174
|
+
"<b>#{format_name(k)}:</b> #{v[0]}#{v[1]}<br/>"
|
175
|
+
end.join('') + '<br/>' unless res.stats.empty?
|
176
|
+
end
|
177
|
+
|
178
|
+
##
|
179
|
+
# Write +file+ within the browse folder of project +p+ using the passed
|
180
|
+
# block output as content
|
181
|
+
def write_file(p, file)
|
182
|
+
File.open(browse_file(p, file), 'w') { |fh| fh.print yield }
|
183
|
+
end
|
184
|
+
|
185
|
+
##
|
186
|
+
# Use a +template+ file to generate content with a hash of +data+ over the
|
187
|
+
# layout page if +layout+ is true
|
188
|
+
def build_from_template(template, data = {}, layout = true)
|
189
|
+
cont = File.read(template_file(template)).miga_variables(data)
|
190
|
+
return cont unless layout
|
191
|
+
|
192
|
+
build_from_template(
|
193
|
+
'layout.html',
|
194
|
+
data.merge(content: cont, project_name: cli.load_project.name),
|
195
|
+
false
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
##
|
200
|
+
# Path to the template browse file
|
201
|
+
def template_file(file)
|
202
|
+
File.join(
|
203
|
+
MiGA::MiGA.root_path,
|
204
|
+
'lib', 'miga', 'cli', 'action', 'browse', file
|
205
|
+
)
|
206
|
+
end
|
207
|
+
|
208
|
+
##
|
209
|
+
# Path to the browse file in the project
|
210
|
+
def browse_file(p, file)
|
211
|
+
File.join(p.path, 'browse', file)
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<h1 class="h2 border-bottom pt-3 pb-2 mb-3">About MiGA</h1>
|
2
|
+
<p>
|
3
|
+
MiGA is developed and maintained by
|
4
|
+
<a href='https://rodriguez-r.com/'>Luis M. Rodriguez-R</a>.
|
5
|
+
|
6
|
+
The MiGA codebase is
|
7
|
+
<a href='http://code.microbial-genomes.org/miga'>freely available</a> under the
|
8
|
+
terms of the terms of the
|
9
|
+
<a href='http://code.microbial-genomes.org/miga/blob/master/LICENSE'>Artistic License 2.0</a>.
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<p>
|
13
|
+
MiGA is the result of a collaboration between the
|
14
|
+
<a href='http://enve-omics.gatech.edu/'>Kostas Lab</a>
|
15
|
+
(<a href='http://www.gatech.edu/'>Georgia Institute of Technology</a>) and the
|
16
|
+
<a href='http://rdp.cme.msu.edu/'>RDP team</a>
|
17
|
+
(<a href='http://cme.msu.edu/'>Center for Microbial Ecology</a>,
|
18
|
+
<a href='https://msu.edu/'>Michigan State University</a>).
|
19
|
+
The MiGA project is funded by the
|
20
|
+
<a href='http://nsf.gov/'>US National Science Foundation</a>
|
21
|
+
(Awards <a href='http://nsf.gov/awardsearch/showAward?AWD_ID=1356288'>#1356288</a> &
|
22
|
+
<a href='https://xras.xsede.org/public/requests/31162-XSEDE-MCB190042-1190572'>#MCB190042</a>).
|
23
|
+
</p>
|
24
|
+
|
25
|
+
<h1 class="h2 border-bottom pt-3 pb-2 mb-3">Citation</h1>
|
26
|
+
If you use MiGA in your work, consider citing:
|
27
|
+
<blockquote class='border-left p-3'>
|
28
|
+
{{citation}}
|
29
|
+
</blockquote>
|
30
|
+
|
31
|
+
|
Binary file
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<head>
|
3
|
+
<meta charset="utf-8">
|
4
|
+
<title>MiGA | {{project_name}}</title>
|
5
|
+
|
6
|
+
<!-- Remote assets -->
|
7
|
+
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
|
8
|
+
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
10
|
+
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
|
11
|
+
|
12
|
+
<!-- Local assets -->
|
13
|
+
<link href="style.css" rel="stylesheet">
|
14
|
+
<link rel="icon" href="favicon-32.png" sizes="32x32" type="image/png">
|
15
|
+
</head>
|
16
|
+
<body>
|
17
|
+
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
|
18
|
+
<a class="navbar-brand col-md-12 col-lg-12 mr-0 px-3"
|
19
|
+
href="index.html">MiGA | {{project_name}}</a>
|
20
|
+
<button class="navbar-toggler position-absolute d-md-none collapsed"
|
21
|
+
type="button" data-toggle="collapse" data-target="#sidebarMenu"
|
22
|
+
aria-controls="sidebarMenu" aria-expanded="false"
|
23
|
+
aria-label="Toggle navigation">
|
24
|
+
<span class="navbar-toggler-icon"></span>
|
25
|
+
</button>
|
26
|
+
</nav>
|
27
|
+
<div class="container-fluid">
|
28
|
+
<div class="row">
|
29
|
+
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
30
|
+
<div class="sidebar-sticky pt-3">
|
31
|
+
<ul class="nav flex-column">
|
32
|
+
<li class="nav-item">
|
33
|
+
<a class="nav-link {{project_active}}" href="index.html">Project</a>
|
34
|
+
</li>
|
35
|
+
<li class="nav-item">
|
36
|
+
<a class="nav-link {{ref_datasets_active}}"
|
37
|
+
href="ref_datasets.html">Reference datasets</a>
|
38
|
+
</li>
|
39
|
+
<li class="nav-item">
|
40
|
+
<a class="nav-link {{qry_datasets_active}}"
|
41
|
+
href="qry_datasets.html">Query datasets</a>
|
42
|
+
</li>
|
43
|
+
<li class="nav-item border-top mt-4">
|
44
|
+
<a class="nav-link {{about_miga_active}}"
|
45
|
+
href="about.html">About MiGA</a>
|
46
|
+
</li>
|
47
|
+
</ul>
|
48
|
+
</div>
|
49
|
+
</nav>
|
50
|
+
|
51
|
+
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
|
52
|
+
{{content}}
|
53
|
+
</main>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
</body>
|
57
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<head>
|
3
|
+
<title>MiGA Project</title>
|
4
|
+
<meta http-equiv = "refresh" content = "1; url = browse/index.html" />
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<div style='font-size:200%; margin-top: 5em; text-align: center;'>
|
8
|
+
Redirecting to <a href='browse/index.html'>Project page</a>...
|
9
|
+
</div>
|
10
|
+
</body>
|
11
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
body {
|
2
|
+
font-size: .875rem;
|
3
|
+
}
|
4
|
+
|
5
|
+
/*
|
6
|
+
* Sidebar
|
7
|
+
*/
|
8
|
+
|
9
|
+
.sidebar {
|
10
|
+
position: fixed;
|
11
|
+
top: 0;
|
12
|
+
bottom: 0;
|
13
|
+
left: 0;
|
14
|
+
z-index: 100; /* Behind the navbar */
|
15
|
+
padding: 48px 0 0; /* Height of navbar */
|
16
|
+
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
|
17
|
+
}
|
18
|
+
|
19
|
+
@media (max-width: 767.98px) {
|
20
|
+
.sidebar {
|
21
|
+
top: 3rem;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
.sidebar-sticky {
|
26
|
+
position: relative;
|
27
|
+
top: 0;
|
28
|
+
height: calc(100vh - 48px);
|
29
|
+
padding-top: .5rem;
|
30
|
+
overflow-x: hidden;
|
31
|
+
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
32
|
+
}
|
33
|
+
|
34
|
+
@supports ((position: -webkit-sticky) or (position: sticky)) {
|
35
|
+
.sidebar-sticky {
|
36
|
+
position: -webkit-sticky;
|
37
|
+
position: sticky;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
.sidebar .nav-link {
|
42
|
+
font-weight: 500;
|
43
|
+
color: #333;
|
44
|
+
}
|
45
|
+
|
46
|
+
.sidebar .nav-link .feather {
|
47
|
+
margin-right: 4px;
|
48
|
+
color: #999;
|
49
|
+
}
|
50
|
+
|
51
|
+
.sidebar .nav-link.active {
|
52
|
+
color: #007bff;
|
53
|
+
}
|
54
|
+
|
55
|
+
.sidebar .nav-link:hover .feather,
|
56
|
+
.sidebar .nav-link.active .feather {
|
57
|
+
color: inherit;
|
58
|
+
}
|
59
|
+
|
60
|
+
.sidebar-heading {
|
61
|
+
font-size: .75rem;
|
62
|
+
text-transform: uppercase;
|
63
|
+
}
|
64
|
+
|
65
|
+
/*
|
66
|
+
* Navbar
|
67
|
+
*/
|
68
|
+
|
69
|
+
.navbar-brand {
|
70
|
+
padding-top: .75rem;
|
71
|
+
padding-bottom: .75rem;
|
72
|
+
font-size: 1rem;
|
73
|
+
background-color: rgba(0, 0, 0, .25);
|
74
|
+
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
|
75
|
+
}
|
76
|
+
|
77
|
+
.navbar .navbar-toggler {
|
78
|
+
top: .25rem;
|
79
|
+
right: 1rem;
|
80
|
+
}
|
81
|
+
|
82
|
+
.navbar .form-control {
|
83
|
+
padding: .75rem 1rem;
|
84
|
+
border-width: 0;
|
85
|
+
border-radius: 0;
|
86
|
+
}
|
87
|
+
|
88
|
+
.form-control-dark {
|
89
|
+
color: #fff;
|
90
|
+
background-color: rgba(255, 255, 255, .1);
|
91
|
+
border-color: rgba(255, 255, 255, .1);
|
92
|
+
}
|
93
|
+
|
94
|
+
.form-control-dark:focus {
|
95
|
+
border-color: transparent;
|
96
|
+
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
|
97
|
+
}
|