From 9957f40f1c809d6e3725397ae5281193eeaa8290 Mon Sep 17 00:00:00 2001
From: "Hartung, Michael" <michael.hartung@uni-hamburg.de>
Date: Fri, 15 Jul 2022 11:57:54 +0200
Subject: [PATCH] selection of algorithms available to user

---
 src/app/config.ts                             | 13 +++++--
 .../launch-analysis.component.ts              | 34 +++++++++++--------
 src/app/interfaces.ts                         | 21 ++++++++++--
 .../explorer-page.component.html              |  1 -
 src/app/services/analysis/analysis.service.ts | 17 +---------
 .../netex-controller.service.ts               |  3 +-
 6 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/src/app/config.ts b/src/app/config.ts
index 13229016..c575eae9 100644
--- a/src/app/config.ts
+++ b/src/app/config.ts
@@ -1,3 +1,5 @@
+import { AlgorithmTarget, AlgorithmType, QuickAlgorithmType } from "./interfaces";
+
 // https://visjs.github.io/vis-network/docs/network/nodes.html
 export interface NodeGroup {
   groupName?: string;
@@ -24,9 +26,9 @@ export interface EdgeGroup {
   shadow?: any;
 }
 
-export type Identifier = 'symbol'|'uniprot'|'ensg';
-export type InteractionDrugProteinDB = 'DrugBank'|'Chembl'|'DGIdb' | 'NeDRex';
-export type InteractionProteinProteinDB = 'STRING'|'BioGRID'|'APID' | 'NeDRex';
+export type Identifier = 'symbol' | 'uniprot' | 'ensg';
+export type InteractionDrugProteinDB = 'DrugBank' | 'Chembl' | 'DGIdb' | 'NeDRex';
+export type InteractionProteinProteinDB = 'STRING' | 'BioGRID' | 'APID' | 'NeDRex';
 export type IndicationDrugDisorderDB = 'DrugBank' | 'NeDRex';
 export type AssociatedProteinDisorderDB = 'NeDRex' | 'DisGeNET';
 
@@ -79,6 +81,7 @@ export interface IConfig {
   nodeShadow?: boolean;
   edgeShadow?: boolean;
   useNedrexLicensed?: boolean;
+  algorithms: { [key in AlgorithmTarget]: Array<AlgorithmType | QuickAlgorithmType> }
 }
 
 /**
@@ -126,6 +129,10 @@ export const defaultConfig: IConfig = {
   physicsOn: false,
   useNedrexLicensed: true,
   selfReferences: false,
+  algorithms: { 
+    'drug': ['trustrank', 'closeness', 'degree', 'proximity'], 
+    'drug-target': ['trustrank', 'multisteiner', 'keypathwayminer', 'degree', 'closeness', 'betweenness'] 
+  },
   nodeGroups: {
     // all NodeGroups but the default group must be set, if not provided by the user, they will be taken from here
     // IMPORTANT: node color must be hexacode!
diff --git a/src/app/dialogs/launch-analysis/launch-analysis.component.ts b/src/app/dialogs/launch-analysis/launch-analysis.component.ts
index bf4637eb..2810fcc7 100644
--- a/src/app/dialogs/launch-analysis/launch-analysis.component.ts
+++ b/src/app/dialogs/launch-analysis/launch-analysis.component.ts
@@ -1,15 +1,13 @@
-import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
+import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
 import {
-  Algorithm,
-  AlgorithmType,
   AnalysisService, BETWEENNESS_CENTRALITY, CLOSENESS_CENTRALITY,
   DEGREE_CENTRALITY,
   KEYPATHWAYMINER, MAX_TASKS,
   MULTISTEINER, NETWORK_PROXIMITY,
-  QuickAlgorithmType,
   TRUSTRANK
 } from '../../services/analysis/analysis.service';
-import { IConfig } from 'src/app/config';
+import { Algorithm, AlgorithmType, QuickAlgorithmType } from 'src/app/interfaces';
+import { DrugstoneConfigService } from 'src/app/services/drugstone-config/drugstone-config.service';
 
 @Component({
   selector: 'app-launch-analysis',
@@ -23,9 +21,7 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges {
   @Input()
   public target: 'drug' | 'drug-target';
   @Input()
-  public inputNetwork: {nodes: any, edges: any};
-  @Input()
-  public config: IConfig;
+  public inputNetwork: { nodes: any, edges: any };
   @Output()
   public showChange = new EventEmitter<boolean>();
   @Output()
@@ -82,7 +78,7 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges {
 
   public maxTasks = MAX_TASKS;
 
-  constructor(public analysis: AnalysisService) {
+  constructor(public analysis: AnalysisService, public drugstoneConfig: DrugstoneConfigService) {
   }
 
   ngOnInit(): void {
@@ -91,10 +87,18 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges {
   ngOnChanges(changes: SimpleChanges): void {
     if (this.target === 'drug-target') {
       this.algorithms = [MULTISTEINER, KEYPATHWAYMINER, TRUSTRANK, CLOSENESS_CENTRALITY, DEGREE_CENTRALITY, BETWEENNESS_CENTRALITY];
-      this.algorithm = MULTISTEINER.slug;
     } else if (this.target === 'drug') {
       this.algorithms = [TRUSTRANK, CLOSENESS_CENTRALITY, DEGREE_CENTRALITY, NETWORK_PROXIMITY];
-      this.algorithm = TRUSTRANK.slug;
+    } else {
+      // return because this.target === undefined
+      return
+    }
+    this.algorithms = this.algorithms.filter(algorithm => this.drugstoneConfig.config.algorithms[this.target].includes(algorithm.slug));
+    // sanity check to fallback algorithm, trustrank works on all targets
+    if (!this.algorithms.length) {
+      this.algorithms = [TRUSTRANK];
+    } else {
+      this.algorithm = this.algorithms[0].slug;
     }
   }
 
@@ -111,12 +115,12 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges {
     });
     const parameters: any = {
       seeds: seedsFiltered,
-      config: this.config,
+      config: this.drugstoneConfig.config,
       input_network: this.inputNetwork
     };
 
-    parameters.ppi_dataset = this.config.interactionProteinProtein;
-    parameters.pdi_dataset = this.config.interactionDrugProtein;
+    parameters.ppi_dataset = this.drugstoneConfig.config.interactionProteinProtein;
+    parameters.pdi_dataset = this.drugstoneConfig.config.interactionDrugProtein;
     parameters.target = this.target === 'drug' ? 'drug' : 'drug-target';
     // pass network data to reconstruct network in analysis result to connect non-proteins to results
     // drop interactions in nodes beforehand to no cause cyclic error, information is contained in edges
@@ -176,7 +180,7 @@ export class LaunchAnalysisComponent implements OnInit, OnChanges {
       parameters.hub_penalty = this.multisteinerHubPenalty;
     }
     const token = await this.analysis.startAnalysis(this.algorithm, this.target, parameters);
-    const object = {taskId: token, algorithm: this.algorithm, target: this.target, params: parameters};
+    const object = { taskId: token, algorithm: this.algorithm, target: this.target, params: parameters };
     this.taskEvent.emit(object);
   }
 
diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts
index 8f5eacee..16048966 100644
--- a/src/app/interfaces.ts
+++ b/src/app/interfaces.ts
@@ -1,5 +1,3 @@
-import {AlgorithmType, QuickAlgorithmType} from './services/analysis/analysis.service';
-
 export interface Node {
   ctxRenderer?: any;
   label: string;
@@ -67,10 +65,12 @@ export interface NetworkEdge {
   label: string;
 }
 
+export type AlgorithmTarget = 'drug' | 'drug-target'
+
 export interface Task {
   token: string;
   info: {
-    target: 'drug' | 'drug-target',
+    target: AlgorithmTarget,
     algorithm: AlgorithmType | QuickAlgorithmType;
     parameters?: { [key: string]: any };
 
@@ -231,3 +231,18 @@ export interface Dataset {
   id: string;
   data: Array<[string, string]>;
 }
+
+export type AlgorithmType =
+  'trustrank'
+  | 'keypathwayminer'
+  | 'multisteiner'
+  | 'closeness'
+  | 'degree'
+  | 'proximity'
+  | 'betweenness';
+export type QuickAlgorithmType = 'quick' | 'super';
+
+export interface Algorithm {
+  slug: AlgorithmType | QuickAlgorithmType;
+  name: string;
+}
diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html
index fbeb61c7..2bc4959d 100644
--- a/src/app/pages/explorer-page/explorer-page.component.html
+++ b/src/app/pages/explorer-page/explorer-page.component.html
@@ -6,7 +6,6 @@
     <app-launch-analysis
       [(show)]="showAnalysisDialog"
       [target]="analysisDialogTarget"
-      [config]="drugstoneConfig.config"
       [inputNetwork]="{ nodes: proteins, edges: edges }"
       (taskEvent)="emitTaskEvent($event)"
     >
diff --git a/src/app/services/analysis/analysis.service.ts b/src/app/services/analysis/analysis.service.ts
index 96030cbf..f85cb23f 100644
--- a/src/app/services/analysis/analysis.service.ts
+++ b/src/app/services/analysis/analysis.service.ts
@@ -1,4 +1,4 @@
-import {Wrapper, Task, getWrapperFromNode, Node, Dataset, Tissue} from '../../interfaces';
+import {Wrapper, Task, getWrapperFromNode, Node, Dataset, Tissue, Algorithm} from '../../interfaces';
 import {Subject} from 'rxjs';
 import {HttpClient} from '@angular/common/http';
 import {environment} from '../../../environments/environment';
@@ -6,16 +6,6 @@ import {toast} from 'bulma-toast';
 import {Injectable} from '@angular/core';
 import {NetexControllerService} from '../netex-controller/netex-controller.service';
 
-export type AlgorithmType =
-  'trustrank'
-  | 'keypathwayminer'
-  | 'multisteiner'
-  | 'closeness'
-  | 'degree'
-  | 'proximity'
-  | 'betweenness';
-export type QuickAlgorithmType = 'quick' | 'super';
-
 export const algorithmNames = {
   trustrank: 'TrustRank',
   keypathwayminer: 'KeyPathwayMiner',
@@ -28,11 +18,6 @@ export const algorithmNames = {
   super: 'Quick-Start',
 };
 
-export interface Algorithm {
-  slug: AlgorithmType | QuickAlgorithmType;
-  name: string;
-}
-
 export const TRUSTRANK: Algorithm = {slug: 'trustrank', name: algorithmNames.trustrank};
 export const CLOSENESS_CENTRALITY: Algorithm = {slug: 'closeness', name: algorithmNames.closeness};
 export const DEGREE_CENTRALITY: Algorithm = {slug: 'degree', name: algorithmNames.degree};
diff --git a/src/app/services/netex-controller/netex-controller.service.ts b/src/app/services/netex-controller/netex-controller.service.ts
index 81c3d7bd..64d13472 100644
--- a/src/app/services/netex-controller/netex-controller.service.ts
+++ b/src/app/services/netex-controller/netex-controller.service.ts
@@ -1,9 +1,8 @@
 import {Injectable} from '@angular/core';
 import {environment} from '../../../environments/environment';
 import {HttpClient, HttpParams} from '@angular/common/http';
-import {AlgorithmType, QuickAlgorithmType} from '../analysis/analysis.service';
 import {Observable} from 'rxjs';
-import {Tissue, Node, EdgeType} from 'src/app/interfaces';
+import {Tissue, Node, EdgeType, QuickAlgorithmType, AlgorithmType} from 'src/app/interfaces';
 import {InteractionDrugProteinDB, InteractionProteinProteinDB} from 'src/app/config';
 
 @Injectable({
-- 
GitLab