ruby-igv 0.0.8 → 0.0.10
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 +4 -4
- data/README.md +69 -19
- data/lib/igv/version.rb +1 -1
- data/lib/igv.rb +401 -131
- metadata +4 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19fb874a7ea3fe0edee703b42b481db4c718609287a1ed4c1407a03bec2b1e9a
|
4
|
+
data.tar.gz: 982188fc06b54fc0d772f1b0fb21228c2aa9a0d7c2319c527b03f0b5411cb916
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e6035336e6cf7a1d850dd33bf565a54e8c32283a40992e496f94ec516ba8a1a054ea283b5dfb16d5bf700efc296b37a85cb19827f7154b0b9756b6baa123d53
|
7
|
+
data.tar.gz: 36bac381a140a15803418711682e5b4f82c1442703d467042f0d3a76db311ed2da675846792333582465aff98e4f6647469d03bc11d5dfaf1a9c542ccfd6595e
|
data/README.md
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
# ruby-igv
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/ruby-igv)
|
4
|
-
[](https://rubydoc.info/gems/ruby-igv)
|
5
|
+
[](https://kojix2.github.io/ruby-igv)
|
5
6
|
[](LICENSE.txt)
|
6
7
|
[](https://zenodo.org/badge/latestdoi/281373245)
|
7
8
|
|
8
9
|
Ruby-IGV is a simple tool for controlling the Integrated Genomics Viewer (IGV) from the Ruby language. It provides an automated way to load files, specify genome locations, and take and save screenshots using IGV.
|
9
10
|
|
10
|
-
<img src="https://user-images.githubusercontent.com/5798442/182540876-c3ca2906-7d05-4c93-9107-ce4135ae9765.png" align="right">
|
11
|
-
|
12
11
|
## Installation
|
13
12
|
|
14
|
-
|
13
|
+
<img src="https://user-images.githubusercontent.com/5798442/182540876-c3ca2906-7d05-4c93-9107-ce4135ae9765.png" width="300" align="right">
|
14
|
+
|
15
|
+
Requirement :
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
- [Ruby](https://github.com/ruby/ruby)
|
18
|
+
- [IGV (Integrative Genomics Viewer)](http://software.broadinstitute.org/software/igv/)
|
19
|
+
- [Enable IGV to listen on the port](https://software.broadinstitute.org/software/igv/Preferences#Advanced)
|
20
|
+
- View > Preference > Advanced > Enable port ☑
|
20
21
|
|
21
22
|
```ruby
|
22
23
|
gem install ruby-igv
|
@@ -24,7 +25,7 @@ gem install ruby-igv
|
|
24
25
|
|
25
26
|
## Quickstart
|
26
27
|
|
27
|
-
<img src="https://user-images.githubusercontent.com/5798442/182623864-a9fa59aa-abb9-4cb1-8311-2b3479b7414e.png" width="300" align="
|
28
|
+
<img src="https://user-images.githubusercontent.com/5798442/182623864-a9fa59aa-abb9-4cb1-8311-2b3479b7414e.png" width="300" align="right">
|
28
29
|
|
29
30
|
```ruby
|
30
31
|
require 'igv'
|
@@ -42,9 +43,9 @@ igv.snapshot 'region.png'
|
|
42
43
|
|
43
44
|
## Usage
|
44
45
|
|
45
|
-
### commands
|
46
|
+
### IGV batch commands
|
46
47
|
|
47
|
-
The commonly used commands in IGV are summarized in the official [list of
|
48
|
+
The commonly used commands in IGV are summarized in the official [list of batch commands](https://igv.org/doc/desktop/#UserGuide/tools/batch/#script-commands). (but even this does not seem to be all of them). You can also call the `commands` method from Ruby to open a browser and view the list.
|
48
49
|
|
49
50
|
```ruby
|
50
51
|
igv.commands # Show the IGV command reference in your browser
|
@@ -52,16 +53,35 @@ igv.commands # Show the IGV command reference in your browser
|
|
52
53
|
|
53
54
|
### docs
|
54
55
|
|
55
|
-
See [docs](https://
|
56
|
+
See [yard docs](https://kojix2.github.io/ruby-igv/).
|
57
|
+
Most IGV batch commands are available as Ruby methods of the same name.
|
58
|
+
If you need to use a command not directly wrapped, you can use the `send` method as shown below.
|
56
59
|
|
57
60
|
### send
|
58
61
|
|
59
|
-
|
62
|
+
You can send any IGV batch command using the `send` method.
|
60
63
|
|
61
64
|
```ruby
|
62
65
|
igv.send("maxPanelHeight", 10)
|
66
|
+
igv.send("scrollToTop")
|
67
|
+
igv.send("setAccessToken", "token", "host")
|
63
68
|
```
|
64
69
|
|
70
|
+
To avoid unexpected behavior, ruby-igv does not use the `method_missing` mechanism.
|
71
|
+
|
72
|
+
### Supported IGV batch commands
|
73
|
+
|
74
|
+
Most official IGV batch commands are available as Ruby methods, including:
|
75
|
+
|
76
|
+
- collapse, color_by, echo, exit, expand, genome, goto, group, load, max_panel_height, new, overlay, preference, region, save_session, scroll_to_top, separate, set_alt_color, set_color, set_data_range, set_log_scale, set_sequence_strand, set_sequence_show_translation, set_sleep_interval, set_track_height, snapshot_dir, snapshot, sort, squish, viewaspairs, set_access_token, clear_access_tokens
|
77
|
+
|
78
|
+
See the [official IGV batch command list](https://igv.org/doc/desktop/#UserGuide/tools/batch/#script-commands) for details.
|
79
|
+
|
80
|
+
### Return values and error handling
|
81
|
+
|
82
|
+
Most methods return the IGV response string (e.g. "OK" or an error message).
|
83
|
+
You can check the return value to handle errors or confirm success.
|
84
|
+
|
65
85
|
### Launch IGV
|
66
86
|
|
67
87
|
Launch IGV from Ruby script.
|
@@ -70,11 +90,39 @@ Launch IGV from Ruby script.
|
|
70
90
|
igv = IGV.start # launch IGV app using spawn
|
71
91
|
```
|
72
92
|
|
93
|
+
You can specify the port.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
igv = IGV.start(port: 60152)
|
97
|
+
```
|
98
|
+
|
99
|
+
If you start IGV in this way, you can force IGV to terminate by calling the kill method.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
igv.kill
|
103
|
+
```
|
104
|
+
|
73
105
|
### Open socket connection to IGV
|
74
106
|
|
107
|
+
If IGV is already running, use `new` or `open`.
|
108
|
+
|
109
|
+
new
|
110
|
+
|
75
111
|
```ruby
|
76
112
|
igv = IGV.new # create an IGV object. Then you will type `igv.connect`
|
113
|
+
igv = IGV.new(host: "127.0.0.1", port: 60151, snapshot_dir: "~/igv_snapshot")
|
114
|
+
igv.connect # To start a connection, call connect explicitly.
|
115
|
+
igv.close
|
116
|
+
```
|
117
|
+
|
118
|
+
open
|
119
|
+
|
120
|
+
```ruby
|
77
121
|
igv = IGV.open # create an IGV object and connect it to an already activated IGV.
|
122
|
+
igv.close
|
123
|
+
IGV.open(host: "127.0.0.1", port: 60151, snapshot_dir: "~/igv_snapshot") do |igv|
|
124
|
+
# do something
|
125
|
+
end # The socket is automatically closed.
|
78
126
|
```
|
79
127
|
|
80
128
|
### Close IGV
|
@@ -90,20 +138,22 @@ igv.kill # kill group pid created with IGV.start
|
|
90
138
|
|
91
139
|
## Contributing
|
92
140
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
141
|
+
- [Report bugs](https://github.com/kojix2/ruby-igv/issues)
|
142
|
+
- Fix bugs and submit [pull requests](https://github.com/kojix2/ruby-igv/pulls)
|
143
|
+
- Write, clarify, or fix documentation
|
144
|
+
- Suggest or add new features
|
97
145
|
|
98
146
|
```
|
99
|
-
Do you need commit rights to
|
147
|
+
Do you need commit rights to this repository?
|
100
148
|
Do you want to get admin rights and take over the project?
|
101
149
|
If so, please feel free to contact me @kojix2.
|
102
150
|
```
|
103
151
|
|
104
152
|
## Acknowledgement
|
153
|
+
|
105
154
|
This gem is strongly inspired by a Python script developed by Brent Pedersen.
|
106
|
-
|
155
|
+
|
156
|
+
- [brentp/bio-playground/igv](https://github.com/brentp/bio-playground).
|
107
157
|
|
108
158
|
## License
|
109
159
|
|
data/lib/igv/version.rb
CHANGED
data/lib/igv.rb
CHANGED
@@ -1,25 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'igv/version'
|
4
|
+
require 'uri'
|
4
5
|
require 'socket'
|
5
6
|
require 'fileutils'
|
6
7
|
|
7
|
-
# The Integrative Genomics Viewer (IGV)
|
8
|
-
#
|
8
|
+
# The Integrative Genomics Viewer (IGV) Ruby client.
|
9
|
+
# Provides a Ruby interface to control IGV via its batch command protocol.
|
10
|
+
#
|
11
|
+
# @see https://igv.org/doc/desktop/#UserGuide/tools/batch/#script-commands IGV Batch Script Documentation
|
9
12
|
class IGV
|
10
13
|
class Error < StandardError; end
|
11
14
|
|
12
15
|
attr_reader :host, :port, :history
|
13
16
|
|
14
|
-
# Create IGV client object
|
17
|
+
# Create IGV client object.
|
15
18
|
#
|
16
|
-
# @param host [String]
|
17
|
-
# @param port [Integer]
|
18
|
-
# @param
|
19
|
-
# @return [IGV] IGV client object
|
20
|
-
|
19
|
+
# @param host [String] Hostname or IP address of IGV server.
|
20
|
+
# @param port [Integer] Port number of IGV server.
|
21
|
+
# @param snapshot_dir [String] Directory path to save snapshots.
|
22
|
+
# @return [IGV] IGV client object.
|
21
23
|
def initialize(host: '127.0.0.1', port: 60_151, snapshot_dir: Dir.pwd)
|
22
|
-
raise ArgumentError, '
|
24
|
+
raise ArgumentError, 'IGV#initialize does not accept a block.' if block_given?
|
23
25
|
|
24
26
|
@host = host
|
25
27
|
@port = port
|
@@ -27,15 +29,14 @@ class IGV
|
|
27
29
|
@history = []
|
28
30
|
end
|
29
31
|
|
30
|
-
# Create IGV object and connect to IGV server
|
32
|
+
# Create IGV object and connect to IGV server.
|
31
33
|
# This method accepts a block.
|
32
34
|
#
|
33
|
-
# @param host [String]
|
34
|
-
# @param port [Integer]
|
35
|
-
# @param
|
36
|
-
# @
|
37
|
-
# @
|
38
|
-
|
35
|
+
# @param host [String] Hostname or IP address of IGV server.
|
36
|
+
# @param port [Integer] Port number of IGV server.
|
37
|
+
# @param snapshot_dir [String] Directory path to save snapshots.
|
38
|
+
# @yield [IGV] IGV client object.
|
39
|
+
# @return [IGV] IGV client object.
|
39
40
|
def self.open(host: '127.0.0.1', port: 60_151, snapshot_dir: Dir.pwd)
|
40
41
|
igv = new(host: host, port: port, snapshot_dir: snapshot_dir)
|
41
42
|
igv.connect
|
@@ -49,23 +50,27 @@ class IGV
|
|
49
50
|
igv
|
50
51
|
end
|
51
52
|
|
53
|
+
# Check if a port is open.
|
54
|
+
# @param port [Integer] Port number.
|
55
|
+
# @return [Boolean, nil] true if open, false if closed, nil if unknown.
|
52
56
|
def self.port_open?(port)
|
53
|
-
|
57
|
+
system("lsof -i:#{port}", out: '/dev/null')
|
54
58
|
end
|
55
59
|
private_class_method :port_open?
|
56
60
|
|
57
|
-
# Launch IGV from
|
61
|
+
# Launch IGV from Ruby script.
|
58
62
|
#
|
59
|
-
# @param port [Integer]
|
60
|
-
# @param command [String]
|
61
|
-
# @param snapshot_dir [String]
|
62
|
-
# @return [IGV] IGV client object
|
63
|
-
|
63
|
+
# @param port [Integer] Port number.
|
64
|
+
# @param command [String] Command to launch IGV.
|
65
|
+
# @param snapshot_dir [String] Directory path to save snapshots.
|
66
|
+
# @return [IGV] IGV client object.
|
67
|
+
# @note This will spawn a new IGV process and connect to it.
|
64
68
|
def self.start(port: 60_151, command: 'igv', snapshot_dir: Dir.pwd)
|
65
69
|
case port_open?(port)
|
66
|
-
when nil then warn "Cannot tell if port #{port} is open"
|
67
|
-
when
|
68
|
-
when
|
70
|
+
when nil then warn "[ruby-igv] Cannot tell if port #{port} is open"
|
71
|
+
when true then raise("Port #{port} is already in use")
|
72
|
+
when false then warn "[ruby-igv] Port #{port} is available"
|
73
|
+
else raise "Unexpected return value from port_open?(#{port})"
|
69
74
|
end
|
70
75
|
r, w = IO.pipe
|
71
76
|
pid_igv = spawn(command, '-p', port.to_s, pgroup: true, out: w, err: w)
|
@@ -77,43 +82,49 @@ class IGV
|
|
77
82
|
break if line.include? "Listening on port #{port}"
|
78
83
|
end
|
79
84
|
puts "\e[0m"
|
80
|
-
igv = open(port: port, snapshot_dir: snapshot_dir)
|
85
|
+
igv = self.open(port: port, snapshot_dir: snapshot_dir)
|
81
86
|
igv.instance_variable_set(:@pgid_igv, pgid_igv)
|
82
87
|
igv
|
83
88
|
end
|
84
89
|
|
85
|
-
# Kill IGV process by process group id
|
86
|
-
|
90
|
+
# Kill IGV process by process group id.
|
91
|
+
#
|
92
|
+
# @note Only works for IGV processes started by IGV.start.
|
93
|
+
# @return [nil] Kills the IGV process if started by this client, otherwise does nothing.
|
87
94
|
def kill
|
88
95
|
if instance_variable_defined?(:@pgid_igv)
|
89
|
-
warn
|
90
|
-
'This method kills the process with the group ID specified at startup. ' \
|
91
|
-
'Please use exit or quit if possible.'
|
96
|
+
warn '[ruby-igv] This method kills the process with the group ID specified at startup. Please use exit or quit if possible.'
|
92
97
|
else
|
93
|
-
warn
|
94
|
-
|
95
|
-
'Otherwise, use exit or quit.'
|
96
|
-
return
|
98
|
+
warn '[ruby-igv] The kill method terminates only IGV commands invoked by the start method. Otherwise, use exit or quit.'
|
99
|
+
return nil
|
97
100
|
end
|
98
101
|
pgid = @pgid_igv
|
99
102
|
Process.kill(:TERM, -pgid)
|
100
103
|
close
|
104
|
+
nil
|
101
105
|
end
|
102
106
|
|
103
|
-
# Connect to IGV server
|
104
|
-
|
107
|
+
# Connect to IGV server.
|
108
|
+
#
|
109
|
+
# @param host2 [String] Hostname or IP address.
|
110
|
+
# @param port2 [Integer] Port number.
|
111
|
+
# @param connect_timeout [Integer, nil] Timeout in seconds.
|
112
|
+
# @return [self] Returns self for method chaining.
|
105
113
|
def connect(host2 = @host, port2 = @port, connect_timeout: nil)
|
106
114
|
@socket&.close
|
107
115
|
@socket = Socket.tcp(host2, port2, connect_timeout: connect_timeout)
|
116
|
+
self
|
108
117
|
end
|
109
118
|
|
110
|
-
# Close the socket.
|
111
|
-
#
|
112
|
-
|
119
|
+
# Close the socket. This does not exit IGV.
|
120
|
+
# @return [nil] Closes the socket and returns nil.
|
113
121
|
def close
|
114
122
|
@socket&.close
|
123
|
+
nil
|
115
124
|
end
|
116
125
|
|
126
|
+
# Check if the socket is closed.
|
127
|
+
# @return [Boolean]
|
117
128
|
def closed?
|
118
129
|
return true if @socket.nil?
|
119
130
|
|
@@ -122,18 +133,19 @@ class IGV
|
|
122
133
|
|
123
134
|
# Send batch commands to IGV.
|
124
135
|
#
|
125
|
-
# @param
|
126
|
-
# @return [String]
|
127
|
-
|
136
|
+
# @param cmds [Array<String, Symbol, Numeric>] Batch commands.
|
137
|
+
# @return [String] Response from IGV.
|
138
|
+
# @example
|
139
|
+
# igv.send("goto", "chr1:1000-2000")
|
128
140
|
def send(*cmds)
|
129
141
|
cmd = \
|
130
142
|
cmds
|
131
143
|
.compact
|
132
|
-
.map do |
|
133
|
-
case
|
134
|
-
when String, Symbol, Numeric then
|
135
|
-
when ->(c) { c.respond_to?(:to_str) } then
|
136
|
-
else raise ArgumentError, "#{
|
144
|
+
.map do |cm|
|
145
|
+
case cm
|
146
|
+
when String, Symbol, Numeric then cm.to_s
|
147
|
+
when ->(c) { c.respond_to?(:to_str) } then cm.to_str
|
148
|
+
else raise ArgumentError, "#{cm.inspect} is not a string"
|
137
149
|
end.strip.encode(Encoding::UTF_8)
|
138
150
|
end
|
139
151
|
.join(' ')
|
@@ -144,40 +156,42 @@ class IGV
|
|
144
156
|
|
145
157
|
# Syntactic sugar for IGV commands that begin with set.
|
146
158
|
#
|
159
|
+
# @param cmd [String, Symbol] Batch command name (without "set" prefix).
|
160
|
+
# @param params [Array<String, Symbol, Numeric>] Parameters for the command.
|
161
|
+
# @return [String] Response from IGV.
|
147
162
|
# @example
|
148
163
|
# igv.set :SleepInterval, 100
|
149
164
|
# igv.send "setSleepInterval", 100 # same as above
|
150
|
-
# @param cmd [String, Symbol] batch commands
|
151
|
-
# @param *params [String, Symbol, Numeric] batch commands
|
152
|
-
|
153
165
|
def set(cmd, *params)
|
154
166
|
cmd = "set#{cmd}"
|
155
167
|
send(cmd, *params)
|
156
168
|
end
|
157
169
|
|
158
|
-
#
|
159
|
-
# https://github.com/igvteam/igv/wiki/Batch-commands
|
160
|
-
|
170
|
+
# Open IGV batch command documentation in the browser.
|
161
171
|
def commands
|
162
172
|
require 'launchy'
|
163
|
-
Launchy.open('https://
|
173
|
+
Launchy.open('https://igv.org/doc/desktop/#UserGuide/tools/batch/#script-commands')
|
164
174
|
end
|
165
175
|
|
166
|
-
#
|
167
|
-
# @note IGV Batch command
|
176
|
+
# Write the value of "param" back to the response.
|
168
177
|
#
|
169
|
-
# @
|
178
|
+
# @note IGV Batch command: echo
|
179
|
+
# @param param [String, nil] The parameter to echo.
|
170
180
|
# @return [String] The value of "param". If param is not specified, "echo".
|
171
|
-
|
181
|
+
# @example
|
182
|
+
# igv.echo("Hello!") #=> "Hello!"
|
172
183
|
def echo(param = nil)
|
173
184
|
send :echo, param
|
174
185
|
end
|
175
186
|
|
176
|
-
#
|
177
|
-
# @note IGV Batch command
|
187
|
+
# Select a genome by id, or load a genome (or indexed fasta) from the supplied path.
|
178
188
|
#
|
179
|
-
# @
|
180
|
-
|
189
|
+
# @note IGV Batch command: genome
|
190
|
+
# @param name_or_path [String] Genome id (e.g. "hg19") or path to fasta/indexed genome.
|
191
|
+
# @return [String] IGV response.
|
192
|
+
# @example
|
193
|
+
# igv.genome("hg19")
|
194
|
+
# igv.genome("/path/to/genome.fa")
|
181
195
|
def genome(name_or_path)
|
182
196
|
path = File.expand_path(name_or_path)
|
183
197
|
if File.exist?(path)
|
@@ -187,12 +201,15 @@ class IGV
|
|
187
201
|
end
|
188
202
|
end
|
189
203
|
|
190
|
-
#
|
191
|
-
# @note IGV Batch command
|
204
|
+
# Load a data or session file by specifying a full path to a local file or a URL.
|
192
205
|
#
|
193
|
-
# @
|
194
|
-
# @param
|
195
|
-
|
206
|
+
# @note IGV Batch command: load
|
207
|
+
# @param path_or_url [String] Path to a local file or a URL.
|
208
|
+
# @param index [String, nil] Optional index file path.
|
209
|
+
# @return [String] IGV response.
|
210
|
+
# @example
|
211
|
+
# igv.load("http://example.com/data.bam")
|
212
|
+
# igv.load("/path/to/data.bam", index: "/path/to/data.bai")
|
196
213
|
def load(path_or_url, index: nil)
|
197
214
|
path_or_url = if URI.parse(path_or_url).scheme
|
198
215
|
path_or_url
|
@@ -201,29 +218,42 @@ class IGV
|
|
201
218
|
end
|
202
219
|
index = "index=#{index}" if index
|
203
220
|
send :load, path_or_url, index
|
221
|
+
rescue URI::InvalidURIError
|
222
|
+
raise ArgumentError, "Invalid URI or file path: #{path_or_url}"
|
204
223
|
end
|
205
224
|
|
206
|
-
# Go to the specified location
|
207
|
-
# @note IGV Batch command
|
225
|
+
# Go to the specified location or list of loci.
|
208
226
|
#
|
209
|
-
# @
|
210
|
-
|
227
|
+
# @note IGV Batch command: goto
|
228
|
+
# @param position [String] Locus or list of loci (e.g. "chr1:1000-2000").
|
229
|
+
# @return [String] IGV response.
|
230
|
+
# @example
|
231
|
+
# igv.goto("chr1:1000-2000")
|
211
232
|
def goto(position)
|
212
233
|
send :goto, position
|
213
234
|
end
|
214
235
|
alias go goto
|
215
236
|
|
216
|
-
#
|
217
|
-
# @note IGV Batch command
|
237
|
+
# Define a region of interest bounded by the two loci.
|
218
238
|
#
|
219
|
-
# @
|
220
|
-
# @param
|
221
|
-
# @param
|
222
|
-
|
239
|
+
# @note IGV Batch command: region
|
240
|
+
# @param chr [String] Chromosome name.
|
241
|
+
# @param start [Integer] Start position.
|
242
|
+
# @param end_ [Integer] End position.
|
243
|
+
# @return [String] IGV response.
|
244
|
+
# @example
|
245
|
+
# igv.region("chr1", 100, 200)
|
223
246
|
def region(chr, start, end_)
|
224
247
|
send :region, chr, start, end_
|
225
248
|
end
|
226
249
|
|
250
|
+
# Sort alignment or segmented copy number tracks.
|
251
|
+
#
|
252
|
+
# @note IGV Batch command: sort
|
253
|
+
# @param option [String] Sort option (e.g. "base", "position", "strand", "quality", "sample", "readGroup").
|
254
|
+
# @return [String] IGV response.
|
255
|
+
# @example
|
256
|
+
# igv.sort("position")
|
227
257
|
def sort(option = 'base')
|
228
258
|
vop = %w[base position strand quality sample readGroup]
|
229
259
|
raise "options is one of: #{vop.join(', ')}" unless vop.include? option
|
@@ -231,66 +261,97 @@ class IGV
|
|
231
261
|
send :sort, option
|
232
262
|
end
|
233
263
|
|
234
|
-
#
|
235
|
-
# @note IGV Batch command
|
264
|
+
# Expand a given track. If not specified, expands all tracks.
|
236
265
|
#
|
237
|
-
# @
|
238
|
-
#
|
239
|
-
|
266
|
+
# @note IGV Batch command: expand
|
267
|
+
# @param track [String, nil] Track name (optional).
|
268
|
+
# @return [String] IGV response.
|
269
|
+
# @example
|
270
|
+
# igv.expand
|
271
|
+
# igv.expand("track1")
|
240
272
|
def expand(track = nil)
|
241
273
|
send :expand, track
|
242
274
|
end
|
243
275
|
|
244
|
-
#
|
245
|
-
# @note IGV Batch command
|
276
|
+
# Collapse a given track. If not specified, collapses all tracks.
|
246
277
|
#
|
247
|
-
# @
|
248
|
-
#
|
249
|
-
|
278
|
+
# @note IGV Batch command: collapse
|
279
|
+
# @param track [String, nil] Track name (optional).
|
280
|
+
# @return [String] IGV response.
|
281
|
+
# @example
|
282
|
+
# igv.collapse
|
283
|
+
# igv.collapse("track1")
|
250
284
|
def collapse(track = nil)
|
251
285
|
send :collapse, track
|
252
286
|
end
|
253
287
|
|
254
|
-
# Squish a given track.
|
255
|
-
# @note IGV Batch command
|
288
|
+
# Squish a given track. If not specified, squishes all annotation tracks.
|
256
289
|
#
|
257
|
-
# @
|
258
|
-
#
|
259
|
-
|
290
|
+
# @note IGV Batch command: squish
|
291
|
+
# @param track [String, nil] Track name (optional).
|
292
|
+
# @return [String] IGV response.
|
293
|
+
# @example
|
294
|
+
# igv.squish
|
295
|
+
# igv.squish("track1")
|
260
296
|
def squish(track = nil)
|
261
297
|
send :squish, track
|
262
298
|
end
|
263
299
|
|
264
300
|
# Set the display mode for an alignment track to "View as pairs".
|
265
301
|
#
|
266
|
-
# @
|
267
|
-
#
|
268
|
-
|
302
|
+
# @note IGV Batch command: viewaspairs
|
303
|
+
# @param track [String, nil] Track name (optional).
|
304
|
+
# @return [String] IGV response.
|
305
|
+
# @example
|
306
|
+
# igv.viewaspairs
|
307
|
+
# igv.viewaspairs("track1")
|
269
308
|
def viewaspairs(track = nil)
|
270
309
|
send :viewaspairs, track
|
271
310
|
end
|
272
311
|
|
273
|
-
#
|
312
|
+
# Create a new session. Unloads all tracks except the default genome annotations.
|
313
|
+
#
|
314
|
+
# @note IGV Batch command: new
|
315
|
+
# @return [self] Returns self for method chaining.
|
316
|
+
# @example
|
317
|
+
# igv.new
|
318
|
+
def new
|
319
|
+
send :new
|
320
|
+
self
|
321
|
+
end
|
274
322
|
|
323
|
+
# Clear all loaded tracks and data.
|
324
|
+
#
|
325
|
+
# @note IGV Batch command: clear
|
326
|
+
# @return [self] Returns self for method chaining.
|
327
|
+
# @example
|
328
|
+
# igv.clear
|
275
329
|
def clear
|
276
330
|
send :clear
|
331
|
+
self
|
277
332
|
end
|
278
333
|
|
279
334
|
# Exit (close) the IGV application and close the socket.
|
280
|
-
#
|
281
|
-
|
335
|
+
#
|
336
|
+
# @note IGV Batch command: exit
|
337
|
+
# @return [nil] Exits IGV and closes the socket.
|
338
|
+
# @example
|
339
|
+
# igv.exit
|
282
340
|
def exit
|
283
341
|
send :exit
|
284
342
|
@socket.close
|
343
|
+
nil
|
285
344
|
end
|
286
345
|
alias quit exit
|
287
346
|
|
288
|
-
#
|
289
|
-
# Retruns the current snapshot directory if no argument is given.
|
290
|
-
# @note IGV Batch command (modified)
|
347
|
+
# Set or get the directory in which to write images (snapshots).
|
291
348
|
#
|
292
|
-
# @
|
293
|
-
|
349
|
+
# @note IGV Batch command: snapshotDirectory
|
350
|
+
# @param dir_path [String, nil] Directory path. If nil, returns current snapshot directory.
|
351
|
+
# @return [String] IGV response or current directory.
|
352
|
+
# @example
|
353
|
+
# igv.snapshot_dir("/tmp/snapshots")
|
354
|
+
# igv.snapshot_dir #=> "/tmp/snapshots"
|
294
355
|
def snapshot_dir(dir_path = nil)
|
295
356
|
return @snapshot_dir if dir_path.nil?
|
296
357
|
|
@@ -304,60 +365,269 @@ class IGV
|
|
304
365
|
|
305
366
|
private def snapshot_dir_internal(dir_path)
|
306
367
|
dir_path = File.expand_path(dir_path)
|
368
|
+
warn "[ruby-igv] Directory #{dir_path} does not exist. Creating it." unless File.exist?(dir_path)
|
307
369
|
FileUtils.mkdir_p(dir_path)
|
308
370
|
send :snapshotDirectory, dir_path
|
309
371
|
end
|
310
372
|
|
311
|
-
#
|
312
|
-
# If filename is omitted, writes a PNG file with a filename generated based on the locus.
|
313
|
-
# If filename is specified, the filename extension determines the image file format,
|
314
|
-
# which must be either .png or .svg.
|
315
|
-
# @note IGV Batch command (modified)
|
316
|
-
# @note In Ruby-IGV, it is possible to pass absolute or relative paths as well as file names;
|
317
|
-
# the Snapshot directory is set to Dir.pwd by default.
|
373
|
+
# Save a snapshot of the IGV window to an image file.
|
318
374
|
#
|
319
|
-
# @
|
375
|
+
# @note IGV Batch command: snapshot
|
376
|
+
# @param file_name [String, nil] Name of the image file. If nil, uses the current locus.
|
377
|
+
# If filename is omitted, writes a PNG file with a filename generated based on the locus.
|
378
|
+
# If filename is specified, the filename extension determines the image file format, which must be either .png or .svg.
|
379
|
+
# Passing a path might work, but is not recommended.
|
380
|
+
# @example
|
381
|
+
# igv.snapshot("region.png")
|
382
|
+
def snapshot(file_name = nil)
|
383
|
+
return send(:snapshot) if file_name.nil?
|
384
|
+
dir_path = File.dirname(file_name)
|
385
|
+
|
386
|
+
# file_name is a file name
|
387
|
+
return send(:snapshot, file_name) if dir_path == "."
|
320
388
|
|
321
|
-
|
322
|
-
|
389
|
+
# file_name is a path
|
390
|
+
file_path = file_name
|
391
|
+
warn "[ruby-igv] snapshot: Passing a path is not recommended. "
|
392
|
+
|
393
|
+
if File.absolute_path?(file_path)
|
394
|
+
dir_path = File.expand_path(dir_path)
|
395
|
+
else
|
396
|
+
dir_path = File.expand_path(File.join(@snapshot_dir, dir_path))
|
397
|
+
end
|
323
398
|
|
324
|
-
dir_path = File.dirname(file_path)
|
325
399
|
filename = File.basename(file_path)
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
r
|
400
|
+
|
401
|
+
# Only change directory if needed
|
402
|
+
if dir_path == @snapshot_dir
|
403
|
+
send(:snapshot, filename)
|
331
404
|
else
|
332
|
-
|
405
|
+
# Temporarily change snapshot directory
|
406
|
+
original_dir = @snapshot_dir
|
407
|
+
snapshot_dir_internal(dir_path)
|
408
|
+
result = send(:snapshot, filename)
|
409
|
+
snapshot_dir_internal(original_dir)
|
410
|
+
result
|
333
411
|
end
|
334
412
|
end
|
335
413
|
|
336
414
|
# Temporarily set the preference named key to the specified value.
|
337
|
-
# @note IGV Batch command
|
338
415
|
#
|
339
|
-
# @
|
340
|
-
# @param
|
341
|
-
|
416
|
+
# @note IGV Batch command: preference
|
417
|
+
# @param key [String] Preference key.
|
418
|
+
# @param value [String] Preference value.
|
419
|
+
# @return [String] IGV response.
|
420
|
+
# @see https://raw.githubusercontent.com/igvteam/igv/master/src/main/resources/org/broad/igv/prefs/preferences.tab
|
421
|
+
# @example
|
422
|
+
# igv.preferences("SAM.READ_GROUP_COLOR", "sample")
|
342
423
|
def preferences(key, value)
|
343
424
|
send :preferences, key, value
|
344
425
|
end
|
345
426
|
|
346
427
|
# Show "preference.tab" in your browser.
|
347
|
-
|
348
428
|
def show_preferences_table
|
349
429
|
require 'launchy'
|
350
430
|
Launchy.open('https://raw.githubusercontent.com/igvteam/igv/master/src/main/resources/org/broad/igv/prefs/preferences.tab')
|
351
431
|
end
|
352
432
|
|
353
433
|
# Save the current session.
|
354
|
-
# It is recommended that a full path be used for filename. IGV release 2.11.1
|
355
|
-
# @note IGV Batch command
|
356
434
|
#
|
357
|
-
# @
|
358
|
-
|
435
|
+
# @note IGV Batch command: saveSession
|
436
|
+
# @param file_path [String] Path to the session file.
|
437
|
+
# @return [String] IGV response.
|
438
|
+
# @example
|
439
|
+
# igv.save_session("session.xml")
|
359
440
|
def save_session(file_path)
|
360
441
|
file_path = File.expand_path(file_path)
|
361
442
|
send :saveSession, file_path
|
362
443
|
end
|
444
|
+
|
445
|
+
# Set the track "altColor", used for negative values in a wig track or negative strand features.
|
446
|
+
#
|
447
|
+
# @note IGV Batch command: setAltColor
|
448
|
+
# @param color [String] Color string (e.g. "255,0,0" or "FF0000").
|
449
|
+
# @param track [String] Track name.
|
450
|
+
# @return [String] IGV response.
|
451
|
+
# @example
|
452
|
+
# igv.set_alt_color("255,0,0", "track1")
|
453
|
+
def set_alt_color(color, track)
|
454
|
+
send :setAltColor, color, track
|
455
|
+
end
|
456
|
+
|
457
|
+
# Set the track color.
|
458
|
+
#
|
459
|
+
# @note IGV Batch command: setColor
|
460
|
+
# @param color [String] Color string (e.g. "255,0,0" or "FF0000").
|
461
|
+
# @param track [String] Track name.
|
462
|
+
# @return [String] IGV response.
|
463
|
+
# @example
|
464
|
+
# igv.set_color("FF0000", "track1")
|
465
|
+
def set_color(color, track)
|
466
|
+
send :setColor, color, track
|
467
|
+
end
|
468
|
+
|
469
|
+
# Set the data range (scale) for all numeric tracks, or a specific track.
|
470
|
+
#
|
471
|
+
# @note IGV Batch command: setDataRange
|
472
|
+
# @param range [String] Range string (e.g. "0,100" or "auto").
|
473
|
+
# @param track [String] Track name.
|
474
|
+
# @return [String] IGV response.
|
475
|
+
# @example
|
476
|
+
# igv.set_data_range("0,100", "track1")
|
477
|
+
def set_data_range(range, track)
|
478
|
+
send :setDataRange, range, track
|
479
|
+
end
|
480
|
+
|
481
|
+
# Set the data scale to log (true) or linear (false).
|
482
|
+
#
|
483
|
+
# @note IGV Batch command: setLogScale
|
484
|
+
# @param bool [Boolean] true for log scale, false for linear.
|
485
|
+
# @param track [String] Track name (optional).
|
486
|
+
# @return [String] IGV response.
|
487
|
+
# @example
|
488
|
+
# igv.set_log_scale(true, "track1")
|
489
|
+
def set_log_scale(bool, track)
|
490
|
+
bool = 'true' if bool == true
|
491
|
+
bool = 'false' if bool == false
|
492
|
+
send :setLogScale, bool, track
|
493
|
+
end
|
494
|
+
|
495
|
+
# Set the sequence strand to positive (+) or negative (-).
|
496
|
+
#
|
497
|
+
# @note IGV Batch command: setSequenceStrand
|
498
|
+
# @param strand [String] "+" or "-".
|
499
|
+
# @return [String] IGV response.
|
500
|
+
# @example
|
501
|
+
# igv.set_sequence_strand("+")
|
502
|
+
def set_sequence_strand(strand)
|
503
|
+
send :setSequenceStrand, strand
|
504
|
+
end
|
505
|
+
|
506
|
+
# Show or hide the 3-frame translation rows of the sequence track.
|
507
|
+
#
|
508
|
+
# @note IGV Batch command: setSequenceShowTranslation
|
509
|
+
# @param bool [Boolean] true to show, false to hide.
|
510
|
+
# @return [String] IGV response.
|
511
|
+
# @example
|
512
|
+
# igv.set_sequence_show_translation(true)
|
513
|
+
def set_sequence_show_translation(bool)
|
514
|
+
bool = 'true' if bool == true
|
515
|
+
bool = 'false' if bool == false
|
516
|
+
send :setSequenceShowTranslation, bool
|
517
|
+
end
|
518
|
+
|
519
|
+
# Set a delay (sleep) time in milliseconds between successive commands.
|
520
|
+
#
|
521
|
+
# @note IGV Batch command: setSleepInterval
|
522
|
+
# @param ms [Integer] Milliseconds to sleep.
|
523
|
+
# @return [String] IGV response.
|
524
|
+
# @example
|
525
|
+
# igv.set_sleep_interval(200)
|
526
|
+
def set_sleep_interval(ms)
|
527
|
+
send :setSleepInterval, ms
|
528
|
+
end
|
529
|
+
|
530
|
+
# Set the specified track's height in integer units.
|
531
|
+
#
|
532
|
+
# @note IGV Batch command: setTrackHeight
|
533
|
+
# @param height [Integer] Height in pixels.
|
534
|
+
# @param track [String] Track name.
|
535
|
+
# @return [String] IGV response.
|
536
|
+
# @example
|
537
|
+
# igv.set_track_height(50, "track1")
|
538
|
+
def set_track_height(height, track)
|
539
|
+
send :setTrackHeight, height, track
|
540
|
+
end
|
541
|
+
|
542
|
+
# Set the number of vertical pixels (height) of each panel to include in image.
|
543
|
+
#
|
544
|
+
# @note IGV Batch command: maxPanelHeight
|
545
|
+
# @param height [Integer] Height in pixels.
|
546
|
+
# @return [String] IGV response.
|
547
|
+
# @example
|
548
|
+
# igv.max_panel_height(2000)
|
549
|
+
def max_panel_height(height)
|
550
|
+
send :maxPanelHeight, height
|
551
|
+
end
|
552
|
+
|
553
|
+
# Set the "color by" option for alignment tracks.
|
554
|
+
#
|
555
|
+
# @note IGV Batch command: colorBy
|
556
|
+
# @param option [String] Color by option (e.g. "SAMPLE", "READ_GROUP", "TAG", ...).
|
557
|
+
# @param tag [String, nil] Tag name (required for option "TAG").
|
558
|
+
# @return [String] IGV response.
|
559
|
+
# @example
|
560
|
+
# igv.color_by("SAMPLE")
|
561
|
+
# igv.color_by("TAG", "NM")
|
562
|
+
def color_by(option, tag)
|
563
|
+
send :colorBy, option, tag
|
564
|
+
end
|
565
|
+
|
566
|
+
# Group alignments by the specified option.
|
567
|
+
#
|
568
|
+
# @note IGV Batch command: group
|
569
|
+
# @param option [String] Group option (e.g. "SAMPLE", "READ_GROUP", "TAG", ...).
|
570
|
+
# @param tag [String, nil] Tag name or position (required for option "TAG").
|
571
|
+
# @return [String] IGV response.
|
572
|
+
# @example
|
573
|
+
# igv.group("SAMPLE")
|
574
|
+
# igv.group("TAG", "NM")
|
575
|
+
def group(option, tag)
|
576
|
+
send :group, option, tag
|
577
|
+
end
|
578
|
+
|
579
|
+
# Overlay a list of tracks.
|
580
|
+
#
|
581
|
+
# @note IGV Batch command: overlay
|
582
|
+
# @param overlaid_track [String] The track to overlay.
|
583
|
+
# @param tracks [Array<String>] List of tracks to overlay.
|
584
|
+
# @return [String] IGV response.
|
585
|
+
# @example
|
586
|
+
# igv.overlay("track1", "track2", "track3")
|
587
|
+
def overlay(overlaid_track, *tracks)
|
588
|
+
send :overlay, overlaid_track, *tracks
|
589
|
+
end
|
590
|
+
|
591
|
+
# Scroll all panels to the top of the view.
|
592
|
+
#
|
593
|
+
# @note IGV Batch command: scrollToTop
|
594
|
+
# @return [String] IGV response.
|
595
|
+
# @example
|
596
|
+
# igv.scroll_to_top
|
597
|
+
def scroll_to_top
|
598
|
+
send :scrollToTop
|
599
|
+
end
|
600
|
+
|
601
|
+
# Separate an overlaid track into its constituitive tracks.
|
602
|
+
#
|
603
|
+
# @note IGV Batch command: separate
|
604
|
+
# @param overlaid_track_name [String] The name of the overlaid track to separate.
|
605
|
+
# @return [String] IGV response.
|
606
|
+
# @example
|
607
|
+
# igv.separate("track1")
|
608
|
+
def separate(overlaid_track_name)
|
609
|
+
send :separate, overlaid_track_name
|
610
|
+
end
|
611
|
+
|
612
|
+
# Set an access token to be used in an Authorization header for all requests to host.
|
613
|
+
#
|
614
|
+
# @note IGV Batch command: setAccessToken
|
615
|
+
# @param token [String] The access token.
|
616
|
+
# @param host [String, nil] The host to use the token for (optional).
|
617
|
+
# @return [String] IGV response.
|
618
|
+
# @example
|
619
|
+
# igv.set_access_token("mytoken", "example.com")
|
620
|
+
def set_access_token(token, host = nil)
|
621
|
+
send :setAccessToken, token, host
|
622
|
+
end
|
623
|
+
|
624
|
+
# Clears all access tokens.
|
625
|
+
#
|
626
|
+
# @note IGV Batch command: clearAccessTokens
|
627
|
+
# @return [String] IGV response.
|
628
|
+
# @example
|
629
|
+
# igv.clear_access_tokens
|
630
|
+
def clear_access_tokens
|
631
|
+
send :clearAccessTokens
|
632
|
+
end
|
363
633
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-igv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kojix2
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: launchy
|
@@ -95,7 +94,6 @@ homepage: https://github.com/kojix2/ruby-igv
|
|
95
94
|
licenses:
|
96
95
|
- MIT
|
97
96
|
metadata: {}
|
98
|
-
post_install_message:
|
99
97
|
rdoc_options: []
|
100
98
|
require_paths:
|
101
99
|
- lib
|
@@ -103,15 +101,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
101
|
requirements:
|
104
102
|
- - ">="
|
105
103
|
- !ruby/object:Gem::Version
|
106
|
-
version: '2.
|
104
|
+
version: '2.6'
|
107
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
106
|
requirements:
|
109
107
|
- - ">="
|
110
108
|
- !ruby/object:Gem::Version
|
111
109
|
version: '0'
|
112
110
|
requirements: []
|
113
|
-
rubygems_version: 3.
|
114
|
-
signing_key:
|
111
|
+
rubygems_version: 3.6.7
|
115
112
|
specification_version: 4
|
116
113
|
summary: Control IGV (Integrative Genomics Viewer) with Ruby.
|
117
114
|
test_files: []
|