1 /*
2 
3 PhyML:  a program that  computes maximum likelihood phylogenies from
4 DNA or AA homologous sequences.
5 
6 Copyright (C) Stephane Guindon. Oct 2003 onward.
7 
8 All parts of the source except where indicated are distributed under
9 the GNU public licence. See http://www.opensource.org for details.
10 
11 */
12 
13 #include "interface.h"
14 #include "mg.h"
15 
16 
Launch_Interface(option * io)17 void Launch_Interface(option *io)
18 {
19   Launch_Interface_Input(io);
20   io->ready_to_go = 0;
21   do
22     {
23       switch(io->curr_interface)
24 	{
25 	case INTERFACE_DATA_TYPE :
26 	  {
27 	    Launch_Interface_Data_Type(io);
28 	    break;
29 	  }
30 	case INTERFACE_MULTIGENE :
31 	  {
32 	    Launch_Interface_Multigene(io);
33 	    break;
34 	  }
35 	case INTERFACE_MODEL :
36 	  {
37 	    Launch_Interface_Model(io);
38 	    break;
39 	  }
40 	case INTERFACE_TOPO_SEARCH :
41 	  {
42 	    Launch_Interface_Topo_Search(io);
43 	    break;
44 	  }
45 	case INTERFACE_BRANCH_SUPPORT :
46 	  {
47 	    Launch_Interface_Branch_Support(io);
48 	    break;
49 	  }
50 	default :
51 	  {
52 	    PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__);
53 	    Exit("");
54 	    break;
55 	  }
56 	}
57     }while(!io->ready_to_go);
58 
59 
60   if(io->in_tree == 2)
61     {
62       PhyML_Printf("\n. Enter the name of the input tree file > ");
63       Getstring_Stdin(io->in_tree_file);
64       io->fp_in_tree = Openfile(io->in_tree_file,0);
65     }
66 
67   if((io->mod->whichmodel == CUSTOMAA) && (io->datatype == AA))
68     {
69       char *filename;
70 
71       filename = (char *)mCalloc(T_MAX_NAME,sizeof(char));
72 
73       fflush(NULL);
74       PhyML_Printf("\n");
75       PhyML_Printf("\n. Enter the rate matrix file name > "); fflush(NULL);
76       Getstring_Stdin(filename);
77       io->mod->fp_aa_rate_mat = Openfile(filename,0);
78       strcpy(io->mod->aa_rate_mat_file->s,filename);
79       PhyML_Printf("\n");
80       Free(filename);
81       fflush(NULL);
82     }
83 
84   if((io->mod->s_opt->n_rand_starts)           &&
85      (io->mod->s_opt->topo_search == NNI_MOVE) &&
86      (io->mod->s_opt->random_input_tree))
87     {
88       Warn_And_Exit("\n. The random starting tree option is only compatible with SPR based search options.\n");
89     }
90 
91   if ((io->datatype == NT) && (io->mod->whichmodel > 10))
92     {
93       char choix;
94       PhyML_Printf("\n== Err: model incompatible with the data type. Please use JC69, K80, F81, HKY, F84, TN93 or GTR\n");
95       PhyML_Printf("\n. Type any key to exit.\n");
96       if(!scanf("%c",&choix)) Exit("\n");
97       Warn_And_Exit("\n");
98     }
99   else if ((io->datatype == AA) && (io->mod->whichmodel < 11))
100     {
101       char choix;
102       PhyML_Printf("\n== Err: model incompatible with the data type. Please use LG, Dayhoff, JTT, MtREV, WAG, DCMut, RtREV, CpREV, VT, Blosum62, MtMam, MtArt, HIVw, HIVb or AB.\n");
103       PhyML_Printf("\n. Type any key to exit.\n");
104       if(!scanf("%c",&choix)) Exit("\n");
105       Exit("\n");
106     }
107 
108   if(io->m4_model == YES)
109     {
110 #ifdef M4
111       io->mod->ns *= io->mod->m4mod->n_h;
112       io->mod->use_m4mod = 1;
113       M4_Make_Complete(io->mod->m4mod->n_h,
114 		       io->mod->m4mod->n_o,
115 		       io->mod->m4mod);
116 #endif
117     }
118   else
119     {
120       io->mod->s_opt->opt_cov_delta      = 0;
121       io->mod->s_opt->opt_cov_alpha      = 0;
122       io->mod->s_opt->opt_cov_free_rates = 0;
123     }
124 
125   if((io->mod->s_opt->opt_cov_free_rates) && (io->mod->s_opt->opt_cov_alpha))
126     {
127       io->mod->s_opt->opt_cov_free_rates = 0;
128       io->mod->m4mod->use_cov_alpha      = 0;
129       io->mod->m4mod->use_cov_free       = 1;
130     }
131 
132 
133   if(io->print_site_lnl)
134     {
135       strcpy(io->out_lk_file,io->in_align_file);
136       strcat(io->out_lk_file, "_phyml_lk.txt");
137 
138       if(io->append_run_ID) { strcat(io->out_lk_file,"_"); strcat(io->out_lk_file,io->run_id_string); }
139       io->fp_out_lk = Openfile(io->out_lk_file,1);
140     }
141 
142   if(io->print_trace)
143     {
144       strcpy(io->out_trace_file,io->in_align_file);
145       strcat(io->out_trace_file,"_phyml_trace.txt");
146 
147       if(io->append_run_ID) { strcat(io->out_trace_file,"_"); strcat(io->out_trace_file,io->run_id_string); }
148       io->fp_out_trace = Openfile(io->out_trace_file,1);
149     }
150 
151   if(io->mod->s_opt->random_input_tree)
152     {
153       strcpy(io->out_trees_file,io->in_align_file);
154       strcat(io->out_trees_file,"_phyml_trees.txt");
155 
156       if(io->append_run_ID) { strcat(io->out_trees_file,"_"); strcat(io->out_trees_file,io->run_id_string); }
157       io->fp_out_trees = Openfile(io->out_trees_file,1);
158     }
159 
160   if((io->print_boot_trees) && (io->n_boot_replicates > 0))
161     {
162       strcpy(io->out_boot_tree_file,io->in_align_file);
163       strcat(io->out_boot_tree_file,"_phyml_boot_trees.txt");
164 
165       if(io->append_run_ID) { strcat(io->out_boot_tree_file,"_"); strcat(io->out_boot_tree_file,io->run_id_string); }
166       io->fp_out_boot_tree = Openfile(io->out_boot_tree_file,1);
167 
168       strcpy(io->out_boot_stats_file,io->in_align_file);
169       strcat(io->out_boot_stats_file,"_phyml_boot_stats.txt");
170 
171       if(io->append_run_ID) { strcat(io->out_boot_stats_file,"_"); strcat(io->out_boot_stats_file,io->run_id_string); }
172       io->fp_out_boot_stats = Openfile(io->out_boot_stats_file,1);
173     }
174 
175   if(io->append_run_ID)
176     {
177       strcat(io->out_tree_file,"_");
178       strcat(io->out_stats_file,"_");
179       strcat(io->out_tree_file,io->run_id_string);
180       strcat(io->out_stats_file,io->run_id_string);
181     }
182 
183   if(io->mod->ras->n_catg == 1) io->mod->s_opt->opt_alpha = 0;
184 
185   if(io->mod->whichmodel != K80 &&
186      io->mod->whichmodel != HKY85 &&
187      io->mod->whichmodel != F84 &&
188      io->mod->whichmodel != TN93)
189     {
190       io->mod->s_opt->opt_kappa = 0;
191     }
192 
193   io->fp_out_tree  = Openfile(io->out_tree_file,1);
194   io->fp_out_stats = Openfile(io->out_stats_file,1);
195 
196 // VINCENT: do not necessarily optimize relative rate parameters, they could be set by user
197 	if(io->mod->whichmodel == GTR)
198 	{
199 		if (io->mod->s_opt->opt_subst_param)
200 			io->mod->s_opt->opt_rr = YES;
201 		else
202 			io->mod->s_opt->opt_rr = NO;
203 	}
204 }
205 
206 //////////////////////////////////////////////////////////////
207 //////////////////////////////////////////////////////////////
208 
209 
Clear()210 void Clear()
211 {
212 #ifdef WIN32
213   system("cls");
214 #elif UNIX
215   PhyML_Printf("\033[2J\033[H");
216 #endif
217 }
218 
219 //////////////////////////////////////////////////////////////
220 //////////////////////////////////////////////////////////////
221 
Launch_Interface_Input(option * io)222 void Launch_Interface_Input(option *io)
223 {
224   char choix;
225   int n_trial;
226 
227   Clear();
228   Print_Banner(stdout);
229 
230 
231 #ifdef EVOLVE
232 
233   char *n_data_sets;
234 
235   PhyML_Printf("\n\n");
236   PhyML_Printf("\n. Enter the tree file name > "); fflush(NULL);
237   Getstring_Stdin(io->in_tree_file);
238   io->fp_in_tree = Openfile(io->in_tree_file,0);
239   PhyML_Printf("\n");
240 
241   PhyML_Printf("\n. Enter the reference sequence file name > "); fflush(NULL);
242   Getstring_Stdin(io->in_align_file);
243   io->fp_in_align = Openfile(io->in_align_file,0);
244   PhyML_Printf("\n");
245 
246   PhyML_Printf("\n. Number of data sets > ");
247   n_data_sets = (char *)mCalloc(10000,sizeof(char));
248   Getstring_Stdin(n_data_sets);
249   n_trial = 0;
250   while((!atoi(n_data_sets)) || (atoi(n_data_sets) < 0))
251     {
252       if(++n_trial > 10) Exit("\n== Err : the number of sets must be a positive integer");
253       PhyML_Printf("\n. The number of sets must be a positive integer");
254       PhyML_Printf("\n. Enter a new value > ");
255       Getstring_Stdin(n_data_sets);
256     }
257   io->n_data_set_asked = atoi(n_data_sets);
258   Free(n_data_sets);
259 
260 #elif OPTIMIZ
261 
262   PhyML_Printf("\n. Enter the tree file name > "); fflush(NULL);
263   Getstring_Stdin(io->in_tree_file);
264   io->fp_in_tree = Openfile(io->in_tree_file,0);
265   PhyML_Printf("\n");
266 
267   PhyML_Printf("\n. Enter the reference sequence file name > "); fflush(NULL);
268   Getstring_Stdin(io->in_align_file);
269   io->fp_in_align = Openfile(io->in_align_file,0);
270   PhyML_Printf("\n");
271 
272 #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
273 
274   PhyML_Printf("\n. Enter the sequence file name > "); fflush(NULL);
275   Getstring_Stdin(io->in_align_file);
276   io->fp_in_align = Openfile(io->in_align_file,0);
277 
278 #endif
279 
280 
281 #if defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
282 
283   strcpy(io->out_stats_file,io->in_align_file);
284 
285   strcat(io->out_stats_file,"_phyml_stats.txt");
286   strcpy(io->out_tree_file,io->in_align_file);
287 
288   strcat(io->out_tree_file,"_phyml_tree.txt");
289   strcpy(io->out_lk_file,io->in_align_file);
290 
291   strcat(io->out_lk_file,"_phyml_lk.txt");
292 #endif
293 
294 #ifdef EVOLVE
295   if(Filexists("evolve_out.txt"));
296 #elif OPTIMIZ
297   if(Filexists("optimiz_out.txt"))
298 #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
299   if(Filexists(io->out_stats_file))
300 #endif
301     {
302       PhyML_Printf("\n");
303 #ifdef EVOLVE
304       PhyML_Printf("\n. A file 'evolve_out' already exists");
305 #elif OPTIMIZ
306       PhyML_Printf("\n. A file 'optimiz_out' already exists");
307 #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
308       PhyML_Printf("\n. A file '%s' already exists",io->out_stats_file);
309 #endif
310       PhyML_Printf("\n. Do you want to Replace it or Append to it ? ");
311       n_trial = 0;
312       do
313 	{
314 	  PhyML_Printf("\n. Please type R or A > ");
315 	  if(!scanf("%c",&choix)) Exit("\n");
316 	  if(choix == '\n') choix = 'r';
317 	  else getchar();
318 	  if(++n_trial>10) Exit("\n");
319 	  Uppercase(&choix);
320 	}
321       while((choix != 'R') && (choix != 'A'));
322       if(choix == 'R') io->out_stats_file_open_mode = 1;
323       else             io->out_stats_file_open_mode = 2;
324     }
325 
326   /* io->fp_out_stats = Openfile(io->out_stats_file,io->out_stats_file_open_mode); */
327 
328 #ifdef EVOLVE
329   if(Filexists("evolve_seq.txt"))
330 #elif OPTIMIZ
331   if(Filexists("optimiz_tree.txt"))
332 #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
333   if(Filexists(io->out_tree_file))
334 #endif
335     {
336       PhyML_Printf("\n");
337 #ifdef EVOLVE
338       PhyML_Printf("\n. A file 'evolve_seq' already exists");
339 #elif OPTIMIZ
340       PhyML_Printf("\n. A file 'optimiz_tree' already exists");
341 #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT)
342       PhyML_Printf("\n. A file '%s' already exists",io->out_tree_file);
343 #endif
344       PhyML_Printf("\n. Do you want to Replace it or Append to it ? ");
345       n_trial = 0;
346       do
347 	{
348 	  PhyML_Printf("\n. Please type R or A > ");
349 	  if(!scanf("%c",&choix)) Exit("\n");
350 	  if(choix == '\n') choix = 'r';
351 	  else getchar();
352 	  Uppercase(&choix);
353 	  if(++n_trial>10) Exit("\n");
354 	}
355       while((choix != 'R') && (choix != 'A'));
356       if(choix == 'R') io->out_tree_file_open_mode = 1;
357       else             io->out_tree_file_open_mode = 2;
358     }
359 
360   /* io->fp_out_tree = Openfile(io->out_tree_file,io->out_tree_file_open_mode); */
361 }
362 
363 //////////////////////////////////////////////////////////////
364 //////////////////////////////////////////////////////////////
365 
366 
Launch_Interface_Data_Type(option * io)367 void Launch_Interface_Data_Type(option *io)
368 {
369   char choix;
370   char *s;
371   char *buff;
372 
373   Clear();
374   Print_Banner(stdout);
375   if(io->config_multigene) Print_Data_Set_Number(io,stdout);
376 
377   s    = (char *)mCalloc(100,sizeof(char));
378   buff = (char *)mCalloc(100,sizeof(char));
379 
380 
381   PhyML_Printf("\n\n");
382 
383   PhyML_Printf("                                   ...................                                              \n");
384   PhyML_Printf("                                    Menu : Input Data                                               \n");
385   PhyML_Printf("                                .........................                                           \n");
386 
387   PhyML_Printf("\n\n");
388 
389   PhyML_Printf("                [+] "
390 	 ".................................... Next sub-menu\n");
391 
392   PhyML_Printf("                [-] "
393 	 "................................ Previous sub-menu\n");
394 
395   PhyML_Printf("                [Y] "
396 	 ".............................. Launch the analysis\n");
397 
398   PhyML_Printf("\n");
399 
400   if(io->datatype == NT)      strcpy(s,"DNA");
401   else if(io->datatype == AA) strcpy(s,"AA");
402   else strcpy(s,"Generic");
403 
404   PhyML_Printf("                [D] "
405 	 "....................... Data type (DNA/AA/Generic) "
406 	 " %-15s \n",s);
407 
408   PhyML_Printf("                [I] "
409 	 "...... Input sequences interleaved (or sequential) "
410 	 " %-15s \n",
411 	 (io->interleaved)?("interleaved"):("sequential"));
412 
413   strcpy(s,"");
414   sprintf(s," (%d sets)",io->n_data_sets);
415   strcpy(buff,(io->n_data_sets > 1)?("yes"):("no"));
416   buff=strcat(buff,(io->n_data_sets > 1)?(s):("\0"));
417   PhyML_Printf("                [M] "
418 	 "....................... Analyze multiple data sets "
419 	 " %-15s \n",buff);
420 
421   if(!io->append_run_ID) strcpy(s,"none");
422   else strcpy(s,io->run_id_string);
423   PhyML_Printf("                [R] "
424 	 "........................................... Run ID "
425 	 " %-15s \n",s);
426 
427 
428   PhyML_Printf("\n\n. Are these settings correct ? "
429 	 "(type '+', '-', 'Y' or other letter for one to change)  ");
430 
431 
432   if(!scanf("%c",&choix)) Exit("\n");
433   if(choix != '\n') getchar(); /* \n */
434   fflush(NULL);
435 
436   Uppercase(&choix);
437 
438   switch(choix)
439     {
440 /*     case '\n': */
441 /*       { */
442 /* 	io->curr_interface++; */
443 /* 	break; */
444 /*       } */
445     case 'R' :
446       {
447 	io->append_run_ID = (io->append_run_ID)?(0):(1);
448 	PhyML_Printf("\n. Enter a run ID (any string of characters) > ");
449 	Getstring_Stdin(io->run_id_string);
450 	break;
451       }
452 
453 
454     case 'M' :
455       {
456 	char *c;
457 	int n_trial;
458 
459 	PhyML_Printf("\n. How many data sets > ");
460 	c = (char *)mCalloc(100,sizeof(char));
461 	Getstring_Stdin(c);
462 	n_trial = 0;
463 	while((!atoi(c)) || (atoi(c) < 0))
464 	  {
465 	    if(++n_trial > 10) Exit("\n== Err : The number of data sets must be a positive integer");
466 	    PhyML_Printf("\n. The number of data sets must be a positive integer");
467 	    PhyML_Printf("\n. Enter a new value > ");
468 	    Getstring_Stdin(c);
469 	  }
470 	io->n_data_sets = atoi(c);
471 
472 	#ifdef PART
473 	if(io->n_data_sets > 1)
474 	  {
475 	    io->multigene = 1;
476 	  }
477 	#endif
478 
479 	if((io->do_boot || io->do_tbe) && (io->n_data_sets > 1))
480 	  {
481 	    PhyML_Printf("\n. Bootstrap option is not allowed with multiple data sets !\n");
482 	    PhyML_Printf("\n. Type any key to exit.");
483 	    if(!scanf("%c",&choix)) Exit("\n");
484 	    Exit("\n");
485 	  }
486 
487 	Free(c);
488 	break;
489       }
490     case 'I' :
491       {
492 	if(io->interleaved)
493 	  io->interleaved = 0;
494 	else io->interleaved = 1;
495 	break;
496       }
497     case 'D' :
498       {
499 	if(io->datatype == NT)
500 	  {
501 	    io->datatype              = AA;
502 	    io->mod->ns               = 20;
503 	    io->mod->s_opt->opt_kappa = 0;
504 	    io->mod->whichmodel       = LG;
505 	    strcpy(io->mod->modelname->s,"LG");
506 	  }
507 	else if(io->datatype == AA)
508 	  {
509 	    io->datatype              = GENERIC;
510 	    io->mod->whichmodel       = JC69;
511 	    strcpy(io->mod->modelname->s,"JC69");
512 	    strcpy(io->nt_or_cd,"natural numbers");
513 	  }
514 	else if(io->datatype == GENERIC)
515 	  {
516 	    io->datatype              = NT;
517 	    io->mod->ns               = 4;
518 	    io->mod->whichmodel       = HKY85;
519 	    strcpy(io->mod->modelname->s,"HKY85");
520 	    strcpy(io->nt_or_cd,"nucleotides");
521 	  }
522 	break;
523       }
524     case '-' :
525       {
526 	io->curr_interface = (io->config_multigene)?(INTERFACE_MODEL):(INTERFACE_BRANCH_SUPPORT);
527 	break;
528       }
529     case '+' :
530       {
531 	io->curr_interface = (io->multigene)?(INTERFACE_MULTIGENE):(INTERFACE_MODEL);
532 	break;
533       }
534     case 'Y' :
535       {
536 	io->ready_to_go = 1;
537 	break;
538       }
539     default :
540       {
541 	break;
542       }
543     }
544 
545   Free(s);
546   Free(buff);
547 }
548 //////////////////////////////////////////////////////////////
549 //////////////////////////////////////////////////////////////
550 
551 
Launch_Interface_Model(option * io)552 void Launch_Interface_Model(option *io)
553 {
554   char choix;
555   char *s;
556 
557   s = (char *)mCalloc(100,sizeof(char));
558 
559   Clear();
560   Print_Banner(stdout);
561   if(io->config_multigene) Print_Data_Set_Number(io,stdout);
562 
563 
564   PhyML_Printf("\n\n");
565 
566   PhyML_Printf("                                ...........................                                      \n");
567   PhyML_Printf("                                 Menu : Substitution Model                                       \n");
568   PhyML_Printf("                             .................................                                   \n");
569 
570   PhyML_Printf("\n\n");
571 
572   PhyML_Printf("                [+] "
573 	 ".................................... Next sub-menu\n");
574 
575   PhyML_Printf("                [-] "
576 	 "................................ Previous sub-menu\n");
577 
578   PhyML_Printf("                [Y] "
579 	 ".............................. Launch the analysis\n");
580 
581   PhyML_Printf("\n");
582 
583   if (io->datatype == NT)
584     {
585       if(!strcmp(io->nt_or_cd,"nucleotides"))
586 	{
587 	  PhyML_Printf("                [M] "
588 		 "................. Model of nucleotide substitution "
589 		 " %-15s \n", io->mod->modelname->s);
590 
591 	  if((io->mod->whichmodel == F81)   ||
592 	     (io->mod->whichmodel == HKY85) ||
593 	     (io->mod->whichmodel == F84)   ||
594 	     (io->mod->whichmodel == TN93)  ||
595 	     (io->mod->whichmodel == GTR)   ||
596 	     (io->mod->whichmodel == CUSTOM))
597 	    {
598 /* 	      PhyML_Printf("                [F] " */
599 /* 		     ".......... Base frequency estimates (empirical/ML) " */
600 /* 		     " %-15s \n", */
601 /* 		     (io->mod->s_opt->opt_state_freq)?("ML"):("empirical")); */
602 /* 	    } */
603 /* 	  else if(io->mod->whichmodel == CUSTOM) */
604 /* 	    { */
605 	      PhyML_Printf("                [F] "
606 		     "................. Optimise equilibrium frequencies "
607 		     " %-15s \n",
608 		     (io->mod->s_opt->opt_state_freq)?("yes"):("no"));
609 	    }
610 
611 
612 	  if(io->mod->whichmodel == CUSTOM)
613 	    {
614 	      if(!io->mod->s_opt->opt_state_freq)
615 		{
616 		  PhyML_Printf("                [E] "
617 			 "......... Equilibrium frequencies (empirical/user) "
618 			 " %-15s \n",
619 			 (io->mod->e_frq->user_state_freq)?("user defined"):("empirical"));
620 		}
621 	      PhyML_Printf("                [K] "
622 		     "............................. Current custom model "
623 		     " %-15s \n", io->mod->custom_mod_string->s);
624 
625 	      PhyML_Printf("                [O] "
626 		     "................ Optimise relative rate parameters "
627 		     " %-15s \n",(io->mod->s_opt->opt_rr)?("yes"):("no"));
628 	    }
629 	}
630     }
631   else if(io->datatype == AA)
632     {
633       PhyML_Printf("                [M] "
634 	     "................ Model of amino-acids substitution "
635 	     " %-15s \n", io->mod->modelname->s);
636 
637       PhyML_Printf("                [F] "
638 	     ". Amino acid frequencies (empirical/model defined) "
639 	     " %-15s \n",
640 	     (io->mod->s_opt->opt_state_freq)?("empirical"):("model"));
641     }
642   else if(io->datatype == GENERIC)
643     {
644       PhyML_Printf("                [M] "
645 		   "................. Model of nucleotide substitution "
646 		   " %-15s \n", io->mod->modelname->s);
647     }
648 
649   if ((io->datatype == NT)   &&
650       ((io->mod->whichmodel == K80)  ||
651        (io->mod->whichmodel == HKY85)||
652        (io->mod->whichmodel == F84)  ||
653        (io->mod->whichmodel == TN93)))
654     {
655       strcpy(s,(io->mod->s_opt->opt_kappa)?("estimated"):("fixed"));
656       if(io->mod->s_opt->opt_kappa) strcat(s,"");
657       else strcat(s," (ts/tv = ");
658 
659 /*       (io->mod->s_opt->opt_kappa)?((char *)strcat(s,"")):((char *)sprintf(s+(int)strlen((char *)s),"%3.2f)",io->mod->kappa->v)); */
660       if(io->mod->s_opt->opt_kappa)
661 	{
662 	  strcat((char *)s,"");
663 	}
664       else
665 	{
666 	  sprintf((char *)(s+(int)strlen(s)),"%3.2f)",io->mod->kappa->v);
667 	}
668 
669       PhyML_Printf("                [T] "
670 	     ".................... Ts/tv ratio (fixed/estimated) "
671 	     " %-15s \n",s);
672     }
673 
674 
675   strcpy(s,io->mod->s_opt->opt_pinvar?"estimated":"fixed");
676   strcat(s,io->mod->s_opt->opt_pinvar?"":" (p-invar = ");
677 
678   if(io->mod->s_opt->opt_pinvar)
679     {
680       strcat(s,"");
681     }
682   else
683     {
684       sprintf((char *)(s+strlen((char *)s)),"%3.2f)",io->mod->ras->pinvar->v);
685     }
686 
687   PhyML_Printf("                [V] "
688 	 ". Proportion of invariable sites (fixed/estimated)"
689 	 "  %-15s \n",s);
690 
691   PhyML_Printf("                [R] "
692 	 "....... One category of substitution rate (yes/no) "
693 	 " %-15s \n",
694 	 (io->mod->ras->n_catg > 1)?("no"):("yes"));
695 
696   if(io->mod->ras->n_catg > 1)
697     {
698       PhyML_Printf("                [C] "
699 	     "........... Number of substitution rate categories "
700 	     " %-15d \n",
701 	     io->mod->ras->n_catg);
702     }
703 
704 
705   if(io->mod->ras->n_catg > 1)
706     {
707       PhyML_Printf("                [G] "
708 		   "............. Gamma distributed rates across sites "
709 		   " %-15s \n",(io->mod->ras->free_mixt_rates)?("no"):("yes"));
710     }
711 
712 
713   if((io->mod->ras->n_catg > 1) && (io->mod->ras->free_mixt_rates == NO))
714     {
715       strcpy(s,(io->mod->s_opt->opt_alpha)?("estimated"):("fixed"));
716       strcat(s,io->mod->s_opt->opt_alpha?"":" (alpha = ");
717 
718       if(io->mod->s_opt->opt_alpha)
719 	{
720 	  strcat(s, "");
721 	}
722       else
723 	{
724 	  sprintf(s+strlen(s),"%3.2f)",io->mod->ras->alpha->v);
725 	}
726 
727       PhyML_Printf("                [A] "
728 	     "... Gamma distribution parameter (fixed/estimated) "
729 	     " %-15s \n",s);
730 
731 
732 /*       strcpy(s,(io->mod->ras->gamma_median)?("median"):("mean")); */
733 
734 /*       PhyML_Printf("                [G] " */
735 /* 	     ".........'Middle' of each rate class (mean/median) " */
736 /* 	     " %-15s \n",s); */
737 
738 
739     }
740 
741   PhyML_Printf("\n\n. Are these settings correct ? "
742 	 "(type '+', '-', 'Y' or other letter for one to change)  ");
743 
744 
745   if(!scanf("%c",&choix)) Exit("\n");
746   if(choix != '\n') getchar(); /* \n */
747 
748   Uppercase(&choix);
749 
750   switch(choix)
751     {
752 /*     case '\n': */
753 /*       { */
754 /* 	io->curr_interface++; */
755 /* 	break; */
756 /*       } */
757 
758     case 'G' :
759       {
760 	io->mod->ras->free_mixt_rates = (io->mod->ras->free_mixt_rates)?(NO):(YES);
761 	break;
762       }
763 
764     case 'O' :
765       {
766 	io->mod->s_opt->opt_rr = (io->mod->s_opt->opt_rr)?(0):(1);
767 	break;
768       }
769 
770     case 'K' :
771       {
772 	int i,j;
773 	char **rr_param,*rr;
774 	t_mod *mod;
775 	int n_trial;
776 
777 	if(io->mod->whichmodel == CUSTOM)
778 	  {
779 	    rr_param = (char **)mCalloc(6,sizeof(char *));
780 	    for(i=0;i<6;i++) rr_param[i] = (char *)mCalloc(10,sizeof(char));
781 	    rr = (char *)mCalloc(50,sizeof(char));
782 
783 	    mod = io->mod;
784 	    mod->s_opt->opt_rr = 1;
785 
786 	    n_trial = 0;
787 	    do
788 	      {
789 		PhyML_Printf("\n. Enter a new custom model > ");
790 		Getstring_Stdin(io->mod->custom_mod_string->s);
791 		if(strlen(io->mod->custom_mod_string->s) == 6)
792 		  {
793 		    for(i=0;i<6;i++)
794 		      {
795 			while(!isdigit((int)io->mod->custom_mod_string->s[i]))
796 			  {
797 			    if(++n_trial > 10) Exit("\n== Err : this string is not valid !\n");
798 			    PhyML_Printf("\n. This string is not valid\n");
799 			    PhyML_Printf("\n. Enter a new model > ");
800 			    Getstring_Stdin(io->mod->custom_mod_string->s);
801 			  }
802 		      }
803 		    if(i == 6) break;
804 		  }
805 		else
806 		  {
807 		    PhyML_Printf("\n. The string should be of length 6\n");
808 		    n_trial++;
809 		  }
810 	      }while(n_trial < 10);
811 	    if(n_trial == 10) Exit("");
812 
813             if(!mod->r_mat)
814               {
815                 mod->r_mat = (t_rmat *)Make_Rmat(mod->ns);
816                 Init_Rmat(mod->r_mat);
817                 Make_Custom_Model(mod);
818                 Translate_Custom_Mod_String(io->mod);
819               }
820 
821 	    strcpy(rr_param[0],"A<->C");
822 	    strcpy(rr_param[1],"A<->G");
823 	    strcpy(rr_param[2],"A<->T");
824 	    strcpy(rr_param[3],"C<->G");
825 	    strcpy(rr_param[4],"C<->T");
826 	    strcpy(rr_param[5],"G<->T");
827 
828 	    PhyML_Printf("\n. Set the relative rate values\n");
829 	    for(i=0;i<mod->r_mat->n_diff_rr;i++)
830 	      {
831 		sprintf(rr,"\n. [");
832 		for(j=0;j<6;j++)
833 		  {
834 		    if(mod->r_mat->rr_num->v[j] == i)
835 		      {
836 			sprintf(rr+strlen(rr),"%s = ",rr_param[j]);
837 		      }
838 		  }
839 		sprintf(rr+strlen(rr)-3,"]");
840 		PhyML_Printf("%s",rr);
841 
842 		PhyML_Printf("  (current=%.2f) > ",mod->r_mat->rr_val->v[i]);
843 
844 		Getstring_Stdin(rr);
845 
846 		if(rr[0] != '\0')
847 		  {
848 		    n_trial = 0;
849 		    while((atof(rr) < .0))
850 		      {
851 			if(++n_trial > 10)
852 			  Exit("\n== Err : the value of this parameter must be a positive number\n");
853 			PhyML_Printf("\n. The value of this parameter must be a positive number\n");
854 			PhyML_Printf("\n. Enter a new value > ");
855 			Getstring_Stdin(rr);
856 		      }
857 		    io->mod->r_mat->rr_val->v[i] = (phydbl)atof(rr);
858 		  }
859 	      }
860 
861 	    for(i=0;i<6;i++) Free(rr_param[i]);
862 	    Free(rr_param);
863 	    Free(rr);
864 	  }
865 	break;
866       }
867     case 'E' :
868       {
869 	int i;
870 
871 	if(io->mod->whichmodel == CUSTOM)
872 	  {
873 	    io->mod->e_frq->user_state_freq = (io->mod->e_frq->user_state_freq)?(0):(1);
874 
875 	    if(io->mod->e_frq->user_state_freq)
876 	      {
877 		if(!io->mod->s_opt->opt_state_freq)
878 		  {
879 		    char **bases;
880 		    char *bs;
881 		    phydbl sum;
882 		    int n_trial;
883 
884 		    bases = (char **)mCalloc(4,sizeof(char *));
885 		    for(i=0;i<4;i++) bases[i] = (char *)mCalloc(50,sizeof(char));
886 		    bs = (char *)mCalloc(100,sizeof(char));
887 
888 		    strcpy(bases[0],". f(A)> ");
889 		    strcpy(bases[1],". f(C)> ");
890 		    strcpy(bases[2],". f(G)> ");
891 		    strcpy(bases[3],". f(T)> ");
892 
893 		    PhyML_Printf("\n. Set nucleotide frequencies \n");
894 		    sum = .0;
895 		    for(i=0;i<4;i++)
896 		      {
897 			PhyML_Printf("%s",bases[i]);
898 			Getstring_Stdin(bs);
899 			n_trial = 0;
900 
901 			while((atof(bs) < .0001) || (bs[0] == '\0'))
902 			  {
903 			    if(++n_trial > 10)
904 			      Exit("\n== Err : the value of this parameter must be a positive number\n");
905 			    PhyML_Printf("\n. The value of this parameter must be a positive number\n");
906 			    PhyML_Printf("\n. Enter a new value > ");
907 			    Getstring_Stdin(bs);
908 			  }
909 			io->mod->e_frq->user_b_freq->v[i] = (phydbl)atof(bs);
910 			sum += io->mod->e_frq->user_b_freq->v[i];
911 		      }
912 
913 		    for(i=0;i<4;i++) io->mod->e_frq->user_b_freq->v[i] /= sum;
914 
915 		    if(sum > 1.0 || sum < 1.0)
916 		      {
917 			PhyML_Printf("\n. The nucleotide frequencies have to be normalised in order to sum to 1.0.\n");
918 			PhyML_Printf("\n. The frequencies are now : f(A)=%f, f(C)=%f, f(G)=%f, f(T)=%f.\n",
919 			       io->mod->e_frq->user_b_freq->v[0],
920 			       io->mod->e_frq->user_b_freq->v[1],
921 			       io->mod->e_frq->user_b_freq->v[2],
922 			       io->mod->e_frq->user_b_freq->v[3]);
923 			PhyML_Printf("\n. Enter any key to continue.\n");
924 			if(!scanf("%c",bs)) Exit("\n");
925 		      }
926 
927 		    for(i=0;i<4;i++) Free(bases[i]);
928 		    Free(bases);
929 		    Free(bs);
930 		  }
931 		else
932 		  {
933 		    Warn_And_Exit("\n. 'E' is not a valid option with these model settings.\n");
934 		  }
935 	      }
936 	  }
937 	break;
938       }
939     case 'A' :
940       {
941 	char answer;
942 	int n_trial;
943 
944         answer = 0;
945 
946 	switch(io->mod->s_opt->opt_alpha)
947 	  {
948 	  case 0 :
949 	    {
950 	      PhyML_Printf("\n. Optimise alpha ? [Y/n] ");
951 	      if(!scanf("%c",&answer)) Exit("\n");
952 	      if(answer == '\n') answer = 'Y';
953 	      else getchar();
954 	      break;
955 	    }
956 	  case 1 :
957 	    {
958 	      PhyML_Printf("\n. Optimise alpha ? [N/y] ");
959 	      if(!scanf("%c",&answer)) Exit("\n");
960 	      if(answer == '\n') answer = 'N';
961 	      else getchar();
962 	      break;
963 	    }
964 	  default : Exit("\n");
965 	  }
966 
967 	n_trial = 0;
968 	while((answer != 'Y') && (answer != 'y') &&
969 	      (answer != 'N') && (answer != 'n'))
970 	  {
971 	    if(++n_trial > 10) Exit("\n== Err : wrong answers !");
972 	    PhyML_Printf("\n. Optimise alpha ? [N/y] ");
973 	    if(!scanf("%c",&answer)) Exit("\n");
974 	    if(answer == '\n') answer = 'N';
975 	    else getchar();
976 	  }
977 
978 	switch(answer)
979 	  {
980 	  case 'Y' : case 'y' :
981 	    {
982 	      io->mod->s_opt->opt_alpha = 1;
983 	      io->mod->s_opt->opt_subst_param = 1;
984 	      break;
985 	    }
986 	  case 'N' : case 'n' :
987 	    {
988 	      char *a;
989 	      a = (char *)mCalloc(100,sizeof(char));
990 	      io->mod->ras->alpha->v = 10.0;
991 	      io->mod->s_opt->opt_alpha = 0;
992 	      PhyML_Printf("\n. Enter your value of alpha > ");
993 	      Getstring_Stdin(a);
994 	      n_trial = 0;
995 	      while(atof(a) < 1.E-10)
996 		{
997 		  if(++n_trial > 10) Exit("\n== Err : alpha must be > 1.E-10\n");
998 		  PhyML_Printf("\n. Alpha must be 1.E-10\n");
999 		  PhyML_Printf("\n. Enter a new value > ");
1000 		  Getstring_Stdin(a);
1001 		}
1002 	      io->mod->ras->alpha->v = (phydbl)atof(a);
1003 	      Free(a);
1004 	      io->mod->s_opt->opt_alpha  = 0;
1005 	      break;
1006 	    }
1007 	  }
1008 	break;
1009       }
1010 
1011     case 'C' :
1012       {
1013 	char *c;
1014 	int n_trial;
1015 
1016 	PhyML_Printf("\n. Enter your number of categories > ");
1017 	c = (char *)mCalloc(100,sizeof(char));
1018 	Getstring_Stdin(c);
1019 	n_trial = 0;
1020 	while((!atoi(c)) || (atoi(c) < 0))
1021 	  {
1022 	    if(++n_trial > 10) Exit("\n== Err : the number of categories must be a positive integer\n");
1023 	    PhyML_Printf("\n. The number of categories must be a positive integer\n");
1024 	    PhyML_Printf("\n. Enter a new value > ");
1025 	    Getstring_Stdin(c);
1026 	  }
1027 	io->mod->ras->n_catg = atoi(c);
1028 	Free(c);
1029 	break;
1030       }
1031 
1032     case 'R' :
1033       {
1034 	io->mod->ras->n_catg = (io->mod->ras->n_catg == 1)?(4):(1);
1035 	break;
1036       }
1037 
1038     case 'V' :
1039       {
1040 	char answer;
1041 	int n_trial;
1042 
1043         answer = 0;
1044 
1045 	switch(io->mod->s_opt->opt_pinvar)
1046 	  {
1047 	  case 0 :
1048 	    {
1049 	      PhyML_Printf("\n. Optimise p-invar ? [Y/n] ");
1050               answer = 0;
1051 	      if(!scanf("%c", &answer)) Exit("\n");
1052 	      if(answer == '\n') answer = 'Y';
1053 	      else getchar();
1054 	      break;
1055 	    }
1056 	  case 1 :
1057 	    {
1058 	      PhyML_Printf("\n. Optimise p-invar ? [N/y] ");
1059 	      if(!scanf("%c", &answer)) Exit("\n");
1060 	      if(answer == '\n') answer = 'N';
1061 	      else getchar();
1062 	      break;
1063 	    }
1064 	  default : Exit("\n");
1065 	  }
1066 
1067 	n_trial = 0;
1068 	while((answer != 'Y') && (answer != 'y') &&
1069 	      (answer != 'N') && (answer != 'n'))
1070 	  {
1071 	    if(++n_trial > 10) Exit("\n== Err : wrong answers !");
1072 	    PhyML_Printf("\n. Optimise p-invar ? [N/y] ");
1073 	    if(!scanf("%c", &answer)) Exit("\n");
1074 	    if(answer == '\n') answer = 'N';
1075 	    else getchar();
1076 	  }
1077 
1078 	switch(answer)
1079 	  {
1080 	  case 'Y' : case 'y' :
1081 	    {
1082 	      io->mod->s_opt->opt_subst_param = 1;
1083 	      io->mod->s_opt->opt_pinvar = 1;
1084 	      io->mod->ras->pinvar->v = 0.2;
1085 	      io->mod->ras->invar  = 1;
1086 	      break;
1087 	    }
1088 	  case 'N' : case 'n' :
1089 	    {
1090 	      char *p;
1091 	      p = (char *)mCalloc(100,sizeof(char));
1092 	      PhyML_Printf("\n. Enter your value of p-invar > ");
1093 	      Getstring_Stdin(p);
1094 	      n_trial = 0;
1095 	      while((atof(p) < 0.0) || (atof(p) > 1.0))
1096 		{
1097 		  if(++n_trial > 10)
1098 		    Exit("\n== Err : the proportion of invariable sites must be a positive number between 0.0 and 1.0");
1099 		  PhyML_Printf("\n. The proportion must be a positive number between 0.0 and 1.0\n");
1100 		  PhyML_Printf("\n. Enter a new value > ");
1101 		  Getstring_Stdin(p);
1102 		}
1103 	      io->mod->ras->pinvar->v = (phydbl)atof(p);
1104 
1105 	      if(io->mod->ras->pinvar->v > 0.0+SMALL) io->mod->ras->invar = 1;
1106 	      else                             io->mod->ras->invar = 0;
1107 
1108 	      Free(p);
1109 
1110 	      io->mod->s_opt->opt_pinvar = 0;
1111 	      break;
1112 	    }
1113 	  }
1114 	break;
1115       }
1116 
1117     case 'T' :
1118       {
1119 	char answer;
1120 	int n_trial;
1121 
1122         answer = 0;
1123 
1124 	if((io->datatype == AA)  ||
1125 	   (io->mod->whichmodel == JC69)||
1126 	   (io->mod->whichmodel == F81) ||
1127 	   (io->mod->whichmodel == GTR) ||
1128 	   (io->mod->whichmodel == CUSTOM))
1129 	  {
1130 	    PhyML_Printf("\n. 'K' is not a valid choice for this model\n");
1131 	    PhyML_Printf("\n. Type any key to exit.\n");
1132 	    if(!scanf("%c",&choix)) Exit("\n");
1133 	    Exit("\n");
1134 	  }
1135 
1136 	switch(io->mod->s_opt->opt_kappa)
1137 	  {
1138 	  case 0 :
1139 	    {
1140 	      PhyML_Printf("\n. Optimise ts/tv ratio ? [Y/n] ");
1141 	      if(!scanf("%c", &answer)) Exit("\n");
1142 	      if(answer == '\n') answer = 'Y';
1143 	      else getchar();
1144 	      break;
1145 	    }
1146 	  case 1 :
1147 	    {
1148 	      PhyML_Printf("\n. Optimise ts/tv ratio ? [N/y] ");
1149               if(!scanf("%c", &answer)) Exit("\n");
1150 	      if(answer == '\n') answer = 'N';
1151 	      else getchar();
1152 	      break;
1153 	    }
1154 	  default : Exit("\n");
1155 	  }
1156 
1157 	n_trial = 0;
1158 	while((answer != 'Y') && (answer != 'y') &&
1159 	      (answer != 'N') && (answer != 'n'))
1160 	  {
1161 	    if(++n_trial > 10) Exit("\n== Err : wrong answers !");
1162 	    PhyML_Printf("\n. Optimise ts/tv ratio ? [N/y] ");
1163 	    if(!scanf("%c", &answer)) Exit("\n");
1164 	    if(answer == '\n') answer = 'N';
1165 	    else getchar();
1166 	  }
1167 
1168 	switch(answer)
1169 	  {
1170 	  case 'Y' : case 'y' :
1171 	    {
1172 	      io->mod->kappa->v = 4.0;
1173 	      io->mod->s_opt->opt_subst_param = 1;
1174 	      io->mod->s_opt->opt_kappa = 1;
1175 	      if(io->mod->whichmodel == TN93)
1176 		io->mod->s_opt->opt_lambda = 1;
1177 	      break;
1178 	    }
1179 	  case 'N' : case 'n' :
1180 	    {
1181 	      char *t;
1182 	      t = (char *)mCalloc(100,sizeof(char));
1183 	      io->mod->s_opt->opt_kappa = 0;
1184 	      PhyML_Printf("\n. Enter your value of the ts/tv ratio > ");
1185 	      Getstring_Stdin(t);
1186 	      n_trial = 0;
1187 	      while(atof(t) < .0)
1188 		{
1189 		  if(++n_trial > 10) Exit("\n== Err : the ts/tv ratio must be a positive number\n");
1190 		  PhyML_Printf("\n. The ratio must be a positive number");
1191 		  PhyML_Printf("\n. Enter a new value > ");
1192 		  Getstring_Stdin(t);
1193 		}
1194 	      io->mod->kappa->v = (phydbl)atof(t);
1195 	      io->mod->s_opt->opt_kappa  = 0;
1196 	      io->mod->s_opt->opt_lambda = 0;
1197 	      Free(t);
1198 	      break;
1199 	    }
1200 	  }
1201 	break;
1202       }
1203 
1204     case 'F' :
1205       {
1206 	if((io->mod->whichmodel == JC69) ||
1207 	   (io->mod->whichmodel == K80))
1208 	  {
1209 	    Warn_And_Exit("\n. 'F' is not a valid choice with these model settings.\n");
1210 	  }
1211 	io->mod->s_opt->opt_state_freq = (io->mod->s_opt->opt_state_freq)?(0):(1);
1212 	break;
1213       }
1214 
1215     case 'M' :
1216       {
1217 	if(io->datatype == NT)
1218 	  {
1219 	    if(!strcmp(io->nt_or_cd,"nucleotides"))
1220 	      {
1221 		if(io->mod->whichmodel == JC69)
1222 		  {
1223 		    io->mod->whichmodel = K80;
1224 		  }
1225 		else if(io->mod->whichmodel == K80)
1226 		  {
1227 		    io->mod->whichmodel = F81;
1228 		  }
1229 		else if(io->mod->whichmodel == F81)
1230 		  {
1231 		    io->mod->whichmodel = HKY85;
1232 		  }
1233 		else if(io->mod->whichmodel == HKY85)
1234 		  {
1235 		    io->mod->whichmodel = F84;
1236 		  }
1237 		else if(io->mod->whichmodel == F84)
1238 		  {
1239 		    io->mod->whichmodel = TN93;
1240 		  }
1241 		else if(io->mod->whichmodel == TN93)
1242 		  {
1243 		    io->mod->whichmodel = GTR;
1244 		  }
1245 		else if(io->mod->whichmodel == GTR)
1246 		  {
1247 		    io->mod->whichmodel = CUSTOM;
1248 		  }
1249 
1250 		else if(io->mod->whichmodel == CUSTOM)
1251 		  {
1252 		    io->mod->whichmodel = JC69;
1253 		  }
1254 	      }
1255 	  }
1256 	else if(io->datatype == AA)
1257 	  {
1258 	    if(io->mod->whichmodel == LG)
1259 	      {
1260 		io->mod->whichmodel = WAG;
1261 	      }
1262 	    else if(io->mod->whichmodel == WAG)
1263 	      {
1264 		io->mod->whichmodel = DAYHOFF;
1265 	      }
1266 	    else if(io->mod->whichmodel == DAYHOFF)
1267 	      {
1268 		io->mod->whichmodel = JTT;
1269 	      }
1270 	    else if(io->mod->whichmodel == JTT)
1271 	      {
1272 		io->mod->whichmodel = BLOSUM62;
1273 	      }
1274 	    else if(io->mod->whichmodel == BLOSUM62)
1275 	      {
1276 		io->mod->whichmodel = MTREV;
1277 	      }
1278 	    else if(io->mod->whichmodel == MTREV)
1279 	      {
1280 		io->mod->whichmodel = RTREV;
1281 	      }
1282 	    else if(io->mod->whichmodel == RTREV)
1283 	      {
1284 		io->mod->whichmodel = CPREV;
1285 	      }
1286 	    else if(io->mod->whichmodel == CPREV)
1287 	      {
1288 		io->mod->whichmodel = DCMUT;
1289 	      }
1290 	    else if(io->mod->whichmodel == DCMUT)
1291 	      {
1292 		io->mod->whichmodel = VT;
1293 	      }
1294 	    else if(io->mod->whichmodel == VT)
1295 	      {
1296 		io->mod->whichmodel = MTMAM;
1297 	      }
1298 	    else if(io->mod->whichmodel == MTMAM)
1299 	      {
1300 		io->mod->whichmodel = MTART;
1301 	      }
1302 	    else if(io->mod->whichmodel == MTART)
1303 	      {
1304 		io->mod->whichmodel = HIVW;
1305 	      }
1306 	    else if(io->mod->whichmodel == HIVW)
1307 	      {
1308 		io->mod->whichmodel = HIVB;
1309 	      }
1310 	    else if(io->mod->whichmodel == HIVB)
1311 	      {
1312 		io->mod->whichmodel = AB;
1313 		  }
1314 		else if(io->mod->whichmodel == AB)
1315 	      {
1316 		io->mod->whichmodel = CUSTOMAA;
1317 	      }
1318 	    else if(io->mod->whichmodel == CUSTOMAA)
1319 	      {
1320 		io->mod->whichmodel = LG;
1321 	      }
1322 	  }
1323 	else if(io->datatype == GENERIC)
1324 	  {
1325 	    io->mod->whichmodel = JC69;
1326 	  }
1327 	Set_Model_Name(io->mod);
1328 	break;
1329       }
1330     case '-' :
1331       {
1332 	io->curr_interface = INTERFACE_DATA_TYPE;
1333 	break;
1334       }
1335     case '+' :
1336       {
1337 	io->curr_interface = (io->config_multigene)?(INTERFACE_DATA_TYPE):(INTERFACE_TOPO_SEARCH);
1338 	break;
1339       }
1340     case 'Y' :
1341       {
1342  	io->ready_to_go = 1;
1343 	break;
1344       }
1345     default :
1346       {
1347 	break;
1348       }
1349     }
1350 
1351   if(io->mod->s_opt->opt_alpha  ||
1352      io->mod->s_opt->opt_kappa  ||
1353      io->mod->s_opt->opt_lambda ||
1354      io->mod->s_opt->opt_pinvar ||
1355      io->mod->s_opt->opt_rr) io->mod->s_opt->opt_subst_param = 1;
1356   else                       io->mod->s_opt->opt_subst_param = 0;
1357 
1358   Free(s);
1359 }
1360 
1361 //////////////////////////////////////////////////////////////
1362 //////////////////////////////////////////////////////////////
1363 
1364 
Launch_Interface_Topo_Search(option * io)1365 void Launch_Interface_Topo_Search(option *io)
1366 {
1367   char choix;
1368   char *s;
1369 
1370   s = (char *)mCalloc(100,sizeof(char));
1371 
1372   Clear();
1373   Print_Banner(stdout);
1374 
1375   PhyML_Printf("\n\n");
1376 
1377 
1378   PhyML_Printf("                                   .......................                                     \n");
1379   PhyML_Printf("                                    Menu : Tree Searching                                        \n");
1380   PhyML_Printf("                                .............................                                  \n");
1381 
1382 
1383   PhyML_Printf("\n\n");
1384 
1385   PhyML_Printf("                [+] "
1386 	 ".................................... Next sub-menu\n");
1387 
1388   PhyML_Printf("                [-] "
1389 	 "................................ Previous sub-menu\n");
1390 
1391   PhyML_Printf("                [Y] "
1392 	 ".............................. Launch the analysis\n");
1393 
1394   PhyML_Printf("\n");
1395 
1396   PhyML_Printf("                [O] "
1397 	 "........................... Optimise tree topology "
1398 	 " %-15s \n",
1399 	 (io->mod->s_opt->opt_topo)?("yes"):("no"));
1400 
1401 
1402   if(io->mod->s_opt->opt_topo)
1403     {
1404       switch(io->in_tree)
1405 	{
1406 	case 0: { strcpy(s,"BioNJ");     break; }
1407 	case 1: { strcpy(s,"parsimony"); break; }
1408 	case 2: { strcpy(s,"user tree"); break; }
1409 	}
1410 
1411       PhyML_Printf("                [U] "
1412 		   "........ Starting tree (BioNJ/parsimony/user tree) "
1413 		   " %-15s \n",s);
1414     }
1415   else
1416     {
1417       switch(io->in_tree)
1418 	{
1419 	case 0: { strcpy(s,"BioNJ");     break; }
1420 	case 2: { strcpy(s,"user tree"); break; }
1421 	}
1422 
1423       PhyML_Printf("                [U] "
1424 		   "..................... Input tree (BioNJ/user tree) "
1425 		   " %-15s \n",s);
1426     }
1427 
1428   if(io->mod->s_opt->opt_topo)
1429     {
1430       char *s;
1431 
1432       s = (char *)mCalloc(T_MAX_OPTION,sizeof(char));
1433 
1434       io->mod->s_opt->topo_search = SPR_MOVE;
1435 
1436       if(io->mod->s_opt->topo_search == NNI_MOVE)
1437 	{
1438 	  /* strcpy(s,"NNI moves (fast, approximate)\0"); */
1439 	  strcpy(s,"SPR moves\0");
1440 	}
1441       else if(io->mod->s_opt->topo_search == SPR_MOVE)
1442 	{
1443 	  strcpy(s,"SPR moves\0");
1444 	}
1445       else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR)
1446 	{
1447 	  strcpy(s,"SPR moves\0");
1448 	  /* strcpy(s,"Best of NNI and SPR \0"); */
1449 	}
1450 
1451       PhyML_Printf("                [S] "
1452 	     ".................. Tree topology search operations "
1453 	     " %-15s \n",s);
1454 
1455       Free(s);
1456 
1457       if(io->mod->s_opt->topo_search != NNI_MOVE)
1458 	{
1459 	  PhyML_Printf("                [R] "
1460 		 "........................ Add random starting trees "
1461 		 " %-15s \n",
1462 		 (io->mod->s_opt->random_input_tree)?("yes"):("no"));
1463 
1464 	  if(io->mod->s_opt->random_input_tree)
1465 	    {
1466 	      PhyML_Printf("                [N] "
1467 		     ".................. Number of random starting trees "
1468 		     " %-15d \n",io->mod->s_opt->n_rand_starts);
1469 	    }
1470 	}
1471     }
1472   else
1473     {
1474       PhyML_Printf("                [L] "
1475 	     ".......................... Optimise branch lengths "
1476 	     " %-15s \n",
1477 	     (io->mod->s_opt->opt_bl)?("yes"):("no"));
1478     }
1479 
1480   PhyML_Printf("\n\n. Are these settings correct ? "
1481 	 "(type '+', '-', 'Y' or other letter for one to change)  ");
1482 
1483 
1484   if(!scanf("%c",&choix)) Exit("\n");
1485   if(choix != '\n') getchar(); /* \n */
1486 
1487   Free(s);
1488 
1489   Uppercase(&choix);
1490 
1491 
1492   switch(choix)
1493     {
1494     case '-' :
1495       {
1496 	io->curr_interface = INTERFACE_MODEL;
1497 	break;
1498       }
1499     case '+' :
1500       {
1501 	io->curr_interface = INTERFACE_BRANCH_SUPPORT;
1502 	break;
1503       }
1504     case 'Y' :
1505       {
1506  	io->ready_to_go = 1;
1507 	break;
1508       }
1509     case 'U' :
1510       {
1511 	io->in_tree++;
1512 	if(!io->mod->s_opt->opt_topo)
1513 	  {
1514 	    if(io->in_tree == 1) io->in_tree = 2;
1515 	  }
1516 	if(io->in_tree == 3) io->in_tree = 0;
1517 	break;
1518       }
1519     case 'N' :
1520       {
1521 	char *n;
1522 	int n_trial;
1523 
1524 	PhyML_Printf("\n. Enter your number of starting trees > ");
1525 	n = (char *)mCalloc(100,sizeof(char));
1526 	Getstring_Stdin(n);
1527 	n_trial = 0;
1528 	while(atoi(n) < 1)
1529 	  {
1530 	    if(++n_trial > 10) Exit("\n== Err : the number of starting trees must be a positive integer\n");
1531 	    PhyML_Printf("\n. The number of starting trees must be a positive integer\n");
1532 	    PhyML_Printf("\n. Enter a new value > ");
1533 	    Getstring_Stdin(n);
1534 	  }
1535 	io->mod->s_opt->n_rand_starts = atoi(n);
1536 	io->n_trees = 1;
1537 	Free(n);
1538 	break;
1539       }
1540     case 'O' :
1541       {
1542 	io->mod->s_opt->opt_topo = (io->mod->s_opt->opt_topo)?(0):(1);
1543 	break;
1544       }
1545 
1546     case 'L' :
1547       {
1548 	if(!io->mod->s_opt->opt_topo)
1549 	  {
1550 	    io->mod->s_opt->opt_bl = (io->mod->s_opt->opt_bl)?(0):(1);
1551 	  }
1552 	break;
1553       }
1554 
1555     case 'S' :
1556       {
1557 	if(io->mod->s_opt->topo_search == NNI_MOVE)
1558 	  {
1559 	    io->mod->s_opt->topo_search         = SPR_MOVE;
1560 	    io->mod->s_opt->n_rand_starts       = 1;
1561 	    io->mod->s_opt->random_input_tree   = 0;
1562 	    io->mod->s_opt->greedy              = 0;
1563 	  }
1564 	else if(io->mod->s_opt->topo_search == SPR_MOVE)
1565 	  {
1566 	    io->mod->s_opt->topo_search         = BEST_OF_NNI_AND_SPR;
1567 	    io->mod->s_opt->n_rand_starts       = 1;
1568 	    io->mod->s_opt->random_input_tree   = 0;
1569 	    io->mod->s_opt->greedy              = 0;
1570 	  }
1571 	else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR)
1572 	  {
1573 	    io->mod->s_opt->topo_search         = NNI_MOVE;
1574 	    io->mod->s_opt->n_rand_starts       = 1;
1575 	    io->mod->s_opt->random_input_tree   = 0;
1576 	    io->mod->s_opt->greedy              = 0;
1577 	  }
1578 	break;
1579       }
1580     case 'R' :
1581       {
1582 	io->mod->s_opt->random_input_tree = (io->mod->s_opt->random_input_tree)?(0):(1);
1583 
1584 	if(io->mod->s_opt->random_input_tree)
1585 	  {
1586 	    if(io->fp_in_tree) fclose(io->fp_in_tree);
1587 /* 	    io->in_tree                   = 0; */
1588 	    io->n_trees                   = 1;
1589 	    io->mod->s_opt->n_rand_starts = 5;
1590 
1591 	    strcpy(io->out_trees_file,io->in_align_file);
1592 	    strcat(io->out_trees_file,"_phyml_trees.txt");
1593 	  }
1594 	break;
1595       }
1596     default :
1597       {
1598 	break;
1599       }
1600     }
1601 }
1602 
1603 //////////////////////////////////////////////////////////////
1604 //////////////////////////////////////////////////////////////
1605 
1606 
Launch_Interface_Branch_Support(option * io)1607 void Launch_Interface_Branch_Support(option *io)
1608 {
1609   char choix;
1610   char *s;
1611 
1612   s = (char *)mCalloc(100,sizeof(char));
1613 
1614   Clear();
1615   Print_Banner(stdout);
1616 
1617   PhyML_Printf("\n\n");
1618 
1619   PhyML_Printf("                                  .......................                                          \n");
1620   PhyML_Printf("                                   Menu : Branch Support                                           \n");
1621   PhyML_Printf("                               .............................                                       \n");
1622 
1623   PhyML_Printf("\n\n");
1624 
1625   PhyML_Printf("                [+] "
1626 	 ".................................... Next sub-menu\n");
1627 
1628   PhyML_Printf("                [-] "
1629 	 "................................ Previous sub-menu\n");
1630 
1631   PhyML_Printf("                [Y] "
1632 	 ".............................. Launch the analysis\n");
1633 
1634   PhyML_Printf("\n");
1635 
1636 
1637   strcpy(s,(io->do_boot || io->do_tbe)?("yes"):("no"));
1638   if(io->n_boot_replicates > 0) sprintf(s+strlen(s)," (%d replicate%s%s)",
1639 					io->n_boot_replicates,
1640 					(io->n_boot_replicates>1)?("s"):(""),
1641 					(io->do_tbe)?(", TBE"):(""));
1642 
1643   /*   PhyML_Printf("                [+] " */
1644   PhyML_Printf("                [B] "
1645 	 "................ Non parametric bootstrap analysis "
1646 	 " %-15s \n",s);
1647 
1648   if(io->ratio_test == 0)
1649     {
1650       strcpy(s,"no");
1651     }
1652   else if(io->ratio_test == 1)
1653     {
1654       strcpy(s,"yes / aLRT statistics");
1655     }
1656   else if(io->ratio_test == 2)
1657     {
1658       strcpy(s,"yes / Chi2-based supports");
1659     }
1660   else if(io->ratio_test == 3)
1661     {
1662       strcpy(s,"yes / min of SH-like & Chi2-based supports");
1663     }
1664   else if(io->ratio_test == 4)
1665     {
1666       strcpy(s,"yes / SH-like supports");
1667     }
1668   else if(io->ratio_test == 5)
1669     {
1670       strcpy(s,"yes / aBayes supports");
1671     }
1672 
1673 
1674   /*   PhyML_Printf("                [+] " */
1675   PhyML_Printf("                [A] "
1676 	 "................ Approximate likelihood ratio test "
1677 	 " %-15s \n",s);
1678 
1679   PhyML_Printf("\n. Are these settings correct ? "
1680 	 "(type '+', '-', 'Y' or other letter for one to change)  ");
1681 
1682 
1683   if(!scanf("%c",&choix)) Exit("\n");
1684   if(choix != '\n') getchar(); /* \n */
1685 
1686   Uppercase(&choix);
1687 
1688   Free(s);
1689 
1690   switch(choix)
1691     {
1692 /*     case '\n': */
1693 /*       { */
1694 /* 	io->curr_interface++; */
1695 /* 	break; */
1696 /*       } */
1697 
1698     case 'B' :
1699       {
1700 	if(io->n_boot_replicates > 0) io->n_boot_replicates = 0;
1701 	else
1702 	  {
1703 	    char *r;
1704 	    char answer;
1705 	    int n_trial;
1706 
1707             answer = 0;
1708 	    io->ratio_test = 0;
1709 
1710 	    if(io->n_data_sets > 1)
1711 	      {
1712 		PhyML_Printf("\n. Bootstrap option is not allowed with multiple data sets.\n");
1713 		PhyML_Printf("\n. Type any key to exit.\n");
1714 		if(!scanf("%c",&choix)) Exit("\n");
1715 		Exit("\n");
1716 	      }
1717 
1718 
1719 	    PhyML_Printf("\n. Number of replicates > ");
1720 	    r = (char *)mCalloc(T_MAX_OPTION,sizeof(char));
1721 	    Getstring_Stdin(r);
1722 	    n_trial = 0;
1723 	    while((!atoi(r)) || (atoi(r) < 0))
1724 	      {
1725 		if(++n_trial > 10) Exit("\n== Err : the number of replicates must be a positive integer\n");
1726 		PhyML_Printf("\n. The number of replicates must be a positive integer");
1727 		PhyML_Printf("\n. Enter a new value > ");
1728 		Getstring_Stdin(r);
1729 	      }
1730 	    io->n_boot_replicates = atoi(r);
1731 
1732 	    PhyML_Printf("\n. Print bootstrap trees (and statistics) ? (%s) > ",
1733                          (io->print_boot_trees)?("Y/n"):("y/N"));
1734 
1735 	    if(!scanf("%c",&answer)) Exit("\n");
1736 	    if(answer == '\n') answer = (io->print_boot_trees)?('Y'):('N');
1737 	    else getchar();
1738 
1739 	    switch(answer)
1740 	      {
1741 	      case 'Y' : case 'y' :
1742 		{
1743 		  io->print_boot_trees = 1;
1744 
1745 		  strcpy(io->out_boot_tree_file,io->in_align_file);
1746 
1747 		  strcat(io->out_boot_tree_file,"_phyml_boot_trees.txt");
1748 		  io->fp_out_boot_tree = Openfile(io->out_boot_tree_file,1);
1749 		  strcpy(io->out_boot_stats_file,io->in_align_file);
1750 
1751 		  strcat(io->out_boot_stats_file,"_phyml_boot_stats.txt");
1752 		  io->fp_out_boot_stats = Openfile(io->out_boot_stats_file,1);
1753 
1754 		  break;
1755 		}
1756 	      case 'N' : case 'n' :
1757 		{
1758 		  io->print_boot_trees  = 0;
1759 		  io->fp_out_boot_tree  = NULL;
1760 		  io->fp_out_boot_stats = NULL;
1761 		  break;
1762 		}
1763 	      }
1764 
1765 	    PhyML_Printf("\n. Compute TBE instead of FBP ? (%s) > ",
1766                          (io->do_tbe)?("Y/n"):("y/N"));
1767 
1768 	    if(!scanf("%c",&answer)) Exit("\n");
1769 	    if(answer == '\n') answer = (io->do_tbe)?('Y'):('N');
1770 	    else getchar();
1771 
1772 	    switch(answer)
1773 	      {
1774 	      case 'Y' : case 'y' :
1775 		{
1776 		  io->do_tbe = YES;
1777 		  io->do_boot = NO;
1778 		  break;
1779 		}
1780 	      case 'N' : case 'n' :
1781 		{
1782 		  io->do_tbe = NO;
1783 		  io->do_boot = YES;
1784 		  break;
1785 		}
1786 	      }
1787 	    Free(r);
1788 	  }
1789 	break;
1790       }
1791     case 'A' :
1792       {
1793         io->do_boot = NO;
1794         io->do_tbe  = NO;
1795         io->do_alrt = YES;
1796 
1797 	io->n_boot_replicates = 0;
1798 
1799 	switch(io->ratio_test)
1800 	  {
1801 	  case 0 :
1802 	    {
1803 	      io->ratio_test = 1;
1804 	      break;
1805 	    }
1806 	  case 1 :
1807 	    {
1808 	      io->ratio_test = 2;
1809 	      break;
1810 	    }
1811 	  case 2 :
1812 	    {
1813 /* 	      io->ratio_test = 3; */
1814 	      io->ratio_test = 4;
1815 	      break;
1816 	    }
1817 	  case 3 :
1818 	    {
1819 	      io->ratio_test = 4;
1820 	      break;
1821 	    }
1822 	  case 4 :
1823 	    {
1824 	      io->ratio_test = 5;
1825 	      break;
1826 	    }
1827 	  case 5 :
1828 	    {
1829 	      io->ratio_test = 0;
1830 	      break;
1831 	    }
1832 	  }
1833 	break;
1834       }
1835 
1836     case '-' :
1837       {
1838 	io->curr_interface = INTERFACE_TOPO_SEARCH;
1839 	break;
1840       }
1841     case '+' :
1842       {
1843 	io->curr_interface = INTERFACE_DATA_TYPE;
1844 	break;
1845       }
1846     case 'Y' :
1847       {
1848  	io->ready_to_go = 1;
1849 	break;
1850       }
1851     default : break;
1852     }
1853 }
1854 
1855 //////////////////////////////////////////////////////////////
1856 //////////////////////////////////////////////////////////////
1857 
Launch_Interface_Multigene(option * io)1858 void Launch_Interface_Multigene(option *io)
1859 {
1860 
1861 #ifdef PART
1862 
1863   if((io->n_data_sets > 1) && (io->multigene))
1864     {
1865       int set, n_trial;
1866       char choix;
1867 
1868       io->n_part     = io->n_data_sets;
1869       io->st       = (supert_tree *)PART_Make_Supert_tree_Light(io);
1870       io->st->n_part = io->n_data_sets;
1871 
1872       for(set=0;set<io->n_part;set++)
1873 	{
1874 	  io->st->optionlist[set] = Make_Input();
1875 	  Set_Defaults_Input(io->st->optionlist[set]);
1876 	  Set_Defaults_Model(io->st->optionlist[set]->mod);
1877 	  Set_Defaults_Optimiz(io->st->optionlist[set]->mod->s_opt);
1878 	  io->st->optionlist[set]->curr_gt = set;
1879 	  PhyML_Printf("\n. Enter the sequence file name [data set %2d] > ",set+1); fflush(NULL);
1880 	  Getstring_Stdin(io->st->optionlist[set]->in_align_file);
1881 	  io->st->optionlist[set]->fp_in_align = Openfile(io->st->optionlist[set]->in_align_file,0);
1882 	}
1883 
1884 
1885       PhyML_Printf("\n. Do you want to use your own initial tree ? [N/y] ");
1886       if(!scanf("%c", &choix)) Exit("\n");
1887       if(choix != '\n') getchar();
1888 
1889       n_trial = 0;
1890       while((choix != 'Y') && (choix != 'y') &&
1891 	    (choix != 'N') && (choix != 'n'))
1892 	{
1893 	  if(++n_trial > 10) Exit("\n== Err : wrong answers !");
1894 	  PhyML_Printf("\n. Do you want to use your own initial tree ? [N/y] ? ");
1895 	  if(!scanf("%c", &choix)) Exit("\n");
1896 	  if(choix == '\n') choix = 'N';
1897 	  else getchar();
1898 	}
1899 
1900       switch(choix)
1901 	{
1902 	case '\n' : break;
1903 	case 'Y' : case 'y' :
1904 	  {
1905 	    io->in_tree = 2;
1906 	    PhyML_Printf("\n. Enter the name of the tree file > ");
1907 	    Getstring_Stdin(io->in_tree_file);
1908 	    io->fp_in_tree = Openfile(io->in_tree_file,0);
1909 	    break;
1910 	  }
1911 	case 'N' : case 'n' :
1912 	  {
1913 	    io->in_tree = 0;
1914 	    break;
1915 	  }
1916 	default : break;
1917 	}
1918 
1919       io->curr_gt = 0;
1920 
1921       do
1922 	{
1923 	  io->st->optionlist[io->curr_gt]->config_multigene = 1;
1924 	  do
1925 	    {
1926 	      switch(io->st->optionlist[io->curr_gt]->curr_interface)
1927 		{
1928 		case INTERFACE_DATA_TYPE :
1929 		  {
1930 		    Launch_Interface_Data_Type(io->st->optionlist[io->curr_gt]);
1931 		    break;
1932 		  }
1933 		case INTERFACE_MODEL :
1934 		  {
1935 		    Launch_Interface_Model(io->st->optionlist[io->curr_gt]);
1936 		    break;
1937 		  }
1938 		default :
1939 		  {
1940 		    PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__);
1941 		    Exit("");
1942 		    break;
1943 		  }
1944 		}
1945 	    }while(!io->st->optionlist[io->curr_gt]->ready_to_go);
1946 	  io->curr_gt++;
1947 	}while(io->curr_gt < io->n_part);
1948     }
1949   io->ready_to_go = 1;
1950   PART_Fill_Model_Partitions_Table(io->st);
1951 #endif
1952 }
1953