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