Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
a60ff6e
Added API so we can track it
scootermorris Jun 7, 2021
637b0f6
moving dimensionality reduction techniques to its own repository
mehumaija Jun 9, 2021
b7616cf
Merge branch 'master' of https://github.com/mehumaija/clusterMaker2
mehumaija Jun 9, 2021
a8e7f82
adding tunables to UMAP
mehumaija Jun 9, 2021
5f745ef
UMAP correct data structure, post and fetch successful now
mehumaija Jun 15, 2021
40e9f08
Merge pull request #14 from mehumaija/master
mehumaija Jun 15, 2021
a82add8
Make all edge attribute tunables dependent on nodeOnly
scootermorris Jun 15, 2021
9440335
New constructor for ScatterPlotDialog that takes an array of nodes and a
scootermorris Jun 15, 2021
365b0af
added logic to make coordinates and cynode lists from UMAP results
mehumaija Jun 21, 2021
f51e09d
Merge branch 'RBVI:master' into master
mehumaija Jun 22, 2021
9263d71
Fix bug in new ScatterPlotDialog constructor
scootermorris Jun 22, 2021
719a41c
Merge branch 'RBVI:master' into master
mehumaija Jun 22, 2021
2edaa38
creating ScatterPlotDialog for UMAP
mehumaija Jun 22, 2021
79724bc
Merge pull request #15 from mehumaija/master
mehumaija Jun 22, 2021
12c926a
Fixed scatterplot, added correct attributes for UMAP, and reordered
scootermorris Jun 22, 2021
b32b323
adding columns for x and y coordinates in NodeTable
mehumaija Jun 25, 2021
b37202c
Fix transclust
scootermorris Jun 29, 2021
c57ba94
Merge branch 'master' into master
mehumaija Jun 30, 2021
4456cc4
Merge pull request #1 from RBVI/master
mehumaija Jun 30, 2021
926d607
added tSNE, path not known yet
mehumaija Jun 30, 2021
b1a3eba
Merge pull request #16 from mehumaija/master
mehumaija Jun 30, 2021
079ff96
Added dimensionality reduction techniques
scootermorris Jul 6, 2021
0389df4
Merge branch 'master' of github.com:RBVI/clusterMaker2
scootermorris Jul 6, 2021
f3d0bc0
added dimensionality reduction embeddings
mehumaija Jul 6, 2021
b9b2e82
Merge branch 'RBVI:master' into master
mehumaija Jul 6, 2021
cd58d16
Merge pull request #17 from mehumaija/master
mehumaija Jul 6, 2021
46a003d
Merge branch 'master' of github.com:RBVI/clusterMaker2
scootermorris Jul 6, 2021
d8e02b1
Renamed linearDiscriminant to linearEmbedding.
scootermorris Jul 6, 2021
200249a
added "remote" to the names of remote algorithms
mehumaija Jul 19, 2021
db8e483
Merge pull request #18 from mehumaija/master
mehumaija Jul 20, 2021
05d0540
First attempt to add tooltip
scootermorris Jul 20, 2021
4dda348
Balanced text a bit
scootermorris Jul 20, 2021
7f76620
Make sure to get the monitor set
scootermorris Jul 20, 2021
8d84e74
added tsne to dimensionality reduction menu and rearranged it alphabe…
mehumaija Jul 21, 2021
12ced55
added monitor = taskMonitor to all dimensionalityReduction and FastGr…
mehumaija Jul 22, 2021
555c741
Merge pull request #19 from mehumaija/master
mehumaija Jul 22, 2021
9bb8cbf
added tooltips to all the remote algorithms
mehumaija Jul 22, 2021
c367c92
Merge pull request #20 from mehumaija/master
mehumaija Jul 23, 2021
39889cc
changed names of the columns where x and y coordinates are written fr…
mehumaija Jul 24, 2021
d22faaa
Merge branch 'master' of https://github.com/mehumaija/clusterMaker2
mehumaija Jul 24, 2021
1c1de44
Merge pull request #21 from mehumaija/master
mehumaija Jul 24, 2021
a1e693b
Updates for clusterMaker2
scootermorris Jul 30, 2021
4a92447
Merge branch 'master' of github.com:RBVI/clusterMaker2
scootermorris Jul 30, 2021
fa60af0
Added LLE
scootermorris Jul 30, 2021
0cab7d0
Added collinsPlus.cys as a test file
scootermorris Aug 3, 2021
0ced7f3
Scatter plot drawn for the dimensionality reduction techniques
mehumaija Aug 4, 2021
29ed611
Deleted extra ClusterManager and Network from the algorithm classes
mehumaija Aug 4, 2021
2f5c041
Merge pull request #22 from mehumaija/master
mehumaija Aug 4, 2021
ab3cc7d
edited the tooltip texts + other minor edits
mehumaija Aug 10, 2021
3ce5ca3
Merge pull request #23 from mehumaija/master
mehumaija Aug 10, 2021
dd30032
Rename remote to (remote)
scootermorris Aug 10, 2021
0054600
created specific classes for DR and network cluster job handlers
mehumaija Aug 15, 2021
96f211e
Merge pull request #24 from mehumaija/master
mehumaija Aug 15, 2021
8f9c8d2
drawing new network in job handler
mehumaija Aug 16, 2021
e088aa4
Merge branch 'RBVI:master' into master
mehumaija Aug 16, 2021
1d3384e
Merge pull request #25 from mehumaija/master
mehumaija Aug 16, 2021
c410b20
Some cleanup and menu reconfiguration
scootermorris Aug 17, 2021
e222e75
explanation what Maija has done during GSoC 21
mehumaija Aug 18, 2021
96c82b7
edits to the layout
mehumaija Aug 18, 2021
d432947
Edits to the layout
mehumaija Aug 18, 2021
e43a01b
Bump to v2
scootermorris Nov 2, 2021
84f0d33
Algorithm updates
scootermorris Nov 8, 2021
d153333
Update ojAlgo to the latest version
scootermorris Nov 8, 2021
8973de7
Added longDescription to the new algorithms
scootermorris Nov 23, 2021
4093a6e
added synchronous tunable and waitTime in configuration map
mehumaija Dec 14, 2021
bdded7c
Merge branch 'master' of https://github.com/mehumaija/clusterMaker2
mehumaija Dec 14, 2021
5bebf58
waitTime in configuration map
mehumaija Dec 14, 2021
57bafd8
Merge pull request #27 from mehumaija/master
mehumaija Dec 14, 2021
3d48b49
Updates, particularly fixes to AutoSome
scootermorris Dec 22, 2021
cccfcd0
Bumped httpcomponents version
scootermorris Dec 22, 2021
7eca5c7
Update pax-logging
scootermorris Dec 27, 2021
be91a5f
added isSynchronous tunable and waitTime in configuration
mehumaija Jan 16, 2022
6f944d0
Merge branch 'RBVI:master' into master
mehumaija Jan 16, 2022
3094d31
Merge pull request #28 from mehumaija/master
mehumaija Jan 16, 2022
0840c5d
Some fixes to provide improved control over the loadings vectors in the
scootermorris Jan 25, 2022
5b7e063
Fix up results panel visualizations and ranking algorithms
scootermorris Jan 25, 2022
d122154
Add export capability to scatter plots
scootermorris Jan 26, 2022
8e08304
Improve export dialog for scatterplot images
scootermorris Feb 16, 2022
3bb2d90
Remove some debugging and improve export function in scatterplot
scootermorris Feb 23, 2022
054e6e8
Oops -- more debugging removed
scootermorris Feb 23, 2022
9d70292
Fix missing handling of arguments
scootermorris Feb 25, 2022
686e2e4
Update UMAPContext.java
mehumaija Mar 13, 2022
7036973
fixed typo
mehumaija Mar 13, 2022
d360337
Merge branch 'master' of https://github.com/mehumaija/clusterMaker2
mehumaija Mar 13, 2022
80d412c
Add "selectedOnly" to all dimensionality reduction algorithms
scootermorris Apr 1, 2022
b72fd3d
added NormalizationContext for attribute value normalization to make …
mehumaija Apr 27, 2022
b521827
Merge branch 'master' into master
mehumaija Apr 27, 2022
846cf6a
Merge pull request #2 from RBVI/master
mehumaija Apr 27, 2022
d4ff320
Merge pull request #29 from mehumaija/master
mehumaija Apr 27, 2022
524296c
Add support for normalization of values.
scootermorris Apr 29, 2022
1f12b9a
PRWP now works properly for a test expression data set
scootermorris Apr 29, 2022
d67946d
OK, normalization code added everywhere appropriate
scootermorris Apr 30, 2022
aab9330
Trying to fix some git messups
scootermorris May 3, 2022
eb6e83d
Merge branch 'master' of github.com:RBVI/clusterMaker2
scootermorris May 3, 2022
38a483c
Updated ranking panel a bit.
scootermorris May 3, 2022
f18f9e4
1) Bump ojAlgo to latest version
scootermorris May 19, 2022
528a737
More fuzzy cluster fixes
scootermorris May 25, 2022
13a1610
Make sure we have the network set
scootermorris Jun 7, 2022
1bb19f2
Make sure to pass network to normalization context
scootermorris Jun 7, 2022
409e6da
Update maven-bundle-plugin
scootermorris Jul 7, 2022
fd6a7ba
Improve ranking panel
scootermorris Aug 16, 2022
9743271
Add some padding around network icon
scootermorris Aug 16, 2022
235117e
Three bug fixes:
scootermorris Nov 23, 2022
23c23b7
Avoid thread deadlock issues by using the SynchronousTaskManager
scootermorris Dec 3, 2022
f8e6cf1
Significantly improves handling results with a large number of clusters.
scootermorris Dec 3, 2022
bd2217f
Added DBScan support
scootermorris Dec 3, 2022
c2e3ca3
Add dbscan to backend
scootermorris Dec 3, 2022
0597ccf
Bump version number
scootermorris Dec 3, 2022
f8b73b4
Match production version
scootermorris Dec 3, 2022
7f85537
Updated to support passing of errors back to Cytoscape
scootermorris Jan 26, 2023
9dcbf82
iGraph wants 'pca' not 'PCA'
scootermorris Jan 26, 2023
9ebd05c
Updates to better handle backend errors
scootermorris Jan 27, 2023
ba08e41
np.float has been deprecated
scootermorris Jun 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# This is git repository for the Cytoscape 3 clustering app: clusterMaker

