Mac binaries
[jabaws.git] / website / archive / binaries / mac / src / clustalw / src / interface / InteractiveMenu.cpp
1 /**
2  * Author: Mark Larkin
3  * 
4  * Copyright (c) 2007 Des Higgins, Julie Thompson and Toby Gibson.  
5  */
6 /**
7  * Mark Larkin Dec 12 2005.
8  * This provides the implementation of the interactive menu functions.
9  * Changes:
10  * 15-5-07: Added changes to clustering algorithm choice in function phylogenticTreeMenu 
11  *          Added iteration to the multipleAlignMenu function.  
12  */
13 #ifdef HAVE_CONFIG_H
14     #include "config.h"
15 #endif
16 #include <stdio.h>
17 #include <string>
18 #include <ctype.h>
19 #include <cstdlib>
20 #include <iostream>
21 #include <iomanip>
22 #include <stdarg.h>
23 #include "InteractiveMenu.h"
24
25 namespace clustalw
26 {
27 using namespace std;
28  
29 InteractiveMenu::InteractiveMenu()
30 {
31     try
32     {
33         clustalObj = new Clustal();
34         lin1 = "";
35         
36         secStructOutputTxt[0] = string("Secondary Structure");
37         secStructOutputTxt[1] = string("Gap Penalty Mask"); 
38         secStructOutputTxt[2] = string("Structure and Penalty Mask"); 
39         secStructOutputTxt[3] = string("None");
40     }
41     catch(bad_alloc)
42     {
43         cerr<<"The memory heap is exhausted. The program must terminate now\n";
44         exit(1);
45     }
46     
47     /* Initialise the menu structs */
48     matrixMenu.noptions = 5;
49     strcpy(matrixMenu.opt[AABLOSUM].title, "BLOSUM series");
50     strcpy(matrixMenu.opt[AABLOSUM].string, "blosum");
51     strcpy(matrixMenu.opt[AAPAM].title, "PAM series");
52     strcpy(matrixMenu.opt[AAPAM].string, "pam");
53     strcpy(matrixMenu.opt[AAGONNET].title, "Gonnet series");
54     strcpy(matrixMenu.opt[AAGONNET].string, "gonnet");
55     strcpy(matrixMenu.opt[AAIDENTITY].title, "Identity matrix");
56     strcpy(matrixMenu.opt[AAIDENTITY].string, "id");
57     strcpy(matrixMenu.opt[AAUSERDEFINED].title, "User defined");
58     strcpy(matrixMenu.opt[AAUSERDEFINED].string, "");
59
60     dnaMatrixMenu.noptions = 3;
61     strcpy(dnaMatrixMenu.opt[DNAIUB].title, "IUB");
62     strcpy(dnaMatrixMenu.opt[DNAIUB].string, "iub");
63     strcpy(dnaMatrixMenu.opt[DNACLUSTALW].title, "CLUSTALW(1.6)");
64     strcpy(dnaMatrixMenu.opt[DNACLUSTALW].string, "clustalw");
65     strcpy(dnaMatrixMenu.opt[DNAUSERDEFINED].title, "User defined");
66     strcpy(dnaMatrixMenu.opt[DNAUSERDEFINED].string, ""); 
67     
68     pwMatrixMenu.noptions = 5;
69     strcpy(pwMatrixMenu.opt[PWAABLOSUM].title, "BLOSUM 30");
70     strcpy(pwMatrixMenu.opt[PWAABLOSUM].string, "blosum");
71     strcpy(pwMatrixMenu.opt[PWAAPAM].title, "PAM 350");
72     strcpy(pwMatrixMenu.opt[PWAAPAM].string, "pam");
73     strcpy(pwMatrixMenu.opt[PWAAGONNET].title, "Gonnet 250");
74     strcpy(pwMatrixMenu.opt[PWAAGONNET].string, "gonnet");
75     strcpy(pwMatrixMenu.opt[PWAAIDENTITY].title, "Identity matrix");
76     strcpy(pwMatrixMenu.opt[PWAAIDENTITY].string, "id");
77     strcpy(pwMatrixMenu.opt[PWAAUSER].title, "User defined");
78     strcpy(pwMatrixMenu.opt[PWAAUSER].string, "");
79     
80 }
81
82 InteractiveMenu::~InteractiveMenu()
83 {
84     delete clustalObj;
85 }
86
87 void InteractiveMenu::mainMenu()
88 {
89     while (true)
90     {
91         lin1 = "";
92         cout<<"\n\n\n";
93         cout<<" **************************************************************\n";
94         cout<<" ******** CLUSTAL "
95             << userParameters->getRevisionLevel()
96             <<" Multiple Sequence Alignments  ********\n";
97         cout<<" **************************************************************\n";
98         cout<<"\n\n";
99
100         cout<<"     1. Sequence Input From Disc\n";
101         cout<<"     2. Multiple Alignments\n";
102         cout<<"     3. Profile / Structure Alignments\n";
103         cout<<"     4. Phylogenetic trees\n\n";
104         cout<<"     S. Execute a system command\n";
105         cout<<"     H. HELP\n";
106         cout<<"     X. EXIT (leave program)\n\n\n";
107
108         choice = utilityObject->getChoice(string("Your choice"));
109         
110         string offendingSeq; // unused here
111         switch (toupper(choice))
112         {
113             case '1':
114                 clustalObj->sequenceInput(false, &offendingSeq); 
115                 break;
116             case '2':
117                 multipleAlignMenu();
118                 break;
119             case '3':
120                 profileAlignMenu();
121                 break;
122             case '4':
123                 phylogeneticTreeMenu();
124                 break;
125             case 'S':
126                 doSystem(); 
127                 break;
128             case '?':
129             case 'H':
130                 clustalObj->getHelp('1'); 
131                 break;
132             case 'Q':
133             case 'X':
134                 exit(0);
135                 break;
136             default:
137                 cout<<"\n\nUnrecognised Command\n\n";
138                 break;
139         }
140     }
141 }
142 void InteractiveMenu::multipleAlignMenu()
143 {
144     while (true)
145     {
146         lin1 = "";
147         cout<<"\n\n\n";
148         cout<<"****** MULTIPLE ALIGNMENT MENU ******\n\n\n";
149
150         cout<<"    1.  Do complete multiple alignment now "
151             <<(!userParameters->getQuickPairAlign() ? "Slow/Accurate" : "Fast/Approximate")
152             <<"\n";
153         cout<<"    2.  Produce guide tree file only\n";
154         cout<<"    3.  Do alignment using old guide tree file\n\n";
155         cout<<"    4.  Toggle Slow/Fast pairwise alignments = "
156             <<((!userParameters->getQuickPairAlign()) ? "SLOW" : "FAST")
157             <<"\n\n";
158         cout<<"    5.  Pairwise alignment parameters\n";
159         cout<<"    6.  Multiple alignment parameters\n\n";
160         cout<<"    7.  Reset gaps before alignment?";
161
162         if (userParameters->getResetAlignmentsNew())
163         {
164             cout<<" = ON\n";
165         }
166         else
167         {
168             cout<<" = OFF\n";
169         }
170
171         cout<<"    8.  Toggle screen display          = "
172             <<((!userParameters->getShowAlign()) ? "OFF" : "ON")
173             <<"\n";
174         cout<<"    9.  Output format options\n";
175         cout<<"    I. Iteration = ";
176         
177         if(userParameters->getDoRemoveFirstIteration() == ALIGNMENT)
178         {
179             cout << "ALIGNMENT\n\n";
180         }
181         else if(userParameters->getDoRemoveFirstIteration() == TREE)
182         {
183             cout << "TREE\n\n";
184         }
185         else
186         {
187             cout << "NONE\n\n";
188         }
189         
190         cout<<"    S.  Execute a system command\n";
191         cout<<"    H.  HELP\n";
192         cout<<"    or press [RETURN] to go back to main menu\n\n\n";
193
194         choice = utilityObject->getChoice(string("Your choice"));
195         if (choice == '\n')
196         {
197             return ;
198         }
199
200         switch (toupper(choice))
201         {
202             case '1':
203                 clustalObj->align(&phylipName);
204                 break;
205             case '2':
206                 clustalObj->doGuideTreeOnly(&phylipName); 
207                 break;
208             case '3':
209                 clustalObj->doAlignUseOldTree(&phylipName);
210                 break;
211             case '4':
212                 userParameters->toggleQuickPairAlign();
213                 break;
214             case '5':
215                 pairwiseMenu();
216                 break;
217             case '6':
218                 multiMenu();
219                 break;
220             case '7':
221                 userParameters->toggleResetAlignmentsNew();
222                 if (userParameters->getResetAlignmentsNew() == true)
223                 {
224                     userParameters->setResetAlignmentsAll(false);
225                 }
226                 break;
227             case '8':
228                 userParameters->toggleShowAlign();
229                 break;
230             case '9':
231                 formatOptionsMenu();
232                 break;
233             case 'I':
234                 iterationMenu();
235                 break;    
236             case 'S':
237                 doSystem();
238                 break;
239             case '?':
240             case 'H':
241                 clustalObj->getHelp('2');
242                 break;
243             case 'Q':
244             case 'X':
245                 return ;
246
247             default:
248                 fprintf(stdout, "\n\nUnrecognised Command\n\n");
249                 break;
250         }
251     }
252 }
253
254 void InteractiveMenu::profileAlignMenu(void)
255 {
256     while (true)
257     {
258         lin1 = "";
259         cout<<"\n\n\n";
260         cout<<"****** PROFILE AND STRUCTURE ALIGNMENT MENU ******\n\n\n";
261
262         cout<<"    1.  Input 1st. profile             ";
263
264         if (!userParameters->getProfile1Empty())
265         {
266             cout<<"(loaded)";
267         }
268
269         cout<<"\n";
270         cout<<"    2.  Input 2nd. profile/sequences   ";
271
272         if (!userParameters->getProfile2Empty())
273         {
274             cout<<"(loaded)";
275         }
276
277         cout<<"\n\n";
278         cout<<"    3.  Align 2nd. profile to 1st. profile\n";
279         
280         cout<<"    4.  Align sequences to 1st. profile "
281             <<((!userParameters->getQuickPairAlign()) 
282                 ? "(Slow/Accurate)\n\n" : "(Fast/Approximate)\n\n");
283                 
284         cout<<"    5.  Toggle Slow/Fast pairwise alignments = "
285             <<((!userParameters->getQuickPairAlign()) 
286                    ? "SLOW\n\n" : "FAST\n\n");
287                    
288         cout<<"    6.  Pairwise alignment parameters\n";
289         cout<<"    7.  Multiple alignment parameters\n\n";
290         
291         cout<<"    8.  Toggle screen display                = "
292             <<((!userParameters->getShowAlign()) ? "OFF\n" : "ON\n");
293             
294         cout<<"    9.  Output format options\n";
295         cout<<"    0.  Secondary structure options\n\n";
296         cout<<"    S.  Execute a system command\n";
297         cout<<"    H.  HELP\n";
298         cout<<"    or press [RETURN] to go back to main menu\n\n\n";
299
300         choice = utilityObject->getChoice(string("Your choice"));
301         if (choice == '\n')
302         {
303             return ;
304         }
305
306         switch (toupper(choice))
307         {
308             case '1':
309                 clustalObj->profile1Input();
310                 break;
311             case '2':
312                 clustalObj->profile2Input();
313                 break;
314             case '3':
315                 clustalObj->profileAlign(&p1TreeName, &p2TreeName); 
316                 break;
317             case '4':
318                 /* align new sequences to profile 1 */
319                 clustalObj->sequencesAlignToProfile(&phylipName);
320                 break;
321             case '5':
322                 userParameters->toggleQuickPairAlign();
323                 break;
324             case '6':
325                 pairwiseMenu();
326                 break;
327             case '7':
328                 multiMenu();
329                 break;
330             case '8':
331                 userParameters->toggleShowAlign();
332                 break;
333             case '9':
334                 formatOptionsMenu();
335                 break;
336             case '0':
337                 ssOptionsMenu();
338                 break;
339             case 'S':
340                 doSystem();
341                 break;
342             case '?':
343             case 'H':
344                 clustalObj->getHelp('6');
345                 break;
346             case 'Q':
347             case 'X':
348                 return ;
349
350             default:
351                 cout<<"\n\nUnrecognised Command\n\n";
352                 break;
353         }
354     }
355 }
356
357 void InteractiveMenu::ssOptionsMenu()
358 {
359     while (true)
360     {
361         lin1 = "";
362         cout<<"\n\n\n";
363         cout<<" ********* SECONDARY STRUCTURE OPTIONS *********\n\n\n";
364
365         cout<<"     1. Use profile 1 secondary structure / penalty mask  ";       
366         if (userParameters->getUseSS1())
367         {
368             cout<<"= YES\n";
369         }
370         else
371         {
372             cout<<"= NO\n";
373         }
374         
375         cout<<"     2. Use profile 2 secondary structure / penalty mask  ";
376         if (userParameters->getUseSS2())
377         {
378             cout<<"= YES\n\n";
379         }
380         else
381         {
382             cout<<"= NO\n\n";
383         }
384
385         cout<<"     3. Output in alignment  ";
386         cout<<"= "<< secStructOutputTxt[userParameters->getOutputStructPenalties()] <<"\n\n";
387
388         cout<<"     4. Helix gap penalty                     : "
389             <<userParameters->getHelixPenalty()<<"\n";
390         cout<<"     5. Strand gap penalty                    : "
391             <<userParameters->getStrandPenalty()<<"\n";
392         cout<<"     6. Loop gap penalty                      : "
393             <<userParameters->getLoopPenalty()<<"\n";
394         cout<<"     7. Secondary structure terminal penalty  : "
395             <<userParameters->getHelixEndPenalty()<<"\n";
396         cout<<"     8. Helix terminal positions       within : "
397             <<userParameters->getHelixEndMinus()
398             <<"      outside : "
399             <<userParameters->getHelixEndPlus()<<"\n";
400         cout<<"     9. Strand terminal positions      within : "
401             <<userParameters->getStrandEndMinus()   
402             <<"      outside : " 
403             <<userParameters->getStrandEndPlus()<<"\n\n\n";
404         cout<<"     H. HELP\n\n\n";
405
406         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
407         if (choice == '\n')
408         {
409             return ;
410         }
411         
412         switch (toupper(choice))
413         {
414             case '1':
415                 userParameters->toggleUseSS1();
416                 break;
417             case '2':
418                 userParameters->toggleUseSS2();
419                 break;
420             case '3':
421                 userParameters->setOutputStructPenalties(secStrOutputOptions());
422                 break;
423             case '4': 
424                 cout<<"Helix Penalty Currently: "
425                     << userParameters->getHelixPenalty()<<"\n";
426                 userParameters->setHelixPenalty(utilityObject->getInt("Enter number",
427                                                   1,9, userParameters->getHelixPenalty()));
428                 break;
429             case '5':
430                 cout<<"Strand Gap Penalty Currently: "
431                     << userParameters->getStrandPenalty() <<"\n";
432                 userParameters->setStrandPenalty(utilityObject->getInt("Enter number",
433                                                   1,9, userParameters->getStrandPenalty()));
434                 break;
435             case '6':
436                 cout<<"Loop Gap Penalty Currently: "
437                     << userParameters->getLoopPenalty() <<"\n";
438                 userParameters->setLoopPenalty(utilityObject->getInt("Enter number", 
439                                                  1, 9, userParameters->getLoopPenalty()));
440                 break;
441             case '7':
442                 cout<<"Secondary Structure Terminal Penalty Currently: "
443                     << userParameters->getHelixEndPenalty() <<"\n";
444                 userParameters->setHelixEndPenalty(utilityObject->getInt("Enter number",
445                                                1, 9,userParameters->getHelixEndPenalty()));
446                 userParameters->setStrandEndPenalty(userParameters->getHelixEndPenalty());
447                 break;
448             case '8':
449                 cout<<"Helix Terminal Positions Currently: \n";
450                 cout<<"        within helix: "
451                     << userParameters->getHelixEndMinus()
452                     << "      outside helix: " 
453                     << userParameters->getHelixEndPlus() <<"\n";
454                     
455                 userParameters->setHelixEndMinus(utilityObject->getInt(
456                                  "Enter number of residues within helix", 
457                                  0, 3, userParameters->getHelixEndMinus()));
458                 userParameters->setHelixEndPlus(utilityObject->getInt(
459                                  "Enter number of residues outside helix", 0, 3,
460                                  userParameters->getHelixEndPlus()));
461                 break;
462             case '9':
463                 cout<<"Strand Terminal Positions Currently: \n";
464                 cout<<"        within strand: "
465                     << userParameters->getStrandEndMinus()
466                     << "      outside strand: "
467                     << userParameters->getStrandEndPlus() <<"\n";
468                 userParameters->setStrandEndMinus(utilityObject->getInt(
469                                  "Enter number of residues within strand", 0, 3,
470                                  userParameters->getStrandEndMinus()));
471                 userParameters->setStrandEndPlus(utilityObject->getInt(
472                                  "Enter number of residues outside strand", 0, 3,
473                                  userParameters->getStrandEndPlus()));
474                 break;
475             case '?':
476             case 'H':
477                 clustalObj->getHelp('B');
478                 break;
479             default:
480                 cout<<"\n\nUnrecognised Command\n\n";
481                 break;
482         }
483     }
484 }
485 int InteractiveMenu::secStrOutputOptions()
486 {
487     while (true)
488     {
489         lin1 = "";
490         cout<<"\n\n\n";
491         cout<<" ********* Secondary Structure Output Menu *********\n\n\n";
492
493         cout<<"     1. "<< secStructOutputTxt[0] <<"\n";
494         cout<<"     2. "<< secStructOutputTxt[1] <<"\n";
495         cout<<"     3. "<< secStructOutputTxt[2] <<"\n";
496         cout<<"     4. "<< secStructOutputTxt[3] <<"\n";
497         cout<<"     H. HELP\n\n";
498         cout<<"     -- Current output is "
499             << secStructOutputTxt[userParameters->getOutputStructPenalties()];
500         cout<<" --\n";
501
502         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
503         if (choice == '\n')
504         {
505             return (userParameters->getOutputStructPenalties());;
506         }
507
508         switch (toupper(choice))
509         {
510             case '1':
511                 return (OUTSECST);
512             case '2':
513                 return (OUTGAP);
514             case '3':
515                 return (OUTBOTH);
516             case '4':
517                 return (OUTNONE);
518             case '?':
519             case 'H':
520                 clustalObj->getHelp('C');
521             case 'Q':
522             case 'X':
523                 return (0);
524
525             default:
526                 cout<< "\n\nUnrecognised Command\n\n";
527                 break;
528         }
529     }
530 }
531
532 void InteractiveMenu::phylogeneticTreeMenu()
533 {
534     while (true)
535     {
536         lin1 = "";
537         cout<<"\n\n\n";
538         cout<<"****** PHYLOGENETIC TREE MENU ******\n\n\n";
539
540         cout<<"    1.  Input an alignment\n";
541         cout<<"    2.  Exclude positions with gaps?        ";
542
543         if (userParameters->getTossGaps())
544         {
545             cout<<"= ON\n";
546         }
547         else
548         {
549             cout<<"= OFF\n";
550         }
551
552         cout<<"    3.  Correct for multiple substitutions? ";
553
554         if (userParameters->getKimura())
555         {
556             cout<<"= ON\n";
557         }
558         else
559         {
560             cout<<"= OFF\n";
561         }
562
563         cout<<"    4.  Draw tree now\n";
564         cout<<"    5.  Bootstrap tree\n";
565         cout<<"    6.  Output format options\n";
566         cout<<"    7.  Clustering algorithm = "; // Mark change 15-5-2007
567         if(userParameters->getClusterAlgorithm() == NJ)
568         {
569             cout << "NJ\n\n";
570         }
571         else
572         {
573             cout << "UPGMA\n\n";
574         }        
575         cout<<"    S.  Execute a system command\n";
576         cout<<"    H.  HELP\n";
577         cout<<"    or press [RETURN] to go back to main menu\n\n\n";
578
579         choice = utilityObject->getChoice(string("Your choice"));
580         if (choice == '\n')
581         {
582             return ;
583         }
584         
585         string offendingSeq; // unused here
586         switch (toupper(choice))
587         {
588             case '1':
589                 clustalObj->sequenceInput(false, &offendingSeq); 
590                 break;
591             case '2':
592                 userParameters->toggleTossGaps();
593                 break;
594             case '3':
595                 userParameters->toggleKimura();
596                 break;
597             case '4':
598                 clustalObj->phylogeneticTree(&phylipName, &clustalName, &distName,
599                     &nexusName, "amenu.pim");
600                 break;
601             case '5':
602                 clustalObj->bootstrapTree(&phylipName, &clustalName, &nexusName);
603                 break;
604             case '6':
605                 treeFormatOptionsMenu();
606                 break;
607             case '7':
608                 clusteringAlgorithmMenu();
609                 break;
610             case 'S':
611                 doSystem();
612                 break;
613             case '?':
614             case 'H':
615                 clustalObj->getHelp('7');
616                 break;
617             case 'Q':
618             case 'X':
619                 return ;
620
621             default:
622                 cout<<"\n\nUnrecognised Command\n\n";
623                 break;
624         }
625     }
626 }
627
628 void InteractiveMenu::treeFormatOptionsMenu()
629 {
630     while (true)
631     {
632         lin1 = "";
633         cout<< "\n\n\n";
634         cout<<" ****** Format of Phylogenetic Tree Output ******\n\n\n";
635         cout<<"     1. Toggle CLUSTAL format tree output    =  "
636             << ((!userParameters->getOutputTreeClustal()) ? "OFF" : "ON")<<"\n";
637         cout<<"     2. Toggle Phylip format tree output     =  "
638             << ((!userParameters->getOutputTreePhylip()) ? "OFF" : "ON")<<"\n";
639         cout<<"     3. Toggle Phylip distance matrix output =  "
640             << ((!userParameters->getOutputTreeDistances()) ? "OFF" : "ON")<<"\n";
641         cout<<"     4. Toggle Nexus format tree output      =  "
642             << ((!userParameters->getOutputTreeNexus()) ? "OFF" : "ON")<<"\n\n";
643         cout<<"     5. Toggle Phylip bootstrap positions    =  "
644             <<((userParameters->getBootstrapFormat() == BS_NODE_LABELS) ? "NODE LABELS" :
645             "BRANCH LABELS") <<"\n\n\n";
646         cout<<"     H. HELP\n\n\n";
647         
648         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
649         if (choice == '\n')
650         {
651             return ;
652         }
653         switch (toupper(choice))
654         {
655             case '1':
656                 userParameters->toggleOutputTreeClustal();
657                 break;
658             case '2':
659                 userParameters->toggleOutputTreePhylip();
660                 break;
661             case '3':
662                 userParameters->toggleOutputTreeDistances();
663                 break;
664             case '4':
665                 userParameters->toggleOutputTreeNexus();
666                 break;
667             case '5':
668                 userParameters->toggleBootstrapFormat();
669                 break;
670             case '?':
671             case 'H':
672                 clustalObj->getHelp('0');
673                 break;
674             default:
675                 cout<< "\n\nUnrecognised Command\n\n";
676                 break;
677         }
678     }
679
680 }
681
682 void InteractiveMenu::formatOptionsMenu()
683 {
684     
685     while (true)
686     {
687         lin1 = "";
688         cout<<"\n\n\n";
689         cout<<" ********* Format of Alignment Output *********\n\n\n";
690         cout<<"     F. Toggle FASTA format output       =  "
691             << ((!userParameters->getOutputFasta()) ? "OFF" : "ON") <<"\n\n";
692         cout<<"     1. Toggle CLUSTAL format output     =  "
693             << ((!userParameters->getOutputClustal()) ? "OFF" : "ON") <<"\n";
694         cout<<"     2. Toggle NBRF/PIR format output    =  "
695             << ((!userParameters->getOutputNbrf()) ? "OFF" : "ON") << "\n";
696         cout<<"     3. Toggle GCG/MSF format output     =  "
697             << ((!userParameters->getOutputGCG()) ? "OFF" : "ON") << "\n";
698         cout<<"     4. Toggle PHYLIP format output      =  "
699             << ((!userParameters->getOutputPhylip()) ? "OFF" : "ON") << "\n";
700         cout<<"     5. Toggle NEXUS format output       =  "
701             << ((!userParameters->getOutputNexus()) ? "OFF" : "ON") << "\n";
702         cout<<"     6. Toggle GDE format output         =  "
703             << ((!userParameters->getOutputGde()) ? "OFF" : "ON") << "\n\n";
704         cout<<"     7. Toggle GDE output case           =  "
705             << ((!userParameters->getLowercase()) ? "UPPER" : "LOWER") << "\n";
706
707         cout<<"     8. Toggle CLUSTALW sequence numbers =  "
708             << ((!userParameters->getClSeqNumbers()) ? "OFF" : "ON") << "\n";
709         cout<<"     9. Toggle output order              =  "
710             << ((userParameters->getOutputOrder() == 0) ? "INPUT FILE" : "ALIGNED")
711             <<"\n\n";
712
713         cout<<"     0. Create alignment output file(s) now?\n\n";
714         cout<<"     T. Toggle parameter output          = "
715             << ((!userParameters->getSaveParameters()) ? "OFF" : "ON") << "\n";
716         cout<<"     R. Toggle sequence range numbers =  "
717             <<((!userParameters->getSeqRange()) ? "OFF" : "ON") << "\n\n";
718
719         cout<<"     H. HELP\n\n\n";
720
721         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
722         if (choice == '\n')
723         {
724             return ;
725         }
726         switch (toupper(choice))
727         {
728             case '1':
729                 userParameters->toggleOutputClustal();
730                 break;
731             case '2':
732                 userParameters->toggleOutputNbrf();
733                 break;
734             case '3':
735                 userParameters->toggleOutputGCG();
736                 break;
737             case '4':
738                 userParameters->toggleOutputPhylip();
739                 break;
740             case '5':
741                 userParameters->toggleOutputNexus();
742                 break;
743             case '6':
744                 userParameters->toggleOutputGde();
745                 break;
746             case '7':
747                 userParameters->toggleLowercase();
748                 break;
749             case '8':
750                 userParameters->toggleClSeqNumbers();
751                 break;
752             case '9':
753                 userParameters->toggleOutputOrder();
754                 break;
755             case 'F':
756                 userParameters->toggleOutputFasta();
757                 break;
758             case 'R':
759                 userParameters->toggleSeqRange();
760                 break;
761             case '0':
762                 clustalObj->outputNow();
763                 break;
764             case 'T':
765                 userParameters->toggleSaveParameters();
766                 break;
767             case '?':
768             case 'H':
769                 clustalObj->getHelp('5');
770                 break;
771             default:
772                 cout<<"\n\nUnrecognised Command\n\n";
773                 break;
774         }
775     }    
776 }
777  
778 void InteractiveMenu::pairwiseMenu()
779 {
780     if (userParameters->getDNAFlag())
781     {
782         userParameters->setPWParamToDNA();
783     }
784     else
785     {
786         userParameters->setPWParamToProtein();
787     }
788
789     while (true)
790     {
791         lin1 = "";
792         cout<<"\n\n\n";
793         cout<<" ********* PAIRWISE ALIGNMENT PARAMETERS *********\n\n\n";
794
795         cout<<"     Slow/Accurate alignments:\n\n";
796
797         cout<<"     1. Gap Open Penalty       : "
798             << fixed << setprecision(2) << userParameters->getPWGapOpen() << "\n";
799         cout<<"     2. Gap Extension Penalty  : "
800             << fixed << setprecision(2) << userParameters->getPWGapExtend() << "\n";
801         cout<< "     3. Protein weight matrix  :"
802             << matrixMenu.opt[subMatrix->getPWMatrixNum() - 1].title 
803             << "\n";
804         cout<<"     4. DNA weight matrix      :"
805             << dnaMatrixMenu.opt[subMatrix->getPWDNAMatrixNum() - 1].title 
806             << "\n\n";
807
808         cout<<"     Fast/Approximate alignments:\n\n";
809
810         cout<<"     5. Gap penalty            :"
811             << userParameters->getWindowGap() << "\n";
812         cout<<"     6. K-tuple (word) size    :"
813             << userParameters->getKtup() << "\n";
814         cout<<"     7. No. of top diagonals   :"
815             << userParameters->getSignif() << "\n";
816         cout<<"     8. Window size            :"
817             << userParameters->getWindow() << "\n\n";
818
819         cout<<"     9. Toggle Slow/Fast pairwise alignments ";
820         if (userParameters->getQuickPairAlign())
821         {
822             cout<<"= FAST\n\n";
823         }
824         else
825         {
826             cout<<"= SLOW\n\n";
827         }
828
829
830         cout<<"     H. HELP\n\n\n";
831         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
832         if (choice == '\n')
833         {
834             if (userParameters->getDNAFlag())
835             {
836                 userParameters->setPWDNAParam();
837             }
838             else
839             {
840                 userParameters->setPWProteinParam();
841             }
842
843             return ;
844         }
845
846
847         switch (toupper(choice))
848         {
849             case '1':
850                 cout<<"Gap Open Penalty Currently: "
851                     << userParameters->getPWGapOpen() << "\n";
852                 userParameters->setPWGapOpen(
853                               (float)utilityObject->getReal("Enter number", (double)0.0,
854                               (double)100.0, (double)userParameters->getPWGapOpen()));
855                 break;
856             case '2':
857                 cout<<"Gap Extension Penalty Currently: "
858                     << userParameters->getPWGapExtend() << "\n";
859                 userParameters->setPWGapExtend(
860                               (float)utilityObject->getReal("Enter number", (double)0.0,
861                               (double)10.0, (double)userParameters->getPWGapExtend()));
862                 break;
863             case '3':            
864                 readMatrix(Protein, Pairwise, pwMatrixMenu);
865                 break;
866             case '4': 
867                 readMatrix(DNA, Pairwise, dnaMatrixMenu);
868                 break;
869             case '5':
870                 cout<<"Gap Penalty Currently: "
871                     << userParameters->getWindowGap() << "\n";
872                 userParameters->setWindowGap(
873                                  utilityObject->getInt("Enter number", 1, 500, 
874                                                 userParameters->getWindowGap()));
875                 break;
876             case '6':
877                 cout<<"K-tuple Currently: "
878                     << userParameters->getKtup() << "\n";
879                 if (userParameters->getDNAFlag())
880                 {
881                     int _ktup = utilityObject->getInt("Enter number", 1, 4,
882                                                       userParameters->getKtup());
883                     userParameters->setKtup(_ktup);
884                     // see bug 185
885                     userParameters->setDNAKtup(_ktup);
886                     userParameters->setWindowGap(_ktup + 4);
887                     userParameters->setDNAWindowGap(_ktup + 4);
888
889                 }
890                 else
891                 {
892                     int _ktup = utilityObject->getInt("Enter number", 1, 2, 
893                                                       userParameters->getKtup());
894                     userParameters->setKtup(_ktup);
895                     // see bug 185
896                     userParameters->setAAKtup(_ktup);
897                     userParameters->setWindowGap(_ktup + 3);
898                     userParameters->setAAWindowGap(_ktup + 3);
899                      
900                 }
901                 break;
902             case '7':
903                 cout<<"Top diagonals Currently: "
904                     << userParameters->getSignif() << "\n";
905                 userParameters->setSignif(
906                                 utilityObject->getInt("Enter number", 1, 50, 
907                                           userParameters->getSignif()));
908                 break;
909             case '8':
910                 cout<<"Window size Currently: "
911                     << userParameters->getWindow() << "\n";
912                 userParameters->setWindow(
913                                 utilityObject->getInt("Enter number", 1, 50, 
914                                            userParameters->getWindow()));
915                 break;
916             case '9':
917                 userParameters->toggleQuickPairAlign();
918                 break;
919             case '?':
920             case 'H':
921                 clustalObj->getHelp('3');
922                 break;
923             default:
924                 cout<< "\n\nUnrecognised Command\n\n";
925                 break;
926         }
927     }
928 }
929
930 void InteractiveMenu::multiMenu()
931 {
932     if (userParameters->getDNAFlag())
933     {
934         userParameters->setDNAMultiGap();
935     }
936     else
937     {
938         userParameters->setProtMultiGap();
939     }
940
941     while (true)
942     {
943         lin1 = "";
944         cout<<"\n\n\n ********* MULTIPLE ALIGNMENT PARAMETERS *********\n\n\n";
945         cout<<"     1. Gap Opening Penalty              :"
946             << fixed << setprecision(2) << userParameters->getGapOpen() << "\n";
947         cout<<"     2. Gap Extension Penalty            :"
948             << fixed << setprecision(2) << userParameters->getGapExtend() << "\n";
949
950         cout<<"     3. Delay divergent sequences        :"
951             << userParameters->getDivergenceCutoff() << " %\n\n";
952
953         cout<<"     4. DNA Transitions Weight           :"
954             << fixed << setprecision(2) << userParameters->getTransitionWeight() << "\n\n";
955         cout<<"     5. Protein weight matrix            :"
956             << matrixMenu.opt[subMatrix->getMatrixNum() - 1].title 
957             << "\n";
958         cout<<"     6. DNA weight matrix                :"
959             << dnaMatrixMenu.opt[subMatrix->getDNAMatrixNum() - 1].title 
960             << "\n";
961         cout<<"     7. Use negative matrix              :"
962             << ((!userParameters->getUseNegMatrix()) ? "OFF" : "ON") << "\n\n";
963         cout<<"     8. Protein Gap Parameters\n\n";
964         cout<<"     H. HELP\n\n\n";
965
966         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
967         if (choice == '\n')
968         {
969             if (userParameters->getDNAFlag())
970             {
971                 //userParameters->setDNAMultiGap();
972                 userParameters->setDNAGapOpen(userParameters->getGapOpen());
973                 userParameters->setDNAGapExtend(userParameters->getGapExtend());
974             }
975             else
976             {
977                 //userParameters->setProtMultiGap();
978                 userParameters->setAAGapOpen(userParameters->getGapOpen());
979                 userParameters->setAAGapExtend(userParameters->getGapExtend());
980             }
981             return ;
982         }
983
984
985         switch (toupper(choice))
986         {
987             case '1':
988                 cout<<"Gap Opening Penalty Currently: "
989                     << userParameters->getGapOpen() << "\n";
990                 userParameters->setGapOpen(
991                                   (float)utilityObject->getReal("Enter number", (double)0.0, 
992                                   (double)100.0, (double)userParameters->getGapOpen()));
993                 break;
994             case '2':
995                 cout<<"Gap Extension Penalty Currently: "
996                     << userParameters->getGapExtend() << "\n";
997                 userParameters->setGapExtend(
998                                 (float)utilityObject->getReal("Enter number", (double)0.0,
999                                 (double)10.0, (double)userParameters->getGapExtend()));
1000                 break;
1001             case '3':
1002                 cout<<"Min Identity Currently: "
1003                     << userParameters->getDivergenceCutoff() << "\n";
1004                 userParameters->setDivergenceCutoff(
1005                                      utilityObject->getInt("Enter number", 0, 100,
1006                                      userParameters->getDivergenceCutoff()));
1007                 break;
1008             case '4':
1009                 cout<<"Transition Weight Currently: "
1010                     << userParameters->getTransitionWeight() << "\n";
1011                 userParameters->setTransitionWeight(
1012                                 (float)utilityObject->getReal("Enter number", (double)0.0,
1013                                 (double)1.0,
1014                                 (double)userParameters->getTransitionWeight()));
1015                 break;
1016             case '5':
1017                 readMatrix(Protein, MultipleAlign, matrixMenu);
1018                 break;
1019             case '6':
1020                 readMatrix(DNA, MultipleAlign, dnaMatrixMenu);
1021                 break;
1022             case '7':
1023                 userParameters->toggleUseNegMatrix();
1024                 break;
1025             case '8':
1026                 gapPenaltiesMenu();
1027                 break;
1028             case '?':
1029             case 'H':
1030                 //clustalObj->getHelp('4');
1031                 break;
1032             default:
1033                 cout<< "\n\nUnrecognised Command\n\n";
1034                 break;
1035         }
1036     }
1037 }
1038  
1039 void InteractiveMenu::gapPenaltiesMenu()
1040 {
1041     
1042     while (true)
1043     {
1044         lin1 = "";
1045         cout<< "\n\n\n ********* PROTEIN GAP PARAMETERS *********\n\n\n\n";
1046         cout<<"     1. Toggle Residue-Specific Penalties :"
1047             << ((userParameters->getNoPrefPenalties()) ? "OFF" : "ON") << "\n\n";
1048         cout<<"     2. Toggle Hydrophilic Penalties      :"
1049             << ((userParameters->getNoHydPenalties()) ? "OFF" : "ON") << "\n";
1050         cout<<"     3. Hydrophilic Residues              :"
1051             << userParameters->getHydResidues() << "\n\n";
1052         cout<<"     4. Gap Separation Distance           :"
1053             << userParameters->getGapDist() << "\n";
1054         cout<<"     5. Toggle End Gap Separation         :"
1055             << ((!userParameters->getUseEndGaps()) ? "OFF" : "ON") << "\n\n";
1056         cout<<"     H. HELP\n\n\n";
1057
1058         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
1059         if (choice == '\n')
1060         {
1061             return ;
1062         }
1063
1064         switch (toupper(choice))
1065         {
1066             case '1':
1067                 userParameters->toggleNoPrefPenalties();
1068                 break;
1069             case '2':
1070                 userParameters->toggleNoHydPenalties();
1071                 break;
1072             case '3':
1073                 cout<<"Hydrophilic Residues Currently: "
1074                     << userParameters->getHydResidues() << "\n";
1075                 lin1 = "";
1076                 utilityObject->getStr(string("Enter residues (or [RETURN] to quit)"), lin1);
1077                 if (lin1.size() > 0)
1078                 {
1079                     userParameters->setHydResidues(lin1);
1080                 }
1081                 break;
1082             case '4':
1083                 cout<<"Gap Separation Distance Currently: "
1084                     << userParameters->getGapDist() << "\n";
1085                 userParameters->setGapDist(
1086                                 utilityObject->getInt("Enter number", 0, 100, 
1087                                 userParameters->getGapDist()));
1088                 break;
1089             case '5':
1090                 userParameters->toggleUseEndGaps();
1091                 break;
1092             case '?':
1093             case 'H':
1094                 clustalObj->getHelp('A');
1095                 break;
1096             default:
1097                 cout<< "\n\nUnrecognised Command\n\n";
1098                 break;
1099         }
1100     }
1101 }
1102
1103 /*
1104  * This function displays the menu for selecting the weight matrix to use.
1105  * It is used for both the protein and DNA menu for pairwise and Multiple alignment.
1106  * This is why it requires the MatMenu struct.
1107  */
1108 int InteractiveMenu::readMatrix(int alignResidueType, int alignType, MatMenu menu)
1109 {
1110     static char userFile[FILENAMELEN + 1];
1111     int i, option;
1112     char title[10];
1113     int matn; // Used to show which is the current matrix.
1114     
1115     if(alignResidueType == Protein)
1116     {
1117         strcpy(title, "PROTEIN");
1118     }
1119     else // DNA
1120     {
1121         strcpy(title, "DNA");
1122     }
1123     
1124     while (true)
1125     {
1126         lin1 = "";
1127         cout<<"\n\n\n ********* "<< title <<" WEIGHT MATRIX MENU *********\n\n\n";
1128         
1129         // Find out what the currently selected matrix is.
1130         matn = subMatrix->getMatrixNumForMenu(alignResidueType, alignType);
1131         
1132         for (i = 0; i < menu.noptions; i++)
1133         {
1134             cout<< "     " << i + 1 << ". " << menu.opt[i].title << "\n";
1135         }
1136
1137         cout<<"     H. HELP\n\n";
1138         cout<<"     -- Current matrix is the "
1139             << menu.opt[matn -1].title << " ";
1140         
1141         if (matn == menu.noptions)
1142         {
1143             cout<<"(file = "<< userFile <<")";;
1144         }
1145
1146         cout<<"--\n";
1147         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
1148         if (choice == '\n')
1149         {
1150             return matn;
1151         }
1152
1153         option = toupper(choice) - '0';
1154         // Select the matrix series to be using 
1155         if (option > 0 && option < menu.noptions)
1156         {
1157             subMatrix->setCurrentNameAndNum(string(menu.opt[i - 1].string), option, 
1158                                             alignResidueType, alignType);
1159         }
1160         else if (option == menu.noptions) // Read in a User defined matrix.
1161         {
1162             // NOTE this will be changed to deal with matrix series.
1163             if (subMatrix->getUserMatFromFile(userFile, alignResidueType, alignType))
1164             {
1165                 subMatrix->setCurrentNameAndNum(userFile, option, 
1166                                             alignResidueType, alignType);
1167             }
1168         }
1169         else
1170         switch (toupper(choice))
1171         {
1172             case '?':
1173             case 'H':
1174                 clustalObj->getHelp('8');
1175                 break;
1176             default:
1177                 cout<< "\n\nUnrecognised Command\n\n";
1178                 break;
1179         }
1180     }
1181
1182
1183 void InteractiveMenu::doSystem()
1184 {
1185     lin1 = "";
1186     utilityObject->getStr(string("\n\nEnter system command"), lin1);
1187
1188     if (lin1.size() > 0)
1189     {
1190         system(lin1.c_str());
1191     }
1192     cout<< "\n\n";
1193 }
1194
1195 void InteractiveMenu::clusteringAlgorithmMenu()
1196 {
1197     string currentAlgorithm = "";
1198     cout<<"****** CLUSTERING ALGORITHM MENU ******\n\n\n";
1199     while (true)
1200     {
1201         if(userParameters->getClusterAlgorithm() == NJ)
1202         {
1203             currentAlgorithm = "Neighbour Joining";
1204         }
1205         else
1206         {
1207             currentAlgorithm = "UPGMA";
1208         }
1209         lin1 = "";
1210         cout<< "\n\n\n";
1211         cout<<" ****** Clustering Algorithms ******\n\n\n";
1212         cout<<"     1. Neighbour Joining \n";
1213         cout<<"     2. UPGMA \n";
1214         cout << "-- Current algorithm is "<< currentAlgorithm << " --\n\n\n";
1215
1216         
1217         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
1218         if (choice == '\n')
1219         {
1220             return ;
1221         }
1222         switch (toupper(choice))
1223         {
1224             case '1':
1225                 userParameters->setClusterAlgorithm(NJ);
1226                 break;
1227             case '2':
1228                 userParameters->setClusterAlgorithm(UPGMA);
1229                 break;
1230             default:
1231                 cout<< "\n\nUnrecognised Command\n\n";
1232                 break;
1233         }
1234     }    
1235 }
1236
1237 void InteractiveMenu::iterationMenu()
1238 {
1239     string currentIteration = "";
1240     cout<<"****** ITERATION MENU ******\n\n\n";
1241     while (true)
1242     {
1243         if(userParameters->getDoRemoveFirstIteration() == ALIGNMENT)
1244         {
1245             currentIteration = "Alignment iteration";
1246         }
1247         else if(userParameters->getDoRemoveFirstIteration() == TREE)
1248         {
1249             currentIteration = "Tree based iteration";
1250         }
1251         else
1252         {
1253             currentIteration = "None";
1254         }
1255         lin1 = "";
1256         cout<< "\n\n\n";
1257         cout<<" ****** Iteration Choices ******\n\n\n";
1258         cout<<"     1. Off \n";
1259         cout<<"     2. Tree based iteration (iterates each profile alignment step) \n";
1260         cout<<"     3. Alignment iteration (iterates final alignment only) \n\n";
1261         cout << "-- Current selection is "<< currentIteration << " --\n\n\n";
1262
1263         
1264         choice = utilityObject->getChoice(string("Enter number (or [RETURN] to exit)"));
1265         if (choice == '\n')
1266         {
1267             return ;
1268         }
1269         switch (toupper(choice))
1270         {
1271             case '1':
1272                 userParameters->setDoRemoveFirstIteration(NONE);
1273                 break;
1274             case '2':
1275                 userParameters->setDoRemoveFirstIteration(TREE);
1276                 break;
1277             case '3':
1278                 userParameters->setDoRemoveFirstIteration(ALIGNMENT);
1279                 break;    
1280             default:
1281                 cout<< "\n\nUnrecognised Command\n\n";
1282                 break;
1283         }
1284     }
1285 }
1286
1287 }
1288