Change Eclipse configuration
[jabaws.git] / website / archive / binaries / mac / src / clustalw / src / general / Utility.cpp
1 /**
2  * Author: Mark Larkin
3  * 
4  * Copyright (c) 2007 Des Higgins, Julie Thompson and Toby Gibson.  
5  *
6  * @author Mark Larkin, Conway Institute, UCD. mark.larkin@ucd.ie
7  *
8  * Changes:
9  *
10  *  2007-12-03, Andreas Wilm (UCD): replaced gets with fgets, and
11  *  got rid of some compiler warning 
12  *
13  */
14 #ifdef HAVE_CONFIG_H
15     #include "config.h"
16 #endif
17 #include <iostream> 
18 #include <algorithm> 
19 #include "Utility.h"
20 #include "general/userparams.h"
21
22 namespace clustalw
23 {
24
25 /**   constructor
26  */
27 Utility::Utility()
28 {
29     quiet=false;
30 }
31
32     
33 /**
34  * Removes trailing blanks from a string
35  */
36 void Utility::rTrim(string *str)
37 {
38     string::reverse_iterator rit = str->rbegin();
39      
40      while(rit != str->rend() && isspace(*rit))
41      {
42          str->erase((++rit).base());
43      }
44 }
45
46 /**
47  * Removes trailing blanks from a string
48  * @param str String to remove trailing blanks from.
49  * @return Pointer to the processed string
50  */
51 char * Utility::rTrim(char *str)
52 {
53     register int p;
54
55     p = strlen(str) - 1;
56
57     while (isspace(str[p]))
58     {
59         p--;
60     }
61
62     str[p + 1] = EOS;
63
64     return str;
65 }
66
67 /**
68  * Replace blanks in a string with underscores. Also replaces , ; : ( or ) with _.
69  * @param str String to process.
70  * @return Pointer to the processed string 
71  */
72 char * Utility::blankToUnderscore(char *str)
73 {
74     int i, p;
75
76     p = strlen(str) - 1;
77
78     for (i = 0; i <= p; i++)
79         if ((str[i] == ' ') || (str[i] == ';') || (str[i] == ',') || (str[i] ==
80             '(') || (str[i] == ')') || (str[i] == ':'))
81         {
82             str[i] = '_';
83         }
84
85     return str;
86 }
87
88 /**
89  * Replace blanks in a string with underscores. Also replaces , ; : ( or ) with _.
90  * @param str String to process.
91  * @return Pointer to the processed string 
92  */
93 string Utility::blankToUnderscore(string str)
94 {
95     int i, p;
96
97     p = str.size() - 1;
98
99     for (i = 0; i <= p; i++)
100         if ((str[i] == ' ') || (str[i] == ';') || (str[i] == ',') || (str[i] ==
101             '(') || (str[i] == ')') || (str[i] == ':'))
102         {
103             str[i] = '_';
104         }
105
106     return str;
107 }
108
109 /**
110  * 
111  * @param instr 
112  * @return 
113  */
114 char Utility::getChoice(string instr)
115 {
116     cout << instr << ": ";
117     cout.flush();
118     char choice;
119     cin.get(choice);
120     // We only want one character, so we ignore the rest.
121     if(choice != '\n')
122     {
123         cin.ignore(150, '\n');
124     }
125     cin.clear();
126     if(isalpha(choice) || isNumeric(choice))
127     {
128         return choice;
129     }
130     else if(choice == '\n')
131     {
132         return '\n';
133     }
134     else
135     {
136         return ' ';
137     }
138 }
139
140 bool Utility::isNumeric(char ch)
141 {
142     if(ch >= '0' && ch <= '9')
143     {
144         return true;
145     }
146     return false;
147 }
148
149
150 /**
151  * 
152  * @param instr 
153  * @param outstr 
154  */
155 void Utility::getStr(string instr, string& outstr)
156 {
157     cout << instr << ": ";
158     cout.flush();    
159     string temp;
160     getline(cin, temp, '\n');
161     outstr = temp;
162     cin.clear();
163 }
164
165 /**
166  * 
167  * @param instr 
168  * @param minx 
169  * @param maxx 
170  * @param def 
171  * @return 
172  */
173 double Utility::getReal(const char *instr, double minx, double maxx, double def)
174 {
175     int status;
176     float ret;
177     char line[MAXLINE];
178
179     while (true)
180     {
181         fprintf(stdout, "%s (%.1f-%.1f)   [%.1f]: ", instr, minx, maxx, def);
182         //gets(line);
183         fgets(line, MAXLINE, stdin);
184         status = sscanf(line, "%f", &ret);
185         if (status == EOF)
186         {
187             return def;
188         }
189         if (ret > maxx)
190         {
191             fprintf(stderr, "ERROR: Max. value=%.1f\n\n", maxx);
192             continue;
193         }
194         if (ret < minx)
195         {
196             fprintf(stderr, "ERROR: Min. value=%.1f\n\n", minx);
197             continue;
198         }
199         break;
200     }
201     return (double)ret;
202 }
203
204 /**
205  * 
206  * @param instr 
207  * @param minx 
208  * @param maxx 
209  * @param def 
210  * @return 
211  */
212 int Utility::getInt(const char *instr, int minx, int maxx, int def)
213 {
214     int ret, status;
215     char line[MAXLINE];
216
217     while (true)
218     {
219         fprintf(stdout, "%s (%d..%d)    [%d]: ", instr, minx, maxx, def);
220         //gets(line);
221         fgets(line, MAXLINE, stdin);
222         status = sscanf(line, "%d", &ret);
223         if (status == EOF)
224         {
225             return def;
226         }
227         if (ret > maxx)
228         {
229             fprintf(stderr, "ERROR: Max. value=%d\n\n", maxx);
230             continue;
231         }
232         if (ret < minx)
233         {
234             fprintf(stderr, "ERROR: Min. value=%d\n\n", minx);
235             continue;
236         }
237         break;
238     }
239     return ret;
240 }
241
242 /**
243  * 
244  * @param line 
245  * @param code 
246  * @return 
247  */
248 bool Utility::lineType(char *line, const char *code)
249 {
250    // AW: introduced sanity check
251    int n;
252    if (strlen(line)<strlen(code))
253      n=strlen(line);
254    else
255      n=strlen(code);
256    
257    return (strncmp(line, code, strlen(code)) == 0);
258 }
259
260 /**
261  * 
262  * @param line 
263  * @return 
264  */
265 bool Utility::blankLine(char *line)
266 {
267     int i;
268
269     for (i = 0; line[i] != '\n' && line[i] != EOS; i++)
270     {
271         if (isdigit(line[i]) || isspace(line[i]) || (line[i] == '*') ||
272             (line[i] == ':') || (line[i] == '.'))
273             ;
274         else
275         {
276             return false;
277         }
278     }
279     return true;
280 }
281
282 /**
283  * 
284  * @param str 
285  * @param path 
286  */
287 void Utility::getPath(string str, string *path)
288 {
289     int i;
290     string _temp;
291     _temp = str;
292     
293     for (i = _temp.length() - 1; i >  - 1; --i)
294     {
295         if (str[i] == DIRDELIM)
296         {
297             i =  - 1;
298             break;
299         }
300         if (str[i] == '.')
301         {
302             break;
303         }    
304     }
305     
306     if (i < 0)
307     {
308         _temp += ".";
309     }
310     else
311     {
312         _temp = _temp.substr(0, i + 1);
313     }
314     *path = _temp;   
315 }
316
317 /**
318  * 
319  * @param title 
320  * @param prompt 
321  * @return
322  *
323  *
324  */
325 char Utility::promptForYesNo(char *title, const char *prompt)
326 {
327     cout << "\n" << title << "\n";
328     string promptMessage = string(prompt) + "(y/n) ? [y]";
329     
330     string answer;
331     getStr(promptMessage, answer);
332     
333     if(!answer.empty())
334     {
335         if ((answer[0] != 'n') && (answer[0] != 'N'))
336         {
337             return ('y');
338         }
339     }
340     return ('n');
341 }
342
343 /**
344  * 
345  * @param title 
346  * @param prompt 
347  * @return
348  *
349  */
350 char Utility::promptForYesNo(const char *title, const char *prompt)
351 {
352     cout << "\n" << title << "\n";
353     string promptMessage = string(prompt) + "(y/n) ? [y]";
354     
355     string answer;
356     getStr(promptMessage, answer);
357     
358     if(!answer.empty())
359     {
360         if ((answer[0] != 'n') && (answer[0] != 'N'))
361         {
362             return ('y');
363         }
364     }
365     return ('n');
366 }
367
368 /**
369  * 
370  * @param msg 
371  */
372 void Utility::error( char *msg,...)
373 {
374     va_list ap;
375
376     va_start(ap, msg);
377     fprintf(stderr, "\n\nERROR: ");
378     vfprintf(stderr, msg, ap);
379     fprintf(stderr, "\n\n");
380     va_end(ap);
381 }
382
383 /**
384  * 
385  * @param msg 
386  */
387 void Utility::warning( char *msg,...)
388 {
389     va_list ap;
390
391     va_start(ap, msg);
392     fprintf(stderr, "\n\nWARNING: ");
393     vfprintf(stderr, msg, ap);
394     fprintf(stderr, "\n\n");
395     va_end(ap);
396 }
397
398 /**
399  * 
400  * @param msg 
401  */
402 void Utility::error( const char *msg,...)
403 {
404     va_list ap;
405
406     va_start(ap, msg);
407     fprintf(stderr, "\n\nERROR: ");
408     vfprintf(stderr, msg, ap);
409     fprintf(stderr, "\n\n");
410     va_end(ap);
411 }
412
413 /**
414  * 
415  * @param msg 
416  */
417 void Utility::warning( const char *msg,...)
418 {
419     va_list ap;
420
421     va_start(ap, msg);
422     fprintf(stderr, "\n\nWARNING: ");
423     vfprintf(stderr, msg, ap);
424     fprintf(stderr, "\n\n");
425     va_end(ap);
426 }
427
428 /**
429  * 
430  * @param msg 
431  */
432 void Utility::info( char *msg,...)
433 {
434     va_list ap;
435     va_start(ap, msg);
436
437     if(! quiet)
438     {
439         fprintf(stdout, "\n");
440         vfprintf(stdout, msg, ap);
441         va_end(ap);
442     }
443 }
444
445 /**
446  * 
447  * @param msg 
448  */
449 void Utility::info(const char *msg,...)
450 {
451     va_list ap;
452     if(! quiet)
453     {
454         va_start(ap, msg);
455         fprintf(stdout, "\n");
456         vfprintf(stdout, msg, ap);
457         va_end(ap);
458     }
459 }
460
461
462     
463 /**
464  * 
465  */
466 void Utility::myname( char *myname)
467 {
468     strcpy(myname, "clustalw\0");
469 }
470
471
472     
473 /**
474  * Change:
475  * Mark 25-1-2007. I made this change to get around the problem of having to keep track
476  * of output indexes in the alignment stage. This function returns the next unique id.
477  */
478 unsigned long Utility::getUniqueSequenceIdentifier()
479 {
480     static unsigned long nextSequenceIdentifier = MinIdentifier;
481     return nextSequenceIdentifier++;
482 }
483
484 void Utility::setInfoLabelPtr(QLabel* ptrToLabelObj)
485 {
486     // Dont do anything. This is here to allow the function to be added to QTUtility.
487     // Polymorphism wont work with different functions in the classes.
488 }
489
490
491 double Utility::average(std::vector<double>& v)
492 {
493     double tmp = 0.0;
494     std::vector<double>::iterator i;
495
496     if (v.size() == 0)
497         return 0.0;
498
499     for (i=v.begin(); i != v.end(); i++)
500         tmp += *i;
501     return (tmp / v.size());
502 }
503
504 double Utility::stdDev(std::vector<double>& v)
505 {
506     std::vector<double>::iterator i;
507     double tmp = 0.0;
508     double avg = average(v);
509
510     if (v.size() == 0)
511         return 0.0;
512     
513     for(i=v.begin(); i != v.end(); ++i)
514         tmp += (*i - avg) * (*i - avg);
515     return sqrt(tmp / v.size());
516 }
517
518 double Utility::median(std::vector<double> v)
519 {
520     // From Moo & Koenig, "Accelerated C++:
521     typedef vector<double>::size_type vec_sz;
522     vec_sz size = v.size();
523     
524     if (v.size() == 0)
525         return 0.0;
526     
527     std::sort(v.begin(), v.end());
528     vec_sz mid = size/2;
529     return size % 2 == 0 ? (v[mid] + v[mid-1]) / 2 : v[mid];
530 }
531
532 }
533