TODO:
1) Fix BiClusterView
2) Add support for BiClustering routines:
Expand All @@ -11,6 +12,34 @@ TODO:





7 JUNE - 23 AUGUST 2021 Google Summer of Code by Maija Utriainen

Implementing remote dimensionality reduction techniques using similar approach to last years remote network clusterers (see below).
- Dimensionality reduction techniques added: Isomap, Local Linear Embedding, MDS, Spectral, tSNE, UMAP
- Changes to ClusterJobExecutionService and RemoteServer: abstracting and replacing code to another class
- Subclasses to ClusterJobHandler specific to network clusterers and dimensionality reduction techniques
- The new algorithms registered in CyActivator

The added and edited code can be found in clusterMaker2/src/main/java/edu/ucsf/rbvi/clusterMaker2/internal/
- utils/remoteUtils
- RemoteServer
- ClusterJobExecutionService
- NetworkClusterJobHandler
- DimensionalityReductionJobHandler
- algorithms/dimensionalityRedcution
- isomap
- linearEmbedding
- mds
- spectral
- tSNERemote
- umap
- CyActivator




1 JUNE - 29 AUGUST 2020 changes done as a Google Summer of Code Project by Maija Utriainen

Implementing new algorithms with a new approach that runs the algorithm remotely on a server instead of in clusterMaker/Cytoscape utilizing interfaces in cytoscape.jobs package.
Expand Down
Empty file added api/api/__init__.py
Empty file.
56 changes: 56 additions & 0 deletions api/api/algorithms/algorithms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from api.jobs import Jobs
from .fastgreedy import FastGreedy
from .infomap import Infomap
from .leiden import Leiden
from .label_propagation import LabelPropagation
from .leading_eigenvector import LeadingEigenvector
from .multilevel import Multilevel
from .dbscan import DBScan
from .umap import UMAP
from .tsne import TSNEREMOTE
from .isomap import IsoMapEmbedding
from .mds import MDS
from .spectral import SpectralEmbedding
#from .lineardisc import LinearDiscriminant
from .lle import LLE
import falcon
import json

