/* this file defines a multi-rate model 
   with multiple substitutions under the 
   F61 parameterization

v0.1 20100524 SLKP spond@ucsd.edu 

*/

ModelMatrixDimension = 0;

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

function PopulateModelMatrix (ModelMatrixName&)
{
	if (!ModelMatrixDimension)
	{
		ModelMatrixDimension = 64;
		for (h = 0 ;h<64; h=h+1)
		{
			if (_Genetic_Code[h]==10)
			{
				ModelMatrixDimension = ModelMatrixDimension-1;
			}
		}
	}
	
	ModelMatrixName = {ModelMatrixDimension,ModelMatrixDimension}; 

	hshift = 0;
	
	modelDefString = "";
	modelDefString*16384;
	
	modelDefString * "global twoNSsubsRate = 1;\nglobal threeNSsubsRate = 1;\nglobal twoSYNsubsRate = 1;\nglobal threeSYNsubsRate = 1;\n";
	
	if (modelType > 0)
	{
		catCounterAL = {};
		if (_AA_RM_NUMERIC > 1)
		{
			ExecuteCommands ("global NS_Scaler = 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; 
			}
			codonProps = CompareCodonProperties (h,v,_Genetic_Code);

			aa1 = _Genetic_Code[h];
			aa2 = _Genetic_Code[v];
			hs = Format(h-hshift,0,0);
			vs = Format(v-vshift,0,0);
			
			nucTerms = "";
			
			for (pos = 0; pos < 3; pos = pos + 1)
			{
				thisPosition = codonProps[1+pos];
				if (thisPosition[0] != thisPosition [1])
				{
					nucTerms = nucTerms + _nucBiasTerms[thisPosition[0]][thisPosition[1]];
				}
			}
						
			if (codonProps["DIFFERENCES"] == 1)
			{
				if (aa1==aa2) 
				{
					modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := "+nucTerms+"synRate;\n"+
									"ModelMatrixName["+vs+"]["+hs+"] := "+nucTerms+"synRate;\n");
				}
				else
				{
					if (modelType > 0)
					{
						if (_AA_RM_NUMERIC)
						{
							if (_AA_RM_NUMERIC > 1)
							{
								bt = "NS_Scaler*" + aaRateMultipliers[aa1][aa2];
							}
							else
							{
								bt = aaRateMultipliers[aa1][aa2];
							}
						}
						else
						{
							bt = aaRateMultipliers[aa1][aa2];
							if (catCounterAL[bt] == 0)
							{
								catCounterAL[bt] = 1;
								modelDefString*("\nglobal NSClass"+bt+"=1;\n");
							}
							bt = "NSClass"+bt;
						}
						
						modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := "+nucTerms+bt+"*synRate;\n"+
														 "ModelMatrixName["+vs+"]["+hs+"] := "+nucTerms+bt+"*synRate;\n");
					}
					else
					{
						bt = "nsClass"+aaRateMultipliers[aa1][aa2];
						modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := "+nucTerms+bt+"*synRate;\n"+
														 "ModelMatrixName["+vs+"]["+hs+"] := "+nucTermsbt+"*synRate;\n");				
					}			
				}
			}
			else
			{
				if (aa1 == aa2)
				{
					if (codonProps["DIFFERENCES"] == 2)
					{
						term = "twoSYNsubsRate";
					}
					else
					{
						term = "threeSYNsubsRate";
					}
				}
				else
				{
					if (codonProps["DIFFERENCES"] == 2)
					{
						term = "twoNSsubsRate";
					}
					else
					{
						term = "threeNSsubsRate";
					}				
				}
				modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := "+nucTerms+"synRate*"+term+";\n"+
								"ModelMatrixName["+vs+"]["+hs+"] := "+nucTerms+"synRate*"+term+";\n");					
			}
	    }
    }		
    
	modelDefString*0;
	ExecuteCommands (modelDefString);
	return 1;
}



#include "MGwAA.ibf";

categoriesUsed = 0;

#include "modelParameters.mdl";

global AC = 1;
global AT = 1;
global CG = 1;
global CT = 1;
global GT = 1;

if (modelType >0)
{
	sharedFlag = 1;
	if (modelType == 2)
	{
		categoriesUsed = 1;
		#include "defineGamma.mdl";
	}
	if (modelType == 3)
	{
		categoriesUsed = 1;
		#include "defineHM.mdl";
	}
}

if (modelType > 1)
{
	MGCustomRateBiasTerms = {{"AC*c*","c*","AT*c*","CG*c*","CT*c*","GT*c*"}};
}
else
{
	MGCustomRateBiasTerms = {{"AC*","","AT*","CG*","CT*","GT*"}};	
}


done = 0;
while (!done)
{
	fprintf (stdout,"\nPlease enter a 6 character model designation (e.g:010010 defines HKY85):");
	fscanf  (stdin,"String", modelDesc);
	if (Abs(modelDesc)==6)
	{	
		done = 1;
	}
}			

		
paramCount	  = 0;
_nucBiasTerms = {4,4};
_nucBiasTerms[0][0] = "";


if (modelDesc[0]==modelDesc[1])
{
	MGCustomRateBiasTerms[0] = MGCustomRateBiasTerms[1];
}

_nucBiasTerms[1][0] = MGCustomRateBiasTerms[0];
_nucBiasTerms[0][1] = MGCustomRateBiasTerms[0];
_nucBiasTerms[2][0] = MGCustomRateBiasTerms[1];
_nucBiasTerms[0][2] = MGCustomRateBiasTerms[1];

h = 0;
v = 3;

for (customLoopCounter2=2; customLoopCounter2<6; customLoopCounter2=customLoopCounter2+1)
{
	for (customLoopCounter=0; customLoopCounter<customLoopCounter2; customLoopCounter=customLoopCounter+1)
	{
		if (modelDesc[customLoopCounter]==modelDesc[customLoopCounter2])
		{
			_nucBiasTerms[h][v] = MGCustomRateBiasTerms[customLoopCounter];
			_nucBiasTerms[v][h] = MGCustomRateBiasTerms[customLoopCounter];
			break;
		}
	}
	if (customLoopCounter == customLoopCounter2)
	{
		_nucBiasTerms[h][v] = MGCustomRateBiasTerms[customLoopCounter2];
		_nucBiasTerms[v][h] = MGCustomRateBiasTerms[customLoopCounter2];
	}
	
	v = v+1;
	if (v==4)
	{
		h=h+1;
		v=h+1;
	}
}



MULTIPLY_BY_FREQS = PopulateModelMatrix ("MG94custom");

FREQUENCY_SENSITIVE = 1;

COUNT_GAPS_IN_FREQUENCIES = 0;

HarvestFrequencies (observedFreq,filteredData,3,3,1);
vectorOfFrequencies = Transpose(observedFreq[Transpose(_Genetic_Code["_MATRIX_ELEMENT_VALUE_!=10"])]); /* cough, cough, cough....HACK! */

Model MG94customModel = (MG94custom,vectorOfFrequencies,1);

USE_POSITION_SPECIFIC_FREQS = 0;
