fishtank 0.1.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +61 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +53 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/fishtank.gemspec +33 -0
- data/lib/fishtank.rb +36 -0
- data/lib/fishtank/draw.rb +68 -0
- data/lib/fishtank/fishtank.rb +132 -0
- data/lib/fishtank/simple_nexml.rb +58 -0
- data/lib/fishtank/tank.rb +17 -0
- data/lib/fishtank/taxon.rb +102 -0
- data/lib/fishtank/taxon/arm.rb +25 -0
- data/lib/fishtank/taxon/fish.rb +24 -0
- data/lib/fishtank/taxon/tetrapod.rb +32 -0
- data/lib/fishtank/version.rb +3 -0
- metadata +166 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: add18ae1c07c493e96189169c4778ed32957d607
|
4
|
+
data.tar.gz: db48f20638c8a6b1e7c862b600ac5eebd1817dd8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e4d6e8a31882916057a05e1124e58202149a559e7610066b5f1402ae4552cf41aa0fc97a8d48dd22cb8cdf76d3ae1ebfe286319ada875abd902bea6816d5e008
|
7
|
+
data.tar.gz: 7bc4637813b2449f45d0019563251da03e34dcc56705f405cc42a03f23cc796e56d72d85d07a38e650c316f2915371b6969750722d5a05ff5c626f2c376288e2
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fishtank (0.1.0)
|
5
|
+
phenoscaperb
|
6
|
+
rasem
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
awesome_print (1.8.0)
|
12
|
+
byebug (9.1.0)
|
13
|
+
diff-lcs (1.3)
|
14
|
+
faraday (0.12.0.1)
|
15
|
+
multipart-post (>= 1.2, < 3)
|
16
|
+
faraday_middleware (0.11.0.1)
|
17
|
+
faraday (>= 0.7.4, < 1.0)
|
18
|
+
mini_portile2 (2.3.0)
|
19
|
+
multi_json (1.12.2)
|
20
|
+
multipart-post (2.0.0)
|
21
|
+
nokogiri (1.8.1)
|
22
|
+
mini_portile2 (~> 2.3.0)
|
23
|
+
phenoscaperb (0.1.0)
|
24
|
+
faraday (~> 0.12.0.1)
|
25
|
+
faraday_middleware (~> 0.11.0.1)
|
26
|
+
multi_json (~> 1.12, >= 1.12.1)
|
27
|
+
nokogiri (~> 1.8, >= 1.8.1)
|
28
|
+
thor (~> 0.20.0)
|
29
|
+
xml-to-hash (~> 1.0, >= 1.0.3)
|
30
|
+
rake (10.5.0)
|
31
|
+
rasem (0.7.1)
|
32
|
+
rspec (3.7.0)
|
33
|
+
rspec-core (~> 3.7.0)
|
34
|
+
rspec-expectations (~> 3.7.0)
|
35
|
+
rspec-mocks (~> 3.7.0)
|
36
|
+
rspec-core (3.7.0)
|
37
|
+
rspec-support (~> 3.7.0)
|
38
|
+
rspec-expectations (3.7.0)
|
39
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
40
|
+
rspec-support (~> 3.7.0)
|
41
|
+
rspec-mocks (3.7.0)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.7.0)
|
44
|
+
rspec-support (3.7.0)
|
45
|
+
thor (0.20.0)
|
46
|
+
xml-to-hash (1.0.3)
|
47
|
+
nokogiri (~> 1, >= 1.6)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
awesome_print
|
54
|
+
bundler (~> 1.16)
|
55
|
+
byebug
|
56
|
+
fishtank!
|
57
|
+
rake (~> 10.0)
|
58
|
+
rspec (~> 3.0)
|
59
|
+
|
60
|
+
BUNDLED WITH
|
61
|
+
1.16.0
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2017 Phenoscape
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Matt Yoder
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
# Fishtank
|
3
|
+
|
4
|
+
This library uses the [phenoscaperb](https://github.com/phenoscape/phenoscaperb) gem to query the [Phenoscape API](http://kb.phenoscape.org/apidocs/) for basic statistics on a taxon, entity, and quality basis. It then renders the results as an SVG visualization.
|
5
|
+
|
6
|
+

|
7
|
+
|
8
|
+
# Basic use
|
9
|
+
|
10
|
+
```
|
11
|
+
gem install fishtank
|
12
|
+
```
|
13
|
+
|
14
|
+
```
|
15
|
+
require 'fishtank'
|
16
|
+
|
17
|
+
fish = 'VTO_0037519'
|
18
|
+
lizard = 'VTO_9007513'
|
19
|
+
pan = 'VTO_0011989'
|
20
|
+
homininae = 'VTO_0011988'
|
21
|
+
|
22
|
+
# Create a new tank
|
23
|
+
tank = FishTank::Tank.new
|
24
|
+
|
25
|
+
# Make some Taxa
|
26
|
+
t = FishTank::Taxon::Arm.new(taxon_id: homininae)
|
27
|
+
f = FishTank::Taxon::Fish.new(taxon_id: fish)
|
28
|
+
v = FishTank::Taxon::Tetrapod.new(taxon_id: lizard)
|
29
|
+
|
30
|
+
# Add the Taxa to the tank
|
31
|
+
tank.add(t)
|
32
|
+
tank.add(f)
|
33
|
+
tank.add(v)
|
34
|
+
|
35
|
+
# Render the tank
|
36
|
+
FishTank::Draw.tank(tank: tank, attributes: FishTank::QUALITIES)
|
37
|
+
```
|
38
|
+
|
39
|
+
Then in the terminal (file is SVG, `.html` is convenience)
|
40
|
+
|
41
|
+
```
|
42
|
+
ruby your_file.rb > index.html
|
43
|
+
open index.html
|
44
|
+
```
|
45
|
+
|
46
|
+
# About, thanks.
|
47
|
+
|
48
|
+
Concieved and implemented at the [2017 Phenoscape KB-DataFest](https://github.com/phenoscape/KB-DataFest-2017). Special thanks to Wasila Dahdul for her help with the taxon models and Scott Chamberlain for phenoscaperb.
|
49
|
+
|
50
|
+
# License
|
51
|
+
|
52
|
+
MIT
|
53
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "fishtank"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/fishtank.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "fishtank/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fishtank"
|
8
|
+
spec.version = Fishtank::VERSION
|
9
|
+
spec.authors = ["Matt Yoder"]
|
10
|
+
spec.email = ["diapriid@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{A visualization experiment for the Phenoscape KB.}
|
13
|
+
spec.description = %q{An experiment to map various attributes of the Phenoscape KB to cartoon figures, using SVG.}
|
14
|
+
spec.homepage = "https://github.com/phenoscape/fishtank"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_dependency 'phenoscaperb'
|
25
|
+
spec.add_dependency 'rasem'
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
28
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
29
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
30
|
+
spec.add_development_dependency "awesome_print"
|
31
|
+
spec.add_development_dependency "byebug"
|
32
|
+
|
33
|
+
end
|
data/lib/fishtank.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
require 'phenoscaperb'
|
5
|
+
require 'awesome_print'
|
6
|
+
require 'byebug'
|
7
|
+
|
8
|
+
require "fishtank/version"
|
9
|
+
|
10
|
+
require 'fishtank/draw'
|
11
|
+
require 'fishtank/simple_nexml'
|
12
|
+
require 'fishtank/tank'
|
13
|
+
require 'fishtank/taxon'
|
14
|
+
require 'fishtank/taxon/fish'
|
15
|
+
require 'fishtank/taxon/tetrapod'
|
16
|
+
require 'fishtank/taxon/arm'
|
17
|
+
|
18
|
+
|
19
|
+
module FishTank
|
20
|
+
|
21
|
+
BASE = 'http://purl.obolibrary.org/obo/'
|
22
|
+
|
23
|
+
# TODO: move to file
|
24
|
+
QUALITIES = [
|
25
|
+
'PATO_0000052', # shape
|
26
|
+
'PATO_0000117', # size
|
27
|
+
'PATO_0000014', # color
|
28
|
+
'PATO_0000070', # count/amount
|
29
|
+
'PATO_0000140' # position
|
30
|
+
]
|
31
|
+
|
32
|
+
def self.attributes
|
33
|
+
QUALITIES + [:otus, :rows, :cells]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rasem'
|
2
|
+
|
3
|
+
module FishTank
|
4
|
+
|
5
|
+
module Draw
|
6
|
+
|
7
|
+
@offset_x = 0
|
8
|
+
@offset_y = 0
|
9
|
+
|
10
|
+
@img = Rasem::SVGImage.new(width: 2000, height: 2000, 'font-size'.to_sym => '8')
|
11
|
+
|
12
|
+
# Draw the tank
|
13
|
+
def self.tank(tank: nil, attributes: [:cells] )
|
14
|
+
raise 'tank please' if tank.nil?
|
15
|
+
|
16
|
+
tank.taxa.each do |t|
|
17
|
+
attributes.each do |a|
|
18
|
+
render_taxon(t, a)
|
19
|
+
|
20
|
+
@img.text(@offset_x, @offset_y + t.pic_height + 2) do
|
21
|
+
raw a
|
22
|
+
end
|
23
|
+
|
24
|
+
@offset_x += t.pic_width + 10
|
25
|
+
end
|
26
|
+
|
27
|
+
@img.text(0, @offset_y + t.pic_height + 15) do
|
28
|
+
raw t.label
|
29
|
+
end
|
30
|
+
|
31
|
+
@offset_x = 0
|
32
|
+
@offset_y += t.pic_height + 40
|
33
|
+
end
|
34
|
+
|
35
|
+
puts @img.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.render_taxon(taxon, attribute)
|
39
|
+
taxon.description.each do |entity, v|
|
40
|
+
s = {
|
41
|
+
fill: svg_color(taxon, entity, attribute),
|
42
|
+
stroke: svg_color(taxon, entity, :otus), # for now we hard code stroke
|
43
|
+
'stroke-width'.to_sym => '0.5'
|
44
|
+
}
|
45
|
+
|
46
|
+
draw_part( v[0] + @offset_x, v[1] + @offset_y, v[2], v[3], style: s )
|
47
|
+
if taxon.symmetry.keys.include?(entity)
|
48
|
+
z = taxon.symmetry[entity]
|
49
|
+
draw_part( z[0] + @offset_x, z[1] + @offset_y, z[2], z[3], style: s )
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.draw_part(x, y, width, height, style: {})
|
56
|
+
@img.rectangle x, y, width, height, style: style
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.svg_color(taxon, entity, attribute)
|
60
|
+
v = (taxon.stats[entity][:crunched][attribute] * 255).to_i
|
61
|
+
"rgb(#{v}, 0, 0)"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
|
2
|
+
require 'rasem'
|
3
|
+
require 'phenoscaperb'
|
4
|
+
require 'awesome_print'
|
5
|
+
|
6
|
+
require_relative 'simple_nexml.rb'
|
7
|
+
|
8
|
+
require 'byebug'
|
9
|
+
|
10
|
+
class FishTank
|
11
|
+
BASE = 'http://purl.obolibrary.org/obo/'
|
12
|
+
|
13
|
+
# TODO: move to file
|
14
|
+
QUALITIES = [
|
15
|
+
'PATO_0000052', # shape
|
16
|
+
'PATO_0000117', # size
|
17
|
+
'PATO_0000014', # color
|
18
|
+
'PATO_0000070', # count/amount
|
19
|
+
'PATO_0000140' # position
|
20
|
+
]
|
21
|
+
|
22
|
+
METADATA = {
|
23
|
+
'UBERON_0001703' => [0, 10, 10, 10], # 'neurocranium'
|
24
|
+
'UBERON_0000970' => [3, 12, 3, 3], # 'eye'
|
25
|
+
'UBERON_0001708' => [1, 17, 5, 2], # 'jaw skeleton'
|
26
|
+
'UBERON_0002090' => [10, 10, 30, 10], # 'post-cranial axial skeleton'
|
27
|
+
'UBERON_0003097' => [12, 0, 10, 10], # 'dorsal fin'
|
28
|
+
'UBERON_0000151' => [5, 20, 10, 10], # 'pectoral fin'
|
29
|
+
'UBERON_0000152' => [17, 20, 10, 10], # 'pelvic fin'
|
30
|
+
'UBERON_4000164' => [30, 5, 10, 20], # 'caudal fin'
|
31
|
+
}
|
32
|
+
|
33
|
+
# the svg image object
|
34
|
+
attr_accessor :img
|
35
|
+
|
36
|
+
attr_accessor :parent_taxon
|
37
|
+
|
38
|
+
# All observed descendants of the parent_taxon
|
39
|
+
attr_accessor :children
|
40
|
+
|
41
|
+
attr_accessor :taxon_stats
|
42
|
+
|
43
|
+
def initialize(taxon: nil)
|
44
|
+
raise 'the tank is empty, sad, and lonely, give it a fish, like "taxon: 123"' if taxon.nil?
|
45
|
+
@img = Rasem::SVGImage.new(width: 100, height: 100)
|
46
|
+
@parent_taxon = taxon
|
47
|
+
@taxon_stats = {}
|
48
|
+
@all_otus = []
|
49
|
+
end
|
50
|
+
|
51
|
+
def render
|
52
|
+
end
|
53
|
+
|
54
|
+
def render_fish(taxon)
|
55
|
+
get_metadata(taxon)
|
56
|
+
|
57
|
+
METADATA.each do |entity, v|
|
58
|
+
draw_fish_part(
|
59
|
+
v[0], v[1], v[2], v[3],
|
60
|
+
style: {
|
61
|
+
fill: svg_color(taxon, entity, :cells),
|
62
|
+
stroke: svg_color(taxon, entity, :rows),
|
63
|
+
'stroke-width'.to_sym => '0.5'
|
64
|
+
}
|
65
|
+
)
|
66
|
+
end
|
67
|
+
puts img.to_s
|
68
|
+
end
|
69
|
+
|
70
|
+
def svg_color(taxon, entity, attribute)
|
71
|
+
"rgb(#{(taxon_stats[taxon][entity][:crunched][attribute] * 255).to_i}, 0, 0)"
|
72
|
+
end
|
73
|
+
|
74
|
+
def draw_fish_part(x, y, width, height, style: {})
|
75
|
+
img.rectangle x, y, width, height, style: style
|
76
|
+
end
|
77
|
+
|
78
|
+
# @return [XML]
|
79
|
+
def get_nexml(taxon, entity)
|
80
|
+
Phenoscape::Ontotrace.ontotrace(taxon: iri_for(taxon), entity: some_iri(entity), ret: 'noko')
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_metadata(taxon)
|
84
|
+
@taxon_stats[taxon] ||= {}
|
85
|
+
METADATA.each do |k, v|
|
86
|
+
@taxon_stats[taxon][k] ||= {}
|
87
|
+
@taxon_stats[taxon][k][:raw] ||= {}
|
88
|
+
|
89
|
+
xml = get_nexml(taxon, k)
|
90
|
+
o = SimpleNexml.new(doc: xml, taxon: taxon)
|
91
|
+
@taxon_stats[taxon][k][:raw] = o.stats[:count]
|
92
|
+
end
|
93
|
+
|
94
|
+
crunch_stats(taxon)
|
95
|
+
end
|
96
|
+
|
97
|
+
def crunch_stats(taxon)
|
98
|
+
totals = { otus: 0, rows: 0, cells: 0}
|
99
|
+
|
100
|
+
taxon_stats[taxon].keys.each do |entity|
|
101
|
+
taxon_stats[taxon][entity][:raw].each do |k, count|
|
102
|
+
totals[k] += count
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
METADATA.each do |entity, v|
|
107
|
+
taxon_stats[taxon][entity][:crunched] ||= {}
|
108
|
+
totals.keys.each do |t|
|
109
|
+
taxon_stats[taxon][entity][:crunched][t] = taxon_stats[taxon][entity][:raw][t].to_f / totals[t].to_f
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_all_metadata
|
115
|
+
get_metadata(parent_taxon)
|
116
|
+
end
|
117
|
+
|
118
|
+
def some_iri(entity)
|
119
|
+
iri_for('BFO_0000050') + ' some ' + iri_for(entity)
|
120
|
+
end
|
121
|
+
|
122
|
+
def iri_for(id)
|
123
|
+
'<' + BASE + id + '>'
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
# f.get_all_metadata
|
131
|
+
|
132
|
+
# curl -X GET "http://kb.phenoscape.org/api/taxon/annotations?entity=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FUBERON_0001703&quality=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FPATO_0000052&in_taxon=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FVTO_0037519&parts=true&historical_homologs=false&serial_homologs=false&limit=20&offset=0&total=true" -H "accept: application/json"
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# TODO: this doesn't belong in this repo
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
# Parse NeXML document and return some data
|
6
|
+
class SimpleNexml
|
7
|
+
|
8
|
+
attr_accessor :doc
|
9
|
+
attr_accessor :taxon
|
10
|
+
attr_accessor :entity
|
11
|
+
|
12
|
+
def initialize(doc: nil, taxon: nil, entity: nil)
|
13
|
+
@doc = doc
|
14
|
+
end
|
15
|
+
|
16
|
+
def stats
|
17
|
+
return {
|
18
|
+
count: {
|
19
|
+
otus: otus.count,
|
20
|
+
rows: rows.count,
|
21
|
+
cells: cells.count
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def otus
|
27
|
+
doc.css("otus")
|
28
|
+
end
|
29
|
+
|
30
|
+
def cells
|
31
|
+
doc.css("cell")
|
32
|
+
end
|
33
|
+
|
34
|
+
def rows
|
35
|
+
doc.css("row")
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Array]
|
39
|
+
# all chars referenced in rows
|
40
|
+
def referenced_chars
|
41
|
+
cells.inject({}) {|hsh, c| hsh.merge!(c.to_h['char'] => nil)}.keys
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Array]
|
45
|
+
# all states referenced in rows
|
46
|
+
def referenced_states
|
47
|
+
cells.inject({}) {|hsh, c| hsh.merge!(c.to_h['state'] => nil)}.keys
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Array]
|
51
|
+
# all chars referenced in rows
|
52
|
+
def referenced_otus
|
53
|
+
rows.css("row").inject({}) {|hsh, c| hsh.merge!(c.to_h['otu'] => nil)}.keys
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module FishTank
|
2
|
+
class Taxon
|
3
|
+
|
4
|
+
# METADATA = {}
|
5
|
+
|
6
|
+
attr_accessor :label
|
7
|
+
attr_accessor :stats
|
8
|
+
|
9
|
+
def initialize(taxon_id: nil)
|
10
|
+
@label = taxon_id
|
11
|
+
@stats = {}
|
12
|
+
get_metadata
|
13
|
+
crunch_stats
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [XML]
|
17
|
+
def get_nexml(entity)
|
18
|
+
Phenoscape::Ontotrace.ontotrace(taxon: iri_for(label), entity: some_iri(entity), ret: 'noko')
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Integer]
|
22
|
+
def get_phenotype_total(entity, quality)
|
23
|
+
Phenoscape::Taxa.annotations(
|
24
|
+
in_taxon: base_for(label),
|
25
|
+
entity: base_for(entity),
|
26
|
+
quality: base_for(quality),
|
27
|
+
total: true,
|
28
|
+
parts: true
|
29
|
+
)['total']
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_metadata
|
33
|
+
@stats ||= {}
|
34
|
+
description.each do |k, v|
|
35
|
+
@stats[k] ||= {}
|
36
|
+
@stats[k][:raw] ||= {}
|
37
|
+
|
38
|
+
xml = get_nexml(k)
|
39
|
+
o = SimpleNexml.new(doc: xml, taxon: label)
|
40
|
+
@stats[k][:raw] = o.stats[:count]
|
41
|
+
|
42
|
+
FishTank::QUALITIES.each do |q|
|
43
|
+
@stats[k][:raw][q] = get_phenotype_total(k, q)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
def crunch_stats
|
50
|
+
totals = {}
|
51
|
+
|
52
|
+
stats.keys.each do |entity|
|
53
|
+
stats[entity][:raw].each do |k, count|
|
54
|
+
totals[k] ||= 0
|
55
|
+
totals[k] += count
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
description.each do |entity, v|
|
60
|
+
stats[entity][:crunched] ||= {}
|
61
|
+
totals.keys.each do |t|
|
62
|
+
v = totals[t] == 0 ? 0.to_f : stats[entity][:raw][t].to_f / totals[t].to_f
|
63
|
+
stats[entity][:crunched][t] = v
|
64
|
+
end
|
65
|
+
end
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
def some_iri(entity)
|
70
|
+
iri_for('BFO_0000050') + ' some ' + iri_for(entity)
|
71
|
+
end
|
72
|
+
|
73
|
+
def iri_for(id)
|
74
|
+
'<' + base_for(id) + '>'
|
75
|
+
end
|
76
|
+
|
77
|
+
def base_for(id)
|
78
|
+
BASE + id
|
79
|
+
end
|
80
|
+
|
81
|
+
def attributes
|
82
|
+
end
|
83
|
+
|
84
|
+
def symmetry
|
85
|
+
return {}
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [Integer]
|
89
|
+
def pic_width
|
90
|
+
60
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [Integer]
|
94
|
+
def pic_height
|
95
|
+
100
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module FishTank
|
2
|
+
|
3
|
+
# Generic Arm/limb
|
4
|
+
class Taxon::Arm < FishTank::Taxon
|
5
|
+
|
6
|
+
def description
|
7
|
+
return {
|
8
|
+
'UBERON_0000976' => [15, 0, 10, 20], # 'humerus'
|
9
|
+
|
10
|
+
'UBERON_0001423' => [12, 22, 6, 20], # 'radius'
|
11
|
+
'UBERON_0001424' => [22, 22, 6, 20], # 'ulna'
|
12
|
+
|
13
|
+
'UBERON_0001435' => [10, 44, 20, 15 ], # 'carpal bone'
|
14
|
+
'UBERON_0002374' => [8, 61, 24, 15 ], # 'metacarpal bone'
|
15
|
+
|
16
|
+
'UBERON_0006048' => [8, 78, 4, 10 ], # 'digit 1'
|
17
|
+
'UBERON_0006049' => [13, 78, 4, 10 ], # 'digit 2'
|
18
|
+
'UBERON_0006050' => [18, 78, 4, 10 ], # 'digit 3'
|
19
|
+
'UBERON_0006051' => [23, 78, 4, 10 ], # 'digit 4'
|
20
|
+
'UBERON_0006052' => [28, 78, 4, 10 ], # 'digit 5'
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
module FishTank
|
3
|
+
class Taxon::Fish < FishTank::Taxon
|
4
|
+
|
5
|
+
# Ugh
|
6
|
+
def description
|
7
|
+
return {
|
8
|
+
'UBERON_0001703' => [0, 10, 10, 10], # 'neurocranium'
|
9
|
+
'UBERON_0000970' => [3, 12, 3, 3], # 'eye'
|
10
|
+
'UBERON_0001708' => [1, 17, 5, 2], # 'jaw skeleton'
|
11
|
+
'UBERON_0002090' => [10, 10, 30, 10], # 'post-cranial axial skeleton'
|
12
|
+
'UBERON_0003097' => [12, 0, 10, 10], # 'dorsal fin'
|
13
|
+
'UBERON_0000151' => [5, 20, 10, 10], # 'pectoral fin'
|
14
|
+
'UBERON_0000152' => [17, 20, 10, 10], # 'pelvic fin'
|
15
|
+
'UBERON_4000164' => [30, 5, 10, 20], # 'caudal fin'
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def pic_height
|
20
|
+
50
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module FishTank
|
2
|
+
|
3
|
+
# Generic Tetrapod
|
4
|
+
class Taxon::Tetrapod < FishTank::Taxon
|
5
|
+
|
6
|
+
# TODO: Update UBERON terms to represent actually meaningful layout, this was cloned from Fish
|
7
|
+
def description
|
8
|
+
return {
|
9
|
+
'UBERON_0001703' => [10, 0, 10, 9], # 'neurocranium'
|
10
|
+
'UBERON_0000970' => [8, 3, 4, 4], # 'eye'
|
11
|
+
'UBERON_0001708' => [12, 0, 4, 2], # 'jaw skeleton'
|
12
|
+
'UBERON_0014477' => [10, 10, 10, 30], # thoracic skeleton
|
13
|
+
'UBERON_0002102' => [0, 16, 10, 6], # forelimb
|
14
|
+
'UBERON_0002103' => [0, 26, 10, 6], # hindlimb
|
15
|
+
'UBERON_0002415' => [13, 40, 3, 15], # tail
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def symmetry
|
20
|
+
return {
|
21
|
+
'UBERON_0000970' => [18, 3, 4, 4],
|
22
|
+
'UBERON_0002102' => [20, 16, 10, 6],
|
23
|
+
'UBERON_0002103' => [20, 26, 10, 6]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def pic_height
|
28
|
+
75
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fishtank
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Yoder
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-12-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: phenoscaperb
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rasem
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.16'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.16'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: awesome_print
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: byebug
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: An experiment to map various attributes of the Phenoscape KB to cartoon
|
112
|
+
figures, using SVG.
|
113
|
+
email:
|
114
|
+
- diapriid@gmail.com
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".gitignore"
|
120
|
+
- ".rspec"
|
121
|
+
- ".travis.yml"
|
122
|
+
- Gemfile
|
123
|
+
- Gemfile.lock
|
124
|
+
- LICENSE
|
125
|
+
- LICENSE.txt
|
126
|
+
- README.md
|
127
|
+
- Rakefile
|
128
|
+
- bin/console
|
129
|
+
- bin/setup
|
130
|
+
- doc/viz.png
|
131
|
+
- fishtank.gemspec
|
132
|
+
- lib/fishtank.rb
|
133
|
+
- lib/fishtank/draw.rb
|
134
|
+
- lib/fishtank/fishtank.rb
|
135
|
+
- lib/fishtank/simple_nexml.rb
|
136
|
+
- lib/fishtank/tank.rb
|
137
|
+
- lib/fishtank/taxon.rb
|
138
|
+
- lib/fishtank/taxon/arm.rb
|
139
|
+
- lib/fishtank/taxon/fish.rb
|
140
|
+
- lib/fishtank/taxon/tetrapod.rb
|
141
|
+
- lib/fishtank/version.rb
|
142
|
+
homepage: https://github.com/phenoscape/fishtank
|
143
|
+
licenses:
|
144
|
+
- MIT
|
145
|
+
metadata: {}
|
146
|
+
post_install_message:
|
147
|
+
rdoc_options: []
|
148
|
+
require_paths:
|
149
|
+
- lib
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
requirements: []
|
161
|
+
rubyforge_project:
|
162
|
+
rubygems_version: 2.6.13
|
163
|
+
signing_key:
|
164
|
+
specification_version: 4
|
165
|
+
summary: A visualization experiment for the Phenoscape KB.
|
166
|
+
test_files: []
|