Example #1
0
/**
 * @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();
}
Example #2
0
/**
 * @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() );
         }
		}
   }
}
Example #3
0
/**
 * @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() );
   }
}
Example #4
0
/**
 * @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;
}
Example #5
0
/**
 * @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;
}
Example #6
0
/**
 * @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() );
	}
}
Example #7
0
/**
 * @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;
}
Example #8
0
/**
 * @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() );
         }
		}
	}
}
Example #9
0
/**
 * @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();
}
Example #10
0
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());
   }

}
Example #11
0
/**
 * @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() );
         }
		}
	}
}
Example #12
0
/**
 * @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;
}
Example #13
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() );
      }
	}
}