Skip to content

Commit

Permalink
Merge pull request #1376 from nextstrain/feat/rename-gene-to-cds
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-aksamentov authored Jan 9, 2024
2 parents 9908d2d + 66d3f21 commit 2e58b16
Show file tree
Hide file tree
Showing 36 changed files with 115 additions and 118 deletions.
3 changes: 0 additions & 3 deletions packages_rs/nextclade-cli/src/cli/nextclade_ordered_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,6 @@ impl NextcladeOrderedWriter {
}) => {
let NextcladeOutputs {
warnings,
insertions,
aa_insertions,
missing_genes,
is_reverse_complement,
..
} = &analysis_result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,15 +244,15 @@ export function ListOfAaMotifMutations({ motifs }: ListOfAaMotifMutationsProps)

const aaMotifsTruncated = motifs.slice(0, 20)

const tbody = aaMotifsTruncated.map(({ gene, position, refSeq, qrySeq }) => {
const cdsObj = cdses.find((cds) => cds.name === gene)
const tbody = aaMotifsTruncated.map(({ cds, position, refSeq, qrySeq }) => {
const cdsObj = cdses.find((cds1) => cds1.name === cds)
const bg = cdsObj?.color ?? theme.gray400
const fg = theme.gray200
return (
<Tr key={`${gene}-${position}`}>
<Tr key={`${cds}-${position}`}>
<TdNormal>
<GeneText $background={bg} $color={fg}>
{gene}
{cds}
</GeneText>
</TdNormal>
<TdNormal className="text-center">{position + 1}</TdNormal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function ColumnNameTooltip({ index }: ColumnNameTooltipProps) {

const warningComponents = useMemo(() => {
return (result?.analysisResult?.warnings ?? []).map((warning) => (
<Alert key={`${warning.geneName}: ${warning.warning}`} color="warning" fade={false} className="px-2 py-1 my-1">
<Alert key={`${warning.cdsName}: ${warning.warning}`} color="warning" fade={false} className="px-2 py-1 my-1">
<WarningIcon />
{warning.warning}
</Alert>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function FrameShiftRows({ frameShifts }: FrameShiftRowsProps) {
return (
<ul>
{frameShifts.map((fs) => (
<li key={`${fs.geneName}_${fs.codon.begin}`}>{formatFrameShift(fs)}</li>
<li key={`${fs.cdsName}_${fs.codon.begin}`}>{formatFrameShift(fs)}</li>
))}
</ul>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,17 +177,17 @@ export function ListOfInsertionsAa({ insertions }: ListOfInsertionsAaProps) {
const { thead, tbody } = useMemo(() => {
const thead = (
<tr>
<ThNormal className="text-center">{t('Gene.')}</ThNormal>
<ThNormal className="text-center">{t('CDS')}</ThNormal>
<ThNormal className="text-center">{t('After ref pos.')}</ThNormal>
<ThNormal className="text-center">{t('Length')}</ThNormal>
<ThFragment className="text-center">{t('Inserted fragment')}</ThFragment>
</tr>
)

const insertionsTruncated = insertions.slice(0, 20)
const tbody = insertionsTruncated.map(({ pos, ins, gene }) => (
const tbody = insertionsTruncated.map(({ pos, ins, cds }) => (
<tr key={pos}>
<TdNormal className="text-center">{gene}</TdNormal>
<TdNormal className="text-center">{cds}</TdNormal>
<TdNormal className="text-center">{pos + 1}</TdNormal>
<TdNormal className="text-center">{ins.length}</TdNormal>
<TdFragment className="text-left">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function StopCodonsItems({ stopCodons }: StopCodonsRowsProps) {
return (
<ul>
{stopCodons.map((sc) => (
<li key={`${sc.geneName}_${sc.codon}`}>{formatStopCodon(sc)}</li>
<li key={`${sc.cdsName}_${sc.codon}`}>{formatStopCodon(sc)}</li>
))}
</ul>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ function PeptideMarkerFrameShiftUnmemoed({
const onMouseEnter = useCallback(() => setShowTooltip(true), [])
const onMouseLeave = useCallback(() => setShowTooltip(false), [])

const { geneName, nucAbs, codon, gapsLeading, gapsTrailing } = frameShift
const { cdsName, nucAbs, codon, gapsLeading, gapsTrailing } = frameShift
const id = getSafeId('frame-shift-aa-marker', { index, seqName, ...frameShift })

const cds = useRecoilValue(cdsAtom(geneName))
const cds = useRecoilValue(cdsAtom(cdsName))
if (!cds) {
return null
}
Expand Down Expand Up @@ -92,8 +92,8 @@ function PeptideMarkerFrameShiftUnmemoed({
</tr>

<tr>
<td>{t('Gene')}</td>
<td>{geneName}</td>
<td>{t('CDS')}</td>
<td>{cdsName}</td>
</tr>

<tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function PeptideViewMissing({ geneName, reasons }: PeptideViewMissingProp
<Tooltip wide fullWidth target={id} isOpen={showTooltip} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<p>{t('This gene is missing due to the following errors during analysis: ')}</p>
{reasons.map((warn) => (
<Alert key={warn.geneName} color="warning" fade={false} className="px-2 py-1 my-1">
<Alert key={warn.cdsName} color="warning" fade={false} className="px-2 py-1 my-1">
<WarningIcon />
{warn.warning}
</Alert>
Expand Down Expand Up @@ -87,7 +87,7 @@ export function PeptideViewUnsized({ width, sequence, warnings, viewedGene }: Pe
)
}

const warningsForThisGene = (warnings ?? []).filter((warn) => warn.geneName === viewedGene)
const warningsForThisGene = (warnings ?? []).filter((warn) => warn.cdsName === viewedGene)
if (warningsForThisGene.length > 0) {
return (
<SequenceViewWrapper>
Expand All @@ -101,11 +101,11 @@ export function PeptideViewUnsized({ width, sequence, warnings, viewedGene }: Pe
const pixelsPerAa = width / Math.round(cdsLength)
const groups = aaChangesGroups.filter((group) => group.name === viewedGene)

const unknownAaRangesForGene = unknownAaRanges.find((range) => range.geneName === viewedGene)
const unknownAaRangesForGene = unknownAaRanges.find((range) => range.cdsName === viewedGene)
const unsequencedRanges = aaUnsequencedRanges[viewedGene] ?? []

const frameShiftMarkers = frameShifts
.filter((frameShift) => frameShift.geneName === cds.name)
.filter((frameShift) => frameShift.cdsName === cds.name)
.map((frameShift) => {
const id = getSafeId('frame-shift-aa-marker', { ...frameShift })
return (
Expand All @@ -120,7 +120,7 @@ export function PeptideViewUnsized({ width, sequence, warnings, viewedGene }: Pe
})

const insertionMarkers = aaInsertions
.filter((ins) => ins.gene === viewedGene)
.filter((ins) => ins.cds === viewedGene)
.map((insertion) => {
return (
<PeptideMarkerInsertion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface FrameShiftMarkerProps extends SVGProps<SVGRectElement> {
export const SequenceMarkerFrameShift = React.memo(SequenceMarkerFrameShiftUnmemoed)

function SequenceMarkerFrameShiftUnmemoed({ index, seqName, frameShift, pixelsPerBase }: FrameShiftMarkerProps) {
const { geneName, nucAbs, codon, gapsTrailing, gapsLeading } = frameShift
const { cdsName, nucAbs, codon, gapsTrailing, gapsLeading } = frameShift

const frameShiftSegments = useMemo(
() =>
Expand All @@ -43,7 +43,7 @@ function SequenceMarkerFrameShiftUnmemoed({ index, seqName, frameShift, pixelsPe
key={id}
identifier={id}
index={index}
geneName={geneName}
geneName={cdsName}
codon={codon}
nucAbs={nucAbs}
gapsTrailing={gapsTrailing}
Expand All @@ -52,7 +52,7 @@ function SequenceMarkerFrameShiftUnmemoed({ index, seqName, frameShift, pixelsPe
/>
)
}),
[codon, gapsLeading, gapsTrailing, geneName, index, nucAbs, pixelsPerBase, seqName],
[codon, gapsLeading, gapsTrailing, cdsName, index, nucAbs, pixelsPerBase, seqName],
)

// eslint-disable-next-line react/jsx-no-useless-fragment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export function SequenceViewUnsized({ sequence, width }: SequenceViewProps) {

const frameShiftMarkers = frameShifts.map((frameShift) => (
<SequenceMarkerFrameShift
key={`${frameShift.geneName}_${frameShift.nucAbs.map((na) => na.begin).join('-')}`}
key={`${frameShift.cdsName}_${frameShift.nucAbs.map((na) => na.begin).join('-')}`}
index={index}
seqName={seqName}
frameShift={frameShift}
Expand Down
4 changes: 2 additions & 2 deletions packages_rs/nextclade-web/src/helpers/formatFrameShift.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { FrameShift } from 'src/types'
import { formatRange } from 'src/helpers/formatRange'

export function formatFrameShift({ geneName, codon }: FrameShift) {
return `${geneName}:${formatRange(codon)}`
export function formatFrameShift({ cdsName, codon }: FrameShift) {
return `${cdsName}:${formatRange(codon)}`
}
4 changes: 2 additions & 2 deletions packages_rs/nextclade-web/src/helpers/formatMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export function formatAADeletion({ cdsName, refAa, pos }: AaDel) {
return `${cdsName}:${notation}`
}

export function formatStopCodon({ geneName, codon }: StopCodonLocation) {
export function formatStopCodon({ cdsName, codon }: StopCodonLocation) {
// NOTE: by convention, codons are numbered starting from 1, however our arrays are 0-based
const codonOneBased = codon + 1
return `${geneName}:${codonOneBased}`
return `${cdsName}:${codonOneBased}`
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function formatQCStopCodons<TFunction extends TFunctionInterface>(

const { score, stopCodons, totalStopCodons } = qcStopCodons

const geneList = uniq(stopCodons.map((sc) => sc.geneName)).join(', ')
const geneList = uniq(stopCodons.map((sc) => sc.cdsName)).join(', ')

return t(
'{{totalStopCodons}} misplaced stop codon(s) detected. Affected gene(s): {{geneList}}. QC score: {{score}}',
Expand Down
6 changes: 3 additions & 3 deletions packages_rs/nextclade/src/align/insertions_strip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub fn insertions_strip<T: Letter<T>>(qry_seq: &[T], ref_seq: &[T]) -> StripInse
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, schemars::JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct AaIns {
pub gene: String,
pub cds: String,
pub pos: i32,

#[schemars(with = "String")]
Expand All @@ -117,7 +117,7 @@ pub struct AaIns {
/// Order amino acid insertions by gene, position, then length
impl Ord for AaIns {
fn cmp(&self, other: &Self) -> Ordering {
(&self.gene, self.pos, self.ins.len()).cmp(&(&other.gene, other.pos, other.ins.len()))
(&self.cds, self.pos, self.ins.len()).cmp(&(&other.cds, other.pos, other.ins.len()))
}
}

Expand All @@ -132,7 +132,7 @@ pub fn get_aa_insertions(translation: &Translation) -> Vec<AaIns> {
.iter_cdses()
.flat_map(|(cds_name, cds_tr)| {
cds_tr.insertions.iter().map(|Insertion::<Aa> { pos, ins }| AaIns {
gene: cds_name.clone(),
cds: cds_name.clone(),
pos: *pos,
ins: ins.clone(),
})
Expand Down
12 changes: 6 additions & 6 deletions packages_rs/nextclade/src/analyze/find_aa_motifs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::alphabet::aa::from_aa_seq;
use crate::analyze::find_aa_motifs_changes::AaMotifsMap;
use crate::analyze::virus_properties::{AaMotifsDesc, CountAaMotifsGeneDesc};
use crate::analyze::virus_properties::{AaMotifsDesc, CountAaMotifsCdsDesc};
use crate::coord::position::AaRefPosition;
use crate::coord::range::{intersect_or_none, AaRefRange};
use crate::translate::translate_genes::{CdsTranslation, Translation};
Expand Down Expand Up @@ -53,16 +53,16 @@ fn process_one_aa_motifs_desc(
let AaMotifsDesc {
name,
motifs,
include_genes,
include_cdses: include_genes,
..
} = aa_motifs_desc;

// If no genes specified, process all genes
let include_genes = if include_genes.is_empty() {
translation
.cdses()
.map(|translation| CountAaMotifsGeneDesc {
gene: translation.name.clone(),
.map(|translation| CountAaMotifsCdsDesc {
cds: translation.name.clone(),
ranges: vec![],
})
.collect_vec()
Expand All @@ -72,10 +72,10 @@ fn process_one_aa_motifs_desc(

include_genes
.iter()
.flat_map(|CountAaMotifsGeneDesc { gene, ranges }| {
.flat_map(|CountAaMotifsCdsDesc { cds, ranges }| {
translation
.cdses()
.filter(|CdsTranslation { name, .. }| name == gene)
.filter(|CdsTranslation { name, .. }| name == cds)
.flat_map(|translation| process_one_translation(translation, name, motifs, ranges))
.collect_vec()
})
Expand Down
8 changes: 4 additions & 4 deletions packages_rs/nextclade/src/analyze/find_aa_motifs_changes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct AaMotifChanges {
#[serde(rename_all = "camelCase")]
pub struct AaMotifMutation {
pub name: String,
pub gene: String,
pub cds: String,
pub position: AaRefPosition,
pub ref_seq: String,
pub qry_seq: String,
Expand Down Expand Up @@ -99,7 +99,7 @@ fn find_aa_motifs_changes_one(
Zip::from((kept_ref, kept_qry))
.map(|(motif_ref, motif_qry)| AaMotifMutation {
name: motif_ref.name,
gene: motif_ref.cds,
cds: motif_ref.cds,
position: motif_ref.position,
ref_seq: motif_ref.seq,
qry_seq: motif_qry.seq,
Expand Down Expand Up @@ -129,7 +129,7 @@ fn add_ref_seq(motif: &AaMotif, ref_translation: &Translation) -> Result<AaMotif

Ok(AaMotifMutation {
name: motif.name.clone(),
gene: motif.cds.clone(),
cds: motif.cds.clone(),
position: motif.position,
ref_seq,
qry_seq: motif.seq.clone(),
Expand All @@ -149,7 +149,7 @@ fn add_qry_seq(motif: &AaMotif, qry_translation: &Translation) -> Option<AaMotif
let qry_seq = from_aa_seq(&tr.seq[sequenced_motif_range.to_std()]);
Some(AaMotifMutation {
name: motif.name.clone(),
gene: motif.cds.clone(),
cds: motif.cds.clone(),
position: motif.position,
ref_seq: motif.seq.clone(),
qry_seq,
Expand Down
10 changes: 5 additions & 5 deletions packages_rs/nextclade/src/analyze/find_private_aa_mutations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::alphabet::letter::Letter;
use crate::analyze::aa_del::AaDel;
use crate::analyze::aa_sub::AaSub;
use crate::analyze::is_sequenced::is_aa_sequenced;
use crate::analyze::letter_ranges::GeneAaRange;
use crate::analyze::letter_ranges::CdsAaRange;
use crate::coord::position::{AaRefPosition, PositionLike};
use crate::coord::range::AaRefRange;
use crate::gene::cds::Cds;
Expand Down Expand Up @@ -33,7 +33,7 @@ pub fn find_private_aa_mutations(
node: &AuspiceGraphNodePayload,
aa_substitutions: &[AaSub],
aa_deletions: &[AaDel],
aa_unknowns: &[GeneAaRange],
aa_unknowns: &[CdsAaRange],
aa_unsequenced_ranges: &BTreeMap<String, Vec<AaRefRange>>,
ref_peptides: &Translation,
gene_map: &GeneMap,
Expand All @@ -56,7 +56,7 @@ pub fn find_private_aa_mutations(

let aa_deletions = aa_deletions.iter().filter(|del| del.cds_name == cds.name).collect_vec();

let aa_unknowns = aa_unknowns.iter().filter(|unk| unk.gene_name == cds.name).collect_vec();
let aa_unknowns = aa_unknowns.iter().filter(|unk| unk.cds_name == cds.name).collect_vec();

let private_aa_mutations = find_private_aa_mutations_for_one_gene(
cds,
Expand All @@ -79,7 +79,7 @@ pub fn find_private_aa_mutations_for_one_gene(
node_mut_map: &BTreeMap<AaRefPosition, Aa>,
aa_substitutions: &[&AaSub],
aa_deletions: &[&AaDel],
aa_unknowns: &[&GeneAaRange],
aa_unknowns: &[&CdsAaRange],
aa_unsequenced_ranges: &[AaRefRange],
ref_peptide: &[Aa],
) -> PrivateAaMutations {
Expand Down Expand Up @@ -246,7 +246,7 @@ fn process_seq_deletions(
fn find_reversions(
cds: &Cds,
node_mut_map: &BTreeMap<AaRefPosition, Aa>,
aa_unknowns: &[&GeneAaRange],
aa_unknowns: &[&CdsAaRange],
aa_unsequenced_ranges: &[AaRefRange],
ref_peptide: &[Aa],
seq_positions_mutated_or_deleted: &mut BTreeSet<AaRefPosition>,
Expand Down
4 changes: 2 additions & 2 deletions packages_rs/nextclade/src/analyze/is_sequenced.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::alphabet::letter::Letter;
use crate::analyze::letter_ranges::{GeneAaRange, NucRange};
use crate::analyze::letter_ranges::{CdsAaRange, NucRange};
use crate::coord::position::{AaRefPosition, NucRefGlobalPosition};
use crate::coord::range::{AaRefRange, NucRefGlobalRange};
use itertools::Itertools;
Expand All @@ -22,7 +22,7 @@ pub fn is_nuc_non_acgtn(pos: NucRefGlobalPosition, non_acgtns: &[NucRange]) -> b

/// Decides whether a given position in peptide is considered "sequenced".
/// The position is considered sequenced if it is not contained in any of the unknown of unsequenced regions
pub fn is_aa_sequenced(pos: AaRefPosition, aa_unknowns: &[&GeneAaRange], aa_unsequenced_ranges: &[AaRefRange]) -> bool {
pub fn is_aa_sequenced(pos: AaRefPosition, aa_unknowns: &[&CdsAaRange], aa_unsequenced_ranges: &[AaRefRange]) -> bool {
let is_missing = aa_unknowns.iter().any(|missing| missing.contains_pos(pos));
let is_unsequenced = aa_unsequenced_ranges
.iter()
Expand Down
Loading

1 comment on commit 2e58b16

@vercel
Copy link

@vercel vercel bot commented on 2e58b16 Jan 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nextclade – ./

nextclade.vercel.app
nextclade-nextstrain.vercel.app
nextclade-git-master-nextstrain.vercel.app

Please sign in to comment.