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