From 49e9a30faef3795cfb34f42facf69b315900f0e4 Mon Sep 17 00:00:00 2001 From: Susanna Kiwala Date: Tue, 8 Oct 2024 14:53:50 -0500 Subject: [PATCH 1/8] Remove . between e and number in exon-specific fusion variant names --- server/app/models/variants/fusion_variant.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/app/models/variants/fusion_variant.rb b/server/app/models/variants/fusion_variant.rb index aa9a90bd3..2eb9eabc7 100644 --- a/server/app/models/variants/fusion_variant.rb +++ b/server/app/models/variants/fusion_variant.rb @@ -132,7 +132,7 @@ def construct_partner_name(name_type:, partner_status:, gene:, exon_coords:) when :representative "#{gene.name}(entrez:#{gene.entrez_id})" when :civic - "e.#{exon_coords.exon}#{exon_coords.formatted_offset}#{exon_coords.exon_offset}" + "e#{exon_coords.exon}#{exon_coords.formatted_offset}#{exon_coords.exon_offset}" when :vicc "#{exon_coords.representative_transcript}(#{gene.name}):e.#{exon_coords.exon}#{exon_coords.formatted_offset}#{exon_coords.exon_offset}" when :molecular_profile From 94103e4f058b2e67656912b73d70a988c42b1c40 Mon Sep 17 00:00:00 2001 From: Susanna Kiwala Date: Tue, 8 Oct 2024 14:54:49 -0500 Subject: [PATCH 2/8] Fusion MP name should be Feature name plus Variant name --- server/app/models/features/fusion.rb | 5 ----- server/app/models/variants/fusion_variant.rb | 14 -------------- 2 files changed, 19 deletions(-) diff --git a/server/app/models/features/fusion.rb b/server/app/models/features/fusion.rb index 891135912..f8d3cdcdc 100644 --- a/server/app/models/features/fusion.rb +++ b/server/app/models/features/fusion.rb @@ -27,11 +27,6 @@ class Fusion < ActiveRecord::Base validate :partner_status_valid_for_gene_ids validate :at_least_one_gene_id - #When displayed as part of an MP, the Variant Name specifies the feature - def mp_name - nil - end - def partner_status_valid_for_gene_ids if !self.in_revision_validation_context [self.five_prime_gene, self.three_prime_gene].zip([self.five_prime_partner_status, self.three_prime_partner_status], [:five_prime_gene, :three_prime_gene]).each do |gene, status, fk| diff --git a/server/app/models/variants/fusion_variant.rb b/server/app/models/variants/fusion_variant.rb index 2eb9eabc7..c28ee1bde 100644 --- a/server/app/models/variants/fusion_variant.rb +++ b/server/app/models/variants/fusion_variant.rb @@ -67,18 +67,6 @@ def required_fields ] end - def mp_name - if name == Constants::REPRESENTATIVE_FUSION_VARIANT_NAME - "#{feature.name} #{Constants::REPRESENTATIVE_FUSION_VARIANT_NAME}" - else - [ - construct_five_prime_name(name_type: :molecular_profile), - construct_three_prime_name(name_type: :molecular_profile) - ].join("::") - end - - end - def generate_vicc_name if name == Constants::REPRESENTATIVE_FUSION_VARIANT_NAME "#{construct_five_prime_name(name_type: :representative)}::#{construct_three_prime_name(name_type: :representative)}" @@ -135,8 +123,6 @@ def construct_partner_name(name_type:, partner_status:, gene:, exon_coords:) "e#{exon_coords.exon}#{exon_coords.formatted_offset}#{exon_coords.exon_offset}" when :vicc "#{exon_coords.representative_transcript}(#{gene.name}):e.#{exon_coords.exon}#{exon_coords.formatted_offset}#{exon_coords.exon_offset}" - when :molecular_profile - "#{gene.name}:e.#{exon_coords.exon}#{exon_coords.formatted_offset}#{exon_coords.exon_offset}" end elsif partner_status == 'unknown' '?' From 45e238e49f9eeab54720c7b82065c255995cc391 Mon Sep 17 00:00:00 2001 From: Susanna Kiwala Date: Tue, 8 Oct 2024 14:55:35 -0500 Subject: [PATCH 3/8] Fix bug in exon fusion coordinate background job --- server/app/jobs/populate_fusion_coordinates.rb | 10 ++++++---- .../app/models/activities/create_fusion_variant.rb | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/server/app/jobs/populate_fusion_coordinates.rb b/server/app/jobs/populate_fusion_coordinates.rb index 43042d62a..f0e336a4d 100644 --- a/server/app/jobs/populate_fusion_coordinates.rb +++ b/server/app/jobs/populate_fusion_coordinates.rb @@ -20,14 +20,14 @@ def perform(variant) def populate_coords(coords, secondary_coordinates) if coords.present? && coords.representative_transcript.present? (exon, highest_exon) = get_exon_for_transcript(coords.representative_transcript, coords.exon) - populate_exon_coordinates(coords, exon) + populate_exon_coordinates(coords, exon, coords.exon) if coords.coordinate_type =~ /Five Prime/ (secondary_exon, _) = get_exon_for_transcript(secondary_coordinates.representative_transcript, 1) - populate_exon_coordinates(secondary_coordinates, secondary_exon) + populate_exon_coordinates(secondary_coordinates, secondary_exon, 1) else (secondary_exon, _) = get_exon_for_transcript(secondary_coordinates.representative_transcript, highest_exon) - populate_exon_coordinates(secondary_coordinates, secondary_exon) + populate_exon_coordinates(secondary_coordinates, secondary_exon, highest_exon) end end end @@ -58,7 +58,9 @@ def get_exon_for_transcript(transcript, exon_number) [exon.first, max_exon_on_transcript] end - def populate_exon_coordinates(coordinates, exon) + def populate_exon_coordinates(coordinates, exon, exon_number) + coordinates.exon = exon_number + strand = if exon['strand'] == -1 'negative' else diff --git a/server/app/models/activities/create_fusion_variant.rb b/server/app/models/activities/create_fusion_variant.rb index 36ce8a929..4e53b0488 100644 --- a/server/app/models/activities/create_fusion_variant.rb +++ b/server/app/models/activities/create_fusion_variant.rb @@ -47,11 +47,21 @@ def call_actions def stub_remaining_coordinates if variant.fusion.five_prime_partner_status == 'known' - variant.five_prime_start_exon_coordinates = ExonCoordinate.generate_stub(variant, 'Five Prime Start Exon Coordinate') + e = ExonCoordinate.generate_stub(variant, 'Five Prime Start Exon Coordinate') + e.representative_transcript = five_prime_end_exon_coords.representative_transcript + e.reference_build = five_prime_end_exon_coords.reference_build + e.ensembl_version = five_prime_end_exon_coords.ensembl_version + e.save! + variant.five_prime_start_exon_coordinates = e variant.five_prime_coordinates = VariantCoordinate.generate_stub(variant, 'Five Prime Fusion Coordinate') end if variant.fusion.three_prime_partner_status == 'known' - variant.three_prime_end_exon_coordinates = ExonCoordinate.generate_stub(variant, 'Three Prime End Exon Coordinate') + e = ExonCoordinate.generate_stub(variant, 'Three Prime End Exon Coordinate') + e.representative_transcript = three_prime_start_exon_coords.representative_transcript + e.reference_build = three_prime_start_exon_coords.reference_build + e.ensembl_version = three_prime_start_exon_coords.ensembl_version + e.save! + variant.three_prime_end_exon_coordinates = e variant.three_prime_coordinates = VariantCoordinate.generate_stub(variant, 'Three Prime Fusion Coordinate') end end From f79cf440cd490aebeaaee5aad24c90c35270c000 Mon Sep 17 00:00:00 2001 From: Susanna Kiwala Date: Wed, 9 Oct 2024 08:25:30 -0500 Subject: [PATCH 4/8] Add VICC compliant name to variant popovers and variant cards --- ...olecular-profile-fusion-variant-card.component.html | 10 ++++++++-- .../variant-popover/variant-popover.component.html | 7 +++++++ .../variants/variant-popover/variant-popover.query.gql | 3 +++ client/src/app/generated/civic.apollo.ts | 7 +++++-- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/client/src/app/components/molecular-profiles/molecular-profile-fusion-variant-card/molecular-profile-fusion-variant-card.component.html b/client/src/app/components/molecular-profiles/molecular-profile-fusion-variant-card/molecular-profile-fusion-variant-card.component.html index 7fe977bb3..3b8d4c3ee 100644 --- a/client/src/app/components/molecular-profiles/molecular-profile-fusion-variant-card/molecular-profile-fusion-variant-card.component.html +++ b/client/src/app/components/molecular-profiles/molecular-profile-fusion-variant-card/molecular-profile-fusion-variant-card.component.html @@ -14,7 +14,7 @@ - + + + + {{ variant.viccCompliantName }} + + + + {{ variant.viccCompliantName }} + ; -export type VariantPopoverQuery = { __typename: 'Query', variant?: { __typename: 'FactorVariant', id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } } | { __typename: 'FusionVariant', id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } } | { __typename: 'GeneVariant', alleleRegistryId?: string | undefined, id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } } | { __typename: 'Variant', id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } } | undefined }; +export type VariantPopoverQuery = { __typename: 'Query', variant?: { __typename: 'FactorVariant', id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } } | { __typename: 'FusionVariant', viccCompliantName: string, id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } } | { __typename: 'GeneVariant', alleleRegistryId?: string | undefined, id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } } | { __typename: 'Variant', id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } } | undefined }; type VariantPopoverFields_FactorVariant_Fragment = { __typename: 'FactorVariant', id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } }; -type VariantPopoverFields_FusionVariant_Fragment = { __typename: 'FusionVariant', id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } }; +type VariantPopoverFields_FusionVariant_Fragment = { __typename: 'FusionVariant', viccCompliantName: string, id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } }; type VariantPopoverFields_GeneVariant_Fragment = { __typename: 'GeneVariant', alleleRegistryId?: string | undefined, id: number, name: string, variantAliases: Array, feature: { __typename: 'Feature', id: number, name: string, link: string, deprecated: boolean, flagged: boolean }, molecularProfiles: { __typename: 'MolecularProfileConnection', totalCount: number }, revisions: { __typename: 'RevisionConnection', totalCount: number }, comments: { __typename: 'CommentConnection', totalCount: number }, flags: { __typename: 'FlagConnection', totalCount: number } }; @@ -11019,6 +11019,9 @@ export const VariantPopoverFieldsFragmentDoc = gql` ... on GeneVariant { alleleRegistryId } + ... on FusionVariant { + viccCompliantName + } feature { id name From 6d2092f9bb5a5ce4fa54650b78d27b829780e2c8 Mon Sep 17 00:00:00 2001 From: Susanna Kiwala Date: Wed, 9 Oct 2024 11:09:30 -0500 Subject: [PATCH 5/8] Only show variant creation/deprecation description list if either activity exists --- .../factor-variant-summary/factor-variant-summary.page.html | 3 ++- .../fusion-variant-summary/fusion-variant-summary.page.html | 3 ++- .../gene-variant-summary/gene-variant-summary.page.html | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/client/src/app/components/variants/factor-variant-summary/factor-variant-summary.page.html b/client/src/app/components/variants/factor-variant-summary/factor-variant-summary.page.html index 55f1008b2..3c0268dbd 100644 --- a/client/src/app/components/variants/factor-variant-summary/factor-variant-summary.page.html +++ b/client/src/app/components/variants/factor-variant-summary/factor-variant-summary.page.html @@ -71,7 +71,8 @@ nzLayout="vertical" nzSize="small" [nzColumn]="{ xxl: 2, xl: 2, lg: 1, md: 1, sm: 1, xs: 1 }" - nzBordered="true"> + nzBordered="true" + *ngIf="variant.creationActivity || variant.deprecationActivity"> diff --git a/client/src/app/components/variants/fusion-variant-summary/fusion-variant-summary.page.html b/client/src/app/components/variants/fusion-variant-summary/fusion-variant-summary.page.html index c89f7df84..e8d3d3b3f 100644 --- a/client/src/app/components/variants/fusion-variant-summary/fusion-variant-summary.page.html +++ b/client/src/app/components/variants/fusion-variant-summary/fusion-variant-summary.page.html @@ -71,7 +71,8 @@ nzLayout="vertical" nzSize="small" [nzColumn]="{ xxl: 2, xl: 2, lg: 1, md: 1, sm: 1, xs: 1 }" - nzBordered="true"> + nzBordered="true" + *ngIf="variant.creationActivity || variant.deprecationActivity"> diff --git a/client/src/app/components/variants/gene-variant-summary/gene-variant-summary.page.html b/client/src/app/components/variants/gene-variant-summary/gene-variant-summary.page.html index 926f68e7f..4876ecf36 100644 --- a/client/src/app/components/variants/gene-variant-summary/gene-variant-summary.page.html +++ b/client/src/app/components/variants/gene-variant-summary/gene-variant-summary.page.html @@ -119,7 +119,8 @@ nzLayout="vertical" nzSize="small" [nzColumn]="{ xxl: 2, xl: 2, lg: 1, md: 1, sm: 1, xs: 1 }" - nzBordered="true"> + nzBordered="true" + *ngIf="variant.creationActivity || variant.deprecationActivity"> From be8ecc33d0e4c14afdc0f514cca25752ec9826cc Mon Sep 17 00:00:00 2001 From: Susanna Kiwala Date: Wed, 9 Oct 2024 11:09:58 -0500 Subject: [PATCH 6/8] Some more bugfixes around fusion coordinate population script --- server/app/jobs/populate_fusion_coordinates.rb | 7 +++++++ server/app/lib/scrapers/ensembl_api_helpers.rb | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/server/app/jobs/populate_fusion_coordinates.rb b/server/app/jobs/populate_fusion_coordinates.rb index f0e336a4d..e8c105953 100644 --- a/server/app/jobs/populate_fusion_coordinates.rb +++ b/server/app/jobs/populate_fusion_coordinates.rb @@ -18,6 +18,13 @@ def perform(variant) end def populate_coords(coords, secondary_coordinates) + #For representative fusions, these fields are empty when the representative exons coords are first curated/revisions accepted + #For all fusions, these require updating when a revision on the primary set of coords edits these fiels + secondary_coordinates.representative_transcript = coords.representative_transcript + secondary_coordinates.reference_build = coords.reference_build + secondary_coordinates.ensembl_version = coords.ensembl_version + secondary_coordinates.save! + if coords.present? && coords.representative_transcript.present? (exon, highest_exon) = get_exon_for_transcript(coords.representative_transcript, coords.exon) populate_exon_coordinates(coords, exon, coords.exon) diff --git a/server/app/lib/scrapers/ensembl_api_helpers.rb b/server/app/lib/scrapers/ensembl_api_helpers.rb index 74da6a728..f2e835160 100644 --- a/server/app/lib/scrapers/ensembl_api_helpers.rb +++ b/server/app/lib/scrapers/ensembl_api_helpers.rb @@ -26,9 +26,12 @@ def self.get_exons_for_ensembl_id(ensembl_id, warning = nil) elsif error_message == "ID '#{ensembl_id}' not found" return EnsemblResult.new(nil, "Transcript doesn't exist in GRCh37 at any version: #{ensembl_id}", warning) else - return EnsemblResult.new(nil, nil, warning) + return EnsemblResult.new(nil, error_message, warning) end end + if data.nil? + return EnsemblResult.new(nil, "No data returned for transcript: #{ensembl_id}", warning) + end EnsemblResult.new(data.sort_by { |exon| exon['start'] }, nil, warning) end From a241f2b6a167323022183ef7bce45733e2b28cf8 Mon Sep 17 00:00:00 2001 From: Susanna Kiwala Date: Wed, 9 Oct 2024 12:55:47 -0500 Subject: [PATCH 7/8] Fix typo --- server/app/jobs/populate_fusion_coordinates.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/app/jobs/populate_fusion_coordinates.rb b/server/app/jobs/populate_fusion_coordinates.rb index e8c105953..1bdfd5a65 100644 --- a/server/app/jobs/populate_fusion_coordinates.rb +++ b/server/app/jobs/populate_fusion_coordinates.rb @@ -19,7 +19,7 @@ def perform(variant) def populate_coords(coords, secondary_coordinates) #For representative fusions, these fields are empty when the representative exons coords are first curated/revisions accepted - #For all fusions, these require updating when a revision on the primary set of coords edits these fiels + #For all fusions, these require updating when a revision on the primary set of coords edits these fields secondary_coordinates.representative_transcript = coords.representative_transcript secondary_coordinates.reference_build = coords.reference_build secondary_coordinates.ensembl_version = coords.ensembl_version From 52cee12ddc39e2fbca31912878cecc651e9abb16 Mon Sep 17 00:00:00 2001 From: Susanna Kiwala Date: Fri, 11 Oct 2024 10:12:25 -0500 Subject: [PATCH 8/8] Enable fusion forbidden field validations --- server/app/models/variants/fusion_variant.rb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/server/app/models/variants/fusion_variant.rb b/server/app/models/variants/fusion_variant.rb index c28ee1bde..8df15a2a4 100644 --- a/server/app/models/variants/fusion_variant.rb +++ b/server/app/models/variants/fusion_variant.rb @@ -2,10 +2,6 @@ module Variants class FusionVariant < Variant has_one :fusion, through: :feature, source: :feature_instance, source_type: 'Features::Fusion' - #TODO - make this - #validates_with FusionVariantValidator - #check feature partner status and corresponding stubbed coords - has_one :five_prime_coordinates, ->() { where(coordinate_type: 'Five Prime Fusion Coordinate') }, foreign_key: 'variant_id', @@ -88,10 +84,10 @@ def generate_name def forbidden_fields [ - # :ncit_id, - # :hgvs_description_ids, - # :clinvar_entry_ids, - # :allele_registry_id, + :ncit_id, + :hgvs_description_ids, + :clinvar_entry_ids, + :allele_registry_id, ] end