miga-base 0.7.11.0 → 0.7.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b4a168130d732c670246cd4a874272e77e5f7d88fdef00e10d81ab8e5f9979a
4
- data.tar.gz: '069e2dd280b4afecb67478612f1dee35bf2cada3ae57cbc61c6e70d0ef3bd233'
3
+ metadata.gz: f99f8fd530489d42672cdd96123f321725b9437ee4a81e822a07854ec924ad53
4
+ data.tar.gz: c4d6607a4b6062b45cc94985b8bc920bb25307232851b20436ee4b9cd8a8986b
5
5
  SHA512:
6
- metadata.gz: a37fd7d69339c7a63d5ac38e0c232fed96d479c3f2f2bc67b2ee956bb908d8690a55f21a6fa0185c05f209139e16b6b2ddcd6b0f36fac471f9e0b4fd2c4a5f04
7
- data.tar.gz: cb156656c79f1a765281f163691650e32f90056dc767827d4b3fe958b4042e6359b810f5a3249c6902bce042f6a457507a027836797c39328889d9cbbbc5c5d0
6
+ metadata.gz: '03478c56a40e948ad9eb4cb09fbedc72bac331072ccf46ce5468f1f78a08e891260684771e455b92841d8af454fcab997d7d51a68360b8337ffa13c8c2ec88a4'
7
+ data.tar.gz: e992d10e5de206a85ac425e15c7594629f86e8088ec6f59ba820c5ecaf6c8901af0142455501a1d8af03902a3ca559d0374692e4df9f41acdceaf45d5d750b1f
@@ -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
@@ -169,6 +169,7 @@ module MiGA::Cli::Action::Wf
169
169
  '--tab', '--ref', '--active'
170
170
  ])
171
171
  end
172
+ call_cli(['browse', '-P', cli[:outdir]])
172
173
  end
173
174
 
174
175
  def cleanup
@@ -11,39 +11,40 @@ module MiGA::Cli::Base
11
11
  preproc_wf: 'Preprocess input genomes or metagenomes',
12
12
  index_wf: 'Generate distance indexing of input genomes',
13
13
  # Projects
14
- new: 'Creates an empty MiGA project',
15
- about: 'Displays information about a MiGA project',
16
- doctor: 'Performs consistency checks on a MiGA project',
17
- get_db: 'Downloads a pre-indexed database',
14
+ new: 'Create an empty MiGA project',
15
+ about: 'Display information about a MiGA project',
16
+ doctor: 'Perform consistency checks on a MiGA project',
17
+ get_db: 'Download a pre-indexed database',
18
+ browse: 'Explore a project locally using a web browser',
18
19
  # Datasets
19
- add: 'Creates a dataset in a MiGA project',
20
- get: 'Downloads a dataset from public databases into a MiGA project',
21
- ncbi_get: 'Downloads all genomes in a taxon from NCBI into a MiGA project',
22
- rm: 'Removes a dataset from an MiGA project',
23
- find: 'Finds unregistered datasets based on result files',
20
+ add: 'Create a dataset in a MiGA project',
21
+ get: 'Download a dataset from public databases into a MiGA project',
22
+ ncbi_get: 'Download all genomes in a taxon from NCBI into a MiGA project',
23
+ rm: 'Remove a dataset from an MiGA project',
24
+ find: 'Find unregistered datasets based on result files',
24
25
  ln: 'Link datasets (including results) from one project to another',
25
- ls: 'Lists all registered datasets in an MiGA project',
26
- archive: 'Generates a tar-ball with all files from select datasets',
26
+ ls: 'List all registered datasets in an MiGA project',
27
+ archive: 'Generate a tar-ball with all files from select datasets',
27
28
  # Results
28
- add_result: 'Registers a result',
29
- stats: 'Extracts statistics for the given result',
30
- files: 'Lists registered files from the results of a dataset or project',
31
- run: 'Executes locally one step analysis producing the given result',
32
- summary: 'Generates a summary table for the statistics of all datasets',
33
- next_step: 'Returns the next task to run in a dataset or project',
29
+ add_result: 'Register a result',
30
+ stats: 'Extract statistics for the given result',
31
+ files: 'List registered files from the results of a dataset or project',
32
+ run: 'Execute locally one step analysis producing the given result',
33
+ summary: 'Generate a summary table for the statistics of all datasets',
34
+ next_step: 'Return the next task to run in a dataset or project',
34
35
  # Objects (Datasets or Projects)
35
- edit: 'Edits the metadata of a dataset or project',
36
+ edit: 'Edit the metadata of a dataset or project',
36
37
  # System
37
38
  init: 'Initialize MiGA to process new projects',
