/** * @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; }
/** * @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() ); } } }