inprogress
[jalview.git] / forester / ruby / evoruby / lib / evo / util / util.rb
1 #
2 # = lib/evo/util/util.rb - Util class
3 #
4 # Copyright::  Copyright (C) 2006-2007 Christian M. Zmasek
5 # License::    GNU Lesser General Public License (LGPL)
6 #
7 # $Id: util.rb,v 1.17 2009/10/06 22:22:46 cmzmasek Exp $
8 #
9 # last modified: 05/15/2007
10
11 require 'lib/evo/util/constants'
12
13 module Evoruby
14
15   class Util
16
17     def Util.normalize_seq_name( name, length, exception_if_too_long = false )
18       if name.length > length
19         if exception_if_too_long
20           error_msg = "sequence name \"#{name}\" is too long (>#{length})"
21           raise StandardError, error_msg
22         end
23         name = name[ 0, length ]
24       elsif name.length < length
25         for i in 0 ... length - name.length
26           name = name + " "
27         end
28       end
29       name
30     end
31
32     # Returns true if char_code corresponds to: space * - . _
33     def Util.is_aa_gap_character?( char_code )
34       return ( char_code <= 32  || char_code == 42 || char_code == 45 || char_code == 46 ||char_code == 95  )
35     end
36
37     # Deletes *, digits, and whitespace, replaces BJOUZ? with X, and replaces non-(letters, -) with -
38     def Util.clean_seq_str( seq_str )
39       seq_str = seq_str.upcase
40       seq_str = seq_str.gsub( /\s+/, '' )
41       seq_str = seq_str.gsub( /\d+/, '' )
42       seq_str = seq_str.gsub( '*', '' )
43       seq_str = seq_str.gsub( /[BJOUZ?]/, 'X' )
44       seq_str = seq_str.gsub( /[^A-Z\-]/, '-' )
45       seq_str
46     end
47
48     # raises ArgumentError
49     def Util.check_file_for_readability( path )
50       unless ( File.exist?( path ) )
51         error_msg = "file [#{path}] does not exist"
52         raise IOError, error_msg
53       end
54       unless ( File.file?( path ) )
55         error_msg = "file [#{path}] is not a regular file"
56         raise IOError, error_msg
57       end
58       unless ( File.readable?( path ) )
59         error_msg = "file [#{path}] is not a readable file"
60         raise IOError, error_msg
61       end
62       if ( File.zero?( path ) )
63         error_msg = "file [#{path}] is empty"
64         raise IOError, error_msg
65       end
66     end
67
68     # raises ArgumentError
69     def Util.check_file_for_writability( path )
70       if File.directory?( path )
71         error_msg = "file [#{path}] is an existing directory"
72         raise IOError, error_msg
73       elsif File.exist?( path )
74         error_msg = "file [#{path}] already exists"
75         raise IOError, error_msg
76       elsif File.writable?( path )
77         error_msg = "file [#{path}] is not writeable"
78         raise IOError, error_msg
79       end
80     end
81
82     def Util.fatal_error_if_not_writable( prg_name, path )
83       begin
84         Util.check_file_for_writability( path )
85       rescue IOError => e
86         Util.fatal_error( prg_name, e.to_s )
87       end
88     end
89
90     def Util.fatal_error_if_not_readable( prg_name, path )
91       begin
92         Util.check_file_for_readability( path )
93       rescue IOError => e
94         Util.fatal_error( prg_name, e.to_s )
95       end
96     end
97
98     def Util.get_env_variable_value( env_variable )
99       value = ENV[env_variable]
100       if value == nil || value.empty?
101         error_msg = "apparently environment variable #{env_variable} has not been set"
102         raise StandardError, error_msg
103       end
104       value
105     end
106
107
108     # raises ArgumentError
109     def Util.file2array( path, split_by_semicolon )
110       Util.check_file_for_readability( path )
111       a = Array.new()
112       c = 0
113       File.open( path ) do | file |
114         while line = file.gets
115           if ( line =~ /^\s*(\S.*?)\s*$/ )
116             s = $1
117             if ( split_by_semicolon && s =~/;/ )
118               sa = s.split( /;/ )
119               for i in 0 ... sa.length()
120                 a[ c ] = sa[ i ].strip!
121               end
122             else
123               a[ c ] = s
124             end
125             c += 1
126           end
127         end
128       end
129       return a
130     end
131
132     def Util.print_program_information( prg_name,
133         prg_version,
134         prg_desc,
135         date,
136         copyright,
137         contact,
138         www,
139         io = STDOUT )
140
141       if RUBY_VERSION !~ /1.9/
142         puts( "Your ruby version is #{RUBY_VERSION}, expected 1.9.x " )
143         exit( -1 )
144       end
145
146       ruby_version = RUBY_VERSION
147       l = prg_name.length + prg_version.length + date.length + ruby_version.length + 12
148       io.print( Evoruby::Constants::LINE_DELIMITER )
149       io.print( prg_name + " " + prg_version + " [" + date + "] [ruby " + ruby_version + "]")
150       io.print( Evoruby::Constants::LINE_DELIMITER )
151       l.times {
152         io.print( "_" )
153       }
154       io.print( Constants::LINE_DELIMITER )
155       io.print( Constants::LINE_DELIMITER )
156       io.print( prg_desc )
157       io.print( Constants::LINE_DELIMITER )
158       io.print( Constants::LINE_DELIMITER )
159       io.print( "Copyright (C) " + copyright )
160       io.print( Constants::LINE_DELIMITER )
161       io.print( "Contact: " + contact )
162       io.print( Constants::LINE_DELIMITER )
163       io.print( "         " + www )
164       io.print( Constants::LINE_DELIMITER )
165       io.print( Constants::LINE_DELIMITER )
166     end
167
168     def Util.fatal_error( prg_name, message, io = STDOUT )
169       io.print( Constants::LINE_DELIMITER )
170       if ( !Util.is_string_empty?( prg_name ) )
171         io.print( "[" + prg_name + "] > " + message )
172       else
173         io.print( " > " + message )
174       end
175       io.print( Constants::LINE_DELIMITER )
176       io.print( Constants::LINE_DELIMITER )
177       exit( -1 )
178     end
179
180     def Util.print_message( prg_name, message, io = STDOUT )
181       if ( !Util.is_string_empty?( prg_name ) )
182         io.print( "[" + prg_name + "] > " + message )
183       else
184         io.print( " > " + message )
185       end
186       io.print( Constants::LINE_DELIMITER )
187     end
188
189     def Util.print_warning_message( prg_name, message, io = STDOUT )
190       if ( !Util.is_string_empty?( prg_name ) )
191         io.print( "[" + prg_name + "] > WARNING: " + message )
192       else
193         io.print( " > " + message )
194       end
195       io.print( Constants::LINE_DELIMITER )
196     end
197
198     def Util.is_string_empty?( s )
199       return ( s == nil || s.length < 1 )
200     end
201
202     # From "Ruby Cookbook"
203     # counts_hash: key is a "name", value is the count (integer)
204     def Util.draw_histogram( counts_hash, char = "#" )
205       pairs = counts_hash.keys.collect { |x| [ x.to_s, counts_hash[ x ] ] }.sort
206       largest_key_size = pairs.max { |x, y| x[ 0 ].size <=> y[ 0 ].size }[ 0 ].size
207       pairs.inject( "" ) do | s, kv |
208         s << "#{ kv[ 0 ].ljust( largest_key_size ) }  | #{ char*kv[ 1 ] }" + Constants::LINE_DELIMITER
209       end
210     end
211
212     def Util.looks_like_fasta?( path )
213       Util.check_file_for_readability( path )
214       File.open( path ) do | file |
215         while line = file.gets
216           if ( line !~ /\S/ || line =~ /^\s*#/ )
217           elsif line =~ /^\s*>\s*(.+)/
218             return true
219           else
220             return false
221           end
222         end
223       end
224       error_msg = "unexpected format"
225       raise IOError, error_msg
226     end
227
228   end # class Util
229
230 end # module Evoruby