/*---------------------------------------------------------------------------------------------------------------------------------------------*/


/* ADD NEW RATE CLASS MATRICES HERE */

allowedAACharacters = "ACDEFGHIKLMNPQRSTVWY";

	
SetDialogPrompt ("Locate an amino-acid profile matrix file:");

mapString = "";
aaRateMatrix = {20,20};
vectorOfFrequencies = {20,1};

fscanf (PROMPT_FOR_FILE,"String,NMatrix,NMatrix",mapString,aaRateMatrix,vectorOfFrequencies);
W_MATRIX_FILE = LAST_FILE_PATH;


if (Abs(mapString) == 20 && Rows(aaRateMatrix) == 20 && Columns(aaRateMatrix) == 20 && Rows(vectorOfFrequencies) == 20)
{
	/* check to see that all characters have been mapped */
	checkAAMap   = {}; /* associative array */
	for (aaIndex = 0; aaIndex < 20; aaIndex = aaIndex+1)
	{
		aChar = allowedAACharacters[aaIndex];
		checkAAMap[aChar] = aaIndex+1;
	
	}

	AAMap = {};
	for (aaIndex = 0; aaIndex < 20; aaIndex = aaIndex+1)
	{
		aChar = mapString[aaIndex];
		daIndex = checkAAMap[aChar];
		if (daIndex==0)
		{
			fprintf (stdout, "\nAmino-acid ordering provided in the file is invalid - could be duplicate or missing characters\n");
			return 0;
		}
		else
		{
			AAMap[aaIndex] = daIndex-1;
			checkAAMap[aChar] = 0;
		}
	}
	
	/*symmetrize the matrix*/
	
	for (aaIndex = 0; aaIndex < 19; aaIndex = aaIndex+1)
	{
		for (aaIndex2 = aaIndex+1; aaIndex2 < 20; aaIndex2 = aaIndex2+1)
		{
			aaRateMatrix[aaIndex2][aaIndex] = aaRateMatrix[aaIndex][aaIndex2];
		}
	}
	
	/* reindex the matrix */
	
	aaRateMultipliers = {20,20};
	
	for (aaIndex = 0; aaIndex < 19; aaIndex = aaIndex+1)
	{
		mappedIndex = AAMap[aaIndex];
		for (aaIndex2 = aaIndex+1; aaIndex2 < 20; aaIndex2 = aaIndex2+1)
		{
			mappedIndex2 								 = AAMap[aaIndex2];
			rateLabel 									 = aaRateMatrix[aaIndex][aaIndex2];
			aaRateMultipliers[mappedIndex][mappedIndex2] = rateLabel;
			aaRateMultipliers[mappedIndex2][mappedIndex] = rateLabel;
		}
	}
	
	aaRateMatrix = 0;
	
}
else
{
	fprintf (stdout, "\nExpected a string of 20 characters followed by a 20x20 rate matrix and a 20x1 frequencies matrix\n");
	return 0;
}

ChoiceList	     (_freqsOption,"Base frequencies",1,SKIP_NONE, "Empirical","Use empirical frequencies provided by the model",
															   "Estimated","Estimate frequencies from the alignment (the +F option)",
															   "ML Estimates","Estimate frequencies as model parameters (19 free parameters)");
															  
if (_freqsOption < 0)
{
	return 0;	
}
else
{
	if (_freqsOption == 1 && SKIP_FREQ_HARVESTING == 0)
	{
		HarvestFrequencies 		 (vectorOfFrequencies,filteredData,1,1,0);
	}
	if (_freqsOption == 2)
	{
		HarvestFrequencies 		 	  (vf,filteredData,1,1,0);
		vectorOfFrequencies 		= {20,1};
		global freqNormalizer 		= 1;
		freqNormalizerStr			= "";
		for (k = 0; k< 20; k=k+1)
		{
			ExecuteCommands ("global freqParam_" + k + "=vf[k]; freqParam_" + k + ":<1;");
			if (k)
			{
				freqNormalizerStr = freqNormalizerStr + "+";
			}
			freqNormalizerStr = freqNormalizerStr + "freqParam_" + k;
			ExecuteCommands ("vectorOfFrequencies[k] := freqParam_" + k + "/freqNormalizer");
		}	
		ExecuteCommands ("freqNormalizer := " + freqNormalizerStr);
	}
	
}


#include "modelParameters2.mdl";

if (modelType == 1)
{
	#include "defineGamma.mdl";
}

if (modelType == 2)
{
	#include "defineHM.mdl";
}

/*---------------------------------------------------------------------------------------------------------------------------------------------*/

function PopulateModelMatrix (ModelMatrixName&, EFV)
{
	ModelMatrixName = {20,20}; 
	
	modelDefString = "";
	modelDefString*16384;
	
	catCounterAL = {};
	
	unitRateIdx = aaRateMultipliers[7][9];
	
	for (aa1 = 0; aa1 < 19; aa1 = aa1+1)
	{
		for (aa2 = aa1+1; aa2 < 20; aa2 = aa2+1)
		{
			bt = 0+aaRateMultipliers[aa1][aa2];
		
			if(modelType)
			{
				modelDefString*("ModelMatrixName["+aa1+"]["+aa2+"] := c*"+bt+"*t;\nModelMatrixName["+aa2+"]["+aa1+"] := c*"+bt+"*t;\n");
			}
			else
			{
				modelDefString*("ModelMatrixName["+aa1+"]["+aa2+"] := "+bt+"*t;\nModelMatrixName["+aa2+"]["+aa1+"] := "+bt+"*t;\n");			
			}
		}	
    }		
	modelDefString*0;
	ExecuteCommands (modelDefString);
	return 0;
}

_customAAModelMatrix = 0;

MULTIPLY_BY_FREQS = PopulateModelMatrix ("_customAAModelMatrix",vectorOfFrequencies);
Model _customAAModel = (_customAAModelMatrix, vectorOfFrequencies);
FREQUENCY_SENSITIVE = 0;
