/** * @method HandleCharset [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * Reads and stores information contained in the command * CHARSET within an ASSUMPTIONS block. */ void AssumptionsBlock::HandleCharset( NexusToken& token ) { bool asterisked = false; // Next token should be either an asterisk or the name of a charset token.GetNextToken(); if( token.Equals("*") ) { asterisked = true; token.GetNextToken(); } // Token now stored should be the name of a charset nxsstring charset_name = token.GetToken(); // Now grab the equals sign token.GetNextToken(); if( !token.Equals("=") ) { errormsg = "Expecting '=' in CHARSET definition but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } assert( charBlockPtr != NULL ); CharactersBlock& charBlock = *charBlockPtr; IntSet s; int totalChars = charBlock.GetNCharTotal(); SetReader( token, totalChars, s, charBlock, SetReader::charset ).Run(); charsets[charset_name] = s; if( asterisked ) def_charset = charset_name; }
/** * @method HandleTaxset [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * ? */ void AssumptionsBlock::HandleTaxset( NexusToken& token ) { bool asterisked = false; // Next token should be either an asterisk or the name of a taxset token.GetNextToken(); if( token.Equals("*") ) { asterisked = true; token.GetNextToken(); } // Token now stored should be the name of a taxset nxsstring taxset_name = token.GetToken(); // Now grab the equals sign token.GetNextToken(); if( !token.Equals("=") ) { errormsg = "Expecting '=' in TAXSET definition but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } IntSet s; int totalTaxa = taxa.GetNumTaxonLabels(); SetReader( token, totalTaxa, s, *this, SetReader::taxset ).Run(); taxsets[taxset_name] = s; if( asterisked ) def_taxset = taxset_name; }
/** * @method HandleExecute [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XBull * * Handles everything after the EXecute keyword and the terminating * semicolon. Flushes all blocks before executing file specified, * and no warning is given of this */ void BullShell::HandleExecute( NexusToken& token ) { token.GetNextToken(); std::string fn = token.GetToken(); token.GetNextToken(); RequireSemicolon(token, "EXECUTE"); cout << "\nExecuting " << fn << "..." << endl; readFile(fn, false); cout << "Done with file "<<fn<<endl; }
EncodingType BullShell::InterpretOutputType(NexusToken &token) const { if (token.Abbreviation("PROtein") || token.Abbreviation("AMino")) return EncodingType(AminoAcid); if (token.Abbreviation("Dna")) return EncodingType(DNANoGap); errormsg.clear(); errormsg << "The output type " << token.GetToken() << " is invalid"; throw XBull(errormsg, token); }
void BullShell::ThrowNoSemicolon(NexusToken & token, const char *cmd) const { errormsg = "Expecting ';'"; if (cmd != NULL) { errormsg += " to terminate the "; errormsg.append(cmd); errormsg += "command,"; } errormsg += " but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XBull(errormsg, token); }
void MyCharactersBlock::handleContMatrix (NexusToken& token) //: read in a matrix of continuous data and store it { std::vector<double> theRow; for(;;) { // grab the first token in the row string theTokenVal; token.GetNextToken(); theTokenVal = (token.GetToken()).c_str(); // if reached the end of the matrix, break loop if (token.Equals (";")) break; // otherwise store the name, read and store the data mTaxaNames.push_back (theTokenVal); theRow.clear(); for (int i = 0; i < nchar; i++) { token.GetNextToken(); theTokenVal = (token.GetToken()).c_str(); theRow.push_back (sbl::toDouble (theTokenVal)); } // store the row in the matrix mContData.appendRow (theRow); } assert (mTaxaNames.size() == mContData.size()); for (sbl::ulong i = 1; i < mContData.size(); i++) assert (mContData[1].size() == mContData[i].size()); // store names in continuous data matrix for (unsigned int i = 0; i < mTaxaNames.size(); i++) mContData.setRowName (i, mTaxaNames[i].c_str()); }
void ReadNexusVector(std::vector<std::string> *v, NexusToken &token) { // TAH changed from above if (token.Equals("(")) { token.GetNextToken(); while (!token.Equals(")")) { v->push_back(token.GetToken()); token.GetNextToken(); } } else v->push_back(token.GetToken()); }
/** * @method HandleEndblock [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * Called when the END or ENDBLOCK command needs to be parsed * from within the ASSUMPTIONS block. Basically just checks to make * sure the next token in the data file is a semicolon. */ void AssumptionsBlock::HandleEndblock( NexusToken& token ) { // get the semicolon following END or ENDBLOCK token // token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate the END or ENDBLOCK command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } }
/** * @method HandleNextPass [int:protected] * @param token [NexusToken&] the token we are using for reading the data file * @param offset [int&] the offset (see below) * * Called from within HandleMatrix, this function is used to deal with interleaved * matrices. It is called once for each pass through the taxa. * * <P>The local variable jmax records the number of columns read in the current * interleaved page and is used to determine the offset used for j in subsequent * pages. */ int DistancesBlock::HandleNextPass( NexusToken& token, int& offset ) { int i, j, k, jmax = 0, done = 0; int i_first = 0; if( triangle == lower ) i_first = offset; int i_last = ntax; for( i = i_first; i < i_last; i++ ) { // Deal with taxon label if provided // if( labels && ( !newtaxa || offset>0 ) ) { do { token.SetLabileFlagBit( NexusToken::newlineIsToken ); token.GetNextToken(); } while( token.AtEOL() ); try { k = taxa.FindTaxon( token.GetToken() ); if( taxonPos[i]==-1 ) taxonPos[i] = k; else if( taxonPos[i] != k ) { errormsg = "Taxon labeled "; errormsg += token.GetToken(); errormsg += " is out of order compared to previous interleave pages"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } catch (std::out_of_range) { errormsg = "Could not find "; errormsg += token.GetToken(); errormsg += " among taxa previously defined"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } else if( labels && newtaxa ) { do { token.SetLabileFlagBit( NexusToken::newlineIsToken ); token.GetNextToken(); } while( token.AtEOL() ); taxa.AddTaxonLabel( token.GetToken() ); taxonPos[i] = i; } // Now deal with the row of distance values // int true_j = 0; for( j = 0; j < ntax; j++ ) { if( i == ntax-1 && j == ntax-1 ) { done = 1; } if( i == ntax-1 && true_j == ntax-1 ) { done = 1; break; } if( i == ntax-1 && !diagonal && triangle==upper ) { done = 1; break; } if( !diagonal && triangle==lower && j == ntax-offset-1) { done = 1; break; } token.SetLabileFlagBit( NexusToken::newlineIsToken ); token.GetNextToken(); if( token.AtEOL() ) { if( j > jmax ) { jmax = j; if( !diagonal && triangle == upper && i >= offset ) jmax++; if( interleave && triangle == upper ) i_last = jmax + offset; } break; } true_j = j+offset; if( triangle==upper && i > offset ) true_j += ( i - offset ); if( !diagonal && triangle==upper && i >= offset ) true_j++; if( true_j == ntax ) { errormsg = "Too many distances specified in row just read in"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } std::string t = token.GetToken(); if( token.GetTokenLength() == 1 && t[0] == missing ) SetMissing( i, true_j ); else SetDistance( i, true_j, atof( t.c_str() ) ); } } offset += jmax; if( done ) return 1; else return 0; }
SimulateOpts BullShell::ParseSimulateCommand(NexusToken& token ) const { token.GetNextToken(); int nOutputs = 0; int nSimChars = 0; SimulateOpts simOpts; const unsigned nTrees = kernel.getNumTrees(); for (; token.GetToken() != ";"; token.GetNextToken()) { if (token.Abbreviation("NReps")) { DemandEquals(token, "after NReps subcommand of Simulate command"); simOpts.nReps = DemandPositiveInt(token, "after NReps subcommand of Simulate command"); } if (token.Abbreviation("Seed")) { DemandEquals(token, "after Seed subcommand of Simulate command"); simOpts.seed = DemandPositiveInt(token, "after Seed subcommand of Simulate command"); } else if (token.Abbreviation("COLLapsefile")) { DemandEquals(token, "after CollapseFile subcommand of Simulate command"); token.GetNextToken(); simOpts.collapsedTreeFilename = token.GetTokenReference(); } else if (token.Abbreviation("NChars")) { DemandEquals(token, "after NChars subcommand of Simulate command"); simOpts.nSimChars = DemandPositiveInt(token, "after NChars subcommand of Simulate command"); } else if (token.Abbreviation("Concat")) { DemandEquals(token, "after Concat subcommand of GetTrees command"); simOpts.concatenations = DemandPositiveInt(token, "after Concat subcommand of GetTrees command"); } else if (token.Abbreviation("Verbose")) { simOpts.verbose = true; } else if (token.Abbreviation("NOUTput")) { DemandEquals(token, "after NOutput subcommand of Simulate command"); nOutputs = DemandPositiveInt(token, "after NOutput subcommand of Simulate command"); if (nOutputs < 1) { errormsg="nOutputs must be > 0"; throw XBull( errormsg, token); } } else if (token.Abbreviation("Paupblockfile")) { DemandEquals(token, "after Paupblockfile subcommand of Simulate"); token.GetNextToken(); ReadNexusVector(&(simOpts.paupBlockFilename), token); } else if (token.Abbreviation("OVERWrite")) simOpts.overwrite = true; else if (token.Abbreviation("File")) { DemandEquals(token, "after File subcommand of Simulate"); token.GetNextToken(); ReadNexusVector(&(simOpts.outputFilenames), token); } else if (token.Abbreviation("TAg")) { DemandEquals(token, "after Tag subcommand of Simulate command"); token.GetNextToken(); simOpts.tagname = token.GetTokenReference(); } else if (token.Abbreviation("AUTOmatic")) simOpts.automatic = true; else if (token.Abbreviation("OUTputtypes")) { DemandEquals(token, "after OutputTypes subcommand of Simulate"); token.GetNextToken(); EncodingType et; if (token.Equals("(")) { token.GetNextToken(); while (!token.Equals(")")) { et = InterpretOutputType(token); simOpts.outTypes.push_back(et); token.GetNextToken(); } } else { et = InterpretOutputType(token); simOpts.outTypes.push_back(et); } } else { Tree * temptree; long tn; if (NxsString::to_long(token.GetTokenAsCStr(), &tn)) { if ((unsigned) tn > nTrees || tn < 1) { errormsg = "Tree "; errormsg += token.GetToken(); errormsg += " unknown. simulation aborted."; throw XBull( errormsg, token); } temptree = kernel.getTree(tn - 1); } else { try { temptree = kernel.FindTreeFromName(token.GetToken()); } catch (NoSuchTree) { errormsg << "Tree " << token.GetToken() << " unknown."; throw XBull( errormsg, token); } } simOpts.treeNames.push_back(token.GetToken()); //keeps track of what the user called the tree simOpts.treeAlias.push_back(temptree); } } if (simOpts.outTypes.size() == 0){ simOpts.outTypes.push_back(EncodingType(DNANoGap)); } if ((nOutputs > 0) && simOpts.outTypes.size() != (unsigned) nOutputs) { errormsg = "The number of OutputTypes in a Simulate command must match the number of specified in the NOutput option"; throw XBull( errormsg, token); } if (simOpts.automatic) { if (simOpts.tagname.empty()) { errormsg = "The Tag option of the Simulate command must be used if the Automatic naming mode is requested."; throw XBull( errormsg, token); } if (!simOpts.outputFilenames.empty()) { errormsg = "The FILE option of the Simulate command cannot be used if the Automatic naming mode is requested (use the Tag instead of file)."; throw XBull( errormsg, token); } simOpts.outputFilenames.clear(); std::vector<EncodingType>::const_iterator ot = simOpts.outTypes.begin(); for (; ot != simOpts.outTypes.end(); ot++) { string ofname = EncodingTypeToString(*ot); ofname.append(simOpts.tagname); simOpts.outputFilenames.push_back(ofname); } } else if (simOpts.outTypes.size() != simOpts.outputFilenames.size()) { errormsg = "The number of OutputTypes in a Simulate command must match the number of Files specified"; throw XBull( errormsg, token); } if ((!simOpts.paupBlockFilename.empty()) && simOpts.paupBlockFilename.size() != simOpts.outTypes.size()) { errormsg = "The number of PaupBlockFile in a Simulate command must match the number of OutputTypes specified"; throw XBull( errormsg, token); } //TEMPORARY lots of the interaction with SSettings assumes that you are using SSRFCodonSubModel if (!kernel.hasModel()) { errormsg="You can't simulate a codon model without first declaring the models using codLikeStartVal"; throw XBull( errormsg, token); } if ( simOpts.concatenations == 0) { if (nSimChars == 0) { errormsg="Either the number of characters or the number of concatenations must be specified"; throw XBull( errormsg, token); } const unsigned naa = kernel.getModelConstRef().getNumAASites(); const unsigned ndna = 3*naa; if (nSimChars % ndna) { errormsg="The number of characters must be a multiple of the number of amino acids"; throw XBull( errormsg, token); } simOpts.concatenations = ndna/nSimChars; } return simOpts; }
/** * @method HandleLog [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XBull * * Called when the LOG command needs to be parsed * from within the BullShell block. */ void BullShell::HandleLog( NexusToken& token ) { bool starting = false; bool stopping = false; bool appending = false; bool replacing = false; std::string logfname; errormsg.clear(); // Retrieve all tokens for this command, stopping only in the event // of a semicolon or an unrecognized keyword // for (token.GetNextToken(); !token.Equals(";"); token.GetNextToken()) { if ( token.Abbreviation("STOp") ) stopping = true; else if ( token.Abbreviation("STArt") ) starting = true; else if ( token.Abbreviation("Replace") ) replacing = true; else if ( token.Abbreviation("Append") ) appending = true; else if ( token.Abbreviation("File") ) { DemandEquals(token, "after file subcommand of Log command"); token.GetNextToken(); logfname = token.GetTokenReference(); } else { errormsg << "Unexpected keyword (" << token.GetToken() << ") encountered reading LOG command"; throw XBull( errormsg, token); } } // Check for incompatible combinations of keywords if ( stopping && ( starting || appending || replacing || !logfname.empty() ) ) { errormsg = "Cannot specify STOP with any of the following START, APPEND, REPLACE, FILE"; throw XBull( errormsg, token); } if ( appending && replacing ) { errormsg = "Cannot specify APPEND and REPLACE at the same time"; throw XBull( errormsg, token); } if ( stopping ) { ioObject.stopLogging(); kernel.logEachStep=false; return; } if (logfname.empty() ) { errormsg << "Must provide a file name when opening a log file\ne.g., log file=doofus.txt start replace;"; throw XBull(errormsg, token); } if (!appending && !replacing && FileExists(logfname.c_str())) { errormsg << "File " << logfname << " exists.\n APPEND or REPLACE must be specified in the LOG command."; throw XBull( errormsg, token); } ioObject.startLogging(logfname, appending); }
/** * @method HandleMatrixCommand [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * Called when MATRIX command needs to be parsed from within the * DISTANCES block. Deals with everything after the token MATRIX * up to and including the semicolon that terminates the MATRIX * command. */ void DistancesBlock::HandleMatrixCommand( NexusToken& token ) { int i; if( ntax == 0 ) ntax = taxa.GetNumTaxonLabels(); if( ntax == 0 ) { errormsg = "MATRIX command cannot be read if NTAX is zero"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } if( triangle == both && !diagonal ) { errormsg = "Cannot specify NODIAGONAL and TRIANGLE=BOTH at the same time"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } if( newtaxa ) taxa.Reset(); // allocate memory to hold the taxonPos array // if( taxonPos != NULL ) delete [] taxonPos; taxonPos = new int[ntax]; for( i = 0; i < ntax; i++ ) taxonPos[i] = -1; // allocate memory to hold the matrix // if( matrix != NULL ) delete matrix; matrix = new DistanceDatum*[ntax]; for( i = 0; i < ntax; i++ ) matrix[i] = new DistanceDatum[ntax]; int offset = 0; int done = 0; while( !done ) { done = HandleNextPass( token, offset ); } // token should be equal to the terminating semicolon token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate MATRIX command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } }
/** * @method HandleTaxlabelsCommand [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * Called when TAXLABELS command needs to be parsed from within the * DISTANCES block. Deals with everything after the token TAXLABELS * up to and including the semicolon that terminates the TAXLABELS * command. */ void DistancesBlock::HandleTaxlabelsCommand( NexusToken& token ) { if( !newtaxa ) { errormsg = "NEWTAXA must have been specified in DIMENSIONS command to use the TAXLABELS command in a "; errormsg += id; errormsg += " block"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } if( ntax == 0 ) { errormsg = "NTAX must be specified before TAXLABELS command"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } for( int i = 0; i < ntax; i++ ) { token.GetNextToken(); taxa.AddTaxonLabel( token.GetToken() ); } token.GetNextToken(); // this should be terminating semicolon if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate TAXLABELS command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } // OPEN ISSUE: Some may object to setting newtaxa to 0 here, because then the // fact that new taxa were specified in this DISTANCES block rather than in // a preceding TAXA block is lost. This will only be important if we wish to // recreate the original data file, which I don't anticipate anyone doing with // this code (too difficult to remember all comments, the order of blocks in // the file, etc.) newtaxa = 0; }
GetTreesOpts BullShell::ParseGetTrees(NexusToken& token ) const { errormsg.clear(); if (kernel.getNumTaxa() == 0) { errormsg="You can't get trees without an active set of taxa"; throw XBull( errormsg, token); } GetTreesOpts gto; bool readingMostRecent = false; gto.fromTree = -1; gto.toTree = -1; gto.mode = 7; std::string filePref; token.GetNextToken(); while (token.GetToken()!=";") { if (token.Abbreviation("STOREBrlens")) { token.GetNextToken(); gto.storeBrLensFromFile=true; if (token.GetToken() == "=") { token.GetNextToken(); if (token.Abbreviation("No")) gto.storeBrLensFromFile=false; else if (!token.Abbreviation("Yes")) { errormsg="Expecting YES or NO after CurrentBranchLengths = option to LSCORE command"; throw XBull(errormsg, token); } } } else if (token.Abbreviation("FRom")) { DemandEquals(token, "after From subcommand of GetTrees command"); gto.fromTree = DemandPositiveInt(token, "after From subcommand of GetTrees command"); if (gto.fromTree < 0) { errormsg="Expecting positive integer after FROM option of GETTREES"; throw XBull(errormsg, token); } } else if (token.Abbreviation("To")) { DemandEquals(token, "after To subcommand of GetTrees command"); gto.toTree = DemandPositiveInt(token, "after To subcommand of GetTrees command"); if (gto.toTree < 0) { errormsg="Expecting positive integer after TO option of GETTREES"; throw XBull(errormsg, token); } } else if (token.Abbreviation("REplace")) gto.mode=3; else if (token.Abbreviation("Mode")) { DemandEquals(token, "after Mode subcommand of GetTrees command"); gto.mode = DemandPositiveInt(token, "after Mode subcommand of GetTrees command"); if (gto.mode!=3 && gto.mode!=7) { errormsg="Right now bull only get trees with mode 3 or mode 7"; throw XBull(errormsg, token); } } else if (token.Abbreviation("FIle")) { DemandEquals(token, "after File subcommand of GetTrees command"); token.GetNextToken(); gto.filename = token.GetTokenReference(); } else if (token.Abbreviation("PREfix")) { token.GetNextToken(); if (token.GetToken() == "=") token.GetNextToken(); filePref = token.GetToken(); } else if (token.Abbreviation("MOStrecent")) readingMostRecent=true; else { errormsg = "Unrecognized subcommand ("; errormsg << token.GetTokenReference() << ") in GetTrees command."; throw XBull(errormsg, token); } token.GetNextToken(); } if (readingMostRecent) { int highNum = GetHighestFileNum(filePref); if (highNum < 0) { errormsg << "Couldn't open file " << filePref << "0"; throw XBull(errormsg, token); } gto.filename = filePref; gto.filename += highNum; } if (gto.fromTree > -1 && gto.toTree > gto.fromTree) { errormsg << "The FromTree setting (" << gto.fromTree << ") cannot be less than the ToTree setting (" << gto.toTree << ")"; throw XBull(errormsg, token); } gto.fromTree = (gto.fromTree < 1 ? -1 : gto.fromTree - 1); gto.toTree = (gto.toTree < 1 ? -1 : gto.toTree - 1); return gto; }
/** * @method Read [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * This function provides the ability to read everything following the block name * (which is read by the Nexus object) to the end or endblock statement. * Characters are read from the input stream in. Overrides the * abstract virtual function in the base class. */ void DistancesBlock::Read( NexusToken& token ) { isEmpty = false; token.GetNextToken(); // this should be the semicolon after the block name if( !token.Equals(";") ) { errormsg = "Expecting ';' after "; errormsg += id; errormsg += " block name, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } for(;;) { token.GetNextToken(); if( token.Equals("DIMENSIONS") ) { HandleDimensionsCommand( token ); } else if( token.Equals("FORMAT") ) { HandleFormatCommand( token ); } else if( token.Equals("TAXLABELS") ) { HandleTaxlabelsCommand( token ); } else if( token.Equals("MATRIX") ) { HandleMatrixCommand( token ); } else if( token.Equals("END") ) { // get the semicolon following END token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate the END command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } break; } else if( token.Equals("ENDBLOCK") ) { // get the semicolon following ENDBLOCK token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate the ENDBLOCK command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } break; } else { SkippingCommand( token.GetToken() ); do { token.GetNextToken(); } while( !token.AtEOF() && !token.Equals(";") ); if( token.AtEOF() ) { errormsg = "Unexpected end of file encountered"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } } }
/** * @method HandleEndblock [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XBull * * Called when the END or ENDBLOCK command needs to be parsed * from within the BullShell block. Basically just checks to make * sure the next token in the data file is a semicolon. */ void BullShell::HandleEndblock( NexusToken& token ) { token.GetNextToken(); RequireSemicolon(token, "END"); }
/** * @method HandleFormatCommand [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * Called when FORMAT command needs to be parsed from within the * DISTANCES block. Deals with everything after the token FORMAT * up to and including the semicolon that terminates the FORMAT * command. */ void DistancesBlock::HandleFormatCommand( NexusToken& token ) { for(;;) { token.GetNextToken(); // token should either be ';' or the name of a subcommand // if( token.Equals(";") ) { break; } else if( token.Equals("TRIANGLE") ) { // this should be the equals sign token.GetNextToken(); if( !token.Equals("=") ) { errormsg = "Expecting '=' but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } // this should be LOWER, UPPER, or BOTH token.GetNextToken(); if( token.Equals("LOWER") ) triangle = lower; else if( token.Equals("UPPER") ) triangle = upper; else if( token.Equals("BOTH") ) triangle = both; else { errormsg = "Expecting UPPER, LOWER, or BOTH but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } else if( token.Equals("DIAGONAL") ) { diagonal = 1; } else if( token.Equals("NODIAGONAL") ) { diagonal = 0; } else if( token.Equals("LABELS") ) { labels = 1; } else if( token.Equals("NOLABELS") ) { labels = 0; } else if( token.Equals("INTERLEAVE") ) { interleave = 1; } else if( token.Equals("NOINTERLEAVE") ) { interleave = 0; } else if( token.Equals("MISSING") ) { // this should be the equals sign token.GetNextToken(); if( !token.Equals("=") ) { errormsg = "Expecting '=' but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } // this should be the missing data symbol token.GetNextToken(); if( token.GetTokenLength() != 1 ) { errormsg = "Missing data symbol specified ("; errormsg += token.GetToken(); errormsg += ") is invalid (must be a single character)"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } missing = token.GetToken()[0]; } else { errormsg = "Token specified ("; errormsg += token.GetToken(); errormsg += ") is an invalid subcommand for the FORMAT command"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } }
/// Throws an XBull excpetion if token is not ";" void BullShell::RequireSemicolon(NexusToken & token, const char *cmd) const { if ( !token.Equals(";")) ThrowNoSemicolon(token, cmd); }
void SkipEqualsIfNext(NexusToken & token) { token.GetNextToken(); if (token.Equals("=")) token.GetNextToken(); }
void MyCharactersBlock::HandleMatrix (NexusToken& token) { int i, j; if (ntax == 0) { errormsg = "Must precede "; errormsg += id; errormsg += " block with a TAXA block or specify NEWTAXA and NTAX in the DIMENSIONS command"; throw XNexus (errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn()); } if (ntaxTotal == 0) ntaxTotal = taxa.GetNumTaxonLabels(); // We use >= rather than just > below because someone might have // ELIMINATEd all characters, and we should allow that (even though it // is absurd) assert (nchar >= 0); if (matrix != NULL) delete matrix; mContData.clear(); if (GetDataType() != continuous) { matrix = new DiscreteMatrix (ntax, nchar); } // Allocate memory for (and initialize) the arrays activeTaxon and // activeChar. // All characters and all taxa are initially active. activeTaxon = new bool[ntax]; for (i = 0; i < ntax; i++) activeTaxon[i] = true; activeChar = new bool[nchar]; for (j = 0; j < nchar; j++) activeChar[j] = true; // The value of ncharTotal is normally identical to the value of nchar // specified in the CHARACTERS block DIMENSIONS command. If an // ELIMINATE command is processed, however, nchar < ncharTotal. Note // that the ELIMINATE command will have already been read by now, and // the ELIMINATEd character numbers will be stored in the IntSet // eliminated. // // Note that if an ELIMINATE command has been read, charPos will have // already been created; thus, we only need to allocate and initialize // charPos if user did not specify an ELIMINATE command if (charPos == NULL) BuildCharPosArray(); // The value of ntaxTotal equals the number of taxa specified in the // TAXA block, whereas ntax equals the number of taxa specified in // the DIMENSIONS command of the CHARACTERS block. These two numbers // will be identical unless some taxa were left out of the MATRIX // command of the CHARACTERS block, in which case ntax < ntaxTotal. if (taxonPos != NULL) delete [] taxonPos; taxonPos = new int[ntaxTotal]; for (i = 0; i < ntaxTotal; i++) taxonPos[i] = -1; if (GetDataType() == continuous) handleContMatrix (token); else if (transposing) HandleTransposedMatrix (token); else HandleStdMatrix (token); // If we've gotten this far, presumably it is safe to // tell the ASSUMPTIONS block that were ready to take on // the responsibility of being the current character-containing // block (to be consulted if characters are excluded or included // or if taxa are deleted or restored) assumptionsBlock.SetCallback(this); // this should be the terminating semicolon at the end of the matrix command if (GetDataType() != continuous) token.GetNextToken(); if (!token.Equals(";")) { errormsg = "Expecting ';' at the end of the MATRIX command; found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus (errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn()); } }
/** * @method Execute [void:public] * @param token [NexusToken&] the token object used to grab Nexus tokens * @param notifyStartStop [bool] if true, ExecuteStarting and ExecuteStopping will be called (true by default) * * Reads the Nexus data file from the input stream provided by token. This function * is responsible for reading through the name of a each block. Once * it has read a block name, it searches blockList for a block object * to handle reading the remainder of the block's contents. The block * object is responsible for reading the end or endblock command as well * as the trailing semicolon. This function also handles reading * comments that are outside of blocks, as well as the initial #NEXUS * keyword. The notifyStartStop argument is provided in case you do not * wish the ExecuteStart and ExecuteStop functions to be called. These functions * are primarily used for creating and destroying a dialog box to show progress, * and nested Execute calls can thus cause problems (e.g., a dialog box is * destroyed when the inner Execute calls ExecuteStop and the outer Execute * still expects the dialog box to be available). Specifying notifyStartStop * false for all the nested Execute calls thus allows the outermost Execute call * to control creation and destruction of the dialog box. */ void Nexus::Execute( NexusToken& token, bool notifyStartStop /* = true */ ) { char id_str[256]; bool disabledBlock = false; nxsstring errormsg; try { token.GetNextToken(); } catch( XNexus x ) { NexusError( token.errormsg, 0, 0, 0 ); return; } if( !token.Equals("#NEXUS") ) { errormsg = "Expecting #NEXUS to be the first token in the file, but found "; errormsg += token.GetToken(); errormsg += " instead"; NexusError( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); return; } if( notifyStartStop ) ExecuteStarting(); for(;;) { token.SetLabileFlagBit( NexusToken::saveCommandComments ); token.GetNextToken(); if( token.AtEOF() ) break; if( token.Equals("BEGIN") ) { disabledBlock = false; token.GetNextToken(); NexusBlock* curr; for( curr = blockList; curr != NULL; curr = curr->next ) { if( !token.Equals( curr->GetID() ) ) continue; if( !curr->IsEnabled() ) { disabledBlock = true; SkippingDisabledBlock( token.GetToken() ); continue; } strcpy( id_str, curr->GetID().c_str() ); EnteringBlock( id_str /*curr->GetID()*/ ); curr->Reset(); try { curr->Read( token ); } catch( XNexus x ) { NexusError( curr->errormsg, x.pos, x.line, x.col ); curr->Reset(); return; } ExitingBlock( id_str /*curr->GetID()*/ ); break; } if( curr == NULL ) { token.BlanksToUnderscores(); nxsstring currBlock = token.GetToken(); if( !disabledBlock ) SkippingBlock( currBlock ); for(;;) { token.GetNextToken(); if( token.Equals("END") || token.Equals("ENDBLOCK") ) { token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' after END or ENDBLOCK command, but found "; errormsg += token.GetToken(); errormsg += " instead"; NexusError( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); return; } break; } if( token.AtEOF() ) { errormsg = "Encountered end of file before END or ENDBLOCK in block "; errormsg += currBlock; NexusError( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); return; } } } // if token not found amongst known block IDs } // if token equals BEGIN else if( token.Equals("&SHOWALL") ) { NexusBlock* curr; for( curr = blockList; curr != NULL; curr = curr->next ) { DebugReportBlock(*curr); } } else if( token.Equals("&LEAVE") ) { break; } } // for(;;) if( notifyStartStop ) ExecuteStopping(); }
void BullShell::ParseCodLikeStartValCommand(CodLikeStartOpts &opts, NexusToken& token) const { opts.aaFreqs.clear(); DblVector blankRow(21, 1.0/20.0); blankRow[20] = 0.0; //zero out the freq of the stop codon. opts.genetic_code = GenCode(MITO); token.GetNextToken(); opts.gtrParams.assign(N_MUT_PARAMS, .25); while (token.GetToken()!=";") { if (token.Abbreviation("CURREntbranchlengths") || token.Abbreviation("CURRBranchlengths")) { token.GetNextToken(); opts.currbrlen = true; if (token.Equals("=")) { token.GetNextToken(); if (token.Abbreviation("No")) opts.currbrlen = false; else if (!token.Abbreviation("Yes")) throw XBull("Expecting YES or NO after CurrentBranchLengths = option to CodLikeStartVal command"); token.GetNextToken(); } } else if (token.Abbreviation("GEneticCode")) { SkipEqualsIfNext(token); if (token.Abbreviation("Mitochondrial")) opts.genetic_code = GenCode(MITO); else if (token.Abbreviation("Nuclear")) opts.genetic_code = GenCode(NUCLEAR); else throw XBull("Expecting either Mito or Nuclear code"); } else if (token.Abbreviation("BASEfreq")) { SkipEqualsIfNext(token); if (!token.Equals("(")) throw XBull("Expecting ( after basefreq option to CodLikeStartVal command"); for (unsigned i = 0; i < 3; i++) { token.GetNextToken(); opts.gtrParams[i] = atof(token.GetToken().c_str()); if (opts.gtrParams[i] <= 0.0) throw XBull("basefreqs must be > 0.0 CodLikeStartVal command"); } if (opts.gtrParams[1] + opts.gtrParams[2] + opts.gtrParams[0] >= 1.0) throw XBull("Sum of A, C, and G must be <1.0 CodLikeStartVal command"); token.GetNextToken(); if (!token.Equals(")")) throw XBull("Expecting ) after basefreq option to CodLikeStartVal command"); } else if (token.Abbreviation("RMATrix")) { SkipEqualsIfNext(token); if (!token.Equals("(")) throw XBull("Expecting ( after rmatrix option to CodLikeStartVal command"); for (int i = 0; i < 6; i++) { token.GetNextToken(); opts.gtrParams[3 + i] = atof(token.GetToken().c_str()); if (opts.gtrParams[3 + i] <= 0.0) throw XBull("rmatrix must be >0.0 CodLikeStartVal command"); } token.GetNextToken(); if (!token.Equals(")")) throw XBull("Expecting ) after rmatrix option to CodLikeStartVal command"); } # ifdef ALLOWMULTIHITS else if (token.Abbreviation("DOublehit")) { //not a great name, but allows multiplier abbreviation to work SkipEqualsIfNext(token); opts.gtrParams[MULTI_HIT_PARAM_INDEX] = atof(token.GetToken().c_str()); if (opts.gtrParams[MULTI_HIT_PARAM_INDEX] < 0.0) throw XBull("DOublehit (MultipleHitProb) must be >= 0.0 CodLikeStartVal command"); } # endif else if (token.Abbreviation("AAFreq")) { SkipEqualsIfNext(token); if (!token.Equals("(")) throw XBull("Expecting ( after aafreq option to CodLikeStartVal command"); token.GetNextToken(); long tmp; if (!NxsString::to_long(token.GetTokenAsCStr(), &tmp)) throw XBull("Expecting number of codons after aafreq=( option to CodLikeStartVal command"); if (tmp < 1) throw XBull("number of codons must be >0 in CodLikeStartVal command"); unsigned naa = (unsigned) tmp; opts.aaFreqs.assign(naa, blankRow); for (unsigned ii = 0; ii < naa; ii++) { token.GetNextToken(); if (!token.Equals("(")) throw XBull("Expecting ( for next site in aafreq option to CodLikeStartVal command", token); DblVector & row = opts.aaFreqs[ii]; for (int j=0; j < 20; j++) { token.SetLabileFlagBit(NxsToken::hyphenNotPunctuation); token.GetNextToken(); row[j] = atof(token.GetToken().c_str()); if (row[j]<0.0) throw XBull("each amino acid freq must be >0.0 CodLikeStartVal command", token); } token.GetNextToken(); if (!token.Equals(")")) throw XBull("Expecting ) for next site in aafreq option to CodLikeStartVal command", token); } token.GetNextToken(); if (!token.Equals(")")) throw XBull("Expecting ) after aafreq option to CodLikeStartVal command"); } else if (token.Abbreviation("MUlt")) { SkipEqualsIfNext(token); if (!token.Equals("(")) throw XBull("Expecting ( after mult option to CodLikeStartVal command"); if (opts.aaFreqs.size() < 1) throw XBull("number of codons must be specified (in the AAFreq subcommand) before the mult option is used in CodLikeStartVal command"); opts.multipliers.assign(opts.aaFreqs.size(), 1.0); for (unsigned ii = 0; ii < opts.aaFreqs.size(); ii++) { token.GetNextToken(); opts.multipliers[ii] = atof(token.GetToken().c_str()); if (opts.multipliers[ii] < 0.0) throw XBull("multiplier must be > 0.0 CodLikeStartVal command"); } token.GetNextToken(); if (!token.Equals(")")) throw XBull("Expecting ) after mult option to CodLikeStartVal command"); } else if (token.Abbreviation("TReescale")) { SkipEqualsIfNext(token); opts.treeScale = atof(token.GetToken().c_str()); if (opts.treeScale < 0.0) throw XBull("The Tree scaling must be >0.0 CodLikeStartVal command"); } token.GetNextToken(); } }
/** * @method Read [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * This function provides the ability to read everything following * the block name (which is read by the Nexus object) to the end or * endblock statement. Characters are read from the input stream * in. Overrides the pure virtual function in the base class. */ void AssumptionsBlock::Read( NexusToken& token ) { isEmpty = false; // this should be the semicolon after the block name // token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' after "; errormsg += id; errormsg += " block name, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } for(;;) { token.GetNextToken(); if( token.Equals("EXSET") ) { HandleExset( token ); } else if( token.Equals("TAXSET") ) { HandleTaxset( token ); } else if( token.Equals("CHARSET") ) { HandleCharset( token ); } else if( token.Equals("END") ) { HandleEndblock( token ); break; } else if( token.Equals("ENDBLOCK") ) { HandleEndblock( token ); break; } else { SkippingCommand( token.GetToken() ); do { token.GetNextToken(); } while( !token.AtEOF() && !token.Equals(";") ); if( token.AtEOF() ) { errormsg = "Unexpected end of file encountered"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } } }
/** * @method Read [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * This function provides the ability to read everything following the block name * (which is read by the Nexus object) to the end or endblock statement. * Characters are read from the input stream in. Overrides the * abstract virtual function in the base class. */ void TaxaBlock::Read( NexusToken& token ) { isEmpty = false; token.GetNextToken(); // this should be the semicolon after the block name if( !token.Equals(";") ) { errormsg = "Expecting ';' after TAXA block name, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } for(;;) { token.GetNextToken(); if( token.Equals("DIMENSIONS") ) { token.GetNextToken(); // this should be the NTAX keyword if( !token.Equals("NTAX") ) { errormsg = "Expecting NTAX keyword, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } token.GetNextToken(); // this should be the equals sign if( !token.Equals("=") ) { errormsg = "Expecting '=', but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } token.GetNextToken(); // this should be the number of taxa ntax = atoi( token.GetToken().c_str() ); if( ntax <= 0 ) { errormsg = "NTAX should be greater than zero ("; errormsg += token.GetToken(); errormsg += " was specified)"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } token.GetNextToken(); // this should be the terminating semicolon if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate DIMENSIONS command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } else if( token.Equals("TAXLABELS") ) { if( ntax <= 0 ) { errormsg = "NTAX must be specified before TAXLABELS command"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } for( int i = 0; i < ntax; i++ ) { token.GetNextToken(); taxonLabels.push_back( token.GetToken() ); } token.GetNextToken(); // this should be terminating semicolon if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate TAXLABELS command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } else if( token.Equals("END") ) { // get the semicolon following END token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate the END command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } break; } else if( token.Equals("ENDBLOCK") ) { // get the semicolon following ENDBLOCK token.GetNextToken(); if( !token.Equals(";") ) { errormsg = "Expecting ';' to terminate the ENDBLOCK command, but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } break; } else { SkippingCommand( token.GetToken() ); do { token.GetNextToken(); } while( !token.AtEOF() && !token.Equals(";") ); if( token.AtEOF() ) { errormsg = "Unexpected end of file encountered"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } } } }
/** * @method HandleDimensionsCommand [void:protected] * @param token [NexusToken&] the token used to read from in * @throws XNexus * * Called when DIMENSIONS command needs to be parsed from within the * DISTANCES block. Deals with everything after the token DIMENSIONS * up to and including the semicolon that terminates the DIMENSIONS * command. */ void DistancesBlock::HandleDimensionsCommand( NexusToken& token ) { for(;;) { token.GetNextToken(); // token should either be ';' or the name of a subcommand // if( token.Equals(";") ) { break; } else if( token.Equals("NEWTAXA") ) { ntax = 0; newtaxa = 1; } else if( token.Equals("NTAX") ) { if( !newtaxa ) { errormsg = "Must specify NEWTAXA before NTAX if new taxa are being defined"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } // this should be the equals sign token.GetNextToken(); if( !token.Equals("=") ) { errormsg = "Expecting '=' but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } // this should be the number of taxa token.GetNextToken(); ntax = atoi( token.GetToken().c_str() ); } else if( token.Equals("NCHAR") ) { // this should be the equals sign token.GetNextToken(); if( !token.Equals("=") ) { errormsg = "Expecting '=' but found "; errormsg += token.GetToken(); errormsg += " instead"; throw XNexus( errormsg, token.GetFilePosition(), token.GetFileLine(), token.GetFileColumn() ); } // this should be the number of characters token.GetNextToken(); nchar = atoi( token.GetToken().c_str() ); } } if( ntax == 0 ) ntax = taxa.GetNumTaxonLabels(); }