38
- daemon: 'Controls the daemon of a MiGA project',
39
- lair: 'Controls groups of daemons for several MiGA projects',
40
- date: 'Returns the current date in standard MiGA format',
41
- console: 'Opens an IRB console with MiGA',
39
+ daemon: 'Control the daemon of a MiGA project',
40
+ lair: 'Control groups of daemons for several MiGA projects',
41
+ date: 'Return the current date in standard MiGA format',
42
+ console: 'Open an IRB console with MiGA',
42
43
  # Taxonomy
43
- tax_set: 'Registers taxonomic information for datasets',
44
- tax_test: 'Returns test of taxonomic distributions for query datasets',
45
- tax_index: 'Creates a taxonomy-indexed list of the datasets',
46
- tax_dist: 'Estimates distributions of distance by taxonomy',
44
+ tax_set: 'Register taxonomic information for datasets',
45
+ tax_test: 'Return test of taxonomic distributions for query datasets',
46
+ tax_index: 'Create a taxonomy-indexed list of the datasets',
47
+ tax_dist: 'Estimate distributions of distance by taxonomy',
47
48
  }
48
49
 
49
50
  @@TASK_ALIAS = {
@@ -66,7 +66,7 @@ module MiGA::Dataset::Base
66
66
  @@PREPROCESSING_TASKS = [
67
67
  :raw_reads, :trimmed_reads, :read_quality, :trimmed_fasta,
68
68
  :assembly, :cds, :essential_genes, :ssu, :mytaxa, :mytaxa_scan,
69
- :distances, :taxonomy, :stats
69
+ :taxonomy, :distances, :stats
70
70
  ]
71
71
 
72
72
  ##
@@ -77,7 +77,7 @@ module MiGA::Dataset::Base
77
77
  ##
78
78
  # Tasks to be executed only in datasets that are not multi-organism. These
79
79
  # tasks are ignored for multi-organism datasets or for unknown types.
80
- @@ONLY_NONMULTI_TASKS = [:mytaxa_scan, :distances, :taxonomy]
80
+ @@ONLY_NONMULTI_TASKS = [:mytaxa_scan, :taxonomy, :distances]
81
81
  @@_ONLY_NONMULTI_TASKS_H = Hash[@@ONLY_NONMULTI_TASKS.map { |i| [i, true] }]
82
82
 
83
83
  ##
@@ -17,6 +17,12 @@ module MiGA::Result::Stats
17
17
  self[:stats]
18
18
  end
19
19
 
20
+ ##
21
+ # Access the stats entry of results
22
+ def stats
23
+ self[:stats]
24
+ end
25
+
20
26
  private
21
27
 
22
28
  def compute_stats_raw_reads
@@ -145,7 +151,7 @@ module MiGA::Result::Stats
145
151
  source.save
146
152
 
147
153
  # Inactivate low-quality datasets
148
- min_qual = (project.metadata[:min_qual] || 50)
154
+ min_qual = (project.metadata[:min_qual] || 25)
149
155
  if min_qual != 'no' && stats[:quality] < min_qual
150
156
  source.inactivate! 'Low quality genome'
151
157
  end
@@ -8,7 +8,7 @@ module MiGA
8
8
  # - Float representing the major.minor version.
9
9
  # - Integer representing gem releases of the current version.
10
10
  # - Integer representing minor changes that require new version number.
11
- VERSION = [0.7, 11, 0]
11
+ VERSION = [0.7, 12, 0]
12
12
 
13
13
  ##
14
14
  # Nickname for the current major.minor version.
@@ -16,7 +16,7 @@ module MiGA
16
16
 
17
17
  ##
18
18
  # Date of the current gem release.
19
- VERSION_DATE = Date.new(2020, 7, 1)
19
+ VERSION_DATE = Date.new(2020, 7, 22)
20
20
 
21
21
  ##
22
22
  # Reference of MiGA.
@@ -20,7 +20,6 @@ fi
20
20
  TYPE=$(miga ls -P "$PROJECT" -D "$DATASET" -m type | cut -f 2)
21
21
  case "$TYPE" in
22
22
  metagenome|virome)
23
- $CMD -p meta
24
23
  prodigal -a "${DATASET}.faa" -d "${DATASET}.fna" -o "${DATASET}.gff3" \
25
24
  -f gff -q -i "../05.assembly/${DATASET}.LargeContigs.fna" -p meta
26
25
  ;;
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miga-base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.11.0
4
+ version: 0.7.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luis M. Rodriguez-R
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-01 00:00:00.000000000 Z
11
+ date: 2020-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: daemons
@@ -118,6 +118,7 @@ files:
118
118
  - lib/miga/cli/action/add.rb
119
119
  - lib/miga/cli/action/add_result.rb
120
120
  - lib/miga/cli/action/archive.rb
121
+ - lib/miga/cli/action/browse.rb
121
122
  - lib/miga/cli/action/classify_wf.rb
122
123
  - lib/miga/cli/action/console.rb
123
124
  - lib/miga/cli/action/daemon.rb