class Algorithms(object):
jobs = None
algorithms = None

def __init__(self, jobs: Jobs):
self.jobs = jobs
self.algorithms = {}

# Initialize the list of algorithms
self.algorithms["leiden"] = Leiden(jobs)
self.algorithms["fastgreedy"] = FastGreedy(jobs)
self.algorithms["infomap"] = Infomap(jobs)
self.algorithms["labelpropagation"] = LabelPropagation(jobs)
self.algorithms["leadingeigenvector"] = LeadingEigenvector(jobs)
self.algorithms["multilevel"] = Multilevel(jobs)
self.algorithms["dbscan"] = DBScan(jobs)

# Dimensionality reduction (manifold) techniques
self.algorithms["umap"] = UMAP(jobs)
self.algorithms["tsneremote"] = TSNEREMOTE(jobs)
self.algorithms["mds"] = MDS(jobs)
self.algorithms["isomap"] = IsoMapEmbedding(jobs)
self.algorithms["spectral"] = SpectralEmbedding(jobs)
self.algorithms["lle"] = LLE(jobs)
# self.algorithms["lineardisc"] = LinearDiscriminant(jobs)

def on_get(self, req: falcon.Request, resp: falcon.Response):
resp.code = falcon.HTTP_200
resp.text = '{"algorithms":'+json.dumps(list(self.algorithms.keys()))+'}'


