import _ from 'lodash' ; import CivicDataFetcher from './CivicDataFetcher' ; import { ICivicEntry , ICivicGeneIndex , ICivicGeneSummary , ICivicVariantIndex , ICivicVariantSummary , } from '../model/Civic' ; import { Mutation } from '../model/Mutation' ; export type MutationSpec = { gene : { hugoGeneSymbol : string ; } ; proteinChange : string ; } ; const civicClient = new CivicDataFetcher ( ) ; export enum CivicAlterationType { AMPLIFICATION = 'AMPLIFICATION' , DELETION = 'DELETION' } export const CIVIC_NA_VALUE = 'NA' ; /**
 * Asynchronously adds the given variant from a gene to the variant map specified.
 */ function lookupCivicVariantAndAddToMap ( variantMap , variantId , variantName , geneSymbol , geneId ) { return civicClient . getCivicVariantSummary ( variantId , variantName , geneId ) . then ( ( result ) => { if ( result ) { if ( ! variantMap [ geneSymbol ] ) { variantMap [ geneSymbol ] = { } ; } variantMap [ geneSymbol ] [ variantName ] = result ; } } ) ; } /**
 * Asynchronously return a map with Civic information from the genes given.
 */ export function getCivicGenes ( entrezGeneIds ) { let promises = [ ] ; const chunkedIds = _ . chunk ( _ . uniq ( entrezGeneIds ) , 400 ) ; chunkedIds . forEach ( entrezGeneIds => promises . push ( civicClient . getCivicGenesBatch ( entrezGeneIds . join ( ',' ) ) ) ) ; return Promise . all ( promises ) . then ( ( responses ) => { return responses . reduce ( ( acc , civicGenes ) => { civicGenes . forEach ( civicGene => ( acc [ civicGene . name ] = civicGene ) ) ; return acc ; } , { } ) ; } ) ; } /**
 * Asynchronously retrieve a map with Civic information from the mutationSpecs given for all genes in civicGenes.
 * If no mutationSpecs are given, then return the Civic information of all the CNA variants of the genes in civicGenes.
 */ export function getCivicVariants ( civicGenes , mutationSpecs ? ) { let civicVariants = { } ; let promises = [ ] ; if ( mutationSpecs ) { let calledVariants = new Set ( [ ] ) ; for ( let mutation of mutationSpecs ) { let geneSymbol = mutation . gene . hugoGeneSymbol ; let geneEntry = civicGenes [ geneSymbol ] ; let proteinChanges = [ mutation . proteinChange ] ; let split = mutation . proteinChange . split ( /[+\/]/ ) ; proteinChanges . push ( split [ 0 ] ) ; for ( let proteinChange of proteinChanges ) { if ( geneEntry && geneEntry . variants [ proteinChange ] ) { if ( ! calledVariants . has ( geneEntry . variants [ proteinChange ] ) ) { calledVariants . add ( geneEntry . variants [ proteinChange ] ) ; promises . push ( lookupCivicVariantAndAddToMap ( civicVariants , geneEntry . variants [ proteinChange ] , proteinChange , geneSymbol , geneEntry . id ) ) ; } } } } } else { for ( let geneName in civicGenes ) { let geneEntry = civicGenes [ geneName ] ; let geneVariants = geneEntry . variants ; if ( ! _ . isEmpty ( geneVariants ) ) { for ( let variantName in geneVariants ) { if ( variantName == CivicAlterationType . AMPLIFICATION || variantName == CivicAlterationType . DELETION ) { promises . push ( lookupCivicVariantAndAddToMap ( civicVariants , geneVariants [ variantName ] , variantName , geneName , geneEntry . id ) ) ; } } } } } return Promise . all ( promises ) . then ( ( ) => civicVariants ) ; } /**
 * Build a Civic Entry with the data given.
 */ export function buildCivicEntry ( geneEntry , geneVariants ) { return { name : geneEntry . name , description : geneEntry . description , url : geneEntry . url , variants : geneVariants , } ; } /**
 * Returns an ICivicEntry if the civicGenes and civicVariants have information about the gene and the mutation (variant) specified. Otherwise it returns null.
 */ export function getCivicEntry ( mutation , civicGenes , civicVariants ) { let geneSymbol = mutation . gene ? mutation . gene . hugoGeneSymbol : '' ; let civicEntry = null ; if ( civicGenes [ geneSymbol ] && civicVariants [ geneSymbol ] && civicVariants [ geneSymbol ] [ mutation . proteinChange ] ) { let geneVariants = { [ mutation . proteinChange ] : civicVariants [ geneSymbol ] [ mutation . proteinChange ] , } ; let geneEntry = civicGenes [ geneSymbol ] ; civicEntry = buildCivicEntry ( geneEntry , geneVariants ) ; } return civicEntry ; } export function fetchCivicGenes ( mutations , getEntrezGeneId ) { if ( mutations . length === 0 ) { return Promise . resolve ( { } ) ; } const entrezGeneSymbols = _ . uniq ( mutations . map ( mutation => getEntrezGeneId ( mutation ) ) ) ; return getCivicGenes ( entrezGeneSymbols ) ; } export function fetchCivicVariants ( civicGenes , mutations ) { let civicVariants ; if ( mutations . length > 0 ) { civicVariants = getCivicVariants ( civicGenes , mutations as MutationSpec [ ] ) ; } else if ( ! _ . isEmpty ( civicGenes ) ) { civicVariants = getCivicVariants ( civicGenes ) ; } else { civicVariants = Promise . resolve ( { } ) ; } return civicVariants ; }