global     AC;
global 	   AT;
global     CG;
global	   CT;
global     GT;

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

nucModelString = "nucModelMatrix = {{*,AC*t,t,AT*t}{AC*t,*,CG*t,CT*t}{t,CG*t,*,GT*t}{AT*t,CT*t,GT*t,*}};";

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

function SetCodonNorm (subWeights)
{
	nSAC = subWeights[0][0];
	nSAG = subWeights[1][0];
	nSAT = subWeights[2][0];
	nSCG = subWeights[3][0];
	nSCT = subWeights[4][0];
	nSGT = subWeights[5][0];

	nNAC = subWeights[0][1];
	nNAG = subWeights[1][1];
	nNAT = subWeights[2][1];
	nNCG = subWeights[3][1];
	nNCT = subWeights[4][1];
	nNGT = subWeights[5][1];
	
	global 	codonFactor:=fudgeFactor__*(R*(AC*nNAC__+nNAG__+AT*nNAT__+CG*nNCG__+CT*nNCT__+GT*nNGT__)+
						   (AC*nSAC__+nSAG__+AT*nSAT__+CG*nSCG__+CT*nSCT__+GT*nSGT__));
	return 0;
}

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

rateMultipliers 		= {{""   ,"AC*",""   ,"AT*"}
						   {"AC*",""   ,"CG*","CT*"}
						   {""   ,"CG*",""   ,"GT*"}
						   {"AT*","CT*","GT*","" }
						  };
						  

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

function PopulateModelMatrix (ModelMatrixName&, EFV, c_string, d_string, aaRateMultipliers)
{
	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;

	if (Abs(c_string))
	{
		synCatRateMult 	  = "("+c_string+")*";
	}
	else
	{
		synCatRateMult    = "";
	}
	if (Abs(d_string))
	{
		nonsynCatRateMult = "("+d_string+")*";;
	}
	else
	{
		nonsynCatRateMult  = "";
	}
	
	
	catCounterAL = {};

	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 = Format(h-hshift,0,0);
				vs = Format(v-vshift,0,0);
				aa1 = _Genetic_Code[0][h];
				aa2 = _Genetic_Code[0][v];
				
				if (aa1==aa2) 
				{
					modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := "+synCatRateMult+rateMultipliers[transition][transition2]+"synRate*"+EFV[transition][nucPosInCodon]+";\n"+
													 "ModelMatrixName["+vs+"]["+hs+"] := "+synCatRateMult+rateMultipliers[transition][transition2]+"synRate*"+EFV[transition2][nucPosInCodon]+";\n");
				}
				else
				{
					if (Abs(aaRateMultipliers))
					{
						if (_AA_RM_NUMERIC)
						{
							bt = ""+aaRateMultipliers[aa1][aa2];
						}
						else
						{
							bt = aaRateMultipliers[aa1][aa2];
							if (catCounterAL[bt] == 0)
							{
								catCounterAL[bt] = 1;
								/* check if already defined */
								GetInformation(_info,"^NSClass"+bt+"$");
								if (Rows(_info)==0)
								{
									modelDefString*("\nglobal NSClass"+bt+"=1;\n");
								}
							}
							bt = "NSClass"+bt;
						}
						bt = bt+"*synRate*";
					}
					else
					{
						bt = "synRate*";
					}
						
					if (Abs(nonsynCatRateMult) == 0)
					{
						modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := "+rateMultipliers[transition][transition2]+bt+EFV[transition][nucPosInCodon]+";\n"+
												 "ModelMatrixName["+vs+"]["+hs+"] := "+rateMultipliers[transition][transition2]+bt+EFV[transition2][nucPosInCodon]+";\n");
					}
					else
					{
						modelDefString*("ModelMatrixName["+hs+"]["+vs+"] := "+nonsynCatRateMult+rateMultipliers[transition][transition2]+bt+EFV[transition][nucPosInCodon]+";\n"+
													 "ModelMatrixName["+vs+"]["+hs+"] := "+nonsynCatRateMult+rateMultipliers[transition][transition2]+bt+EFV[transition2][nucPosInCodon]+";\n");
					}
					
				}
			}
	    }
    }		
    
    if (Abs(catCounterAL)==1)
    {
    	modelDefString * ("NSClass" + catCounterAL[(Rows(catCounterAL))[0]] + " := 1;");
    }
	modelDefString*0;
	ExecuteCommands (modelDefString);
	
	return 0;
}