def get_algorithms(self) -> list:
return self.algorithms.keys()

def get_algorithm(self, algorithm:str):
if algorithm in self.algorithms:
return self.algorithms[algorithm]
return None
108 changes: 108 additions & 0 deletions api/api/algorithms/base_algorithm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""
Algorithm base class
"""

from uuid import UUID
import json

import falcon
import logging

from multiprocessing import Manager,Process
from datetime import datetime

from api.jobs import Jobs
import api.utils as utils

class BaseAlgorithm():
jobs = None
myjobs = {}
logFile = None

def __init__(self, jobs: Jobs):
self.jobs = jobs
self.manager = jobs.get_manager()

def on_post(self, req: falcon.Request, resp: falcon.Response):
""" Get data and arguments """
result = self.manager.dict()
status = self.manager.dict()

#self.logFile.write(repr(req)+"\n")
self.log(repr(req))

# Get our parameters
args = self.get_args(req)
self.log("Arguments: "+repr(args))
#self.logFile.write(repr(args))

# We need to do the load here because we can't pass a stream to our
# child process
if hasattr(req.get_param('data'),'file'):
# Python requests adds an extra dict
args['json_data'] = json.load(req.get_param('data').file)
else:
# Assume it's just straight text
args['json_data'] = json.loads(req.get_param('data'))

#f = open("/var/tmp/wsgi.log", "w")
#f.write(str(args['json_data']))

uuid = self.jobs.create_job(req.path, self)
proc = Process(target=self.community_detection, args=(args, status, result))
self.myjobs[uuid] = (proc, status, result)
proc.start()
resp.code = falcon.HTTP_200
resp.text = json.dumps({'job_id': str(uuid)})

def get_status2(self, uid: UUID) -> dict:
if uid in self.myjobs:
(proc, status, result) = self.myjobs[uid]
json_status = {}
for key, value in status.items():
json_status[key] = value

return json_status
return None

def get_status(self, uid: UUID) -> str:
if uid in self.myjobs:
(proc, status, result) = self.myjobs[uid]
#self.logFile.write("Getting status for "+repr(uid)+"\n")
#self.logFile.write("Status = "+repr(status['status'])+"\n")
self.log("Status for "+repr(uid)+" = "+repr(status['status']))
return status['status']
return None

def fetch_results(self, uid: UUID, req: falcon.Request, resp: falcon.Response):
if uid in self.myjobs:
(proc, status, result) = self.myjobs[uid]
# Add our response
resp.text = utils.get_json_result(status, result)
if status['status'] == 'done':
resp.code = falcon.HTTP_200
elif status['status'] == 'error':
resp.code = falcon.HTTP_500
self.log("Returning 500. Response = "+repr(resp.text))
else:
resp.code = falcon.HTTP_400
resp.text = str({'error':"no such job: "+str(uid)})

def terminate(self, uid: UUID, req: falcon.Request, resp: falcon.Response):
# Terminate the running process
if uid in self.myjobs:
(proc, status, result) = self.myjobs[uid]
proc.terminate()
self.jobs.remove_job(uid)
del self.myjobs[uid]
resp.text = "Job: "+str(uid)+" terminated"
resp.code = falcon.HTTP_200
else:
resp.code = falcon.HTTP_400
resp.text = str({'error':"no such job: "+str(uid)})

def log(self, message: str):
now = datetime.today()
logging.info(str(now)+": "+message)


74 changes: 74 additions & 0 deletions api/api/algorithms/dbscan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""
DBScan cluster algorithm
"""

