/*	this file defines the ECM model as reported in Kosiol, Holmes & Goldman (2007). Molecular Biology and Evolution 24:1464-1479 

	09/03/2009
	
	
	This model is ECM with ML estimated frequency parameters, not defined in KHG but used for comparative purposes.
	
	Coded by Gordon Botha
	Tweaked by Wayne Delport
*/

ECMmodelType = 0;

NUC_LETTERS = "ACGT";
AA = "FLIMVSPTAY*HQNKDECWRG";

CODONS = {64, 1};	
for (i = 0; i < 64; i = i + 1)
{
	CODONS [i] = NUC_LETTERS[i$16] + NUC_LETTERS [(i%16)$4] + NUC_LETTERS [i%4];
}

function PopulateModelMatrix (ModelMatrixName&, VOF )
{		

	ModelMatrixName = {ModelMatrixDimension,ModelMatrixDimension}; 
	hshift = 0;
	
	modelDefString = "";
	modelDefString*16384;
	
	if (ECMmodelType > 1)		/* model where omega is implemented for the first time, ECM + F + omega */
	{
		global globalVariable_omega = 0.192;		/* value initialised as omega_E, p 1476 of paper */
	}
	else {
		global globalVariable_omega := 1;
	}
	
	for (h=0; h<64; h=h+1)
	{
		if (_Genetic_Code[h]==10) 
		{
			hshift = hshift+1;
			continue; 
		}
		vshift = hshift;
		for (v = h+1; v<64; v=v+1)
		{
			diff = v-h;
			if (_Genetic_Code[v]==10) 
			{
				vshift = vshift+1;
				continue; 
			}
			nucPosInCodon = 2;
			if ((h$4==v$4)||((diff%4==0)&&(h$16==v$16))||(diff%16==0))
			{
				if (h$4==v$4)
				{
					transition = v%4;
					transition2= h%4;
				}
				else
				{
					if(diff%16==0)
					{
						transition = v$16;
						transition2= h$16;
						nucPosInCodon = 0;
					}
					else
					{
						transition = v%16$4;
						transition2= h%16$4;
						nucPosInCodon = 1;
					}
				}
				hs = h-hshift;
				vs = v-vshift;
				ts = Format(transition,0,0);
				ts2= Format(transition2,0,0);
				ps = Format(nucPosInCodon,0,0);
				aa1 = _Genetic_Code[0][h];
				aa2 = _Genetic_Code[0][v];
			
				if ( aa1 == aa2 )
				{
					modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := " + _numericRateMatrix[hs][vs] + "*" + VOF[transition][nucPosInCodon]+"*t;\n"+
								"ModelMatrixName["+vs+"]["+hs+"] := " + _numericRateMatrix[hs][vs] + "*" + VOF[transition2][nucPosInCodon]+"*t;\n");
				}
				else
				{
					modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := globalVariable_omega*" + _numericRateMatrix[hs][vs] + "*" + VOF[transition][nucPosInCodon]+"*t;\n"+
								"ModelMatrixName["+vs+"]["+hs+"] := globalVariable_omega*" + _numericRateMatrix[hs][vs] + "*" + VOF[transition2][nucPosInCodon]+"*t;\n");
				}
			}
		}
	}
	modelDefString*0;
	/*fprintf ( stdout, modelDefString, "\n" );*/
	ExecuteCommands (modelDefString);
	return 0;
}

incFileName = HYPHY_LIB_DIRECTORY + "TemplateBatchFiles" + DIRECTORY_SEPARATOR + "TemplateModels" + DIRECTORY_SEPARATOR + "EmpiricalCodon" + DIRECTORY_SEPARATOR + "KHG_ECM";
fscanf ( incFileName, "Matrix,NMatrix,NMatrix", KHG_codonOrder, KHG_RateMatrix, KHG_vof );

ModelMatrixDimension = 0;
for ( i = 0; i < 64; i = i + 1 ) {
	if ( _Genetic_Code [ i ] != 10 ) {
		ModelMatrixDimension = ModelMatrixDimension + 1;
	}
}

/*array of codon indeces in the KHG model*/
CodonCompare = { ModelMatrixDimension, 1 };
ishit = 0;
for ( i = 0; i < 64; i = i + 1 ) {
	if ( _Genetic_Code [ i ] == 10 ) {
		ishit = ishit + 1;
	}	
	else {
		query = CODONS [ i ];
		got = 0;
		j = 0;
		while ( ( got == 0 ) && ( j < Columns(KHG_codonOrder) ) ) {
			if ( query == KHG_codonOrder [ j ] ) {
				/* fprintf ( stdout, query, " ", KHG_codonOrder [ j ], "\n" ); */
				got = 1;
				CodonCompare [ i-ishit ] = j;
			}
			j = j + 1;
		}
	}
}

_numericRateMatrix = { ModelMatrixDimension, ModelMatrixDimension }; /* codons to be ordered as in HYPHY*/
for ( i = 0; i < ModelMatrixDimension; i = i + 1 ) {
	for ( j = i + 1; j < ModelMatrixDimension; j = j + 1 ) {
		_numericRateMatrix [ i ][ j ] = KHG_RateMatrix [ CodonCompare [ i ] ][ CodonCompare [ j ] ];
		_numericRateMatrix [ j ][ i ] = KHG_RateMatrix [ CodonCompare [ j ] ][ CodonCompare [ i ] ];
	}
}

HarvestFrequencies (observedFreq,filteredData,3,1,1);
#include "MGFreqsEstimator.ibf";

		
ECM = 0;
MULTIPLY_BY_FREQS = PopulateModelMatrix ( "ECM", paramFreqs );
FREQUENCY_SENSITIVE = 1;
BuildCodonFrequencies (paramFreqs,"vectorOfFrequencies");

Model ECMModel = ( ECM, vectorOfFrequencies, MULTIPLY_BY_FREQS );

/*
Export ( modelString, ECMModel );
fprintf ( stdout, modelString, "\n" );
*/

USE_POSITION_SPECIFIC_FREQS = 1;
