diff --git a/src/app/components/analysis-panel/analysis-panel.component.html b/src/app/components/analysis-panel/analysis-panel.component.html index 553ba0a6f9983687d7a1b46c5cafa24857b1c340..2de28df86dd706a710b466e30752892a684b2080 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.html +++ b/src/app/components/analysis-panel/analysis-panel.component.html @@ -256,9 +256,9 @@ ID <p-sortIcon [field]="'drugId'"></p-sortIcon> </th> - <th [pSortableColumn]="'name'"> - Name - <p-sortIcon [field]="'name'"></p-sortIcon> + <th [pSortableColumn]="'label'"> + Label + <p-sortIcon [field]="'label'"></p-sortIcon> </th> <th [pSortableColumn]="'status'"> Approved @@ -285,7 +285,7 @@ <ng-template pTemplate="body" let-e> <tr> <td><a href="https://www.drugbank.ca/drugs/{{ e.drugId }}" target="_blank">{{ e.drugId }}</a></td> - <td>{{e.name}}</td> + <td>{{e.label}}</td> <td> <span *ngIf="e.status === 'approved'"> <i class="fa fa-check"></i> @@ -340,9 +340,9 @@ UniProt Code <p-sortIcon [field]="'uniprotAc'"></p-sortIcon> </th> - <th [pSortableColumn]="'name'"> - Gene - <p-sortIcon [field]="'name'"></p-sortIcon> + <th [pSortableColumn]="'symbol'"> + Symbol + <p-sortIcon [field]="'symbol'"></p-sortIcon> </th> <th [pSortableColumn]="'proteinName'"> Name @@ -368,7 +368,7 @@ <p-tableCheckbox [value]="e"></p-tableCheckbox> </td> <td><a href="https://www.uniprot.org/uniprot/{{ e.uniprotAc }}" target="_blank">{{ e.uniprotAc }}</a></td> - <td>{{e.name}}</td> + <td>{{e.symbol}}</td> <td>{{e.proteinName}}</td> <td *ngIf="tableHasScores">{{e.score | number}}</td> <td> diff --git a/src/app/components/analysis-panel/analysis-panel.component.ts b/src/app/components/analysis-panel/analysis-panel.component.ts index 8327f8a0a3ee6e598806e0a63b0ff86583193706..24b6ea5651e06310424c0ca213879f41d52c159f 100644 --- a/src/app/components/analysis-panel/analysis-panel.component.ts +++ b/src/app/components/analysis-panel/analysis-panel.component.ts @@ -33,6 +33,7 @@ import {NetworkSettings} from '../../network-settings'; import { NetexControllerService } from 'src/app/services/netex-controller/netex-controller.service'; import { IConfig } from 'src/app/config'; import { config } from 'rxjs'; +import { wrapReference } from '@angular/compiler/src/render3/util'; declare var vis: any; @@ -387,6 +388,26 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { } } + public inferNodeLabel(config: IConfig, wrapper: Wrapper): string { + if (wrapper.data.label) { + return wrapper.data.label; + } + const identifier = config.identifier; + if (identifier === 'uniprot'){ + return wrapper.data.uniprotAc; + } else if (identifier === 'symbol') { + return wrapper.data.symbol; + } else if (identifier === 'ensg') { + // heuristc to find most important ensg is to look for smallest id + // parse ensg numbers to integers + const ensg_numbers = wrapper.data.ensg.map(x => parseInt(x)); + // get index of smalles number + const i = ensg_numbers.reduce((iMin, x, i, arr) => x < arr[iMin] ? i : iMin, 0); + // return ensg-ID + return wrapper.data.ensg[i]; + } + } + /** * Maps analysis result returned from database to valid Vis.js network input @@ -411,6 +432,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { const scores = attributes.scores || {}; const details = attributes.details || {}; const wrappers: { [key: string]: Wrapper } = {}; + for (const node of network.nodes) { // backend converts object keys to PascalCase: p_123 --> p123 const nodeObjectKey = node.split('_').join(''); @@ -438,6 +460,14 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { }; } + /** + * maps node object returned from backend to frontend node, i.e. input to vis.js + * @param config + * @param wrapper + * @param isSeed + * @param score + * @returns + */ private mapNode(config: IConfig, wrapper: Wrapper, isSeed?: boolean, score?: number): any { // const node = NetworkSettings.getNodeStyle(nodeType, isSeed, this.analysis.inSelection(wrapper)); let group = this.inferNodeGroup(wrapper); @@ -446,7 +476,7 @@ export class AnalysisPanelComponent implements OnInit, OnChanges { } const node = JSON.parse(JSON.stringify(config.nodeGroups[group])); node.id = wrapper.id; - node.label = wrapper.data.symbol; + node.label = this.inferNodeLabel(config, wrapper); node.nodeType = group; node.isSeed = isSeed; node.wrapper = wrapper; diff --git a/src/app/config.ts b/src/app/config.ts index b24458bb037e4466807ab082dd2858cf079f4bc3..efa5056de1ca3f4f0e0f31486692bb411090494b 100644 --- a/src/app/config.ts +++ b/src/app/config.ts @@ -19,7 +19,7 @@ export interface EdgeGroup { color: string; } -export type Identifier = 'hugo'|'uniprot'|'ensg'; +export type Identifier = 'symbol'|'uniprot'|'ensg'; export type InteractionDrugProteinDB = 'DrugBank'|'Chembl'|'DGIdb'; export type InteractionProteinProteinDB = 'STRING'|'BioGRID'|'APID'; @@ -70,7 +70,7 @@ export const defaultConfig: IConfig = { showTasks: true, showFooter: true, showLegend: true, - identifier: 'hugo', + identifier: 'symbol', interactionDrugProtein: 'DrugBank', interactionProteinProtein: 'STRING', nodeGroups: { diff --git a/src/app/dialogs/launch-analysis/launch-analysis.component.ts b/src/app/dialogs/launch-analysis/launch-analysis.component.ts index 4faf19c9f2e4529f2cf9aecb790c7d832e66fa59..bbf91fa33a4d4d6fa489a57c231ae99adce54686 100644 --- a/src/app/dialogs/launch-analysis/launch-analysis.component.ts +++ b/src/app/dialogs/launch-analysis/launch-analysis.component.ts @@ -102,8 +102,14 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges { } public async startTask() { + // filter out all seed nodes that do not have a netex_Id, hence do not + // exist in the backend + const seeds = this.analysis.getSelection().map((item) => item.data.netexId) + const seedsFiltered = seeds.filter(function (el) { + return el != null; + }); const parameters: any = { - seeds: this.analysis.getSelection().map((item) => item.data.netexId), + seeds: seedsFiltered, config: this.config, input_network: this.inputNetwork }; @@ -117,7 +123,6 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges { this.inputNetwork.nodes.forEach(node => { delete node.interactions }); - console.log(this.inputNetwork) if (this.algorithm === 'trustrank') { parameters.damping_factor = this.trustrankDampingFactor; @@ -170,7 +175,9 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges { } parameters.hub_penalty = this.multisteinerHubPenalty; } + console.log('parameters') + console.log(parameters) await this.analysis.startAnalysis(this.algorithm, this.target, parameters); } diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts index 56f660733c3945bd12922b1dcd8803f44b8ec997..0776354581ff56a88fb41150e974c0a499944e26 100644 --- a/src/app/interfaces.ts +++ b/src/app/interfaces.ts @@ -1,7 +1,7 @@ import {AlgorithmType, QuickAlgorithmType} from './services/analysis/analysis.service'; export interface Node { - name: string; + label: string; symbol: string; id: string; netexId?: string; @@ -14,7 +14,6 @@ export interface Node { x?: number; y?: number; expressionLevel?: number; - label?: string; } export interface Tissue { @@ -121,6 +120,8 @@ export function getWrapperFromCustom(gene: Node): Wrapper { /** * Constructs wrapper interface for gene */ + // if gene.label is undefined, set it to id + gene.label = gene.label ? gene.label : gene.id return { id: getNodeId(gene), nodeId: getNodeId(gene), @@ -163,7 +164,7 @@ export interface Wrapper { type: WrapperType; data: { id: string; - name: string; + label: string; symbol?: string; netexId?: string; ensg?: Array<string>; @@ -172,7 +173,6 @@ export interface Wrapper { interactions?: any; group?: string; uniprotAc?: string; - label?: string; expressionLevel?: number; x?: number; y?: number; @@ -186,7 +186,7 @@ export interface Wrapper { export interface Drug { id: string; - name: string; + label: string; status: 'approved' | 'investigational'; inTrial: boolean; inLiterature: boolean; diff --git a/src/app/services/omnipath-controller/omnipath-controller.service.ts b/src/app/services/omnipath-controller/omnipath-controller.service.ts index e86fa86c404b843fa02587c739eed7f7383f0835..4fe4d14c16bf627487b43093ad9a75fefd05cb94 100644 --- a/src/app/services/omnipath-controller/omnipath-controller.service.ts +++ b/src/app/services/omnipath-controller/omnipath-controller.service.ts @@ -34,7 +34,7 @@ export class OmnipathControllerService { // entry 1 is always source uniprot ID, entry 2 always target uniprot ID source = lineValues[0]; target = lineValues[1]; - } else if (identifier === 'hugo') { + } else if (identifier === 'symbol') { // entry 3 is always source name, entry 4 always target name source = lineValues[2]; target = lineValues[3]; diff --git a/src/index.html b/src/index.html index f8606382ed84869563486d49a49286edd34be947..15df6aafbe35e3361391d8cf039524079863257b 100644 --- a/src/index.html +++ b/src/index.html @@ -38,13 +38,13 @@ <network-expander id="netexp1" config='{ - "nodeGroups": {"0.5": {"type": "gene", "color": "rgb(204, 255, 51)", "name": "0.5", "shape": "circle"}, "1.5": {"type": "gene", "color": "rgb(102, 255, 51)", "name": "1.5", "shape": "circle"}, "2.0": {"type": "gene", "color": "rgb(51, 204, 51)", "name": "2.0", "shape": "circle"}, "-2.0": {"type": "gene", "color": "rgb(255, 0, 0)", "name": "-2.0", "shape": "circle"}}, + "nodeGroups": {"0.5": {"type": "gene", "color": "rgb(204, 255, 51)", "name": "0.5", "shape": "circle"}, "patient_group": {"type": "patient", "color": "red", "name": "patient group", "shape": "circle"}, "2.0": {"type": "gene", "color": "rgb(51, 204, 51)", "name": "2.0", "shape": "circle"}, "-2.0": {"type": "gene", "color": "rgb(255, 0, 0)", "name": "-2.0", "shape": "circle"}}, "edgeGroups": {"custom": {"color": "black", "name": "Custom Group"}}, - "identifier": "ensg", + "identifier": "symbol", "legendUrl": "https://exbio.wzw.tum.de/covex/assets/leg1.png" }' network='{ - "nodes": [{"id": "ENSG00000171862", "group": "0.5"}, {"label": "ENSG00000284792", "id": "ENSG00000284792", "group": 0.5}], + "nodes": [{"id": "TP53", "group": "0.5"}, {"id": "C5", "group": "0.5"}, {"id": "Patient", "group": "patient_group"}, {"label": "PTEN", "id": "PTEN", "group": 0.5}], "edges": [] }' style="height: 100%; width: 100vw; display: block;"