2 # = lib/evo/util/util.rb - Util class
4 # Copyright:: Copyright (C) 2017 Christian M. Zmasek
5 # License:: GNU Lesser General Public License (LGPL)
7 # Last modified: 2017/04/27
9 require 'lib/evo/util/constants'
13 def Util.get_matching_files( files, prefix_pattern, suffix_pattern )
14 matching_files = Array.new
16 if ( !File.directory?( file ) &&
18 file =~ /^#{prefix_pattern}.*#{suffix_pattern}$/ )
19 matching_files << file
25 def Util.get_matching_file( dir_name, prefix, suffix )
26 unless Dir.exist? dir_name
27 raise IOError, "directory [#{dir_name}] does not exist"
30 all_files = Dir.entries(dir_name)
32 if ( all_files.size <= 2 )
33 raise IOError, "directory [#{dir_name}] is empty"
35 matching_files = Array.new
36 all_files.each { | file |
37 if (( !File.directory?( file )) && (file.end_with? suffix))
38 matching_files << file
42 if ( matching_files.size == 0 )
43 raise IOError, "no files ending with \"" + suffix + "\" found in [" + dir_name + "]"
51 puts my_prefix #TODO remove me
53 matching_files.each { | file |
54 if file.start_with?( my_prefix )
70 if my_prefix.length <= 1
71 raise IOError, "no file matching \"" + removeFileExtension( prefix )
72 + "\" and ending with \"" + suffix + "\" found in [" + dir_name + "]"
74 my_prefix = my_prefix[ 0 ... ( my_prefix.length - 1 ) ]
81 raise IOError, "multiple files matching \"" + prefix +
82 "\" and ending with \"" + suffix + "\" found in [" + dir_name + "]"
85 raise IOError, "no file matching \"" + prefix + "\" and ending with \"" +
86 suffix + "\" found in [" + dir_name + "]"
91 def Util.normalize_seq_name( name, length, exception_if_too_long = false )
92 if name.length > length
93 if exception_if_too_long
94 error_msg = "sequence name \"#{name}\" is too long (>#{length})"
95 raise StandardError, error_msg
97 name = name[ 0, length ]
98 elsif name.length < length
99 t = length - name.length
107 # Returns true if char_code corresponds to: space * - . _
108 def Util.is_aa_gap_character?( char_code )
109 return ( char_code <= 32 || char_code == 42 || char_code == 45 || char_code == 46 ||char_code == 95 )
112 # Deletes *, digits, and whitespace, replaces BJOUZ? with X, and replaces non-(letters, -) with -
113 def Util.clean_seq_str( seq_str )
114 seq_str = seq_str.upcase
115 seq_str = seq_str.gsub( /\s+/, '' )
116 seq_str = seq_str.gsub( /\d+/, '' )
117 seq_str = seq_str.gsub( '*', '' )
118 seq_str = seq_str.gsub( /[BJOUZ?]/, 'X' )
119 seq_str = seq_str.gsub( /[^A-Z\-]/, '-' )
123 # raises ArgumentError
124 def Util.check_file_for_readability( path )
125 unless ( File.exist?( path ) )
126 error_msg = "file [#{path}] does not exist"
127 raise IOError, error_msg
129 unless ( File.file?( path ) )
130 error_msg = "file [#{path}] is not a regular file"
131 raise IOError, error_msg
133 unless ( File.readable?( path ) )
134 error_msg = "file [#{path}] is not a readable file"
135 raise IOError, error_msg
137 if ( File.zero?( path ) )
138 error_msg = "file [#{path}] is empty"
139 raise IOError, error_msg
143 # raises ArgumentError
144 def Util.check_file_for_writability( path )
145 if File.directory?( path )
146 error_msg = "file [#{path}] is an existing directory"
147 raise IOError, error_msg
148 elsif File.exist?( path )
149 error_msg = "file [#{path}] already exists"
150 raise IOError, error_msg
151 elsif File.writable?( path )
152 error_msg = "file [#{path}] is not writeable"
153 raise IOError, error_msg
157 def Util.fatal_error_if_not_writable( prg_name, path )
159 Util.check_file_for_writability( path )
161 Util.fatal_error( prg_name, e.to_s )
165 def Util.fatal_error_if_not_readable( prg_name, path )
167 Util.check_file_for_readability( path )
169 Util.fatal_error( prg_name, e.to_s )
173 def Util.get_env_variable_value( env_variable )
174 value = ENV[env_variable]
175 if value == nil || value.empty?
176 error_msg = "apparently environment variable #{env_variable} has not been set"
177 raise StandardError, error_msg
182 # raises ArgumentError
183 def Util.file2array( path, split_by_semicolon )
184 Util.check_file_for_readability( path )
187 File.open( path ) do | file |
188 while line = file.gets
189 if ( line =~ /^\s*(\S.*?)\s*$/ )
191 if ( split_by_semicolon && s =~/;/ )
193 for i in 0 ... sa.length()
194 a[ c ] = sa[ i ].strip!
206 def Util.print_program_information( prg_name,
213 ruby_version = RUBY_VERSION
214 l = prg_name.length + prg_version.length + date.length + ruby_version.length + 12
215 io.print( Evoruby::Constants::LINE_DELIMITER )
216 io.print( prg_name + " " + prg_version + " [" + date + "] [ruby " + ruby_version + "]")
217 io.print( Evoruby::Constants::LINE_DELIMITER )
221 io.print( Constants::LINE_DELIMITER )
222 io.print( Constants::LINE_DELIMITER )
224 io.print( Constants::LINE_DELIMITER )
225 io.print( Constants::LINE_DELIMITER )
226 io.print( "Website: " + www )
227 io.print( Constants::LINE_DELIMITER )
228 io.print( Constants::LINE_DELIMITER )
231 def Util.fatal_error( prg_name, message, io = STDOUT )
232 io.print( Constants::LINE_DELIMITER )
233 if ( !Util.is_string_empty?( prg_name ) )
234 io.print( "[" + prg_name + "] > " + message )
236 io.print( " > " + message )
238 io.print( Constants::LINE_DELIMITER )
239 io.print( Constants::LINE_DELIMITER )
243 def Util.print_message( prg_name, message, io = STDOUT )
244 if ( !Util.is_string_empty?( prg_name ) )
245 io.print( "[" + prg_name + "] > " + message )
247 io.print( " > " + message )
249 io.print( Constants::LINE_DELIMITER )
252 def Util.print_warning_message( prg_name, message, io = STDOUT )
253 if ( !Util.is_string_empty?( prg_name ) )
254 io.print( "[" + prg_name + "] > WARNING: " + message )
256 io.print( " > " + message )
258 io.print( Constants::LINE_DELIMITER )
261 def Util.is_string_empty?( s )
262 return ( s == nil || s.length < 1 )
265 # From "Ruby Cookbook"
266 # counts_hash: key is a "name", value is the count (integer)
267 def Util.draw_histogram( counts_hash, char = "#" )
268 pairs = counts_hash.keys.collect { |x| [ x.to_s, counts_hash[ x ] ] }.sort
269 largest_key_size = pairs.max { |x, y| x[ 0 ].size <=> y[ 0 ].size }[ 0 ].size
270 pairs.inject( "" ) do | s, kv |
271 s << "#{ kv[ 0 ].ljust( largest_key_size ) } | #{ char*kv[ 1 ] }" + Constants::LINE_DELIMITER
275 def Util.looks_like_fasta?( path )
276 Util.check_file_for_readability( path )
277 File.open( path ) do | file |
278 while line = file.gets
279 if ( line !~ /\S/ || line =~ /^\s*#/ )
280 elsif line =~ /^\s*>\s*(.+)/
287 error_msg = "unexpected format"
288 raise IOError, error_msg