fusion-tools 2.2.4__tar.gz → 2.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/PKG-INFO +1 -1
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/setup.py +1 -1
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/components/maps.py +1 -1
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/components/segmentation.py +138 -2
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/feature_extraction.py +1 -1
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/visualization/components.py +6 -7
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools.egg-info/PKG-INFO +1 -1
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/LICENSE +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/README.md +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/pyproject.toml +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/setup.cfg +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/__init__.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/components/__init__.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/components/tools.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/dataset.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/handler.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/tileserver.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/utils/__init__.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/utils/omics.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/utils/shapes.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/utils/stats.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/visualization/__init__.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools/visualization/vis_utils.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools.egg-info/SOURCES.txt +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools.egg-info/dependency_links.txt +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools.egg-info/requires.txt +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/src/fusion_tools.egg-info/top_level.txt +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_classification_model.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_custom_component.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_dataset_classes.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_extract_nested_prop.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_feature_annotation.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_feature_extraction.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_generate_property_dict.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_get_gene_info.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_hra_viewer.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_image_overlay.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_model_train.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_multiframe_rgb.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_multiframeslidemap.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_property_plotter.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_read_anndata.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_remote_slide_annotations.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_remote_tileserver.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_segmentation.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_slide_annotations.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_spatial_aggregation.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_tile_server.py +0 -0
- {fusion_tools-2.2.4 → fusion_tools-2.2.5}/tests/test_visualization_component.py +0 -0
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
|
5
5
|
|
|
6
6
|
setuptools.setup(
|
|
7
7
|
name="fusion-tools",
|
|
8
|
-
version="2.2.
|
|
8
|
+
version="2.2.5",
|
|
9
9
|
author="Sam Border",
|
|
10
10
|
author_email="sam.border2256@gmail.com",
|
|
11
11
|
description="Modular visualization and analysis dashboard creation for high-resolution microscopy images",
|
|
@@ -23,10 +23,11 @@ from skimage.measure import label
|
|
|
23
23
|
import dash
|
|
24
24
|
dash._dash_renderer._set_react_version('18.2.0')
|
|
25
25
|
import dash_leaflet as dl
|
|
26
|
-
from dash import dcc, callback, ctx, ALL, MATCH, exceptions, Patch, no_update, dash_table
|
|
26
|
+
from dash import dcc, callback, ctx, ALL, MATCH, exceptions, Patch, no_update, dash_table, ClientsideFunction
|
|
27
27
|
import dash_bootstrap_components as dbc
|
|
28
28
|
import dash_mantine_components as dmc
|
|
29
29
|
from dash_extensions.enrich import DashBlueprint, html, Input, Output, State, PrefixIdTransform, MultiplexerTransform
|
|
30
|
+
from dash_extensions.javascript import Namespace
|
|
30
31
|
|
|
31
32
|
# fusion-tools imports
|
|
32
33
|
from fusion_tools.visualization.vis_utils import get_pattern_matching_value
|
|
@@ -917,6 +918,9 @@ class BulkLabels(Tool):
|
|
|
917
918
|
self.ignore_list = ignore_list
|
|
918
919
|
self.property_depth = property_depth
|
|
919
920
|
|
|
921
|
+
self.assets_folder = os.getcwd()+'/.fusion_assets/'
|
|
922
|
+
self.get_namespace()
|
|
923
|
+
|
|
920
924
|
def __str__(self):
|
|
921
925
|
return 'Bulk Labels'
|
|
922
926
|
|
|
@@ -954,6 +958,112 @@ class BulkLabels(Tool):
|
|
|
954
958
|
|
|
955
959
|
return x_scale, y_scale
|
|
956
960
|
|
|
961
|
+
def get_namespace(self):
|
|
962
|
+
"""Adding JavaScript functions to the BulkLabels Namespace
|
|
963
|
+
"""
|
|
964
|
+
self.js_namespace = Namespace(
|
|
965
|
+
"fusionTools","bulkLabels"
|
|
966
|
+
)
|
|
967
|
+
|
|
968
|
+
self.js_namespace.add(
|
|
969
|
+
name = "propertyFilter",
|
|
970
|
+
src = """
|
|
971
|
+
function(butt_click, structure_names, filter_json, map_annotations, slide_information) {
|
|
972
|
+
var returnFeature = true;
|
|
973
|
+
// Defining function to extract property value
|
|
974
|
+
function checkFilter(feature, filterItem) {
|
|
975
|
+
if (filterItem.name) {
|
|
976
|
+
var filterSubProps = filterItem.name.split(" --> ");
|
|
977
|
+
var prop_dict = feature.properties;
|
|
978
|
+
for (let i=0; i<filterSubProps.length; i++) {
|
|
979
|
+
if (filterSubProps[j] in prop_dict) {
|
|
980
|
+
var prop_dict = prop_dict[filterSubProps[j]];
|
|
981
|
+
var testVal = prop_dict;
|
|
982
|
+
} else {
|
|
983
|
+
var testVal = false;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
if (filterItem.range & testVal) {
|
|
988
|
+
if (typeof filterItem.range[0]==='number') {
|
|
989
|
+
if (testVal < filterItem.range[0]) {
|
|
990
|
+
returnFeature = returnFeature & false;
|
|
991
|
+
}
|
|
992
|
+
if (testVal > filterItem.range[1]) {
|
|
993
|
+
returnFeature = returnFeature & false;
|
|
994
|
+
}
|
|
995
|
+
} else {
|
|
996
|
+
if (filterItem.range.includes(testVal)) {
|
|
997
|
+
returnFeature = returnFeature & true;
|
|
998
|
+
} else {
|
|
999
|
+
returnFeature = returnFeature & false;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
} else {
|
|
1003
|
+
returnFeature = returnFeature & false;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
return returnFeature;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// Reading in filters dictionary
|
|
1011
|
+
const filters = JSON.parse(filter_json);
|
|
1012
|
+
console.log(filters);
|
|
1013
|
+
|
|
1014
|
+
// Reading in annotations
|
|
1015
|
+
const annotations = JSON.parse(map_annotations);
|
|
1016
|
+
var namesList = [];
|
|
1017
|
+
for (let i = 0; i<annotations.length; i++) {
|
|
1018
|
+
namesList.push(annotations[i]["properties"]["name"]);
|
|
1019
|
+
}
|
|
1020
|
+
console.log(namesList);
|
|
1021
|
+
|
|
1022
|
+
// Getting desired annotation for left joins
|
|
1023
|
+
var baseAnnotations = {
|
|
1024
|
+
"type": "FeatureCollection",
|
|
1025
|
+
"features": []
|
|
1026
|
+
};
|
|
1027
|
+
|
|
1028
|
+
for (let i = 0; i<structure_names.length; i++) {
|
|
1029
|
+
baseAnnotations["features"].push(annotations[namesList.indexOf(structure_names[i])]);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// Performing filtration
|
|
1033
|
+
for (let j = 0; j < filters.length; j++) {
|
|
1034
|
+
// Checking if this is a spatial query
|
|
1035
|
+
if ("structure" in filters[j]) {
|
|
1036
|
+
var sqAnnotation = annotations[namesList.indexOf(filters[j]["structure"])];
|
|
1037
|
+
baseAnnotations.splice(i,1,sjoin(baseAnnotations[i],sqAnnotation, { how: "inner", op: filters[j]["type"] }));
|
|
1038
|
+
} else {
|
|
1039
|
+
for (let k = 0; k < baseAnnotations['features'].length; k++) {
|
|
1040
|
+
var check = checkFilter(baseAnnotations["features"], filters[j]);
|
|
1041
|
+
if (!check) {
|
|
1042
|
+
baseAnnotations['features'].splice(k,1);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
console.log(baseAnnotations['features'].length);
|
|
1048
|
+
|
|
1049
|
+
// Creating L.Marker() objects
|
|
1050
|
+
var marker_list = [];
|
|
1051
|
+
for (let j = 0; j < baseAnnotations['features'].length; j++) {
|
|
1052
|
+
var centroid = turf.centroid(turf.polygon(baseAnnotations['features'][j]['geometry']));
|
|
1053
|
+
|
|
1054
|
+
marker_list.push(
|
|
1055
|
+
L.Marker(
|
|
1056
|
+
centroid
|
|
1057
|
+
).bindPopup()
|
|
1058
|
+
);
|
|
1059
|
+
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
"""
|
|
1063
|
+
)
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
957
1067
|
def gen_layout(self, session_data:dict):
|
|
958
1068
|
"""Generating layout for BulkLabels component
|
|
959
1069
|
|
|
@@ -1254,6 +1364,32 @@ class BulkLabels(Tool):
|
|
|
1254
1364
|
Output({'type': 'bulk-labels-apply-labels','index': ALL},'disabled'),
|
|
1255
1365
|
Output({'type': 'bulk-labels-download-labels','index': ALL},'disabled')
|
|
1256
1366
|
],
|
|
1367
|
+
[
|
|
1368
|
+
State({'type': 'bulk-labels-include-structures','index': ALL},'value'),
|
|
1369
|
+
State({'type': 'bulk-labels-filter-data','index': ALL},'data'),
|
|
1370
|
+
State({'type': 'map-annotations-store','index': ALL},'data'),
|
|
1371
|
+
State({'type': 'map-slide-information','index': ALL},'data')
|
|
1372
|
+
]
|
|
1373
|
+
)(self.update_label_structures)
|
|
1374
|
+
|
|
1375
|
+
self.blueprint.clinetside_callback(
|
|
1376
|
+
ClientsideFunction(
|
|
1377
|
+
namespace = 'fusionTools',
|
|
1378
|
+
function_name = ''
|
|
1379
|
+
),
|
|
1380
|
+
[
|
|
1381
|
+
Input({'type': 'bulk-labels-update-structures','index': ALL},'n_clicks')
|
|
1382
|
+
],
|
|
1383
|
+
[
|
|
1384
|
+
Output({'type': 'bulk-labels-current-structures','index': ALL},'children'),
|
|
1385
|
+
Output({'type': 'map-marker-div','index': ALL},'children'),
|
|
1386
|
+
Output({'type': 'bulk-labels-label-source','index': ALL},'children'),
|
|
1387
|
+
Output({'type': 'bulk-labels-label-type','index': ALL},'disabled'),
|
|
1388
|
+
Output({'type': 'bulk-labels-label-text','index': ALL},'disabled'),
|
|
1389
|
+
Output({'type': 'bulk-labels-label-rationale','index': ALL},'disabled'),
|
|
1390
|
+
Output({'type': 'bulk-labels-apply-labels','index': ALL},'disabled'),
|
|
1391
|
+
Output({'type': 'bulk-labels-download-labels','index': ALL},'disabled')
|
|
1392
|
+
],
|
|
1257
1393
|
[
|
|
1258
1394
|
State({'type': 'bulk-labels-include-structures','index': ALL},'value'),
|
|
1259
1395
|
State({'type': 'bulk-labels-add-property-div','index': ALL},'children'),
|
|
@@ -1261,7 +1397,7 @@ class BulkLabels(Tool):
|
|
|
1261
1397
|
State({'type': 'map-annotations-store','index': ALL},'data'),
|
|
1262
1398
|
State({'type': 'map-slide-information','index': ALL},'data')
|
|
1263
1399
|
]
|
|
1264
|
-
)
|
|
1400
|
+
)
|
|
1265
1401
|
|
|
1266
1402
|
# Adding new property
|
|
1267
1403
|
self.blueprint.callback(
|
|
@@ -156,7 +156,7 @@ class ParallelFeatureExtractor:
|
|
|
156
156
|
width = int(bbox[2] - bbox[0])
|
|
157
157
|
|
|
158
158
|
# polygon2mask expects y,x coordinates, scaled to within shape bounding box
|
|
159
|
-
scaled_coords = np.flip(np.squeeze(coords_array)-np.array([bbox[0], bbox[1]
|
|
159
|
+
scaled_coords = np.flip(np.squeeze(coords_array)-np.array([bbox[0], bbox[1]]),axis=1)
|
|
160
160
|
if np.shape(scaled_coords)[-1]==3:
|
|
161
161
|
scaled_coords = scaled_coords[:,1:]
|
|
162
162
|
|
|
@@ -29,15 +29,12 @@ class Visualization:
|
|
|
29
29
|
|
|
30
30
|
components = [
|
|
31
31
|
[
|
|
32
|
-
SlideMap(
|
|
33
|
-
tile_server = LocalTileServer("/path/to/slide.svs"),
|
|
34
|
-
annotations = geojson_list
|
|
35
|
-
)
|
|
32
|
+
SlideMap()
|
|
36
33
|
],
|
|
37
34
|
[
|
|
38
35
|
[
|
|
39
|
-
OverlayOptions(
|
|
40
|
-
PropertyViewer(
|
|
36
|
+
OverlayOptions(),
|
|
37
|
+
PropertyViewer()
|
|
41
38
|
]
|
|
42
39
|
]
|
|
43
40
|
]
|
|
@@ -95,7 +92,9 @@ class Visualization:
|
|
|
95
92
|
MultiplexerTransform()
|
|
96
93
|
],
|
|
97
94
|
'external_scripts': [
|
|
98
|
-
'https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.0/chroma.min.js'
|
|
95
|
+
'https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.0/chroma.min.js',
|
|
96
|
+
'https://cdn.jsdelivr.net/npm/spatialmerge',
|
|
97
|
+
'https://cdn.jsdelivr.net/npm/@turf/turf@7/turf.min.js'
|
|
99
98
|
]
|
|
100
99
|
}
|
|
101
100
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|