import numpy as np
import falcon
import api.utils as utils
from .base_algorithm import BaseAlgorithm
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN
from scipy.sparse import csgraph

class DBScan(BaseAlgorithm):

def get_args(self, req: falcon.Request) -> dict:
""" Get the arguments """

# Get our parameters
args = {}
args['eps'] = utils.get_param_as_float(req, 'eps', 0.5)
args['min_samples'] = utils.get_param_as_int(req, 'min_samples', 5)
args['metric'] = utils.get_param_as_string(req, 'metric', 'euclidean')
args['algorithm'] = utils.get_param_as_string(req, 'algorithm', 'auto')
args['leaf_size'] = utils.get_param_as_int(req, 'leaf_size', 30)
args['p'] = utils.get_param_as_float(req, 'p', 2)

return args

def community_detection(self, args:dict, status:dict, result:dict):
status['status'] = 'running'

# Get our parameters
eps = args['eps']
min_samples = args['min_samples']
metric = args['metric']
algorithm = args['algorithm']
leaf_size = args['leaf_size']
p = args['p']
data = args['json_data']

# We handle two different types of data -- either a square matrix with
# weights in the cells or a matrix with columns representing features
# If the metric is 'precomputed' then we're dealing with a square matrix
# otherwise, we assume we have a standard column matrix
if metric == 'precomputed':
# Get the graph
graph = utils.get_graph(data)
# Get the matrix from the graph
data = graph.get_adjacency_sparse(attribute="weights")
else:
df = utils.get_matrix(data)
columns = df.columns.to_list()

# We need to drop any NaNs
df = df.dropna()

data = df[columns[1:]].values # skip over the label and just pull the data

if (args['scale']):
data = StandardScaler().fit_transform(data)


db = DBSCAN(eps=eps, min_samples=min_samples, metric=metric,metric_params=None,
algorithm=algorithm,leaf_size=leaf_size,p=p,n_jobs=None).fit(data)

core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
# List of labels -- each element refers to a row
labels = db.labels_

result['partitions'] = labels

status['status'] = 'done'

38 changes: 38 additions & 0 deletions api/api/algorithms/fastgreedy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
Fast Greedy cluster algorithm
"""

import falcon
import logging
import api.utils as utils
from api.jobs import Jobs
from .base_algorithm import BaseAlgorithm

class FastGreedy(BaseAlgorithm):

def get_args(self, req: falcon.Request) -> dict:
return {}

def community_detection(self, args:dict, status:dict, result:dict):
status['status'] = 'running'

# Get our parameters
data = args['json_data']

# Get our data file
graph = utils.get_graph(data)

try:
# FastGreedy doesn't work for multigraphs
graph = graph.simplify(multiple=True, loops=True, combine_edges=sum);
part = graph.community_fastgreedy(weights="weights")
except Exception as e:
exc = utils.parse_igraph_exception(repr(e))
status['status'] = 'error'
status['message'] = exc
return

result['partitions'] = utils.get_vertex_list(graph, part.as_clustering())

status['status'] = 'done'

34 changes: 34 additions & 0 deletions api/api/algorithms/infomap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""
Infomap cluster algorithm
"""
import falcon
import api.utils as utils
from .base_algorithm import BaseAlgorithm

class Infomap(BaseAlgorithm):
def get_args(self, req: falcon.Request) -> dict:
args = {}
args['trials'] = utils.get_param_as_int(req, 'trials', 10)
return args

def community_detection(self, args:dict, status:dict, result:dict):
status['status'] = 'running'

# Get our parameters
trials = args['trials']
data = args['json_data']

graph = utils.get_graph(data)

try:
part = graph.community_infomap(edge_weights="weights", trials=trials)
except Exception as e:
exc = utils.parse_igraph_exception(repr(e))
status['status'] = 'error'
status['message'] = exc
return

result['partitions'] = utils.get_vertex_list(graph, part)

status['status'] = 'done'

Loading