<?php
/**
* TranslateDna.php
* http://tasuke.dna.affrc.go.jp/
*
* Author: Norio Tabei
*
* Copyright (c) 2023 National Institute of Agrobiological Sciences
*
*/

class TranslateDna {
	static protected $AA_LIST = array(
"F","L","I","M","V","S",
"P","T","A","Y","*","H",
"Q","N","K","D","E","C",
"W","R","G"
	);
	static protected $CODON_TABLES = array(
"standard" => array(
"TTT,TTC","TTA,TTG,CTN","ATT,ATC,ATA","ATG","GTN","TCN,AGT,AGC",
"CCN","ACN","GCN","TAT,TAC","TAA,TAG,TGA","CAT,CAC",
"CAA,CAG","AAT,AAC","AAA,AAG","GAT,GAC","GAA,GAG","TGT,TGC",
"TGG","CGN,AGA,AGG","GGN"
),
"protozoa" => array(
"TTT,TTC","TTA,TTG,CTN","ATT,ATC,ATA","ATG","GTN","TCN,AGT,AGC",
"CCN","ACN","GCN","TAT,TAC","TAA,TAG","CAT,CAC",
"CAA,CAG","AAT,AAC","AAA,AAG","GAT,GAC","GAA,GAG","TGT,TGC",
"TGG,TGA","CGN,AGA,AGG","GGN"
),
"ciliate" => array(
"TTT,TTC","TTA,TTG,CTN","ATT,ATC,ATA","ATG","GTN","TCN,AGT,AGC",
"CCN","ACN","GCN","TAT,TAC","TGA","CAT,CAC",
"CAA,CAG,TAA,TAG","AAT,AAC","AAA,AAG","GAT,GAC","GAA,GAG","TGT,TGC",
"TGG","CGN,AGA,AGG","GGN"
)
	);

	public function __construct() {
		self::$CODON_TABLES['bacteria'] = self::$CODON_TABLES['standard'];
		self::$CODON_TABLES['plastid'] = self::$CODON_TABLES['standard'];
		self::$CODON_TABLES['mold'] = self::$CODON_TABLES['protozoa'];
		self::$CODON_TABLES['mycoplasma'] = self::$CODON_TABLES['protozoa'];
		self::$CODON_TABLES['spiroplasma'] = self::$CODON_TABLES['protozoa'];
	}
	public function getGeneticCodes() {
		return array_keys(self::$CODON_TABLES);
	}

	/*
	 * Note!!: Non-base strings such as gaps"-" must be removed in advance.
	*/
	public function translate($dna, $ctable) {
		$prot = "";
		$lenSeq = strlen($dna);
		for($i=0; $i+3 <= $lenSeq; $i+=3) {
			$codon = substr($dna, $i, 3);
			$prot .= $this->getAA($codon, $ctable);
		}
		return $prot; 
	}
	public function translateStandard($dna) {
		$ctable = $this->getCodonTable('standard');
		return $this->translate($dna, $ctable);
	}

	public function getAA($codon, $codonTable) {
		$uCodon = strtoupper($codon);
		return isset($codonTable[$uCodon]) ? $codonTable[$uCodon] : 'X';
	}
	public function getCodonTable($gcode) {
		$atgcArray = array("A", "T", "G", "C");

		$preCodonTable = self::$CODON_TABLES[$gcode];
		$len = count($preCodonTable);
		$codonTable = array();
		for($i=0; $i<$len; $i++) {
			$aa = self::$AA_LIST[$i];
			$codons = explode(",", $preCodonTable[$i]);
			$lenCodons = count($codons);
			for($j=0; $j<$lenCodons; $j++) {
				$codon = $codons[$j];
				$codonTable[$codon] = $aa;
				if(strpos($codon, "N") >= 0) {
					for($k=0; $k<4; $k++) {
						$subCodon = str_replace('N', $atgcArray[$k], $codon);
						$codonTable[$subCodon] = $aa;
					}
				}
			}
		}
		return $codonTable;
	}
	public function getRnaCodonTable($gcode) {
		$dnaCodonTable = $this->getCodonTable($gcode);
		$dnaCcodons = array_keys($dnaCodonTable);
		$lenDnaCcodons = count($dnaCcodons);
		$rnaCodonTable = array();
		for($i=0; $i<$lenDnaCcodons; $i++) {
			$dnaCodon = $dnaCcodons[$i];
			$rnaCodon = str_replace('T', 'U', $dnaCodon);
			$rnaCodonTable[$rnaCodon] = $dnaCodonTable[$dnaCodon];
		}
		return $rnaCodonTable;
	}
	static public function removeNonBaseChar($seq) {
		$convSeq = preg_replace('/\W/', '', $seq);
		return $convSeq;
	}
}
?>
