Model_Name  		= "MG94xHKY85x3_4x2_Rates";
Model_Options 		= 2;
Model_Dimension 	= 64;
Model_EFV_Type		= "Observed Nuc 9 params.";

function GUIBuildCodonFrequencies (EFV)
{
	PIStop = 1.0;
	result = {ModelMatrixDimension,1};
	hshift = 0;
	
	for (h=0; h<64; h=h+1)
	{
		first = h$16;
		second = h%16$4;
		third = h%4;
		if (ModelGeneticCode[h]==10) 
		{
			hshift = hshift+1;
			PIStop = PIStop-EFV[first][0]*EFV[second][1]*EFV[third][2];
			continue; 
		}
		result[h-hshift][0]=EFV[first][0]*EFV[second][1]*EFV[third][2];
	}
	return result*(1.0/PIStop);
}

function GUIPopulateModelMatrix (ModelMatrixName&, EFV)
{
	global globalVariable_TVTS;
	
	if (!ModelMatrixDimension)
	{
		ModelMatrixDimension = 64;
		for (h = 0 ;h<64; h=h+1)
		{
			if (ModelGeneticCode[h]==10)
			{
				ModelMatrixDimension = ModelMatrixDimension-1;
			}
		}
	}
	
	ModelMatrixName = {ModelMatrixDimension,ModelMatrixDimension}; 

	hshift = 0;
	
	if (modelType == 0)
	{
		for (h=0; h<64; h=h+1)
		{
			if (ModelGeneticCode[h]==10) 
			{
				hshift = hshift+1;
				continue; 
			}
			vshift = hshift;
			for (v = h+1; v<64; v=v+1)
			{
				diff = v-h;
				if (ModelGeneticCode[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;
			  			}
			  		}
			  		
			  		if (ModelGeneticCode[0][h]==ModelGeneticCode[0][v]) 
			  		{
			  			if ((Abs(transition-transition2)%2)==1)
			  			{
			  				ModelMatrixName[h-hshift][v-vshift] := globalVariable_TVTS*synRate*EFV__[transition__][nucPosInCodon__];
			  				ModelMatrixName[v-vshift][h-hshift] := globalVariable_TVTS*synRate*EFV__[transition2__][nucPosInCodon__];
			  			
			  			}
			  			else
			  			{
			  				ModelMatrixName[h-hshift][v-vshift] := synRate*EFV__[transition__][nucPosInCodon__];
			  				ModelMatrixName[v-vshift][h-hshift] := synRate*EFV__[transition2__][nucPosInCodon__];
			  			}
				  	}
			  		else
			  		{
			  			if ((Abs(transition-transition2)%2)==0)
			  			{
			  				ModelMatrixName[h-hshift][v-vshift] := globalVariable_TVTS*nonSynRate*EFV__[transition__][nucPosInCodon__];
			  				ModelMatrixName[v-vshift][h-hshift] := globalVariable_TVTS*nonSynRate*EFV__[transition2__][nucPosInCodon__];
			  			
			  			}
			  			else
			  			{
			  				ModelMatrixName[h-hshift][v-vshift] := nonSynRate*EFV__[transition__][nucPosInCodon__];
			  				ModelMatrixName[v-vshift][h-hshift] := nonSynRate*EFV__[transition2__][nucPosInCodon__];
			  			}
				  	}
			  	}
			 }
		}		
	}
	else
	{
		global  globalVariable_DNDS  = 1.;
		global shapeParameter_alpha = .5;
		shapeParameter_alpha:>0.01;
		shapeParameter_alpha:<100;
		category     categoryVariable_alpha = 
					(rateClassCount, EQUAL, MEAN, GammaDist(_x_,shapeParameter_alpha,shapeParameter_alpha), CGammaDist(_x_,shapeParameter_alpha,shapeParameter_alpha), 0 , 
			  									  1e25,CGammaDist(_x_,shapeParameter_alpha+1,shapeParameter_alpha));



		global shapeParameter_beta = .5;
		shapeParameter_beta:>0.01;
		shapeParameter_beta:<100;
		
		global shapeParameter_beta_Inv;
		shapeParameter_beta_Inv :< 1-(1e-10);
		shapeParameter_beta_Inv = 1/rateClassCount;
		
		
		CFM = {rateClassCount,1};
		CFM [0] := shapeParameter_beta_Inv;
		
		for (h=1; h<rateClassCount;h=h+1)
		{
			CFM [h] := (1-shapeParameter_beta_Inv)/(rateClassCount-1);
		}
		
		category categoryVariable_beta = (rateClassCount, CFM, MEAN, 
						(1-shapeParameter_beta_Inv)*GammaDist(_x_,shapeParameter_beta,shapeParameter_beta)*(_x_>0), 
						(1-shapeParameter_beta_Inv)*CGammaDist(_x_,shapeParameter_beta,shapeParameter_beta)*(_x_>0)+shapeParameter_beta_Inv, 
						0, 
				  	    1e25,
				  	    (1-shapeParameter_beta_Inv)*CGammaDist(_x_,shapeParameter_beta+1,shapeParameter_beta)*(_x_>0)
				  	 );


		for (h=0; h<64; h=h+1)
		{
			if (ModelGeneticCode[h]==10) 
			{
				hshift = hshift+1;
				continue; 
			}
			vshift = hshift;
			for (v = h+1; v<64; v=v+1)
			{
				diff = v-h;
				if (ModelGeneticCode[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;
			  			}
			  		}
			  		
			  		if (ModelGeneticCode[0][h]==ModelGeneticCode[0][v]) 
			  		{
			  			if ((Abs(transition-transition2)%2)==1)
			  			{
			  				ModelMatrixName[h-hshift][v-vshift] := categoryVariable_alpha*globalVariable_TVTS*synRate*EFV__[transition__][nucPosInCodon__];
			  				ModelMatrixName[v-vshift][h-hshift] := categoryVariable_alpha*globalVariable_TVTS*synRate*EFV__[transition2__][nucPosInCodon__];
			  			
			  			}
			  			else
			  			{
			  				ModelMatrixName[h-hshift][v-vshift] := categoryVariable_alpha*synRate*EFV__[transition__][nucPosInCodon__];
			  				ModelMatrixName[v-vshift][h-hshift] := categoryVariable_alpha*synRate*EFV__[transition2__][nucPosInCodon__];
			  			}
				  	}
			  		else
			  		{
			  			if ((Abs(transition-transition2)%2)==0)
			  			{
			  				ModelMatrixName[h-hshift][v-vshift] := categoryVariable_beta*globalVariable_DNDS*globalVariable_TVTS*synRate*EFV__[transition__][nucPosInCodon__];
			  				ModelMatrixName[v-vshift][h-hshift] := categoryVariable_beta*globalVariable_DNDS*globalVariable_TVTS*synRate*EFV__[transition2__][nucPosInCodon__];
			  			
			  			}
			  			else
			  			{
			  				ModelMatrixName[h-hshift][v-vshift] := categoryVariable_beta*globalVariable_DNDS*synRate*EFV__[transition__][nucPosInCodon__];
			  				ModelMatrixName[v-vshift][h-hshift] := categoryVariable_beta*globalVariable_DNDS*synRate*EFV__[transition2__][nucPosInCodon__];
			  			}
				  	}
			  	}
			 }
		}			
	}
	return 0;
}
