You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Codon optimization is essentially identifying the optimal RNA sequence that will encode for the creation of a protein. Proteins drive every biological function in our bodies. For example, the enzymes that break down molecules, the antibodies that fight infections, and receptors that send signals between cells, are all proteins.
The cases where producing a protein would help correct bodily functions are:
A harmful protein is being produced (a cancer cell's surface protein)
A benficial protein is no longer being produced (insulin in diabetes, reduced production causing aging)
An unknown protein is in your immune system (from virus or infection)
In these cases we can either increase protein production, produce a protein to combat a negative protein or prepare your immune system for foreign proteins.
Once we identify our desired protein, we need a way to produce the protein in the desired area. We do this by injecting the strand of mRNA into the body, and letting the ribosomes synthesize the protein inside the cell. Injecting mRNA is prefered over injecting the protein itself, as it is much cheaper and it is more easily modified
This graphic shows the process of synthesizing proteins from mRNA
But there are nearly infinite ways for a mRNA sequence to encode a large protein, so how do we determine the optimal encoding. This is where codon optimization comes in, it looks to optimize:
Translation efficiency: different organisms have different concentrations of codons, so choosing more common codons will lead to faster translation
Structural stability: the RNA sequence determines the structure it will fold into, the more stable it is, the less likely it will degrade in the cell.
This table shows which codons encode which amino acids and we can see the degeneracy here
Algorithms
CDSfold
This was the first algorithm to optimize the RNA sequence given a target protein sequence. CDSfold builds off the Zuker algorithm to determine the rna encoding sequence that minimizes minimum free energy. This sequence is our most durable RNA structure.
The Zuker algorithm is a very complicated method that determines the structure that minimizes the free energy. Base pairs contribute differently to free energy, stacking these pairs also contribute differently, and all loops contribute differently: (a) Hairpin loop, (b) bulge loop, (c) internal loops and (d) multi-loop
CDSfold needs to maintain two DP tables to find the optimal structure, $F^{n_i, n_j}(i,j)$ stores the minimum free energy (MFE) of the
sub-sequence from $i$ to $j$, where $n_i$ and $n_j$ are the boundary
nucleotides:
However, CDSfold does not account for the Translation efficiency of the gerated protein sequence.
DERNA
DERNA expands on CDSfold by including translational efficiency to the problem including the Codon Adaptation Index. This way DERNA is optimizing both aspects of the codon optimization problem.
The codon adaptation index (CAI) uses a frequency table of the organism's codon usage, and the CAI weighs the possible codons by their relative frequencies, for a codon $x$ encoding amino acid $w_a$, the
log-CAI term is:
$g(x)$ is the relative usage frequency of codon $x$ in the target
organism
$S(w_a)$ is the set of all codons that encode amino acid $w_a$
$\max_{x' \in S(w_a)} g(x')$ is the frequency of the most common
codon for that amino acid
Since $g(x) \leq \max_{x'} g(x')$ always, we have $\gamma(a, x) \leq 0$
for all codons. A value of $\gamma = 0$ means codon $x$ is the most
frequently used codon for that amino acid
DERNA requires 4 DP tables with an extentive amount of conditions leading to lengthy and confusing equations, but in essense DERNA is finding a secondary structure that minimizes a combination of MFE and CAI, where we can change the tradeoff parameter:
When $\lambda = 1$: pure MFE minimization.
When $\lambda = 0$: pure CAI maximization.
My approach (Nussinov + CAI)
To simplify the DERNA idea into an approachable mini project, my idea is to optimize the RNA sequence by using Nussinov plus the CAI term as defined earlier, where my overall function will be:
MFE adds the majority of the complexity, and with Nussinov I will only have to manage 1 DP table.
DP Setup
$N[i,\, c_i;\, j,\, c_j]$ stores the maximum score over the nucleotide range $[i, j]$, where $c_i \in S(\alpha(i))$ and $c_j \in S(\alpha(j))$ are the codons at the left and right boundaries.
Notation
$i, j$: 0-indexed nucleotide positions ($0$ to $3m-1$)
$\alpha(i) = \lfloor i/3 \rfloor$: amino acid index for nucleotide $i$
$S(a)$: set of synonymous codons for amino acid $a$
$\text{cai}(a, c) = (1-\lambda)\,\gamma(a, c)$: weighted CAI contribution of codon $c$ for amino acid $a$
$c[p]$: nucleotide at 0-indexed position $p$ within codon $c$
$\mathcal{G}$: set of valid Watson-Crick/wobble base pairs
Pair — form base pair $(i, j)$; only when $(c_i[i \bmod 3],\, c_j[j \bmod 3]) \in \mathcal{G}$ and $j - i - 1 \geq \ell_{\min}$. Let $\Delta_L = [\alpha(i{+}1) \neq \alpha(i)]$ and $\Delta_R = [\alpha(j{-}1) \neq \alpha(j)]$:
The pair cases cover all four combinations of whether each pointer crosses a codon boundary when advancing inward; the inner recursion, $\lambda$ reward, and CAI credits are the same — only which codons must be re-chosen differs.
The codon-forcing constraints (e.g. $c' = c_j$ if $\alpha(i{+}1) = \alpha(j)$) arise when the advancing pointer lands inside the opposite boundary's codon, fixing that codon rather than allowing a free choice.
During bifurication if k and k+1 are pointing to the same amino acid, we subtract one $\text{cai}$ to prevent double-counting: the shared codon at the split appears as the right boundary of the left sub-problem and the left boundary of the right sub-problem simultaneously.