Next version of JABA
[jabaws.git] / binaries / src / clustalw / src / interface / CommandLineParser.cpp
1 /**
2  * Author: Mark Larkin
3  * 
4  * Copyright (c) 2007 Des Higgins, Julie Thompson and Toby Gibson.  
5  */
6 #ifdef HAVE_CONFIG_H
7     #include "config.h"
8 #endif
9 #include <cctype>
10 #include <cstdio>
11 #include <iostream>
12 #include <fstream>
13 #include "CommandLineParser.h"
14 #include "../substitutionMatrix/globalmatrix.h"
15 #include "general/Utility.h"
16 #include "general/statsObject.h"
17
18
19
20 using namespace std;
21
22 namespace clustalw
23 {
24
25 CommandLineParser::CommandLineParser(StringArray* args, bool xmenus)
26    :setOptions(-1),
27     setHelp(-1),
28     setFullHelp(-1),
29     setQuiet(-1),
30     setInteractive(-1),
31     setBatch(-1),
32     setGapOpen(-1),
33     setGapExtend(-1),
34     setPWGapOpen(-1),
35     setPWGapExtend(-1),
36     setOutOrder(-1),
37     setBootLabels(-1),
38     setPWMatrix(-1),
39     setMatrix(-1),
40     setPWDNAMatrix(-1),
41     setDNAMatrix(-1),
42     setNegative(-1),
43     setNoWeights(-1),
44     setOutput(-1),
45     setOutputTree(-1),
46     setQuickTree(-1),
47     setType(-1),
48     setCase(-1),
49     setSeqNo(-1),
50     setSeqNoRange(-1),
51     setRange(-1),
52     setTransWeight(-1),
53     setSeed(-1),
54     setScore(-1),
55     setWindow(-1),
56     setKtuple(-1),
57     setKimura(-1),
58     setTopDiags(-1),
59     setPairGap(-1),
60     setTossGaps(-1),
61     setNoPGap(-1),
62     setNoHGap(-1),
63     setNoVGap(-1),
64     setHGapRes(-1),
65     setUseEndGaps(-1),
66     setMaxDiv(-1),
67     setGapDist(-1),
68     setDebug(-1),
69     setOutfile(-1),
70     setInfile(-1),
71     setProfile1(-1),
72     setProfile2(-1),
73     setAlign(-1),
74     setConvert(-1),
75     setNewTree(-1),
76     setUseTree(-1),
77     setNewTree1(-1),
78     setUseTree1(-1),
79     setNewTree2(-1),
80     setUseTree2(-1),
81     setBootstrap(-1),
82     setTree(-1),
83     setProfile(-1),
84     setSequences(-1),
85     setSecStruct1(-1),
86     setSecStruct2(-1),
87     setSecStructOutput(-1),
88     setHelixGap(-1),
89     setStrandGap(-1),
90     setLoopGap(-1),
91     setTerminalGap(-1),
92     setHelixEndIn(-1),
93     setHelixEndOut(-1),
94     setStrandEndIn(-1),
95     setStrandEndOut(-1),
96     profileType(PROFILE),
97     setDoIteration(-1),
98     setNumIterations(-1),
99     setTreeAlgorithm(-1),
100     setMaxSeqLen(-1),
101     setStatsFile(-1),
102     setOutputPim(-1)
103 {
104     int ctr=0;
105     
106     // The rest of the variables are arrays!
107     try
108     {
109         clustalObj = new Clustal();
110         
111         // selecting the size prevents the resizing of the vector which is expensive. 
112         typeArg = new StringArray(3);
113         bootLabelsArg = new StringArray(3);
114         outOrderArg = new StringArray(3);
115         caseArg = new StringArray(3);
116         seqNoArg = new StringArray(3);
117         seqNoRangeArg = new StringArray(3);
118         scoreArg = new StringArray(3);
119         outputArg = new StringArray(7);
120         outputTreeArg = new StringArray(5);
121         outputSecStrArg = new StringArray(5);
122         cmdLineType = new StringArray(6);
123         clusterAlgorithm = new StringArray(3);
124         iterationArg = new StringArray(4);
125         
126         params = new StringArray; // Wait until I need it!!!!!!!!!
127         paramArg = new StringArray;
128     }
129     catch(const exception &ex)
130     {
131         cerr << ex.what() << endl;
132         cerr << "Terminating program. Cannot continue" << std::endl;
133         exit(1);
134     }
135                            
136     (*typeArg)[0] = "protein";
137     (*typeArg)[1] = "dna";
138     (*typeArg)[2] = "";
139         
140     (*bootLabelsArg)[0] = "node";
141     (*bootLabelsArg)[1] = "branch";
142     (*bootLabelsArg)[2] = "";
143     
144     (*outOrderArg)[0] = "input";
145     (*outOrderArg)[1] = "aligned";
146     (*outOrderArg)[2] = "";
147     
148     (*caseArg)[0] = "lower";
149     (*caseArg)[1] = "upper";
150     (*caseArg)[2] = "";
151     
152     (*seqNoArg)[0] = "off";
153     (*seqNoArg)[1] = "on";
154     (*seqNoArg)[2] = "";
155     
156     (*seqNoRangeArg)[0] = "off";
157     (*seqNoRangeArg)[1] = "on";
158     (*seqNoRangeArg)[2] = "";
159         
160     (*scoreArg)[0] = "percent";
161     (*scoreArg)[1] = "absolute";
162     (*scoreArg)[2] = "";
163     
164     (*outputArg)[0] = "gcg";
165     (*outputArg)[1] = "gde";
166     (*outputArg)[2] = "pir";
167     (*outputArg)[3] = "phylip";
168     (*outputArg)[4] = "nexus";
169     (*outputArg)[5] = "fasta";
170     (*outputArg)[6] = "";
171     
172     (*outputTreeArg)[0] = "nj";
173     (*outputTreeArg)[1] = "phylip";
174     (*outputTreeArg)[2] = "dist";
175     (*outputTreeArg)[3] = "nexus";
176     (*outputTreeArg)[4] = "";
177     
178     (*outputSecStrArg)[0] = "structure";
179     (*outputSecStrArg)[1] = "mask";
180     (*outputSecStrArg)[2] = "both";
181     (*outputSecStrArg)[3] = "none";
182     (*outputSecStrArg)[4] = "";
183     
184     (*cmdLineType)[0] = " ";
185     (*cmdLineType)[1] = "=n ";
186     (*cmdLineType)[2] = "=f ";
187     (*cmdLineType)[3] = "=string ";
188     (*cmdLineType)[4] = "=filename ";
189     (*cmdLineType)[5] = "";
190     
191     (*clusterAlgorithm)[0] = "nj";
192     (*clusterAlgorithm)[1] = "upgma";
193     (*clusterAlgorithm)[2] = "";
194
195     (*iterationArg)[0] = "tree";
196     (*iterationArg)[1] = "alignment";
197     (*iterationArg)[2] = "none";
198     (*iterationArg)[3] = "";
199         
200     userMatrixName = "";
201     pwUserMatrixName = "";
202     DNAUserMatrixName = "";
203     pwDNAUserMatrixName = "";
204     
205     clustalTreeName = "";
206     distTreeName = "";
207     phylipTreeName = "";
208     nexusTreeName = "";
209     p1TreeName = "";
210     p2TreeName = "";
211     pimName = "";
212
213     // NOTE there were only 3 params for the last one, so I put in NULL for the 4th.
214     ctr=0;
215     cmdLineFile[ctr++] = getCmdLineDataStruct("infile", &setInfile, FILARG, NULL);
216     cmdLineFile[ctr++] = getCmdLineDataStruct("profile1", &setProfile1, FILARG, NULL);
217     cmdLineFile[ctr++] = getCmdLineDataStruct("profile2", &setProfile2, FILARG, NULL);
218     cmdLineFile[ctr++] = getCmdLineDataStruct("", NULL, -1, NULL);
219     // FIXME: final ctr index is hardcoded in CommandLineParser
220     
221     ctr=0;
222     cmdLineVerb[ctr++] = getCmdLineDataStruct("help", &setHelp, NOARG, NULL);
223     cmdLineVerb[ctr++] = getCmdLineDataStruct("fullhelp", &setFullHelp, NOARG, NULL);
224     cmdLineVerb[ctr++] = getCmdLineDataStruct("quiet", &setQuiet, NOARG, NULL);
225     cmdLineVerb[ctr++] = getCmdLineDataStruct("check", &setHelp, NOARG, NULL);
226     cmdLineVerb[ctr++] = getCmdLineDataStruct("options", &setOptions, NOARG, NULL);
227     cmdLineVerb[ctr++] = getCmdLineDataStruct("align", &setAlign, NOARG, NULL);
228     cmdLineVerb[ctr++] = getCmdLineDataStruct("newtree", &setNewTree, FILARG, NULL);
229     cmdLineVerb[ctr++] = getCmdLineDataStruct("usetree", &setUseTree, FILARG, NULL);
230     cmdLineVerb[ctr++] = getCmdLineDataStruct("newtree1", &setNewTree1, FILARG, NULL);
231     cmdLineVerb[ctr++] = getCmdLineDataStruct("usetree1", &setUseTree1, FILARG, NULL);
232     cmdLineVerb[ctr++] = getCmdLineDataStruct("newtree2", &setNewTree2, FILARG, NULL);
233     cmdLineVerb[ctr++] = getCmdLineDataStruct("usetree2", &setUseTree2, FILARG, NULL);
234     cmdLineVerb[ctr++] = getCmdLineDataStruct("bootstrap", &setBootstrap, NOARG, NULL);
235     cmdLineVerb[ctr++] = getCmdLineDataStruct("tree", &setTree, NOARG, NULL);
236     cmdLineVerb[ctr++] = getCmdLineDataStruct("quicktree", &setQuickTree, NOARG, NULL);
237     cmdLineVerb[ctr++] = getCmdLineDataStruct("convert", &setConvert, NOARG, NULL);
238     cmdLineVerb[ctr++] = getCmdLineDataStruct("interactive", &setInteractive, NOARG, NULL);
239     cmdLineVerb[ctr++] = getCmdLineDataStruct("batch", &setBatch, NOARG, NULL);
240     // Mark change 16-feb-2007 I added options for doing LE and iteration
241     cmdLineVerb[ctr++] = getCmdLineDataStruct("iteration", &setDoIteration, 
242                                            OPTARG, iterationArg);
243     cmdLineVerb[ctr++] = getCmdLineDataStruct("", NULL, -1, NULL);
244     // FIXME: final ctr index is hardcoded in CommandLineParser.h
245     
246     // NOTE Start back here!!!!!!!!!!!!
247     ctr=0;
248     cmdLinePara[ctr++] = getCmdLineDataStruct("type", &setType, OPTARG, typeArg);
249     cmdLinePara[ctr++] = getCmdLineDataStruct("profile", &setProfile, NOARG, NULL);
250     cmdLinePara[ctr++] = getCmdLineDataStruct("sequences", &setSequences, NOARG, NULL);
251     cmdLinePara[ctr++] = getCmdLineDataStruct("matrix", &setMatrix, FILARG, NULL);
252     cmdLinePara[ctr++] = getCmdLineDataStruct("dnamatrix", &setDNAMatrix, FILARG, NULL);
253     cmdLinePara[ctr++] = getCmdLineDataStruct("negative", &setNegative, NOARG, NULL);
254     cmdLinePara[ctr++] = getCmdLineDataStruct("noweights", &setNoWeights, NOARG, NULL);
255     cmdLinePara[ctr++] = getCmdLineDataStruct("gapopen", &setGapOpen, FLTARG, NULL);
256     cmdLinePara[ctr++] = getCmdLineDataStruct("gapext", &setGapExtend, FLTARG, NULL);
257     cmdLinePara[ctr++] = getCmdLineDataStruct("endgaps", &setUseEndGaps, NOARG, NULL);
258     cmdLinePara[ctr++] = getCmdLineDataStruct("nopgap", &setNoPGap, NOARG, NULL);
259     cmdLinePara[ctr++] = getCmdLineDataStruct("nohgap", &setNoHGap, NOARG, NULL);
260     cmdLinePara[ctr++] = getCmdLineDataStruct("novgap", &setNoVGap, NOARG, NULL);
261     cmdLinePara[ctr++] = getCmdLineDataStruct("hgapresidues", &setHGapRes, STRARG, NULL);
262     cmdLinePara[ctr++] = getCmdLineDataStruct("maxdiv", &setMaxDiv, INTARG, NULL);
263     cmdLinePara[ctr++] = getCmdLineDataStruct("gapdist", &setGapDist, INTARG, NULL);
264     cmdLinePara[ctr++] = getCmdLineDataStruct("pwmatrix", &setPWMatrix, FILARG, NULL);
265     cmdLinePara[ctr++] = getCmdLineDataStruct("pwdnamatrix", &setPWDNAMatrix, FILARG, NULL);
266     cmdLinePara[ctr++] = getCmdLineDataStruct("pwgapopen", &setPWGapOpen, FLTARG, NULL);
267     cmdLinePara[ctr++] = getCmdLineDataStruct("pwgapext", &setPWGapExtend, FLTARG, NULL);
268     cmdLinePara[ctr++] = getCmdLineDataStruct("ktuple", &setKtuple, INTARG, NULL);
269     cmdLinePara[ctr++] = getCmdLineDataStruct("window", &setWindow, INTARG, NULL);
270     cmdLinePara[ctr++] = getCmdLineDataStruct("pairgap", &setPairGap, INTARG, NULL);
271     cmdLinePara[ctr++] = getCmdLineDataStruct("topdiags", &setTopDiags, INTARG, NULL);
272     cmdLinePara[ctr++] = getCmdLineDataStruct("score", &setScore, OPTARG, scoreArg);
273     cmdLinePara[ctr++] = getCmdLineDataStruct("transweight", &setTransWeight, FLTARG, NULL);
274     cmdLinePara[ctr++] = getCmdLineDataStruct("seed", &setSeed, INTARG, NULL);
275     cmdLinePara[ctr++] = getCmdLineDataStruct("kimura", &setKimura, NOARG, NULL);
276     cmdLinePara[ctr++] = getCmdLineDataStruct("tossgaps", &setTossGaps, NOARG, NULL);
277     cmdLinePara[ctr++] = getCmdLineDataStruct("bootlabels", &setBootLabels, OPTARG,
278                                              bootLabelsArg);
279     cmdLinePara[ctr++] = getCmdLineDataStruct("debug", &setDebug, INTARG, NULL);
280     cmdLinePara[ctr++] = getCmdLineDataStruct("output", &setOutput, OPTARG, outputArg);
281     cmdLinePara[ctr++] = getCmdLineDataStruct("outputtree", &setOutputTree, OPTARG,
282                                              outputTreeArg);
283     cmdLinePara[ctr++] = getCmdLineDataStruct("outfile", &setOutfile, FILARG, NULL);
284     cmdLinePara[ctr++] = getCmdLineDataStruct("outorder", &setOutOrder, OPTARG, outOrderArg);
285     cmdLinePara[ctr++] = getCmdLineDataStruct("case", &setCase, OPTARG, caseArg);
286     cmdLinePara[ctr++] = getCmdLineDataStruct("seqnos", &setSeqNo, OPTARG, seqNoArg);
287     cmdLinePara[ctr++] = getCmdLineDataStruct("seqno_range", &setSeqNoRange, OPTARG,
288                                              seqNoRangeArg);
289     cmdLinePara[ctr++] = getCmdLineDataStruct("range", &setRange, STRARG, NULL);
290     cmdLinePara[ctr++] = getCmdLineDataStruct("nosecstr1", &setSecStruct1, NOARG, NULL);
291     cmdLinePara[ctr++] = getCmdLineDataStruct("nosecstr2", &setSecStruct2, NOARG, NULL);
292     cmdLinePara[ctr++] = getCmdLineDataStruct("secstrout", &setSecStructOutput, OPTARG,
293                                              outputSecStrArg);
294     cmdLinePara[ctr++] = getCmdLineDataStruct("helixgap", &setHelixGap, INTARG, NULL);
295     cmdLinePara[ctr++] = getCmdLineDataStruct("strandgap", &setStrandGap, INTARG, NULL);
296     cmdLinePara[ctr++] = getCmdLineDataStruct("loopgap", &setLoopGap, INTARG, NULL);
297     cmdLinePara[ctr++] = getCmdLineDataStruct("terminalgap", &setTerminalGap, INTARG, NULL);
298     cmdLinePara[ctr++] = getCmdLineDataStruct("helixendin", &setHelixEndIn, INTARG, NULL);
299     cmdLinePara[ctr++] = getCmdLineDataStruct("helixendout", &setHelixEndOut, INTARG, NULL);
300     cmdLinePara[ctr++] = getCmdLineDataStruct("strandendin", &setStrandEndIn, INTARG, NULL);
301     cmdLinePara[ctr++] = getCmdLineDataStruct("strandendout",&setStrandEndOut, INTARG, NULL);
302     // NOTE these one was added to test the new LE scoring and iterations
303     cmdLinePara[ctr++] = getCmdLineDataStruct("numiter",&setNumIterations, INTARG, NULL);
304     cmdLinePara[ctr++] = getCmdLineDataStruct("clustering", &setTreeAlgorithm, OPTARG,
305                                            clusterAlgorithm);
306     cmdLinePara[ctr++] = getCmdLineDataStruct("maxseqlen", &setMaxSeqLen, INTARG, NULL);
307     cmdLinePara[ctr++] = getCmdLineDataStruct("stats", &setStatsFile, FILARG, NULL);
308     cmdLinePara[ctr++] = getCmdLineDataStruct("pim", &setOutputPim, NOARG, NULL);
309     cmdLinePara[ctr++] = getCmdLineDataStruct("", NULL, -1, NULL);
310     // FIXME: final ctr index is hardcoded in CommandLineParser
311     
312     parseParams(args, xmenus);
313 }
314
315 CommandLineParser::~CommandLineParser()
316 {
317     // Free up menory used here!
318     // NOTE any dynamically allocated memory (new) must be deleted.
319     delete clustalObj;
320     delete typeArg;
321     delete bootLabelsArg;
322     delete outOrderArg;
323     delete caseArg;
324     delete seqNoArg;
325     delete seqNoRangeArg;
326     delete scoreArg;
327     delete outputArg;
328     delete outputTreeArg;
329     delete outputSecStrArg;
330     delete cmdLineType;        
331     delete params;
332     delete paramArg;   
333     delete clusterAlgorithm;
334     delete iterationArg;
335 }
336
337 void CommandLineParser::parseParams(StringArray* args, bool xmenus)
338 {
339     #if DEBUGFULL 
340         if(logObject && DEBUGLOG)
341         {
342             logObject->logMsg("Parsing Command line Parameters!\n");
343         }
344     #endif
345         
346     int i, j, temp;
347     //int len;
348     //static int cl_error_code = 0;
349     //char path[FILENAMELEN];
350     int numparams = 0;
351
352     bool doAlign, doConvert, doAlignUseOldTree, doGuideTreeOnly, doTreeFromAlign, 
353          doBootstrap, doProfileAlign, doSomething;
354
355     if (!xmenus && userParameters->getDisplayInfo())
356     {
357         cout <<  std::endl << std::endl << std::endl;
358         cout << " CLUSTAL " << userParameters->getRevisionLevel() 
359              << " Multiple Sequence Alignments" << std::endl << std::endl << std::endl;
360     }
361
362     doAlign = doConvert = doAlignUseOldTree = doGuideTreeOnly = doTreeFromAlign = false;
363     doBootstrap = doProfileAlign = doSomething = false; 
364     
365     numparams = checkParam(args, params, paramArg);
366     
367     if (numparams < 0) 
368     {
369         exit(1);
370     }
371
372 //**********************************************************************
373 //*** Note: This part of the code is to print out the options with  ****
374 //*** their expected value types/ranges                             ****
375 //**********************************************************************
376     
377     if(setHelp != -1) 
378     {
379         userParameters->setHelpFlag(true);
380         if (xmenus) {
381             // gui will display help
382             // but parse rest of args anyway and don't return
383         } else {
384             clustalObj->getHelp('9');
385             exit(1);
386         }
387     }
388
389     if(setFullHelp != -1) 
390     {
391         userParameters->setFullHelpFlag(true);
392         if (xmenus) {
393             // gui will handle this
394             // but parse rest of args anyway and don't return
395         } else {
396             clustalObj->getFullHelp();
397             exit(1);
398         }
399     }
400
401     if(setQuiet != -1) 
402     {
403         userParameters->setDisplayInfo(false);
404         utilityObject->beQuiet(true);
405     } else {
406         userParameters->setDisplayInfo(true);
407         utilityObject->beQuiet(false);
408     }
409
410         
411     // need to check maxseqlen before reading input file
412     if (setMaxSeqLen != -1)
413     {
414         #if DEBUGFULL 
415             if(logObject && DEBUGLOG)
416             {
417                 logObject->logMsg("    Setting max allowed sequence length.");
418             }    
419         #endif      
420         temp = 0;
421         if((*paramArg)[setMaxSeqLen].length() > 0)
422         {
423             if (sscanf((*paramArg)[setMaxSeqLen].c_str(),"%d", &temp) != 1) 
424             {
425                 reportBadOptionAndExit("maxseqlen", "integer");
426             }
427         }
428         if(temp > 0)
429         {
430             userParameters->setMaxAllowedSeqLength(temp);
431         }
432         else
433         {
434             cerr << "Cannot use a negative value for maximum sequence length. Using default"  << std::endl;
435         }
436         
437     }
438
439     if (setStatsFile != -1)
440     {
441         if((*paramArg)[setStatsFile].length() > 0) 
442         {
443             statsObject->setEnabled(true);
444             statsObject->setStatsFile((*paramArg)[setStatsFile]);
445         }
446     }
447
448
449     if (setOutputPim != -1)
450     {
451             userParameters->setOutputPim(true);
452     }
453
454
455     /*if(setDoIteration != -1)
456     {
457         userParameters->setDoRemoveFirstIteration(true);
458     }*/
459     
460     if(setDoIteration != -1)
461     {
462         #if DEBUGFULL 
463             if(logObject && DEBUGLOG)
464             {
465                 logObject->logMsg("    Setting iteration parameter.");
466             }
467         #endif
468         if((*paramArg)[setDoIteration].length() > 0) 
469         { 
470             temp = findMatch((*paramArg)[setDoIteration], iterationArg, 3);
471             if(temp == 0)
472             {
473                 userParameters->setDoRemoveFirstIteration(TREE);
474             }
475             else if(temp == 1)
476             {
477                 userParameters->setDoRemoveFirstIteration(ALIGNMENT);
478             }
479             else if(temp == 2)
480             {               
481                 userParameters->setDoRemoveFirstIteration(NONE);
482             }
483             else
484             {
485                 cerr << "Unknown option for iteration. Setting to NONE"  << std::endl;
486                 userParameters->setDoRemoveFirstIteration(NONE);
487             }
488         }
489     }    
490     if(setOptions != -1) 
491     {
492         #if DEBUGFULL 
493             if(logObject && DEBUGLOG)
494             {
495                 logObject->logMsg("Displaying options!\n");
496             }
497         #endif
498                 
499         cout << "clustalw option list:-" << std::endl;
500         
501         for (i = 0; cmdLineVerb[i].str[0] != '\0'; i++) 
502         {
503             cout << "\t\t" << default_commandsep << cmdLineVerb[i].str 
504                  << (*cmdLineType)[cmdLineVerb[i].type];
505
506             if (cmdLineVerb[i].type == OPTARG) 
507             {
508                 if (cmdLineVerb[i].arg !=  NULL)
509                 {     
510                     cout << "=" << cmdLineVerb[i].arg->at(0);
511                     for(j = 1; j < (int)cmdLineVerb[i].arg->size() - 1; j++)
512                     {
513                         cout << " OR " << cmdLineVerb[i].arg->at(j);
514                     }
515                 }
516             }
517             cout << std::endl;
518         }
519         for (i = 0; cmdLineFile[i].str[0] != '\0'; i++) 
520         {
521             cout<<"\t\t" << default_commandsep << cmdLineFile[i].str 
522                 << (*cmdLineType)[cmdLineFile[i].type];
523                 
524             if (cmdLineFile[i].type == OPTARG) 
525             {
526                 if (cmdLineFile[i].arg !=  NULL)
527                 {
528                     
529                     cout << "=" << cmdLineFile[i].arg->at(0);
530                     for(j = 1; j < (int)cmdLineFile[i].arg->size() - 1; j++)
531                     {
532                         cout << " OR " << cmdLineFile[i].arg->at(j);
533                     }
534                 }
535             }
536             cout << std::endl;
537         }
538         for (i = 0; cmdLinePara[i].str[0] != '\0'; i++) 
539         {
540             cout <<"\t\t" << default_commandsep << cmdLinePara[i].str 
541                  << (*cmdLineType)[cmdLinePara[i].type];
542      
543             if (cmdLinePara[i].type == OPTARG) 
544             {
545                 if (cmdLinePara[i].arg !=  NULL)
546                 {
547                     
548                     cout << "=" << cmdLinePara[i].arg->at(0);
549                     for(j = 1; j < (int)cmdLinePara[i].arg->size() - 1; j++)
550                     {
551                         cout << " OR " << cmdLinePara[i].arg->at(j);
552                     }
553                 }
554             }
555             cout << std::endl;
556         }
557         exit(1);
558     }
559
560
561 //*****************************************************************************
562 //  Check to see if sequence type is explicitely stated..override ************
563 // the automatic checking (DNA or Protein).   /type=d or /type=p *************
564 //****************************************************************************
565
566     if(setType != -1)
567     {
568         string msg;
569         if(((*paramArg)[setType].length()) > 0) 
570         {
571             temp = findMatch((*paramArg)[setType], typeArg, 2);
572             if(temp == 0) 
573             { 
574                 userParameters->setDNAFlag(false);
575                 userParameters->setExplicitDNAFlag(true);
576                 msg = "Sequence type explicitly set to Protein";
577                 cout << msg << std::endl;
578             }
579             else if(temp == 1) 
580             {
581                 msg = "Sequence type explicitly set to DNA";
582                 cout << msg << std::endl;
583                 userParameters->setDNAFlag(true);
584                 userParameters->setExplicitDNAFlag(true);
585             }
586             else
587             {
588                 msg = "Unknown sequence type " + (*paramArg)[setType];
589                 cerr << std::endl << msg << endl;
590             }
591             #if DEBUGFULL 
592                 if(logObject && DEBUGLOG)
593                 {
594                     logObject->logMsg(msg);
595                 }
596             #endif            
597         }
598     }
599
600
601 //***************************************************************************
602 //   check to see if 1st parameter does not start with '/' i.e. look for an *
603 //   input file as first parameter.   The input file can also be specified  *
604 //   by /infile=fname.                                                      *
605 //***************************************************************************
606 // JULIE - moved to checkParam()
607   //  if(paramstr[0] != '/') 
608   //  {
609   //      strcpy(seqName, params[0]);
610   //  }
611
612
613 //*************************************************
614 //  Look for /infile=file.ext on the command line *
615 //*************************************************
616
617     if(setInfile != -1) 
618     {
619         if((*paramArg)[setInfile].length() <= 0) 
620         {
621             exitWithErrorMsg("Bad sequence file name");
622         }
623         userParameters->setSeqName((*paramArg)[setInfile]);
624
625         #if DEBUGFULL 
626             if(logObject && DEBUGLOG)
627             {
628                 string msg = "Sequence file name (seqName) has been set to ";
629                 msg += userParameters->getSeqName();             
630                 logObject->logMsg(msg);
631             }
632         #endif        
633     }
634     
635     // NOTE keep an eye on this part to see if it works.
636     if(userParameters->getSeqName() != "") 
637     {
638         // NOTE I will need to cheack if it has been successful before setting
639         // doSomething to true.
640         int code;
641         code = clustalObj->commandLineReadSeq(1);
642         if(code == OK)
643         {
644             doSomething = true;
645         }
646         else
647         {
648             doSomething = false;
649             exit(1);
650         }
651     }
652
653     // NOTE call the other function to set the parameter values!!
654     setOptionalParam();
655
656 //*********************************************************
657 // Look for /profile1=file.ext  AND  /profile2=file2.ext *
658 // You must give both file names OR neither.             *
659 //********************************************************
660
661
662     if(setProfile1 != -1) 
663     {
664         if((*paramArg)[setProfile1].length() <= 0) 
665         {
666             exitWithErrorMsg("Bad profile 1 file name");
667         }
668                 
669         clustalObj->profile1Input((*paramArg)[setProfile1]);
670     }
671
672     if(setProfile2 != -1) 
673     {
674         if((*paramArg)[setProfile2].length() <= 0) 
675         {
676             exitWithErrorMsg("Bad profile 2 file name");
677         }
678         if(userParameters->getProfile1Empty()) 
679         {
680             exitWithErrorMsg("Only 1 profile file (profile 2) specified.");
681         }
682         
683         clustalObj->profile2Input((*paramArg)[setProfile2]);
684         doSomething = doProfileAlign = true; 
685     }
686
687 //************************************************************************
688 // Look for /tree or /bootstrap or /align or /usetree ******************
689 //************************************************************************
690
691     if (setBatch != -1)
692     {
693         userParameters->setInteractive(false);
694     }
695
696     if (setInteractive != -1)
697     {
698         userParameters->setInteractive(true);
699         if (setQuiet!=-1) {
700             cout << "interactive menu: overriding " << default_commandsep << "quiet" << std::endl;
701             userParameters->setDisplayInfo(true);
702             utilityObject->beQuiet(false);
703         }
704     }
705
706     if (userParameters->getInteractive()) 
707     {
708         setTree = -1;
709         setBootstrap = -1;
710         setAlign = -1;
711         setUseTree = -1;
712         setUseTree1 = -1;
713         setUseTree2 = -1;
714         setNewTree = -1;
715         setConvert = -1;
716     }
717
718     if(setTree != -1 )
719     {
720         if(userParameters->getEmpty()) 
721         {
722             exitWithErrorMsg("Cannot draw tree.  No input alignment file");
723         }
724         else
725         { 
726             doTreeFromAlign = true;
727         }
728     }
729
730     if(setBootstrap != -1)
731     {
732         if(userParameters->getEmpty()) 
733         {
734             exitWithErrorMsg("Cannot bootstrap tree. No input alignment file");
735         }
736         else 
737         {
738             temp = 0;
739             // Check if there is anything in the string!
740             if((*paramArg)[setBootstrap].length() > 0)
741             {
742                 if (sscanf((*paramArg)[setBootstrap].c_str(), "%d", &temp) != 1) 
743                 {
744                     reportBadOptionAndExit("bootstrap", "integer");
745                 }
746             }
747             if(temp > 0)
748             {    
749                 userParameters->setBootNumTrials(temp);
750             }
751             doBootstrap = true;
752         }
753     }
754
755     if(setAlign != -1)
756     {
757         if(userParameters->getEmpty()) 
758         {
759             exitWithErrorMsg("Cannot align sequences.  No input file");
760         }
761         else
762         { 
763             doAlign = true;
764         }
765     }
766
767     if(setConvert != -1)
768     {
769         if(userParameters->getEmpty()) 
770         {
771             exitWithErrorMsg("Cannot convert sequences.  No input file");
772         }
773         else
774         { 
775             doConvert = true;
776         }
777     }
778  
779     if(setUseTree != -1)
780     {
781         if(userParameters->getEmpty()) 
782         {
783             exitWithErrorMsg("Cannot align sequences.  No input file");
784         }
785         else  
786         {
787            if((*paramArg)[setUseTree].length() == 0) 
788            {
789                exitWithErrorMsg("Cannot align sequences.  No tree file specified");
790            }
791            else 
792            {
793                phylipTreeName = (*paramArg)[setUseTree];
794            }
795            userParameters->setUseTreeFile(true);
796            doAlignUseOldTree = true;
797         }
798     }
799
800     if(setNewTree != -1)
801     {
802         if(userParameters->getEmpty()) 
803         {
804             exitWithErrorMsg("Cannot align sequences.  No input file");
805         }
806         else  
807         {
808             if((*paramArg)[setNewTree].length() == 0) 
809             {
810                 exitWithErrorMsg("Cannot align sequences.  No tree file specified");
811             }
812             else 
813             {
814                 phylipTreeName = (*paramArg)[setNewTree];
815             }
816             userParameters->setNewTreeFile(true);
817             doGuideTreeOnly = true;
818         }
819     }
820  
821     if(setUseTree1 != -1)
822     {
823         if(userParameters->getProfile1Empty()) 
824         {
825             exitWithErrorMsg("Cannot align profiles.  No input file");
826         }
827         else if(profileType == SEQUENCE) 
828         {
829             reportInvalidOptionAndExit("usetree1");
830         }
831         else  
832         {
833             if((*paramArg)[setUseTree1].length() == 0) 
834             {
835                 exitWithErrorMsg("Cannot align profiles.  No tree file specified");
836             }
837             else 
838             {
839                 p1TreeName = (*paramArg)[setUseTree1];
840             }
841             userParameters->setUseTree1File(true);
842             doAlignUseOldTree = true;
843         }
844     }
845
846     if(setNewTree1 != -1)
847     {
848         if(userParameters->getProfile1Empty()) 
849         {
850             exitWithErrorMsg("Cannot align profiles.  No input file");
851         }
852         else if(profileType == SEQUENCE) 
853         {
854             reportInvalidOptionAndExit("newtree1");
855         }
856         else  
857         {
858            if((*paramArg)[setNewTree1].length() == 0) 
859            {
860                exitWithErrorMsg("Cannot align profiles. No tree file specified");
861            }
862            else 
863            {
864                 p1TreeName = (*paramArg)[setNewTree1];
865            }
866            userParameters->setNewTree1File(true);
867         }
868     }
869  
870     if(setUseTree2 != -1)
871     {
872         if(userParameters->getProfile2Empty()) 
873         {
874             exitWithErrorMsg("Cannot align profiles.  No input file");
875         }
876         else if(profileType == SEQUENCE) 
877         {
878             reportInvalidOptionAndExit("usetree2");
879         }
880         else  
881         {
882             if((*paramArg)[setUseTree2].length() == 0) 
883             {
884                 exitWithErrorMsg("Cannot align profiles.  No tree file specified");
885             }
886             else 
887             {
888                 p2TreeName = (*paramArg)[setUseTree2];
889             }
890             userParameters->setUseTree2File(true);
891             doAlignUseOldTree = true;
892         }
893     }
894
895     if(setNewTree2 != -1)
896     {
897         if(userParameters->getProfile2Empty()) 
898         {
899             exitWithErrorMsg("Cannot align profiles.  No input file");
900         }
901         else if(profileType == SEQUENCE) 
902         {
903             reportInvalidOptionAndExit("newtree2");
904         }
905         else  
906         {
907             if((*paramArg)[setNewTree2].length() == 0) 
908             {
909                 exitWithErrorMsg("Cannot align profiles.  No tree file specified");
910             }
911             else 
912             {
913                 p2TreeName = (*paramArg)[setNewTree2];
914             }
915             userParameters->setNewTree2File(true);
916         }
917     }
918
919
920     if( (!doTreeFromAlign) && (!doBootstrap) && (!userParameters->getEmpty()) && (!doProfileAlign) && 
921       (!doAlignUseOldTree) && (!doGuideTreeOnly) && (!doConvert))
922     { 
923         doAlign = true;
924     }
925
926 //** ? /quicktree 
927     if(setQuickTree != -1)
928     {
929         userParameters->setQuickPairAlign(true);
930     }
931
932     // NOTE 
933     if(userParameters->getDNAFlag()) 
934     {
935         userParameters->setDNAParams();
936     }
937     else 
938     {
939         userParameters->setProtParams();
940     }
941     
942     if(userParameters->getInteractive()) 
943     {
944         if (!xmenus)
945         { 
946             userParameters->setMenuFlag(true);
947         }
948         return;
949     }
950
951
952     if(!doSomething) 
953     {
954         exitWithErrorMsg("No input file(s) specified");
955     }
956
957
958     
959
960 //***************************************************************************
961 // Now do whatever has been requested ***************************************
962 //***************************************************************************
963 // NOTE This part is obviously not done yet! Functions not working in Clustal!!!!
964     #if DEBUGFULL 
965         if(logObject && DEBUGLOG)
966         {
967             logObject->logMsg("Now doing the requested task(s)");
968         }
969     #endif
970         
971     if(doProfileAlign) 
972     {
973         #if DEBUGFULL 
974             if(logObject && DEBUGLOG)
975             {
976                 logObject->logMsg("    Doing profile align");
977             }
978         #endif        
979         if (profileType == PROFILE)
980         {
981             #if DEBUGFULL 
982                 if(logObject && DEBUGLOG)
983                 {
984                     logObject->logMsg("        Calling Profile_align in clustal obj!");
985                 }
986             #endif            
987             clustalObj->profileAlign(&p1TreeName, &p2TreeName);
988         }
989         else
990         {
991             #if DEBUGFULL 
992                 if(logObject && DEBUGLOG)
993                 {
994                 logObject->logMsg("        Calling sequencesAlignToProfile in clustal obj!");
995                 }
996             #endif
997             clustalObj->sequencesAlignToProfile(&phylipTreeName);
998         }
999     }
1000
1001     else if(doAlign)
1002     {
1003         #if DEBUGFULL 
1004             if(logObject && DEBUGLOG)
1005             {
1006                 logObject->logMsg("    Doing Alignment");
1007             }
1008         #endif               
1009         clustalObj->align(&phylipTreeName);
1010     }
1011
1012     else if(doConvert) 
1013     {
1014         #if DEBUGFULL 
1015             if(logObject && DEBUGLOG)
1016             {
1017                 logObject->logMsg("    Doing filetype conversion");
1018             }
1019         #endif                  
1020         clustalObj->outputNow();
1021     }
1022
1023     else if (doAlignUseOldTree)
1024     {
1025         #if DEBUGFULL 
1026             if(logObject && DEBUGLOG)
1027             {
1028                 logObject->logMsg("    Doing Alignment only");
1029             }
1030         #endif                 
1031         clustalObj->doAlignUseOldTree(&phylipTreeName);
1032     }
1033
1034     else if(doGuideTreeOnly)
1035     {
1036         #if DEBUGFULL 
1037             if(logObject && DEBUGLOG)
1038             {
1039                 logObject->logMsg("    Doing tree only");
1040             }
1041         #endif               
1042         clustalObj->doGuideTreeOnly(&phylipTreeName);
1043     }
1044
1045     else if(doTreeFromAlign)
1046     {
1047         #if DEBUGFULL 
1048             if(logObject && DEBUGLOG)
1049             {   
1050                 logObject->logMsg("    Doing tree");
1051             }
1052         #endif                  
1053         clustalObj->phylogeneticTree(&phylipTreeName, &clustalTreeName, &distTreeName,
1054                                      &nexusTreeName, pimName);
1055     }
1056
1057     else if(doBootstrap)
1058     {
1059         #if DEBUGFULL 
1060             if(logObject && DEBUGLOG)
1061             {
1062                 logObject->logMsg("    Doing Bootstrap");
1063             }
1064         #endif            
1065             clustalObj->bootstrapTree(&phylipTreeName, &clustalTreeName, &nexusTreeName);
1066     }
1067
1068     cout << std::endl;
1069     
1070 }
1071
1072
1073
1074 int CommandLineParser::checkParam(StringArray* args, StringArray* params,
1075                                   StringArray* paramArg)
1076 {
1077     int len, i, j, nameFirst, num;
1078     //int k;
1079     vector<int> match;
1080     match.resize(MAXARGS);
1081     bool name1 = false;
1082     
1083     #if DEBUGFULL 
1084         if(logObject && DEBUGLOG)
1085         {
1086             logObject->logMsg("Checking Parameters!");
1087         }
1088     #endif
1089         
1090     if(args->size() == 0) // NOTE I think this will work better!
1091     {
1092         cout << "The argument list is empty\n";
1093         return 0;
1094     }
1095
1096     // AW: first arg is an input file if it doesnt start with commandsep
1097     if (VALID_COMMAND_SEP.find((*args)[0][0], 0) == string::npos)
1098     {
1099         name1 = true;
1100         params->push_back((*args)[0]); // Put the string at the back of this vector.
1101         paramArg->push_back(""); // Push a blank string onto the first element.
1102     }
1103     else // It is not a file name
1104     {
1105         params->push_back((*args)[0].substr(1));
1106     }
1107     
1108     for (i = 1; i < (int)args->size(); i++) 
1109     {
1110         params->push_back(""); // Empty string!
1111
1112         for(j = 0; j < (int)(*args)[i].length() - 1; j++)
1113         {
1114             if(isprint((*args)[i][j + 1])) // Character printable?
1115             {
1116                 // We start at j + 1 because each option should begin with commandsep
1117                 (*params)[i].append((*args)[i].substr(j + 1, 1));
1118             }
1119         }
1120     }
1121     num = i;
1122
1123
1124     // AW:
1125     // params are now setup
1126     // extract paramArgs in next step
1127
1128     
1129     if ((int)args->size() > MAXARGS)
1130     {
1131         cerr << "Error: too many command line arguments\n";
1132         return(-1);
1133     }
1134     /*
1135       special case - first parameter is input fileName
1136     */
1137     nameFirst = 0;
1138     if(name1 == true) // If name of file is first argument
1139     {
1140         userParameters->setSeqName((*params)[0]);
1141         /* Andreas Wilm (UCD) 2008-03-19:
1142            conversion nowadays unnecessary and makes trouble
1143            
1144            /@  JULIE
1145            convert to lower case now
1146            @/
1147            #ifndef UNIX
1148            if(logObject && DEBUGLOG)
1149            {
1150            logObject->logMsg("Converting seqName to lower case.\n");
1151            }         
1152            string temp = ConvertStringToLower(userParameters->getSeqName());
1153            userParameters->setSeqName(temp);
1154            #endif
1155         */
1156         nameFirst = 1;
1157     }
1158   
1159     // NOTE if name first we should start at the 2nd element in paramArg
1160     // This loop is used to set up the paramArg vector!
1161     for (i = nameFirst; i < num; i++) 
1162     {
1163         bool has_arg=false;
1164         paramArg->push_back(""); // Push a new empty string on.
1165         len = (*params)[i].length();
1166         for(j = 0; j < len; j++)
1167         {
1168             if((*params)[i][j] == '=') 
1169             {
1170                 has_arg=true;
1171                 (*paramArg)[i].assign((*params)[i].substr(j + 1, len - j -1));               
1172                 // Trim off the bit from the '=' to the end, and put all in lower case!
1173                 (*params)[i].assign(ConvertStringToLower((*params)[i].substr(0, j)));
1174                 break;
1175             }
1176         }
1177         // Andreas Wilm (UCD): 2008-03-19:
1178         // this convert nonarg params to lowercase (-QuIcKtReE etc)
1179         if (!has_arg) {
1180             (*params)[i].assign(ConvertStringToLower((*params)[i]));          
1181         }
1182     }
1183
1184     if(paramArg->size() != params->size())
1185     {
1186         cerr << "There is something wrong with arguments. Lengths different\n";
1187         return -1;
1188     }
1189     
1190     /*
1191       for each parameter given on the command line, first search the list of recognised
1192       optional parameters....
1193     */
1194     for (i = 0; i < num; i++) 
1195     {
1196         if ((i == 0) && (name1 == true))
1197         { 
1198             continue;
1199         }
1200         j = 0;
1201         match[i] = -1;
1202         for(;;) 
1203         {
1204             if (cmdLinePara[j].str[0] == '\0')
1205             { 
1206                 // Think this means we have not found it!
1207                 break;
1208             }
1209             if (!(*params)[i].compare(cmdLinePara[j].str))
1210             {
1211                 match[i] = j; // Match has been found!
1212                 *cmdLinePara[match[i]].flag = i;
1213                 
1214                 if ((cmdLinePara[match[i]].type != NOARG) && ((*paramArg)[i] == "")) 
1215                 {
1216                     cerr <<  "Error: parameter required for " << default_commandsep << (*params)[i] << endl;
1217                     return -1;
1218                 
1219                 /* Andreas Wilm (UCD) 2008-03-19:
1220                  *  conversion nowadays unnecessary and breaks things
1221                  *  
1222                  * //  JULIE
1223                  * //    convert parameters to lower case now, unless the parameter is a fileName
1224                  * #ifdef UNIX
1225                  * else if (cmdLinePara[match[i]].type != FILARG && (*paramArg)[i] != "")
1226                  * #endif
1227                 */
1228
1229                 } else if (cmdLinePara[match[i]].type != FILARG && (*paramArg)[i] != "") {
1230                     if ((*paramArg)[i] != "") 
1231                     {
1232                         // lowercase arg if not a filename to support mixed case
1233                         (*paramArg)[i].assign(ConvertStringToLower((*paramArg)[i]));
1234                     }
1235                 }
1236                 break;
1237             }
1238             j++;
1239         }
1240     }
1241     
1242     /*
1243       ....then the list of recognised input files,.... 
1244     */
1245     for (i = 0; i < num; i++) 
1246     {
1247         if ((i == 0) && (name1 == true)) 
1248         {
1249             continue;
1250         }
1251         if (match[i] != -1) 
1252         {
1253             continue;
1254         }
1255         j = 0;
1256         for(;;) 
1257         {
1258             if (cmdLineFile[j].str[0] == '\0') 
1259             {
1260                 // Have not found a match!
1261                 break;
1262             }
1263             if (!(*params)[i].compare(cmdLineFile[j].str)) 
1264             {
1265                 match[i] = j;
1266                 *cmdLineFile[match[i]].flag = i;
1267                 if ((cmdLineFile[match[i]].type != NOARG) &&
1268                                     ((*paramArg)[i] == "")) 
1269                 {
1270                     cerr << "Error: parameter required for " << default_commandsep << (*params)[i] << endl;
1271                     return -1;
1272                 }
1273                 break;
1274             }
1275             j++;
1276         }
1277     }
1278     
1279     /*
1280       ....and finally the recognised verbs. 
1281     */
1282     for (i = 0; i < num; i++) 
1283     {
1284         if ((i == 0) && (name1 == true)) 
1285         {
1286             continue;
1287         }
1288         if (match[i] != -1) 
1289         {
1290             continue;
1291         }
1292         j = 0;
1293         for(;;) 
1294         {
1295             if (cmdLineVerb[j].str[0] == '\0') 
1296             {
1297                 // Havent found it!
1298                 break;
1299             }
1300             if (!(*params)[i].compare(cmdLineVerb[j].str)) 
1301             {
1302                 match[i] = j;
1303                 *cmdLineVerb[match[i]].flag = i;
1304                 if ((cmdLineVerb[match[i]].type != NOARG) && ((*paramArg)[i] == "")) 
1305                 {
1306                     cerr << "Error: parameter required for " << default_commandsep << (*params)[i] << endl;
1307                     return -1;
1308                 }
1309                 break;
1310             }
1311             j++;
1312         }
1313     }
1314
1315     /*
1316       check for any unrecognised parameters.
1317     */
1318     for (i = 0; i < num; i++) 
1319     {
1320         if (match[i] == -1) 
1321         {
1322             cerr << "Error: unknown option " << default_commandsep << (*params)[i] << endl;
1323             return -1;
1324         }
1325     }
1326     return(num);
1327 }
1328
1329 void CommandLineParser::setOptionalParam()
1330 {
1331     int temp;
1332     int _ktup, _windgap, _signif, _window = 0;
1333     string _matrixname;
1334     //int c, i;
1335     float ftemp;
1336     //char tstr[100];
1337
1338     #if DEBUGFULL 
1339         if(logObject && DEBUGLOG)
1340         {
1341             logObject->logMsg("Setting optional parameters.");
1342         }
1343     #endif      
1344     //****************************************************************************
1345     //* look for parameters on command line  e.g. gap penalties, k-tuple etc.    *
1346     //****************************************************************************
1347   
1348     // Mark change 16-2-2007. 
1349     
1350     if(setNumIterations != -1)
1351     {
1352         #if DEBUGFULL 
1353             if(logObject && DEBUGLOG)
1354             {
1355                 logObject->logMsg("    Setting num iterations parameter.");
1356             }    
1357         #endif      
1358         temp = 0;
1359         if((*paramArg)[setNumIterations].length() > 0)
1360         {
1361             if (sscanf((*paramArg)[setNumIterations].c_str(),"%d", &temp) != 1) 
1362             {
1363                 reportBadOptionAndExit("numiter", "int");
1364                 temp = 0;
1365             }
1366         }
1367         if(temp > 0)
1368         {
1369             userParameters->setNumIterations(temp);
1370         }
1371         else
1372         {
1373             exitWithErrorMsg("Cannot use a negative value for number of iterations.");
1374         }
1375     }
1376
1377     
1378     //** ? /score=percent or /score=absolute *
1379     if(setScore != -1)
1380     {    
1381         if((*paramArg)[setScore].length() > 0) 
1382         {
1383             temp = findMatch((*paramArg)[setScore], scoreArg, 2);
1384             if(temp == 0)
1385             {
1386                 userParameters->setPercent(true);
1387                 #if DEBUGFULL 
1388                     if(logObject && DEBUGLOG)
1389                     {
1390                         logObject->logMsg("    Setting score parameter = percent");
1391                     }
1392                 #endif                 
1393             }
1394             else if(temp == 1)
1395             {
1396                 userParameters->setPercent(false);
1397                 #if DEBUGFULL 
1398                     if(logObject && DEBUGLOG)
1399                     {
1400                         logObject->logMsg("    Setting score parameter = absolute");
1401                     }
1402                 #endif                 
1403             }
1404             else
1405             {
1406                 cerr << "\nUnknown SCORE type: " << (*paramArg)[setScore] << endl;
1407                 #if DEBUGFULL 
1408                     if(logObject && DEBUGLOG)
1409                     {
1410                         logObject->logMsg("    problem setting score type!!!!!");
1411                     }
1412                 #endif                
1413             }
1414         }
1415     }
1416     // NOTE I decided to stay with sscanf for getting the int. Options in c++ no better.
1417     //** ? /seed=n *
1418     if(setSeed != -1) 
1419     {
1420         #if DEBUGFULL 
1421             if(logObject && DEBUGLOG)
1422             {
1423                 logObject->logMsg("    Setting seed parameter.");
1424             }    
1425         #endif      
1426         temp = 0;
1427         if((*paramArg)[setSeed].length() > 0)
1428         {
1429             if (sscanf((*paramArg)[setSeed].c_str(),"%d",&temp) != 1) 
1430             {
1431                 reportBadOptionAndExit("seed", "integer");
1432             }
1433         }
1434         if(temp > 0)
1435         {
1436             userParameters->setBootRanSeed(temp);
1437         }
1438         cout<< "\ntemp = " << temp << "; seed = " << userParameters->getBootRanSeed() 
1439             << ";\n";
1440     }
1441   
1442     if(setTreeAlgorithm != -1)
1443     {
1444         #if DEBUGFULL 
1445             if(logObject && DEBUGLOG)
1446             {
1447                 logObject->logMsg("    Setting clustering algorithm parameter.");
1448             }
1449         #endif
1450         if((*paramArg)[setTreeAlgorithm].length() > 0) 
1451         { 
1452             temp = findMatch((*paramArg)[setTreeAlgorithm], clusterAlgorithm, 2);
1453             if(temp == 0)
1454             {
1455                 userParameters->setClusterAlgorithm(NJ);
1456             }
1457             else if(temp == 1)
1458             {
1459                 userParameters->setClusterAlgorithm(UPGMA);
1460             }
1461             else
1462             {
1463                 cerr << "Unknown option for clustering algorithm. Using default\n";
1464                 userParameters->setClusterAlgorithm(NJ);
1465             }
1466         }
1467     }
1468     
1469     
1470     //** ? /output=PIR, GCG, GDE or PHYLIP *
1471     if(setOutput != -1)
1472     {
1473         
1474         #if DEBUGFULL 
1475             if(logObject && DEBUGLOG)
1476             {
1477                 logObject->logMsg("    Setting output parameter.");
1478             }
1479         #endif          
1480         if((*paramArg)[setOutput].length() > 0) 
1481         {
1482             temp = findMatch((*paramArg)[setOutput], outputArg, 6);
1483             if (temp >= 0 && temp <= 5) 
1484             {
1485                 userParameters->setOutputClustal(false);
1486                 userParameters->setOutputGCG(false);
1487                 userParameters->setOutputPhylip(false);
1488                 userParameters->setOutputNbrf(false);
1489                 userParameters->setOutputGde(false);
1490                 userParameters->setOutputNexus(false);
1491                 userParameters->setOutputFasta(false);
1492             }
1493             switch (temp) 
1494             {
1495                 case 0: // GCG 
1496                     userParameters->setOutputGCG(true);
1497                     break;
1498                 case 1: // GDE 
1499                     userParameters->setOutputGde(true);
1500                     break;
1501                 case 2: // PIR 
1502                     userParameters->setOutputNbrf(true);
1503                     break;
1504                 case 3: // PHYLIP
1505                     userParameters->setOutputPhylip(true);
1506                     break;
1507                 case 4: // NEXUS
1508                     userParameters->setOutputNexus(true);
1509                     break;
1510                 case 5: // NEXUS
1511                     userParameters->setOutputFasta(true);
1512                     break;
1513                 default:
1514                     // FIXME AW: 1.83 behaves the same, but shouldnt
1515                     // we exit here?
1516                     exitWithErrorMsg("Unknown OUTPUT type: " + (*paramArg)[setOutput]);
1517             }
1518         }
1519     }
1520     //** ? /outputtree=NJ or PHYLIP or DIST or NEXUS 
1521     if(setOutputTree != -1)
1522     {
1523         #if DEBUGFULL 
1524             if(logObject && DEBUGLOG)
1525             {
1526                 logObject->logMsg("    Setting outputtree parameter.");
1527             }   
1528         #endif           
1529         if((*paramArg)[setOutputTree].length() > 0) 
1530         {
1531             temp = findMatch((*paramArg)[setOutputTree], outputTreeArg, 4);
1532             switch (temp) 
1533             {
1534                 case 0: // NJ 
1535                     userParameters->setOutputTreeClustal(true);
1536                     break;
1537                 case 1: // PHYLIP
1538                     userParameters->setOutputTreePhylip(true);
1539                     break;
1540                 case 2: // DIST
1541                     userParameters->setOutputTreeDistances(true);
1542                     break;
1543                 case 3: // NEXUS 
1544                     userParameters->setOutputTreeNexus(true);
1545                     break;
1546                 default:
1547                     cerr << "\nUnknown OUTPUT TREE type: " 
1548                          << (*paramArg)[setOutputTree] << endl;
1549             }
1550         }
1551     }
1552     
1553     //** ? /profile (sets type of second input file to profile) 
1554     if(setProfile != -1)
1555     {
1556         #if DEBUGFULL 
1557             if(logObject && DEBUGLOG)
1558             {
1559                 logObject->logMsg("    Setting profileType = PROFILE.");
1560             }         
1561         #endif 
1562         profileType = PROFILE;
1563     }
1564   
1565     //** ? /sequences (sets type of second input file to list of sequences)
1566     if(setSequences != -1)
1567     {
1568         #if DEBUGFULL 
1569             if(logObject && DEBUGLOG)
1570             {
1571                 logObject->logMsg("    Setting profileType = SEQUENCE.");
1572             }         
1573         #endif
1574         profileType = SEQUENCE;
1575     } 
1576   
1577   
1578     //** ? /ktuple=n
1579     if(setKtuple != -1) 
1580     {
1581         #if DEBUGFULL 
1582             if(logObject && DEBUGLOG)
1583             {
1584                 logObject->logMsg("    Setting ktup parameter.");
1585             }
1586         #endif         
1587         _ktup = 0;
1588         if((*paramArg)[setKtuple].length() > 0)
1589         {
1590             if (sscanf((*paramArg)[setKtuple].c_str(),"%d",&_ktup)!=1) 
1591             {
1592                 reportBadOptionAndExit("ktuple", "integer");
1593                 _ktup = 0;
1594             }
1595         }
1596         
1597         if(_ktup > 0) 
1598         {
1599             if(userParameters->getDNAFlag()) 
1600             {
1601                 if(_ktup <= 4) 
1602                 {
1603                     userParameters->setKtup(_ktup);
1604                     userParameters->setDNAKtup(_ktup);
1605                     userParameters->setWindowGap(_ktup + 4);
1606                     userParameters->setDNAWindowGap(_ktup + 4);
1607                 } else {
1608                     // see comment in bug 185
1609                     cerr << "WARNING: Ignoring invalid ktuple of " << _ktup <<  " (must be <=4)" << std::endl;
1610                 }
1611             }
1612             else 
1613             {
1614                 if(_ktup <= 2) 
1615                 {
1616                     userParameters->setKtup(_ktup);
1617                     userParameters->setAAKtup(_ktup);
1618                     userParameters->setWindowGap(_ktup + 3);
1619                     userParameters->setAAWindowGap(_ktup + 3);
1620                     // AW: why set setDNAWindowGap? we are in AA mode
1621                     // userParameters->setDNAWindowGap(_ktup + 4);
1622                 } else {
1623                     // see comment in bug 185
1624                    cerr << "WARNING: Ignoring invalid ktuple of " << _ktup << " (must be <=2)" << std::endl;
1625                 }
1626             }
1627         }
1628     }
1629     
1630     //** ? /pairgap=n 
1631     if(setPairGap != -1) 
1632     {
1633         #if DEBUGFULL 
1634             if(logObject && DEBUGLOG)
1635             {
1636                 logObject->logMsg("    Setting pairgap parameter.");
1637             }
1638         #endif         
1639         _windgap = 0;
1640         if((*paramArg)[setPairGap].length() > 0)
1641         {
1642             if (sscanf((*paramArg)[setPairGap].c_str(),"%d",&_windgap)!=1) 
1643             {
1644                 reportBadOptionAndExit("pairgap", "integer");
1645                 _windgap = 0;
1646             }
1647             if(_windgap > 0)
1648             {
1649                 if(userParameters->getDNAFlag()) 
1650                 {
1651                     if(_windgap > userParameters->getKtup()) 
1652                     {
1653                         userParameters->setWindowGap(_windgap);
1654                         userParameters->setDNAWindowGap(_windgap);
1655                     }
1656                 }
1657                 else 
1658                 {
1659                     if(_windgap > userParameters->getKtup()) 
1660                     {
1661                         userParameters->setWindowGap(_windgap);
1662                         userParameters->setAAWindowGap(_windgap);
1663                     }
1664                 }
1665             }
1666         }
1667     } 
1668   
1669     //** ? /topdiags=n  
1670     if(setTopDiags != -1) 
1671     {
1672         #if DEBUGFULL 
1673             if(logObject && DEBUGLOG)
1674             {
1675                 logObject->logMsg("    Setting topdiags parameter.");
1676             }
1677         #endif          
1678         _signif = 0;
1679         if((*paramArg)[setTopDiags].length() > 0)
1680         {
1681             if (sscanf((*paramArg)[setTopDiags].c_str(),"%d",&_signif)!=1) 
1682             {
1683                 reportBadOptionAndExit("topdiags", "integer");
1684             }
1685         }
1686         if(_signif > 0)
1687         {
1688             if(userParameters->getDNAFlag()) 
1689             {
1690                 if(_signif > userParameters->getKtup()) 
1691                 {
1692                     userParameters->setSignif(_signif);
1693                     userParameters->setDNASignif(_signif);
1694                 }
1695             }
1696             else 
1697             {
1698                 if(_signif > userParameters->getKtup()) 
1699                 {
1700                     userParameters->setSignif(_signif);
1701                     userParameters->setAASignif(_signif);
1702                 }
1703             }
1704         }
1705     }
1706     
1707
1708     //** ? /window=n 
1709     if(setWindow != -1) 
1710     {
1711         #if DEBUGFULL 
1712             if(logObject && DEBUGLOG)
1713             {
1714                 logObject->logMsg("    Setting window parameter.");
1715             }
1716         #endif        
1717         _window = 0;
1718         if((*paramArg)[setWindow].length() > 0)
1719         {
1720             if (sscanf((*paramArg)[setWindow].c_str(),"%d",&_window)!=1) 
1721             {
1722                 reportBadOptionAndExit("window", "integer");
1723                 _window = 0;
1724             }
1725         }
1726         if(_window > 0)
1727         {
1728             if(userParameters->getDNAFlag()) 
1729             {
1730                 if(_window > userParameters->getKtup()) 
1731                 {
1732                     userParameters->setWindow(_window);
1733                     userParameters->setDNAWindow(_window);
1734                 }
1735             }
1736             else 
1737             {
1738                 if(_window > userParameters->getKtup()) 
1739                 {
1740                     userParameters->setWindow(_window);
1741                     userParameters->setAAWindow(_window);
1742                 }
1743             }
1744         }
1745     }
1746   
1747     //** ? /kimura 
1748     if(setKimura != -1)
1749     {
1750         #if DEBUGFULL 
1751             if(logObject && DEBUGLOG)
1752             {
1753                 logObject->logMsg("    Setting kimura=true");
1754             }
1755         #endif        
1756         userParameters->setKimura(true);
1757     }
1758   
1759     //** ? /tossgaps 
1760     if(setTossGaps != -1)
1761     {
1762         #if DEBUGFULL 
1763             if(logObject && DEBUGLOG)
1764             {
1765                 logObject->logMsg("    Setting tossgaps=true");
1766             }
1767         #endif        
1768         userParameters->setTossGaps(true);
1769     }
1770     
1771     //** ? /negative  
1772     if(setNegative != -1)
1773     {
1774         #if DEBUGFULL 
1775             if(logObject && DEBUGLOG)
1776             {
1777                 logObject->logMsg("    Setting useNegMatrix=true");
1778             }         
1779         #endif 
1780         userParameters->setUseNegMatrix(true);
1781     }
1782   
1783     //** ? /noweights
1784     if(setNoWeights!= -1)
1785     {
1786         #if DEBUGFULL 
1787             if(logObject && DEBUGLOG)
1788             {
1789                 logObject->logMsg("    Setting noweights=true");
1790             }       
1791         #endif 
1792         userParameters->setNoWeights(true);
1793     }
1794   
1795   
1796     //** ? /pwmatrix=ID (user's file) 
1797     if(setPWMatrix != -1)
1798     {
1799         #if DEBUGFULL 
1800             if(logObject && DEBUGLOG)
1801             {
1802                 logObject->logMsg("    Setting pwmatrix parameter.");
1803             }        
1804         #endif
1805         temp = (*paramArg)[setPWMatrix].length();
1806         if(temp > 0) 
1807         {
1808             _matrixname = ConvertStringToLower((*paramArg)[setPWMatrix]);
1809             if (_matrixname.compare("blosum") == 0) 
1810             {
1811                 subMatrix->setCurrentNameAndNum(_matrixname, 1, Protein, Pairwise);
1812             }
1813             else if (_matrixname.compare("pam") == 0) 
1814             {
1815                 subMatrix->setCurrentNameAndNum(_matrixname, 2, Protein, Pairwise);
1816             }
1817             else if (_matrixname.compare("gonnet") == 0) 
1818             {
1819                 subMatrix->setCurrentNameAndNum(_matrixname, 3, Protein, Pairwise);
1820             }
1821             else if (_matrixname.compare("id") == 0) 
1822             {
1823                 subMatrix->setCurrentNameAndNum(_matrixname, 4, Protein, Pairwise);
1824             }
1825             else 
1826             {
1827                 char hackTempName[FILENAMELEN + 1];
1828                 strcpy(hackTempName, (*paramArg)[setPWMatrix].c_str());
1829                 
1830                 if(subMatrix->getUserMatFromFile(hackTempName, Protein, Pairwise))
1831                 {                      
1832                     subMatrix->setCurrentNameAndNum((*paramArg)[setPWMatrix], 5, 
1833                                                      Protein, Pairwise);
1834                     pwUserMatrixName = (*paramArg)[setPWMatrix];
1835                 }
1836                 else 
1837                     exit(1);
1838             }
1839         }
1840     }
1841
1842         
1843     //** ? /matrix=ID (user's file)
1844     if(setMatrix != -1)
1845     {
1846         #if DEBUGFULL 
1847             if(logObject && DEBUGLOG)
1848             {
1849                 logObject->logMsg("    Setting matrix parameter.");
1850             }       
1851         #endif 
1852         temp = (*paramArg)[setMatrix].length();
1853         if(temp > 0) 
1854         {
1855             _matrixname = ConvertStringToLower((*paramArg)[setMatrix]);
1856
1857             if (_matrixname.compare("blosum")==0) 
1858             {
1859                 subMatrix->setCurrentNameAndNum(_matrixname, 1, Protein, MultipleAlign);
1860             }
1861             else if (_matrixname.compare("pam")==0) 
1862             {
1863                 subMatrix->setCurrentNameAndNum(_matrixname, 2, Protein, MultipleAlign);
1864             }
1865             else if (_matrixname.compare("gonnet")==0) 
1866             {
1867                 subMatrix->setCurrentNameAndNum(_matrixname, 3, Protein, MultipleAlign);
1868             }
1869             else if (_matrixname.compare("id")==0) 
1870             {
1871                 subMatrix->setCurrentNameAndNum(_matrixname, 4, Protein, MultipleAlign);
1872             }
1873             else 
1874             {
1875                 char hackTempName[FILENAMELEN + 1];
1876                 strcpy(hackTempName, (*paramArg)[setMatrix].c_str());
1877                                     
1878                 if(subMatrix->getUserMatSeriesFromFile(hackTempName))
1879                 {
1880                     subMatrix->setCurrentNameAndNum((*paramArg)[setMatrix], 4, 
1881                                                      Protein, MultipleAlign);
1882                     userMatrixName = (*paramArg)[setMatrix];
1883                 }
1884                 else 
1885                     exit(1);
1886             }
1887         }
1888     }
1889
1890     //** ? /pwdnamatrix=ID (user's file)
1891     if(setPWDNAMatrix != -1)
1892     {
1893         #if DEBUGFULL 
1894             if(logObject && DEBUGLOG)
1895             {
1896                 logObject->logMsg("    Setting pwdnamatrix parameter.");
1897             }       
1898         #endif 
1899         temp = (*paramArg)[setPWDNAMatrix].length();
1900         if(temp > 0) 
1901         {
1902             _matrixname = ConvertStringToLower((*paramArg)[setPWDNAMatrix]);
1903
1904             if (_matrixname.compare("iub") == 0) 
1905             {
1906                 subMatrix->setCurrentNameAndNum(_matrixname, 1, DNA, Pairwise);
1907             }
1908             else if (_matrixname.compare("clustalw") == 0) 
1909             {
1910                 subMatrix->setCurrentNameAndNum(_matrixname, 2, DNA, Pairwise);
1911             }
1912             else 
1913             {
1914                 char hackTempName[FILENAMELEN + 1];
1915                 strcpy(hackTempName, (*paramArg)[setPWDNAMatrix].c_str());
1916                     
1917                 if(subMatrix->getUserMatFromFile(hackTempName, DNA, Pairwise))
1918                 {
1919                     subMatrix->setCurrentNameAndNum((*paramArg)[setPWDNAMatrix], 3, 
1920                                                      Protein, Pairwise);
1921                     pwDNAUserMatrixName = (*paramArg)[setPWDNAMatrix];
1922                 }
1923                 else 
1924                     exit(1);
1925             }
1926         }
1927     }
1928
1929     //** ? /dnamatrix=ID (user's file)
1930     if(setDNAMatrix != -1)
1931     {
1932         #if DEBUGFULL 
1933             if(logObject && DEBUGLOG)
1934             {
1935                 logObject->logMsg("    Setting dnamatrix parameter.");
1936             }        
1937         #endif 
1938         temp = (*paramArg)[setDNAMatrix].length();
1939         if(temp > 0) 
1940         {
1941             _matrixname = ConvertStringToLower((*paramArg)[setDNAMatrix]);
1942
1943             if (_matrixname.compare("iub") == 0) 
1944             {
1945                 subMatrix->setCurrentNameAndNum(_matrixname, 1, DNA, MultipleAlign);
1946             }
1947             else if (_matrixname.compare("clustalw") == 0) 
1948             {
1949                 subMatrix->setCurrentNameAndNum(_matrixname, 2, DNA, MultipleAlign);
1950             }
1951             else 
1952             {
1953                 char hackTempName[FILENAMELEN + 1];
1954                 strcpy(hackTempName, (*paramArg)[setDNAMatrix].c_str());
1955                     
1956                 if(subMatrix->getUserMatFromFile(hackTempName, DNA, MultipleAlign))
1957                 {
1958                     subMatrix->setCurrentNameAndNum((*paramArg)[setDNAMatrix], 3, 
1959                                                      Protein, MultipleAlign);
1960                     DNAUserMatrixName = (*paramArg)[setDNAMatrix];
1961                 }
1962                 else 
1963                     exit(1);
1964             }
1965         }
1966     }
1967  
1968        
1969     //** ? /maxdiv= n
1970     if(setMaxDiv != -1) 
1971     {
1972         #if DEBUGFULL 
1973             if(logObject && DEBUGLOG)
1974             {
1975                 logObject->logMsg("    Setting maxdiv parameter.");
1976             }       
1977         #endif 
1978         temp = 0;
1979         if((*paramArg)[setMaxDiv].length() > 0)
1980         {
1981             if (sscanf((*paramArg)[setMaxDiv].c_str(),"%d",&temp)!=1) 
1982             {
1983                 reportBadOptionAndExit("maxdiv", "integer");
1984                 temp = 0;
1985             }
1986         }
1987         if (temp >= 0)
1988         {
1989             userParameters->setDivergenceCutoff(temp);
1990         }
1991     }
1992
1993     //** ? /gapdist= n
1994     if(setGapDist != -1) 
1995     {
1996         #if DEBUGFULL 
1997             if(logObject && DEBUGLOG)
1998             {
1999                 logObject->logMsg("    Setting gapdist parameter.");
2000             }       
2001         #endif
2002          
2003         temp = 0;
2004         if((*paramArg)[setGapDist].length() > 0)
2005             if (sscanf((*paramArg)[setGapDist].c_str(),"%d",&temp)!=1) 
2006             {
2007                 reportBadOptionAndExit("gapdist", "integer");
2008             }
2009         if (temp >= 0)
2010         {
2011             userParameters->setGapDist(temp);
2012         }
2013     }
2014
2015     //** ? /debug= n 
2016     if(setDebug != -1) 
2017     {
2018         temp = 0;
2019         if((*paramArg)[setDebug].length() > 0)
2020             if (sscanf((*paramArg)[setDebug].c_str(),"%d",&temp)!=1) 
2021             {
2022                 reportBadOptionAndExit("debug", "integer");
2023             }
2024         if (temp >= 0)
2025         {
2026             userParameters->setDebug(temp);
2027         }
2028     }
2029
2030     //** ? /outfile= (user's file) 
2031     if(setOutfile != -1)
2032     {
2033         #if DEBUGFULL 
2034             if(logObject && DEBUGLOG)
2035             {
2036                 logObject->logMsg("    Setting outfile parameter.");
2037             }        
2038         #endif
2039         if((*paramArg)[setOutfile].length() > 0) 
2040         {
2041             userParameters->setOutfileName((*paramArg)[setOutfile]);
2042         }
2043     }
2044
2045     //*** ? /case= lower/upper 
2046     if(setCase != -1) 
2047     {
2048         #if DEBUGFULL 
2049             if(logObject && DEBUGLOG)
2050             {
2051                 logObject->logMsg("    Setting case parameter.");
2052             }       
2053         #endif 
2054         if((*paramArg)[setCase].length() > 0) 
2055         {
2056             temp = findMatch((*paramArg)[setCase], caseArg, 2);
2057             if(temp == 0) 
2058             {
2059                 userParameters->setLowercase(true);
2060             }
2061             else if(temp == 1) 
2062             {
2063                 userParameters->setLowercase(false);
2064             }
2065             else
2066             {
2067                 cerr << "\nUnknown case " <<  (*paramArg)[setCase] << endl;
2068             }
2069         }
2070     }
2071
2072     //*** ? /seqnos=off/on 
2073     if(setSeqNo != -1) 
2074     {
2075         #if DEBUGFULL 
2076             if(logObject && DEBUGLOG)
2077             {
2078                 logObject->logMsg("    Setting seqnos parameter.");
2079             }         
2080         #endif
2081         if((*paramArg)[setSeqNo].length() > 0) 
2082         {
2083             temp = findMatch((*paramArg)[setSeqNo], seqNoArg, 2);
2084             if(temp == 0) 
2085             {
2086                 userParameters->setClSeqNumbers(false);
2087             }
2088             else if(temp == 1) 
2089             {
2090                 userParameters->setClSeqNumbers(true);
2091             }
2092             else
2093             {
2094                 cerr << "\nUnknown SEQNO option " << (*paramArg)[setSeqNo] << endl;
2095             }
2096         }
2097     }
2098
2099
2100     if(setSeqNoRange != -1) 
2101     {
2102         #if DEBUGFULL 
2103             if(logObject && DEBUGLOG)
2104             {
2105                 logObject->logMsg("    Setting seqno range parameter.");
2106             }        
2107         #endif
2108         if((*paramArg)[setSeqNoRange].length() > 0) 
2109         {
2110             temp = findMatch((*paramArg)[setSeqNoRange], seqNoRangeArg, 2);
2111             cout << "\n comparing  " 
2112                  << "\nparamArg[setSeqNoRange]= " << (*paramArg)[setSeqNoRange]
2113                  << "\n comparing \n "; 
2114
2115             if(temp == 0) 
2116             {
2117                 userParameters->setSeqRange(false);
2118             }
2119             else if(temp == 1) 
2120             {
2121                 userParameters->setSeqRange(true);
2122             }
2123             else
2124             {
2125                 cerr << "\nUnknown Sequence range  option " 
2126                      << (*paramArg)[setSeqNoRange] << endl;
2127             }
2128         }
2129     }
2130
2131     //*** ? /range=n:m
2132     if(setRange != -1) 
2133     {
2134         #if DEBUGFULL 
2135             if(logObject && DEBUGLOG)
2136             {
2137                 logObject->logMsg("    Setting range parameter.");
2138             }        
2139         #endif
2140         temp = 0;
2141         if((*paramArg)[setRange].length() > 0)
2142         {
2143             // NOTE I have made a big change here! Mark march 14th 2006. This was being done
2144             // in the Alignment output functions. 
2145             int iFirstRes = -1; 
2146             int iLastRes = -1;
2147             char ignore;
2148             
2149             if (sscanf((*paramArg)[setRange].c_str(), "%d%[ :,-]%d", &iFirstRes,
2150                         &ignore, &iLastRes) != 3) 
2151             {
2152                 cerr << "setRange:  Syntax Error: Cannot set range, should be from:to \n";
2153             }
2154             else
2155             {
2156                 userParameters->setRangeFrom(iFirstRes);
2157                 userParameters->setRangeTo(iLastRes);
2158             }
2159         }
2160     }
2161
2162     //*** ? /gapopen=n 
2163     if(setGapOpen != -1) 
2164     {
2165         #if DEBUGFULL 
2166             if(logObject && DEBUGLOG)
2167             {
2168                 logObject->logMsg("    Setting gapopen parameter.");
2169             }        
2170         #endif
2171         ftemp = 0.0;
2172         if((*paramArg)[setGapOpen].length() > 0)
2173         {
2174             if (sscanf((*paramArg)[setGapOpen].c_str(),"%f",&ftemp) != 1) 
2175             {
2176                 reportBadOptionAndExit("gapopen", "real number");
2177                 ftemp = 0.0;
2178             }
2179             if(ftemp >= 0.0)
2180             {
2181                 if( userParameters->getDNAFlag()) 
2182                 {
2183                     userParameters->setGapOpen(ftemp);
2184                     userParameters->setDNAGapOpen(ftemp);
2185                 }
2186                 else 
2187                 {
2188                     userParameters->setGapOpen(ftemp);
2189                     userParameters->setProteinGapOpen(ftemp);
2190                 }
2191             }
2192         }
2193     }
2194
2195     //*** ? /gapext=n
2196     if(setGapExtend != -1) 
2197     {
2198         #if DEBUGFULL 
2199             if(logObject && DEBUGLOG)
2200             {
2201                 logObject->logMsg("    Setting gap extention parameter.");
2202             }        
2203         #endif
2204         
2205         ftemp = 0.0;
2206         if((*paramArg)[setGapExtend].length() > 0)
2207         {
2208             if (sscanf((*paramArg)[setGapExtend].c_str(),"%f",&ftemp) != 1) 
2209             {
2210                 reportBadOptionAndExit("gapext", "real number");
2211                ftemp = 0.0;
2212             }
2213             if(ftemp >= 0)
2214             {
2215                 if(userParameters->getDNAFlag()) 
2216                 {
2217                     userParameters->setGapExtend(ftemp);
2218                     userParameters->setDNAGapExtend(ftemp);
2219                 }
2220                 else 
2221                 {
2222                     userParameters->setGapExtend(ftemp);
2223                     userParameters->setProteinGapExtend(ftemp);
2224                 }
2225             }
2226         }
2227     }
2228
2229     //*** ? /transweight=n
2230     if(setTransWeight != -1) 
2231     {
2232         #if DEBUGFULL 
2233             if(logObject && DEBUGLOG)
2234             {
2235                 logObject->logMsg("    Setting transweight parameter.");
2236             }        
2237         #endif
2238         
2239         ftemp = 0.0;
2240         if((*paramArg)[setTransWeight].length() > 0)
2241         {
2242             if (sscanf((*paramArg)[setTransWeight].c_str(), "%f", &ftemp) != 1) 
2243             {
2244                 reportBadOptionAndExit("transweight", "real number");
2245             }
2246         }
2247         userParameters->setTransitionWeight(ftemp);
2248     }
2249
2250     //*** ? /pwgapopen=n 
2251     if(setPWGapOpen != -1) 
2252     {
2253         #if DEBUGFULL 
2254             if(logObject && DEBUGLOG)
2255             {
2256                 logObject->logMsg("    Setting pwgapopen parameter.");
2257             }        
2258         #endif
2259         
2260         ftemp = 0.0;
2261         if((*paramArg)[setPWGapOpen].length() > 0)
2262         {
2263             if (sscanf((*paramArg)[setPWGapOpen].c_str(), "%f", &ftemp) != 1) 
2264             {
2265                 reportBadOptionAndExit("pwgapopen", "real number");
2266             }
2267         }
2268         if(ftemp >= 0.0)
2269         {
2270             if(userParameters->getDNAFlag()) 
2271             {
2272                 userParameters->setPWGapOpen(ftemp);
2273                 userParameters->setDNAPWGapOpenPenalty(ftemp);
2274             }
2275             else 
2276             {
2277                 userParameters->setPWGapOpen(ftemp);
2278                 userParameters->setProteinPWGapOpenPenalty(ftemp);
2279             }
2280         }
2281     }
2282
2283
2284     //*** ? /gapext=n 
2285     if(setPWGapExtend != -1) 
2286     {
2287         #if DEBUGFULL 
2288             if(logObject && DEBUGLOG)
2289             {
2290                 logObject->logMsg("    Setting pwgapext parameter.");
2291             }        
2292         #endif
2293         
2294         ftemp = 0.0;
2295         if((*paramArg)[setPWGapExtend].length() > 0)
2296         {
2297             if (sscanf((*paramArg)[setPWGapExtend].c_str(), "%f", &ftemp) != 1) 
2298             {
2299                 reportBadOptionAndExit("pwgapext", "real number");
2300             }
2301         }
2302         if(ftemp >= 0)
2303         {
2304             if(userParameters->getDNAFlag()) 
2305             {
2306                 userParameters->setPWGapExtend(ftemp);
2307                 userParameters->setDNAPWGapExtendPenalty(ftemp);
2308             }
2309             else 
2310             {
2311                 userParameters->setPWGapExtend(ftemp);
2312                 userParameters->setProteinPWGapExtendPenalty(ftemp);
2313             }
2314         }
2315     }
2316
2317
2318
2319     //*** ? /outorder=n 
2320     if(setOutOrder != -1) 
2321     {
2322         #if DEBUGFULL 
2323             if(logObject && DEBUGLOG)
2324             {
2325                 logObject->logMsg("    Setting outorder parameter.");
2326             }        
2327         #endif
2328         
2329         if((*paramArg)[setOutOrder].length() > 0)
2330         {
2331             temp = findMatch((*paramArg)[setOutOrder],outOrderArg,2);
2332         }
2333
2334         if(temp == 0) 
2335         {    
2336             userParameters->setOutputOrder(INPUT);
2337         }
2338         else if(temp == 1) 
2339         {    
2340             userParameters->setOutputOrder(ALIGNED);
2341         }
2342         else
2343         {
2344             cerr << "\nUnknown OUTPUT ORDER type " <<  (*paramArg)[setOutOrder] << endl;
2345         }
2346     }
2347
2348     //*** ? /bootlabels=n 
2349     if(setBootLabels != -1) 
2350     {
2351
2352         #if DEBUGFULL 
2353             if(logObject && DEBUGLOG)
2354             {
2355                 logObject->logMsg("    Setting bootlabels parameter.");
2356             }        
2357         #endif
2358         
2359         if((*paramArg)[setBootLabels].length() > 0)
2360         {
2361             temp = findMatch((*paramArg)[setBootLabels], bootLabelsArg, 2);
2362         }
2363
2364         if(temp == 0)  
2365         {    
2366             userParameters->setBootstrapFormat(BS_NODE_LABELS);
2367         }
2368         else if(temp == 1)  
2369         {    
2370             userParameters->setBootstrapFormat(BS_BRANCH_LABELS);
2371         }
2372         else
2373         {
2374             cerr << "\nUnknown bootlabels type " << (*paramArg)[setBootLabels] << endl;
2375         }
2376     }
2377
2378     //*** ? /endgaps 
2379     if(setUseEndGaps != -1)
2380     {
2381         #if DEBUGFULL 
2382             if(logObject && DEBUGLOG)
2383             {
2384                 logObject->logMsg("    Setting useendgaps=true");
2385             }        
2386         #endif
2387         
2388         userParameters->setUseEndGaps(false);
2389     }
2390
2391     //*** ? /nopgap 
2392     if(setNoPGap != -1)
2393     {
2394         #if DEBUGFULL 
2395             if(logObject && DEBUGLOG)
2396             {
2397                 logObject->logMsg("    Setting noPrefPenalties=true");
2398             }        
2399         #endif
2400         
2401         userParameters->setNoPrefPenalties(true);
2402     }
2403
2404     //*** ? /nohgap 
2405     if(setNoHGap != -1)
2406     {
2407         #if DEBUGFULL 
2408             if(logObject && DEBUGLOG)
2409             {
2410                 logObject->logMsg("    Setting nohgap=true");
2411             }        
2412         #endif
2413         
2414         userParameters->setNoHydPenalties(true);
2415     }
2416
2417     //*** ? /novgap 
2418     if(setNoVGap != -1)
2419     {
2420         #if DEBUGFULL 
2421             if(logObject && DEBUGLOG)
2422             {
2423                 logObject->logMsg("    Setting novgap=false");
2424             }        
2425         #endif
2426         
2427         userParameters->setNoVarPenalties(false);
2428     }
2429
2430     //*** ? /hgapresidues="string" 
2431     // NOTE I have made some big changes here. It looks as if there was an error here!
2432     if(setHGapRes != -1)
2433     {
2434         #if DEBUGFULL 
2435             if(logObject && DEBUGLOG)
2436             {
2437                 logObject->logMsg("    Setting hgapresidues parameter.");
2438             }        
2439         #endif
2440         
2441         userParameters->setHydResidues((*paramArg)[setHGapRes]);
2442         
2443     }
2444               
2445     //*** ? /nosecstr1 
2446     if(setSecStruct1 != -1)
2447     {
2448         #if DEBUGFULL 
2449             if(logObject && DEBUGLOG)
2450             {
2451                 logObject->logMsg("    Setting useSS1=false");
2452             }        
2453         #endif
2454         
2455         userParameters->setUseSS1(false);
2456     }
2457
2458     //*** ? /nosecstr2 
2459     if(setSecStruct2 != -1)
2460     {
2461         #if DEBUGFULL 
2462             if(logObject && DEBUGLOG)
2463             {
2464                 logObject->logMsg("    Setting useSS2=false");
2465             }        
2466         #endif
2467         
2468         userParameters->setUseSS2(false);
2469     }
2470
2471     //*** ? /secstroutput
2472     if(setSecStructOutput != -1)
2473     {
2474         #if DEBUGFULL 
2475             if(logObject && DEBUGLOG)
2476             {
2477                 logObject->logMsg("    Setting secstroutput parameter.");
2478             }        
2479         #endif
2480         
2481         if((*paramArg)[setSecStructOutput].length() > 0) 
2482         {
2483             temp = findMatch((*paramArg)[setSecStructOutput], outputSecStrArg, 4);
2484             if(temp >= 0 && temp <= 3)
2485             {
2486                 userParameters->setOutputStructPenalties(temp);
2487             }
2488             else
2489             {
2490                 cerr << "\nUnknown case " << (*paramArg)[setSecStructOutput] << endl;
2491             }
2492         }
2493     }
2494
2495
2496     //*** ? /helixgap= n
2497     if(setHelixGap != -1) 
2498     {
2499         #if DEBUGFULL 
2500             if(logObject && DEBUGLOG)
2501             {
2502                 logObject->logMsg("    Setting helixgap parameter.");
2503             }        
2504         #endif
2505         
2506         temp = 0;
2507         if((*paramArg)[setHelixGap].length() > 0)
2508         {
2509             if (sscanf((*paramArg)[setHelixGap].c_str(), "%d", &temp) != 1) 
2510             {
2511                 reportBadOptionAndExit("helixgap", "integer");
2512             }
2513         }
2514         if (temp >= 1 && temp <= 9)
2515         {
2516             userParameters->setHelixPenalty(temp);
2517         }
2518     }
2519     
2520     //*** ? /strandgap= n 
2521     if(setStrandGap != -1) 
2522     {
2523         #if DEBUGFULL 
2524             if(logObject && DEBUGLOG)
2525             {
2526                 logObject->logMsg("    Setting strandgap parameter.");
2527             }         
2528         #endif
2529         
2530         temp = 0;
2531         if((*paramArg)[setStrandGap].length() > 0)
2532         {
2533             if (sscanf((*paramArg)[setStrandGap].c_str(), "%d", &temp) != 1) 
2534             {
2535                 reportBadOptionAndExit("strandgap", "integer");
2536             }
2537         }
2538         if (temp >= 1 && temp <= 9)
2539         {
2540             userParameters->setStrandPenalty(temp);
2541         }
2542     }
2543     
2544     //*** ? /loopgap= n 
2545     if(setLoopGap != -1) 
2546     {
2547         #if DEBUGFULL 
2548             if(logObject && DEBUGLOG)
2549             {
2550                 logObject->logMsg("    Setting loopgap parameter.");
2551             }        
2552         #endif
2553         
2554         temp = 0;
2555         if((*paramArg)[setLoopGap].length() > 0)
2556         {
2557             if (sscanf((*paramArg)[setLoopGap].c_str(), "%d", &temp) != 1) 
2558             {
2559                 reportBadOptionAndExit("loopgap", "integer");
2560             }
2561         }
2562         if (temp >= 1 && temp <= 9)
2563         {
2564             userParameters->setLoopPenalty(temp);
2565         }
2566     }
2567
2568     //*** ? /terminalgap= n
2569     if(setTerminalGap != -1) 
2570     {
2571         #if DEBUGFULL 
2572             if(logObject && DEBUGLOG)
2573             {
2574                 logObject->logMsg("    Setting terminalgap parameter.");
2575             }        
2576         #endif
2577         temp = 0;
2578         if((*paramArg)[setTerminalGap].length() > 0)
2579         {
2580             if (sscanf((*paramArg)[setTerminalGap].c_str(), "%d", &temp) != 1) 
2581             {
2582                 reportBadOptionAndExit("terminalgap", "integer");
2583                 temp = 0;
2584             }
2585         }
2586         if (temp >= 1 && temp <= 9) 
2587         {
2588             userParameters->setHelixEndPenalty(temp);
2589             userParameters->setStrandEndPenalty(temp);
2590         }
2591     }
2592    
2593     //*** ? /helixendin= n
2594     if(setHelixEndIn != -1) 
2595     {
2596         #if DEBUGFULL 
2597             if(logObject && DEBUGLOG)
2598             {
2599                 logObject->logMsg("    Setting helixendin parameter.");
2600             }        
2601         #endif
2602         
2603         temp = 0;
2604         if((*paramArg)[setHelixEndIn].length() > 0)
2605         {
2606             if (sscanf((*paramArg)[setHelixEndIn].c_str(), "%d", &temp) != 1) 
2607             {
2608                 reportBadOptionAndExit("helixendin", "integer");
2609                 temp = 0;
2610             }
2611         }
2612         if (temp >= 0 && temp <= 3)
2613         {
2614             userParameters->setHelixEndMinus(temp);
2615         }
2616     }
2617
2618     //*** ? /helixendout= n
2619     if(setHelixEndOut != -1) 
2620     {
2621         #if DEBUGFULL 
2622             if(logObject && DEBUGLOG)
2623             {
2624                 logObject->logMsg("    Setting helixendout parameter.");
2625             }        
2626         #endif
2627         
2628         temp = 0;
2629         if((*paramArg)[setHelixEndOut].length() > 0)
2630         {
2631             if (sscanf((*paramArg)[setHelixEndOut].c_str(), "%d", &temp) != 1) 
2632             {
2633                 reportBadOptionAndExit("helixendout", "integer");
2634                 temp = 0;
2635             }
2636         }
2637         if (temp >= 0 && temp <= 3)
2638         {
2639             userParameters->setHelixEndPlus(temp);
2640         }
2641     }
2642
2643     //*** ? /strandendin= n 
2644     if(setStrandEndIn != -1) 
2645     {
2646         #if DEBUGFULL 
2647             if(logObject && DEBUGLOG)
2648             {
2649                 logObject->logMsg("    Setting strandendin parameter.");
2650             }        
2651         #endif
2652         
2653         temp = 0;
2654         if((*paramArg)[setStrandEndIn].length() > 0)
2655         {
2656             if (sscanf((*paramArg)[setStrandEndIn].c_str(), "%d", &temp) != 1) 
2657             {
2658                 reportBadOptionAndExit("strandendin", "integer");
2659             }
2660         }
2661         if (temp >= 0 && temp <= 3)
2662         {
2663             userParameters->setStrandEndMinus(temp);
2664         }
2665     }
2666
2667     //*** ? /strandendout= n 
2668     if(setStrandEndOut != -1) 
2669     {
2670         #if DEBUGFULL 
2671             if(logObject && DEBUGLOG)
2672             {
2673                 logObject->logMsg("    Setting strandendout parameter.");
2674             }        
2675         #endif
2676         
2677         temp = 0;
2678         if((*paramArg)[setStrandEndOut].length() > 0)
2679         {
2680             if (sscanf((*paramArg)[setStrandEndOut].c_str(), "%d", &temp) != 1) 
2681             {
2682                 reportBadOptionAndExit("strandendout", "integer");
2683             }
2684         }
2685         if (temp >= 0 && temp <= 3)
2686         {
2687             userParameters->setStrandEndPlus(temp);
2688         }
2689     }
2690 }
2691
2692 int CommandLineParser::findMatch(string probe, StringArray* list, int n)
2693 {
2694     int i, j, len;
2695     int count, match=0;
2696   
2697     len = probe.length();
2698     for (i = 0; i < len; i++) 
2699     {
2700         count = 0;
2701         for (j = 0; j < n; j++) 
2702         { 
2703             if (probe[i] == (*list)[j][i]) 
2704             {
2705                 match = j;
2706                 count++;
2707             }
2708         }
2709         if (count == 0)
2710         { 
2711             return((int)-1);
2712         }
2713         if (count == 1) 
2714         {
2715             return(match);
2716         }
2717     }
2718     return((int)-1);
2719
2720 }
2721
2722 /*
2723  * The function getCmdLineDataStruct is used to return a struct with the values
2724  * specified. It returns it by value. I cant return by reference or else the object will
2725  * be destroyed.
2726  */
2727 CmdLineData CommandLineParser::getCmdLineDataStruct(const char *str, int *flag, int type, 
2728                                                       StringArray* arg)
2729 {
2730     CmdLineData tempStruct = {str, flag, type, arg};
2731     return tempStruct;
2732 }
2733
2734 void CommandLineParser::printCmdLineData(const CmdLineData& temp)
2735 {
2736     std::cout << "The str is: " << temp.str << std::endl;
2737     std::cout << "The int* is: " << *(temp.flag) << std::endl;
2738     std::cout << "The type is: " << temp.type << std::endl;
2739     std::cout << "The StringArray is: " << std::endl;
2740     
2741     if(temp.arg == NULL)
2742     {
2743         std::cout << "    NULL" << std::endl;
2744     }
2745     else
2746     {
2747         cout << "The number of elements is " << temp.arg->size() << std::endl;
2748         for(int i = 0; i < (int)temp.arg->size(); i++)
2749         {
2750             cout << "The " << i << "th element is: " << temp.arg->at(i) << endl;
2751         }
2752     }
2753 }
2754
2755 /*
2756  * Helper function to change string to lower case.
2757  *
2758  */
2759 string CommandLineParser::ConvertStringToLower(string strToConvert)
2760 {
2761    for(unsigned int i=0;i<strToConvert.length();i++)
2762    {
2763       strToConvert[i] = tolower(strToConvert[i]);
2764    }
2765    return strToConvert;
2766 }
2767
2768
2769
2770
2771 void  CommandLineParser::exitWithErrorMsg(string msg)
2772 {
2773     cerr << "ERROR: " << msg << std::endl;
2774     exit(1);
2775 }
2776
2777 void CommandLineParser::reportBadOptionAndExit(string option, string expectedType)
2778 {
2779     string msg;
2780     msg = "Bad option for ";
2781     msg += default_commandsep;// has to be added separately
2782     msg += option + ": expected " +  expectedType;
2783     exitWithErrorMsg(msg);
2784 }
2785
2786 void CommandLineParser::reportInvalidOptionAndExit(string option)
2787 {
2788     string msg = "Invalid option ";
2789     msg += default_commandsep;// has to be added separately
2790     msg += option;
2791     exitWithErrorMsg(msg);
2792 }
2793
2794
2795 }
2796