<p>In <a href='http://snpeff.sourceforge.net/'>SNPEFF-IMPACT</a> tool, What is difference between <strong>STOP_GAINED</strong> and <strong>NON-SYNONYMOUS_STOP</strong>?</p>

<p>In SNPEFF, effects are categorized by their impact including (High, Moderate, Low and Modifier).
I would like to know, what is difference between <strong>STOP-GAINED</strong> and <strong>NON-SYNONYMOUS-STOP</strong>?</p>

<p>STOP-GAINED has been categorized in <strong>High impact</strong> and NON-SYNONYMOUS-STOP has been categorized in <strong>Low impact</strong>.</p>

<p>Reference : <a href='http://snpeff.sourceforge.net/faq.html#How_is_impact_categorized?_%28VCF_output%29'>SNPEFF table</a></p>

<p>Without looking at it, my guess is that the variant changes the original stop codon to a different stop codon (that is, it switches among TAG, TAA, and TGA).  So the codon changes (it's non-synonymous), but the effect for the gene should not.</p>

<p><strong>Edit:</strong> What I described is a <code>SYNONYMOUS_STOP</code>.  As I understand it, a <code>NON_SYNONYMOUS_STOP</code> can't arise, and exists in the code only as an oversight.  As evidence of this, only a <code>SYNONYMOUS STOP</code> is explicitly documented in the <a href="http://snpeff.sourceforge.net/faq.html#What_effects_are_predicted?">FAQ</a>.  Furthermore, in one of my datasets, I observe over 1000 <code>SYNONYMOUS_STOP</code> calls and no <code>NON_SYNONYMOUS_STOP</code> calls.</p>

<p>More explanation from the relevant code:</p>

<pre><code>                        if (aaOld.equals(aaNew)) {
                                // Same AA: Synonymous coding                                                                                                                                                                                 
                                if ((codonNum == 0) &amp;&amp; codonTable.isStartFirst(codonsOld)) {
                                        // details removed
                                } else if (codonTable.isStop(codonsOld)) {
                                        if (codonTable.isStop(codonsNew)) effectType = EffectType.SYNONYMOUS_STOP;
                                        else effectType = EffectType.STOP_LOST;
                                } else effectType = EffectType.SYNONYMOUS_CODING;
                        } else {
                                // Different AA: Non-synonymous coding                                                                                                                                                                        
                                if ((codonNum == 0) &amp;&amp; codonTable.isStartFirst(codonsOld)) {
                                        // details removed
                                } else if (codonTable.isStop(codonsOld)) {
                                        if (codonTable.isStop(codonsNew)) effectType = EffectType.NON_SYNONYMOUS_STOP;
                                        else effectType = EffectType.STOP_LOST;
                                } else if (codonTable.isStop(codonsNew)) effectType = EffectType.STOP_GAINED;
                                else effectType = EffectType.NON_SYNONYMOUS_CODING;
                        }
</code></pre>

<p>There is no way for the old and new codons to be different (to get into the outer else block) and for both codons to be stop.  If they're both stop codons, they'll be the same and go to the first if branch.  So the <code>NON_SYNONYMOUS_STOP</code> branch is never reached.</p>
