/* * MrBayes 3.1.2 * * copyright 2002-2005 * * John P. Huelsenbeck * Section of Ecology, Behavior and Evolution * Division of Biological Sciences * University of California, San Diego * La Jolla, CA 92093-0116 * * johnh@biomail.ucsd.edu * * Fredrik Ronquist * School of Computational Science * Florida State University * Tallahassee, FL 32306-4120 * * ronquist@csit.fsu.edu * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details (www.gnu.org). * */ #include #include #include #include #include #include #include "mb.h" #include "globals.h" #include "bayes.h" #include "command.h" #include "mcmc.h" #ifdef USE_READLINE #include #include static char **readline_completion(const char *, int, int); #endif #if defined (__MWERKS__) # if defined (MAC_VERSION) # include "SIOUX.h" /* My codewarior version doesn't has this file, but compiles fine without Paul # include "fonts.h" */ # elif defined (WIN_VERSION) # include # include # include # endif #endif #if defined (WIN_VERSION) # undef NO_ERROR # undef ERROR # include # include # undef NO_ERROR # undef ERROR # define NO_ERROR 0 # define ERROR 1 #endif /* local prototypes */ int CommandLine (int argc, char **argv); void PrintHeader (void); /* global variables, declared in this file */ int defTaxa; /* flag for whether number of taxa is known */ int defChars; /* flag for whether number of characters is known*/ int defMatrix; /* flag for whether matrix is successfull read */ int defPartition; /* flag for whether character partition is read */ int defConstraints; /* flag for whether constraints on tree are read */ int defPairs; /* flag for whether pairs are read */ Doublet doublet[16]; /* holds information on states for doublets */ int fileNameChanged; /* has file name been changed ? */ long int globalSeed; /* seed that is initialized at start up */ int nBitsInALong; /* number of bits in a long */ int readWord; /* should we read word next ? */ long int runIDSeed; /* seed used only for determining run ID [stamp] */ long int swapSeed; /* seed used only for determining which to swap */ int userLevel; /* user level */ # if defined (MPI_ENABLED) int proc_id; /* process ID (0, 1, ..., num_procs-1) */ int num_procs; /* number of active processors */ MrBFlt myStateInfo[4]; /* likelihood/prior/heat vals of me */ MrBFlt partnerStateInfo[4]; /* likelihood/prior/heat vals of partner */ # endif int main (int argc, char *argv[]) { int i; # if defined (MPI_ENABLED) int ierror; # endif # if defined (WIN_VERSION) HANDLE scbh; BOOL ok; DWORD lastError; COORD largestWindow; CONSOLE_SCREEN_BUFFER_INFO csbi; int currBottom; char poltmp[256]; scbh = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(scbh, &csbi); currBottom = csbi.srWindow.Bottom; largestWindow = GetLargestConsoleWindowSize(scbh); /* Allow for screen buffer 3000 lines long and 140 characters wide */ csbi.dwSize.Y = 3000; csbi.dwSize.X = 140; SetConsoleScreenBufferSize(scbh, csbi.dwSize); /* Allow for maximum possible screen height */ csbi.srWindow.Left = 0; /* no change relative to current value */ csbi.srWindow.Top = 0; /* no change relative to current value */ csbi.srWindow.Right = 0; /* no change relative to current value */ csbi.srWindow.Bottom = largestWindow.Y - currBottom -10; /**/ ok = SetConsoleWindowInfo(scbh, FALSE, &csbi.srWindow); if (ok == FALSE) { lastError = GetLastError(); GetConsoleScreenBufferInfo(scbh, &csbi); sprintf(poltmp, "\nlastError = %d", lastError); printf(poltmp); } # endif /*mtrace();*/ /* calculate the size of a long - used by bit manipulation functions */ nBitsInALong = sizeof(long) * 8; if (nBitsInALong > 32) /* Do not use more than 32 bits until we */ nBitsInALong = 32; /* understand how 64-bit longs are handled. */ # if defined (__MWERKS__) & defined (MAC_VERSION) /* Set up interface when using the Metrowerks compiler. This should work for either Macintosh or Windows. */ SIOUXSetTitle("\pMrBayes v3.1.2"); SIOUXSettings.fontface = 0; /* plain=0; bold=1 */ SIOUXSettings.setupmenus = 0; SIOUXSettings.autocloseonquit = 1; SIOUXSettings.asktosaveonclose = 0; SIOUXSettings.rows = 60; SIOUXSettings.columns = 90; # endif # if defined (MPI_ENABLED) # if defined (MAC_VERSION) printf (" Parallel version of\n\n"); # else MrBayesPrint (" Parallel version of\n\n"); # endif ierror = MPI_Init(&argc, &argv); if (ierror != MPI_SUCCESS) { MrBayesPrint ("%s Problem initializing MPI\n", spacer); exit (1); } ierror = MPI_Comm_size(MPI_COMM_WORLD, &num_procs); if (ierror != MPI_SUCCESS) { MrBayesPrint ("%s Problem getting the number of processors\n", spacer); exit (1); } ierror = MPI_Comm_rank(MPI_COMM_WORLD, &proc_id); if (ierror != MPI_SUCCESS) { MrBayesPrint ("%s Problem getting processors rank\n", spacer); exit (1); } # endif #ifdef USE_READLINE rl_attempted_completion_function = readline_completion; #endif /* Set up parameter table. */ SetUpParms (); /* initialize seed using current time */ GetTimeSeed (); /* Initialize the variables of the program. */ InitializeMrBayes (); /* Print the nifty header. */ PrintHeader (); /* Go to the command line, process any arguments passed to the program and then wait for input. */ i = CommandLine (argc, argv); # if defined (MPI_ENABLED) MPI_Finalize(); # endif if (i == ERROR) return (1); else return (0); } int CommandLine (int argc, char **argv) { int i, message, nProcessedArgs; char cmdStr[CMD_STRING_LENGTH]; #ifdef USE_READLINE char *cmdStrP; #endif # if defined (MPI_ENABLED) int ierror; # endif for(i=0;i' (i is for interactive)\n", spacer); MrBayesPrint ("%s or use 'set mode=interactive'\n\n", spacer); return (NO_ERROR); } /* normally, we simply wait at the prompt for a user action */ # if defined (MPI_ENABLED) if (proc_id == 0) { #ifdef USE_READLINE cmdStrP = readline("MrBayes > "); if(cmdStrP!=NULL) { strncpy(cmdStr,cmdStrP,CMD_STRING_LENGTH - 2); if (*cmdStrP) add_history(cmdStrP); free (cmdStrP); } else /* fall through to if (feof(stdin))..*/ #else MrBayesPrint ("MrBayes > "); fflush (stdin); if (fgets (cmdStr, CMD_STRING_LENGTH - 2, stdin) == NULL) #endif { if (feof(stdin)) MrBayesPrint ("%s End of File encountered on stdin; quitting\n", spacer); else MrBayesPrint ("%s Could not read command from stdin; quitting\n", spacer); strcpy (cmdStr,"quit;\n"); } } ierror = MPI_Bcast (&cmdStr, CMD_STRING_LENGTH, MPI_CHAR, 0, MPI_COMM_WORLD); if (ierror != MPI_SUCCESS) { MrBayesPrint ("%s Problem broadcasting command string\n", spacer); } # else #ifdef USE_READLINE cmdStrP = readline("MrBayes > "); if(cmdStrP!=NULL) { strncpy(cmdStr,cmdStrP,CMD_STRING_LENGTH - 2); if (*cmdStrP) add_history(cmdStrP); free (cmdStrP); } else /* fall through to if (feof(stdin))..*/ #else MrBayesPrint ("MrBayes > "); fflush (stdin); if (fgets (cmdStr, CMD_STRING_LENGTH - 2, stdin) == NULL) #endif { if (feof(stdin)) MrBayesPrint ("%s End of File encountered on stdin; quitting\n", spacer); else MrBayesPrint ("%s Could not read command from stdin; quitting\n", spacer); strcpy (cmdStr,"quit;\n"); } # endif } i = 0; while (cmdStr[i] != '\0' && cmdStr[i] != '\n') i++; cmdStr[i++] = ';'; cmdStr[i] = '\0'; MrBayesPrint ("\n"); if (cmdStr[0] != ';') { /* check that all characters in the string are valid */ if (CheckStringValidity (cmdStr) == ERROR) { MrBayesPrint (" Unknown character in command string\n\n"); } else { expecting = Expecting(COMMAND); message = ParseCommand (cmdStr); if (message == NO_ERROR_QUIT) return (NO_ERROR); if (message == ERROR && quitOnError == YES) { MrBayesPrint ("%s Will exit with signal 1 (error) because quitonerror is set to yes\n", spacer); MrBayesPrint ("%s If you want control to be returned to the command line on error,\n", spacer); MrBayesPrint ("%s use 'mb -i ' (i is for interactive) or use 'set quitonerror=no'\n\n", spacer); return (ERROR); } # if defined (MPI_ENABLED) ierror = MPI_Barrier (MPI_COMM_WORLD); if (ierror != MPI_SUCCESS) { MrBayesPrint ("%s Problem at command barrier\n", spacer); } # endif MrBayesPrint ("\n"); } } } } #ifdef USE_READLINE extern char *command_generator(const char *text, int state); char **readline_completion(const char *text, int start, int stop) { char **matches = (char **) NULL; if(start == 0) matches = rl_completion_matches (text, command_generator); return (matches); } #endif void GetTimeSeed (void) { time_t curTime; # if defined (MPI_ENABLED) int ierror; if (proc_id == 0) { curTime = time(NULL); globalSeed = (long int)curTime; if (globalSeed < 0) globalSeed = -globalSeed; } ierror = MPI_Bcast(&globalSeed, 1, MPI_LONG, 0, MPI_COMM_WORLD); if (ierror != MPI_SUCCESS) { MrBayesPrint ("%s Problem broadcasting seed\n", spacer); } if (proc_id == 0) { curTime = time(NULL); swapSeed = (long int)curTime; if (swapSeed < 0) swapSeed = -swapSeed; } MPI_Bcast(&swapSeed, 1, MPI_LONG, 0, MPI_COMM_WORLD); if (ierror != MPI_SUCCESS) { MrBayesPrint ("%s Problem broadcasting swap seed\n", spacer); } if (proc_id == 0) { curTime = time(NULL); runIDSeed = (long int)curTime; if (runIDSeed < 0) runIDSeed = -runIDSeed; } ierror = MPI_Bcast(&runIDSeed, 1, MPI_LONG, 0, MPI_COMM_WORLD); if (ierror != MPI_SUCCESS) { MrBayesPrint ("%s Problem broadcasting run ID seed\n", spacer); } # else curTime = time(NULL); globalSeed = (long int)curTime; if (globalSeed < 0) globalSeed = -globalSeed; curTime = time(NULL); swapSeed = (long int)curTime; if (swapSeed < 0) swapSeed = -swapSeed; curTime = time(NULL); runIDSeed = (long int)curTime; if (runIDSeed < 0) runIDSeed = -globalSeed; # endif } void InitializeMrBayes (void) { /* this function initializes the program; only call it at the start of execution */ int i; userLevel = STANDARD_USER; /* default user level */ readWord = NO; /* should we read a word next ? */ fileNameChanged = NO; /* has the file name been changed ? */ echoMB = YES; /* flag used by Manual to control printing */ longIntegerSize = sizeof(long int); /* size of an long integer */ # if defined (MPI_ENABLED) sprintf(manFileName, "commref_mb%sp.txt", VERSION_NUMBER); /* name of command reference file */ # else sprintf(manFileName, "commref_mb%s.txt", VERSION_NUMBER); /* name of command reference file */ # endif for (i=0; i\" for information\n"); printf (" on the commands that are available.\n\n\n"); } else { printf (" Remote node number %d\n\n", proc_id + 1); printf (" All information is printed to node 1\n\n\n"); } # else printf (" Type \"help\" or \"help \" for information\n"); printf (" on the commands that are available.\n\n\n"); # endif # else # if !defined (MPI_ENABLED) MrBayesPrint ("\n\n"); # endif MrBayesPrint (" MrBayes v%s\n\n", VERSION_NUMBER); MrBayesPrint (" (Bayesian Analysis of Phylogeny)\n\n"); # if defined (MPI_ENABLED) MrBayesPrint (" (Parallel version)\n"); MrBayesPrint (" (%d processors available)\n\n", num_procs); # endif srand((unsigned int) time (NULL)); if (rand() % 2) { MrBayesPrint (" by\n\n"); MrBayesPrint (" John P. Huelsenbeck and Fredrik Ronquist\n\n"); MrBayesPrint (" Section of Ecology, Behavior and Evolution\n"); MrBayesPrint (" Division of Biological Sciences\n"); MrBayesPrint (" University of California, San Diego\n"); MrBayesPrint (" johnh@biomail.ucsd.edu\n\n"); MrBayesPrint (" School of Computational Science\n"); MrBayesPrint (" Florida State University\n"); MrBayesPrint (" ronquist@csit.fsu.edu \n\n"); } else { MrBayesPrint (" by\n\n"); MrBayesPrint (" Fredrik Ronquist and John P. Huelsenbeck\n\n"); MrBayesPrint (" School of Computational Science\n"); MrBayesPrint (" Florida State University\n"); MrBayesPrint (" ronquist@csit.fsu.edu \n\n"); MrBayesPrint (" Section of Ecology, Behavior and Evolution\n"); MrBayesPrint (" Division of Biological Sciences\n"); MrBayesPrint (" University of California, San Diego\n"); MrBayesPrint (" johnh@biomail.ucsd.edu\n\n"); } MrBayesPrint (" Distributed under the GNU General Public License\n\n"); MrBayesPrint (" Type \"help\" or \"help \" for information\n"); MrBayesPrint (" on the commands that are available.\n\n\n"); # endif } int ReinitializeMrBayes (void) { /* this function resets everything dependent on a matrix */ int i; /* reset all matrix flags */ defTaxa = NO; /* flag for whether number of taxa is known */ defChars = NO; /* flag for whether number of characters is known*/ defMatrix = NO; /* flag for whether matrix is successfull read */ matrixHasPoly = NO; /* flag for whether matrix has polymorphisms */ isInAmbig = NO; /* flag for whether the parser is within () */ isInPoly = NO; /* flag for whether the parser is within {} */ defPartition = NO; /* flag for whether character partition is read */ defConstraints = NO; /* flag for whether constraints on tree are read */ defPairs = NO; /* flag indicating whether pairs have been defnd */ numDefinedPartitions = 0; /* number of defined partitions */ partitionNum = 1; /* partition number currently enforced */ numCurrentDivisions = 0; /* number of partitions of data */ numCharSets = 0; /* holds number of character sets */ numPartitions = 1; /* holds number of partitions */ numDefinedConstraints= 0; /* holds number of defined constraints */ isTranslateDef = NO; /* is translate block defined? */ outGroupNum = 0; /* default outgroup */ isMixed = NO; /* are data mixed ? */ isUserTreeDefined = NO; /* is user tree defined? */ dataType = NONE; /* holds datatype */ matchId = gapId = missingId = 'z'; if (InitializeLinks () == ERROR) { MrBayesPrint ("%s Problem initializing link table\n", spacer); return (ERROR); } SetModelDefaults (); strcpy (spacer, ""); /* holds blanks for indentation */ /* chain parameters */ chainParams.numGen = 1000000; /* number of MCMC cycles */ chainParams.sampleFreq = 100; /* frequency to sample chain */ chainParams.printFreq = 100; /* frequency to print chain */ chainParams.swapFreq = 1; /* frequency of attempting swap of states */ chainParams.numSwaps = 1; /* number of swaps to try each time */ chainParams.mcmcDiagn = YES; /* write MCMC diagnostics to file ? */ chainParams.diagnFreq = 1000; /* diagnostics frequency */ chainParams.minPartFreq = 0.10; /* min partition frequency for diagnostics */ chainParams.allChains = NO; /* calculate diagnostics for all chains ? */ chainParams.allComps = NO; /* do not calc diagn for all run comparisons */ chainParams.relativeBurnin = YES; /* use relative burnin? */ chainParams.burninFraction = 0.25; /* default burnin fraction */ chainParams.stopRule = NO; /* should stopping rule be used? */ chainParams.stopVal = 0.01; /* convergence diagnostic value to reach */ chainParams.numRuns = 2; /* number of runs */ chainParams.numChains = 4; /* number of chains */ chainParams.chainTemp = 0.2; /* chain temperature */ chainParams.redirect = NO; /* should printf be to stdout */ strcpy(chainParams.chainFileName, "temp.out"); /* chain file name for output */ chainParams.chainBurnIn = 0; /* chain burn in length */ chainParams.numStartPerts = 0; /* number of perturbations to starting tree */ strcpy(chainParams.chainStartTree, "Random"); /* starting tree for chain (random/user) */ chainParams.saveBrlens = YES; /* should branch lengths be saved */ chainParams.chainSeed = globalSeed; /* random seed for chain */ chainParams.weightScheme[0] = 0.0; /* percent chars to decrease in weight */ chainParams.weightScheme[1] = 0.0; /* percent chars to increase in weight */ chainParams.weightScheme[2] = 1.0; /* weight increment */ chainParams.calcPbf = NO; /* should we calculate the pseudo-BF? */ chainParams.pbfInitBurnin = 100000; /* initial burnin for pseudo BF */ chainParams.pbfSampleFreq = 10; /* sample frequency for pseudo BF */ chainParams.pbfSampleTime = 2000; /* how many cycles to calcualate site prob. */ chainParams.pbfSampleBurnin = 2000; /* burnin period for each site for pseudo BF */ chainParams.userDefinedTemps = NO; /* should we use the users temperatures? */ for (i=0; i Trp AUA: Ile -> Met AGA: Arg -> Ter AGG: Arg -> Ter */ modelParams[part].codon[ 8] = 21; /* AGA Stop */ modelParams[part].codon[10] = 21; /* AGG Stop */ modelParams[part].codon[12] = 13; /* ATA Met */ modelParams[part].codon[56] = 18; /* TGA Trp */ } else if (!strcmp(modelParams[part].geneticCode, "Mycoplasma")) { /* UGA: Ter -> Trp */ modelParams[part].codon[56] = 18; /* TGA Trp */ } else if (!strcmp(modelParams[part].geneticCode, "Yeast")) { /* UGA: Ter -> Trp AUA: Ile -> Met CUA: Leu -> Thr CUC: Leu -> Thr CUG: Leu -> Thr CUU: Leu -> Thr */ modelParams[part].codon[12] = 13; /* ATA Met */ modelParams[part].codon[28] = 17; /* CTA Thr */ modelParams[part].codon[29] = 17; /* CTC Thr */ modelParams[part].codon[30] = 17; /* CTG Thr */ modelParams[part].codon[31] = 17; /* CTT Thr */ modelParams[part].codon[56] = 18; /* TGA Trp */ } else if (!strcmp(modelParams[part].geneticCode, "Ciliates")) { /* UAA: Ter -> Gln UAG: Ter -> Gln */ modelParams[part].codon[48] = 6; /* TAA Gln */ modelParams[part].codon[50] = 6; /* TAG Gln */ } else if (!strcmp(modelParams[part].geneticCode, "Metmt")) { /* UGA: Ter -> Trp AUA: Ile -> Met AGA: Arg -> Ser AGG: Arg -> Ser */ modelParams[part].codon[ 8] = 16; /* AGA Ser */ modelParams[part].codon[10] = 16; /* AGG Ser */ modelParams[part].codon[12] = 13; /* ATA Met */ modelParams[part].codon[56] = 18; /* TGA Trp */ } else { } ns = 0; for (i=0; i<64; i++) { if (modelParams[part].codon[i] != 21) ns++; } /* printf ("ns = %d\n", ns); */ s = 0; for (s1=0; s1<4; s1++) { for (s2=0; s2<4; s2++) { for (s3=0; s3<4; s3++) { if (modelParams[part].codon[s1*16 + s2*4 + s3] != 21) { modelParams[part].codonNucs[s][0] = s1; modelParams[part].codonNucs[s][1] = s2; modelParams[part].codonNucs[s][2] = s3; modelParams[part].codonAAs[s] = modelParams[part].codon[s1*16 + s2*4 + s3]; s++; } } } } } void MrBayesPrint (char *format, ...) { va_list ptr; # if defined (MPI_ENABLED) if (proc_id == 0) { if (echoMB == YES) { va_start (ptr, format); vprintf (format, ptr); va_end(ptr); fflush (stdout); } if (logToFile == YES) { if (logFileFp == NULL) printf ("%s Could not print log output to file\n", spacer); else { va_start (ptr, format); vfprintf (logFileFp, format, ptr); va_end(ptr); fflush (logFileFp); } } } # else if (chainParams.redirect == NO) { if (echoMB == YES) { va_start (ptr, format); vprintf (format, ptr); va_end(ptr); fflush (stdout); } if (logToFile == YES) { if (logFileFp == NULL) { printf ("%s Could not print log output to file\n", spacer); logToFile = NO; } else { va_start (ptr, format); vfprintf (logFileFp, format, ptr); va_end(ptr); fflush (logFileFp); } } } # endif } void MrBayesPrintf (FILE *f, char *format, ...) { va_list ptr; # if defined (MPI_ENABLED) if (proc_id == 0) { va_start (ptr, format); vfprintf (f, format, ptr); va_end(ptr); fflush(f); } # else va_start (ptr, format); vfprintf (f, format, ptr); va_end(ptr); fflush(f); # endif }