@vitessce/spatial-utils 3.1.2 → 3.2.0
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.
- package/dist/{deflate-6fd0bca9.js → deflate-3240dc7e.js} +1 -1
- package/dist/{index-551fa504.js → index-ca4e31e3.js} +1007 -82
- package/dist/index.js +15 -2
- package/dist/{jpeg-d67d9d82.js → jpeg-76bff48f.js} +1 -1
- package/dist/{lerc-522345a3.js → lerc-1ad8fc7c.js} +1 -1
- package/dist/{lzw-c3783269.js → lzw-c5e8dff0.js} +1 -1
- package/dist/{packbits-209c03d7.js → packbits-ccf26149.js} +1 -1
- package/dist/{raw-8e22b1c4.js → raw-446b6beb.js} +1 -1
- package/dist/{webimage-a5d2769c.js → webimage-bf1c5425.js} +1 -1
- package/dist-tsc/constants.d.ts +2 -0
- package/dist-tsc/constants.d.ts.map +1 -0
- package/dist-tsc/constants.js +12 -0
- package/dist-tsc/index.d.ts +3 -1
- package/dist-tsc/index.js +3 -1
- package/dist-tsc/layer-controller.d.ts +10 -0
- package/dist-tsc/layer-controller.d.ts.map +1 -1
- package/dist-tsc/layer-controller.js +32 -5
- package/dist-tsc/layer-controller.test.d.ts +2 -0
- package/dist-tsc/layer-controller.test.d.ts.map +1 -0
- package/dist-tsc/layer-controller.test.js +22 -0
- package/dist-tsc/spatial.d.ts +25 -4
- package/dist-tsc/spatial.d.ts.map +1 -1
- package/dist-tsc/spatial.js +124 -3
- package/dist-tsc/spatial.test.js +156 -1
- package/package.json +3 -3
- package/src/constants.js +14 -0
- package/src/index.js +17 -0
- package/src/layer-controller.js +34 -5
- package/src/layer-controller.test.js +24 -0
- package/src/spatial.js +141 -3
- package/src/spatial.test.js +160 -1
|
@@ -62,12 +62,62 @@ function baseGetTag(value) {
|
|
|
62
62
|
function isObjectLike$1(value) {
|
|
63
63
|
return value != null && typeof value == "object";
|
|
64
64
|
}
|
|
65
|
+
var symbolTag$4 = "[object Symbol]";
|
|
66
|
+
function isSymbol$1(value) {
|
|
67
|
+
return typeof value == "symbol" || isObjectLike$1(value) && baseGetTag(value) == symbolTag$4;
|
|
68
|
+
}
|
|
65
69
|
var isArray$4 = Array.isArray;
|
|
66
70
|
const isArray$5 = isArray$4;
|
|
71
|
+
var reWhitespace = /\s/;
|
|
72
|
+
function trimmedEndIndex(string) {
|
|
73
|
+
var index2 = string.length;
|
|
74
|
+
while (index2-- && reWhitespace.test(string.charAt(index2))) {
|
|
75
|
+
}
|
|
76
|
+
return index2;
|
|
77
|
+
}
|
|
78
|
+
var reTrimStart = /^\s+/;
|
|
79
|
+
function baseTrim(string) {
|
|
80
|
+
return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, "") : string;
|
|
81
|
+
}
|
|
67
82
|
function isObject$5(value) {
|
|
68
83
|
var type = typeof value;
|
|
69
84
|
return value != null && (type == "object" || type == "function");
|
|
70
85
|
}
|
|
86
|
+
var NAN$1 = 0 / 0;
|
|
87
|
+
var reIsBadHex$1 = /^[-+]0x[0-9a-f]+$/i;
|
|
88
|
+
var reIsBinary$1 = /^0b[01]+$/i;
|
|
89
|
+
var reIsOctal$1 = /^0o[0-7]+$/i;
|
|
90
|
+
var freeParseInt$1 = parseInt;
|
|
91
|
+
function toNumber$3(value) {
|
|
92
|
+
if (typeof value == "number") {
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
if (isSymbol$1(value)) {
|
|
96
|
+
return NAN$1;
|
|
97
|
+
}
|
|
98
|
+
if (isObject$5(value)) {
|
|
99
|
+
var other = typeof value.valueOf == "function" ? value.valueOf() : value;
|
|
100
|
+
value = isObject$5(other) ? other + "" : other;
|
|
101
|
+
}
|
|
102
|
+
if (typeof value != "string") {
|
|
103
|
+
return value === 0 ? value : +value;
|
|
104
|
+
}
|
|
105
|
+
value = baseTrim(value);
|
|
106
|
+
var isBinary2 = reIsBinary$1.test(value);
|
|
107
|
+
return isBinary2 || reIsOctal$1.test(value) ? freeParseInt$1(value.slice(2), isBinary2 ? 2 : 8) : reIsBadHex$1.test(value) ? NAN$1 : +value;
|
|
108
|
+
}
|
|
109
|
+
var INFINITY = 1 / 0, MAX_INTEGER = 17976931348623157e292;
|
|
110
|
+
function toFinite(value) {
|
|
111
|
+
if (!value) {
|
|
112
|
+
return value === 0 ? value : 0;
|
|
113
|
+
}
|
|
114
|
+
value = toNumber$3(value);
|
|
115
|
+
if (value === INFINITY || value === -INFINITY) {
|
|
116
|
+
var sign2 = value < 0 ? -1 : 1;
|
|
117
|
+
return sign2 * MAX_INTEGER;
|
|
118
|
+
}
|
|
119
|
+
return value === value ? value : 0;
|
|
120
|
+
}
|
|
71
121
|
var asyncTag = "[object AsyncFunction]", funcTag$2 = "[object Function]", genTag$1 = "[object GeneratorFunction]", proxyTag = "[object Proxy]";
|
|
72
122
|
function isFunction$3(value) {
|
|
73
123
|
if (!isObject$5(value)) {
|
|
@@ -223,6 +273,16 @@ function isLength(value) {
|
|
|
223
273
|
function isArrayLike(value) {
|
|
224
274
|
return value != null && isLength(value.length) && !isFunction$3(value);
|
|
225
275
|
}
|
|
276
|
+
function isIterateeCall(value, index2, object2) {
|
|
277
|
+
if (!isObject$5(object2)) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
var type = typeof index2;
|
|
281
|
+
if (type == "number" ? isArrayLike(object2) && isIndex$1(index2, object2.length) : type == "string" && index2 in object2) {
|
|
282
|
+
return eq$4(object2[index2], value);
|
|
283
|
+
}
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
226
286
|
var objectProto$b = Object.prototype;
|
|
227
287
|
function isPrototype(value) {
|
|
228
288
|
var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto$b;
|
|
@@ -1045,6 +1105,33 @@ function baseIsEqual(value, other, bitmask, customizer, stack2) {
|
|
|
1045
1105
|
function isEqual$1(value, other) {
|
|
1046
1106
|
return baseIsEqual(value, other);
|
|
1047
1107
|
}
|
|
1108
|
+
var nativeCeil = Math.ceil, nativeMax$1 = Math.max;
|
|
1109
|
+
function baseRange(start, end, step, fromRight) {
|
|
1110
|
+
var index2 = -1, length2 = nativeMax$1(nativeCeil((end - start) / (step || 1)), 0), result = Array(length2);
|
|
1111
|
+
while (length2--) {
|
|
1112
|
+
result[fromRight ? length2 : ++index2] = start;
|
|
1113
|
+
start += step;
|
|
1114
|
+
}
|
|
1115
|
+
return result;
|
|
1116
|
+
}
|
|
1117
|
+
function createRange(fromRight) {
|
|
1118
|
+
return function(start, end, step) {
|
|
1119
|
+
if (step && typeof step != "number" && isIterateeCall(start, end, step)) {
|
|
1120
|
+
end = step = void 0;
|
|
1121
|
+
}
|
|
1122
|
+
start = toFinite(start);
|
|
1123
|
+
if (end === void 0) {
|
|
1124
|
+
end = start;
|
|
1125
|
+
start = 0;
|
|
1126
|
+
} else {
|
|
1127
|
+
end = toFinite(end);
|
|
1128
|
+
}
|
|
1129
|
+
step = step === void 0 ? start < end ? 1 : -1 : toFinite(step);
|
|
1130
|
+
return baseRange(start, end, step, fromRight);
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
var range$4 = createRange();
|
|
1134
|
+
const range$5 = range$4;
|
|
1048
1135
|
function assert$c(condition, message) {
|
|
1049
1136
|
if (!condition) {
|
|
1050
1137
|
throw new Error("math.gl assertion ".concat(message));
|
|
@@ -1800,7 +1887,7 @@ function negate(out, a2) {
|
|
|
1800
1887
|
out[2] = -a2[2];
|
|
1801
1888
|
return out;
|
|
1802
1889
|
}
|
|
1803
|
-
function normalize$
|
|
1890
|
+
function normalize$4(out, a2) {
|
|
1804
1891
|
var x2 = a2[0];
|
|
1805
1892
|
var y2 = a2[1];
|
|
1806
1893
|
var z2 = a2[2];
|
|
@@ -3109,7 +3196,7 @@ function squaredLength$1(a2) {
|
|
|
3109
3196
|
var w2 = a2[3];
|
|
3110
3197
|
return x2 * x2 + y2 * y2 + z2 * z2 + w2 * w2;
|
|
3111
3198
|
}
|
|
3112
|
-
function normalize$
|
|
3199
|
+
function normalize$3(out, a2) {
|
|
3113
3200
|
var x2 = a2[0];
|
|
3114
3201
|
var y2 = a2[1];
|
|
3115
3202
|
var z2 = a2[2];
|
|
@@ -3746,7 +3833,7 @@ var dot$2 = dot$3;
|
|
|
3746
3833
|
var lerp$1 = lerp$2;
|
|
3747
3834
|
var length$2 = length$3;
|
|
3748
3835
|
var squaredLength = squaredLength$1;
|
|
3749
|
-
var normalize$
|
|
3836
|
+
var normalize$2 = normalize$3;
|
|
3750
3837
|
var rotationTo = function() {
|
|
3751
3838
|
var tmpvec3 = create$3();
|
|
3752
3839
|
var xUnitVec3 = fromValues(1, 0, 0);
|
|
@@ -3757,7 +3844,7 @@ var rotationTo = function() {
|
|
|
3757
3844
|
cross$1(tmpvec3, xUnitVec3, a2);
|
|
3758
3845
|
if (len(tmpvec3) < 1e-6)
|
|
3759
3846
|
cross$1(tmpvec3, yUnitVec3, a2);
|
|
3760
|
-
normalize$
|
|
3847
|
+
normalize$4(tmpvec3, tmpvec3);
|
|
3761
3848
|
setAxisAngle(out, tmpvec3, Math.PI);
|
|
3762
3849
|
return out;
|
|
3763
3850
|
} else if (dot2 > 0.999999) {
|
|
@@ -3772,7 +3859,7 @@ var rotationTo = function() {
|
|
|
3772
3859
|
out[1] = tmpvec3[1];
|
|
3773
3860
|
out[2] = tmpvec3[2];
|
|
3774
3861
|
out[3] = 1 + dot2;
|
|
3775
|
-
return normalize$
|
|
3862
|
+
return normalize$2(out, out);
|
|
3776
3863
|
}
|
|
3777
3864
|
};
|
|
3778
3865
|
}();
|
|
@@ -3798,7 +3885,7 @@ var rotationTo = function() {
|
|
|
3798
3885
|
matr[2] = -view[0];
|
|
3799
3886
|
matr[5] = -view[1];
|
|
3800
3887
|
matr[8] = -view[2];
|
|
3801
|
-
return normalize$
|
|
3888
|
+
return normalize$2(out, fromMat3(out, matr));
|
|
3802
3889
|
};
|
|
3803
3890
|
})();
|
|
3804
3891
|
const IDENTITY_QUATERNION = [0, 0, 0, 1];
|
|
@@ -28415,8 +28502,10 @@ const ViewType$1 = {
|
|
|
28415
28502
|
STATUS: "status",
|
|
28416
28503
|
SCATTERPLOT: "scatterplot",
|
|
28417
28504
|
SPATIAL: "spatial",
|
|
28505
|
+
SPATIAL_BETA: "spatialBeta",
|
|
28418
28506
|
HEATMAP: "heatmap",
|
|
28419
28507
|
LAYER_CONTROLLER: "layerController",
|
|
28508
|
+
LAYER_CONTROLLER_BETA: "layerControllerBeta",
|
|
28420
28509
|
GENOMIC_PROFILES: "genomicProfiles",
|
|
28421
28510
|
GATING: "gating",
|
|
28422
28511
|
FEATURE_LIST: "featureList",
|
|
@@ -28428,20 +28517,24 @@ const ViewType$1 = {
|
|
|
28428
28517
|
const DataType$2 = {
|
|
28429
28518
|
OBS_LABELS: "obsLabels",
|
|
28430
28519
|
OBS_EMBEDDING: "obsEmbedding",
|
|
28431
|
-
OBS_LOCATIONS: "obsLocations",
|
|
28432
28520
|
OBS_FEATURE_MATRIX: "obsFeatureMatrix",
|
|
28433
28521
|
OBS_SETS: "obsSets",
|
|
28434
28522
|
FEATURE_LABELS: "featureLabels",
|
|
28435
28523
|
IMAGE: "image",
|
|
28436
28524
|
OBS_SEGMENTATIONS: "obsSegmentations",
|
|
28437
28525
|
NEIGHBORHOODS: "neighborhoods",
|
|
28438
|
-
GENOMIC_PROFILES: "genomic-profiles"
|
|
28526
|
+
GENOMIC_PROFILES: "genomic-profiles",
|
|
28527
|
+
OBS_SPOTS: "obsSpots",
|
|
28528
|
+
OBS_POINTS: "obsPoints",
|
|
28529
|
+
OBS_LOCATIONS: "obsLocations"
|
|
28439
28530
|
};
|
|
28440
28531
|
const FileType$1 = {
|
|
28441
28532
|
// Joint file types
|
|
28442
28533
|
ANNDATA_ZARR: "anndata.zarr",
|
|
28443
28534
|
// Atomic file types
|
|
28444
28535
|
OBS_EMBEDDING_CSV: "obsEmbedding.csv",
|
|
28536
|
+
OBS_SPOTS_CSV: "obsSpots.csv",
|
|
28537
|
+
OBS_POINTS_CSV: "obsPoints.csv",
|
|
28445
28538
|
OBS_LOCATIONS_CSV: "obsLocations.csv",
|
|
28446
28539
|
OBS_LABELS_CSV: "obsLabels.csv",
|
|
28447
28540
|
FEATURE_LABELS_CSV: "featureLabels.csv",
|
|
@@ -28454,6 +28547,8 @@ const FileType$1 = {
|
|
|
28454
28547
|
OBS_FEATURE_MATRIX_ANNDATA_ZARR: "obsFeatureMatrix.anndata.zarr",
|
|
28455
28548
|
OBS_SETS_ANNDATA_ZARR: "obsSets.anndata.zarr",
|
|
28456
28549
|
OBS_EMBEDDING_ANNDATA_ZARR: "obsEmbedding.anndata.zarr",
|
|
28550
|
+
OBS_SPOTS_ANNDATA_ZARR: "obsSpots.anndata.zarr",
|
|
28551
|
+
OBS_POINTS_ANNDATA_ZARR: "obsPoints.anndata.zarr",
|
|
28457
28552
|
OBS_LOCATIONS_ANNDATA_ZARR: "obsLocations.anndata.zarr",
|
|
28458
28553
|
OBS_SEGMENTATIONS_ANNDATA_ZARR: "obsSegmentations.anndata.zarr",
|
|
28459
28554
|
OBS_LABELS_ANNDATA_ZARR: "obsLabels.anndata.zarr",
|
|
@@ -28462,6 +28557,8 @@ const FileType$1 = {
|
|
|
28462
28557
|
OBS_FEATURE_MATRIX_MUDATA_ZARR: "obsFeatureMatrix.mudata.zarr",
|
|
28463
28558
|
OBS_SETS_MUDATA_ZARR: "obsSets.mudata.zarr",
|
|
28464
28559
|
OBS_EMBEDDING_MUDATA_ZARR: "obsEmbedding.mudata.zarr",
|
|
28560
|
+
OBS_SPOTS_MUDATA_ZARR: "obsSpots.mudata.zarr",
|
|
28561
|
+
OBS_POINTS_MUDATA_ZARR: "obsPoints.mudata.zarr",
|
|
28465
28562
|
OBS_LOCATIONS_MUDATA_ZARR: "obsLocations.mudata.zarr",
|
|
28466
28563
|
OBS_SEGMENTATIONS_MUDATA_ZARR: "obsSegmentations.mudata.zarr",
|
|
28467
28564
|
OBS_LABELS_MUDATA_ZARR: "obsLabels.mudata.zarr",
|
|
@@ -28505,10 +28602,8 @@ const FileType$1 = {
|
|
|
28505
28602
|
ANNDATA_EXPRESSION_MATRIX_ZARR: "anndata-expression-matrix.zarr"
|
|
28506
28603
|
};
|
|
28507
28604
|
const CoordinationType$1 = {
|
|
28508
|
-
// Meta coordination scopes
|
|
28509
28605
|
META_COORDINATION_SCOPES: "metaCoordinationScopes",
|
|
28510
28606
|
META_COORDINATION_SCOPES_BY: "metaCoordinationScopesBy",
|
|
28511
|
-
// Other coordination scopes
|
|
28512
28607
|
DATASET: "dataset",
|
|
28513
28608
|
// Entity types
|
|
28514
28609
|
OBS_TYPE: "obsType",
|
|
@@ -28534,6 +28629,7 @@ const CoordinationType$1 = {
|
|
|
28534
28629
|
SPATIAL_TARGET_X: "spatialTargetX",
|
|
28535
28630
|
SPATIAL_TARGET_Y: "spatialTargetY",
|
|
28536
28631
|
SPATIAL_TARGET_Z: "spatialTargetZ",
|
|
28632
|
+
SPATIAL_TARGET_T: "spatialTargetT",
|
|
28537
28633
|
SPATIAL_ROTATION_X: "spatialRotationX",
|
|
28538
28634
|
SPATIAL_ROTATION_Y: "spatialRotationY",
|
|
28539
28635
|
SPATIAL_ROTATION_Z: "spatialRotationZ",
|
|
@@ -28571,7 +28667,46 @@ const CoordinationType$1 = {
|
|
|
28571
28667
|
GATING_FEATURE_SELECTION_X: "gatingFeatureSelectionX",
|
|
28572
28668
|
GATING_FEATURE_SELECTION_Y: "gatingFeatureSelectionY",
|
|
28573
28669
|
FEATURE_VALUE_TRANSFORM_COEFFICIENT: "featureValueTransformCoefficient",
|
|
28574
|
-
TOOLTIPS_VISIBLE: "tooltipsVisible"
|
|
28670
|
+
TOOLTIPS_VISIBLE: "tooltipsVisible",
|
|
28671
|
+
FILE_UID: "fileUid",
|
|
28672
|
+
IMAGE_LAYER: "imageLayer",
|
|
28673
|
+
IMAGE_CHANNEL: "imageChannel",
|
|
28674
|
+
SEGMENTATION_LAYER: "segmentationLayer",
|
|
28675
|
+
SEGMENTATION_CHANNEL: "segmentationChannel",
|
|
28676
|
+
SPATIAL_TARGET_C: "spatialTargetC",
|
|
28677
|
+
SPATIAL_LAYER_VISIBLE: "spatialLayerVisible",
|
|
28678
|
+
SPATIAL_LAYER_OPACITY: "spatialLayerOpacity",
|
|
28679
|
+
SPATIAL_LAYER_COLORMAP: "spatialLayerColormap",
|
|
28680
|
+
SPATIAL_LAYER_TRANSPARENT_COLOR: "spatialLayerTransparentColor",
|
|
28681
|
+
SPATIAL_LAYER_MODEL_MATRIX: "spatialLayerModelMatrix",
|
|
28682
|
+
SPATIAL_SEGMENTATION_FILLED: "spatialSegmentationFilled",
|
|
28683
|
+
SPATIAL_SEGMENTATION_STROKE_WIDTH: "spatialSegmentationStrokeWidth",
|
|
28684
|
+
SPATIAL_CHANNEL_COLOR: "spatialChannelColor",
|
|
28685
|
+
SPATIAL_CHANNEL_VISIBLE: "spatialChannelVisible",
|
|
28686
|
+
SPATIAL_CHANNEL_OPACITY: "spatialChannelOpacity",
|
|
28687
|
+
SPATIAL_CHANNEL_WINDOW: "spatialChannelWindow",
|
|
28688
|
+
PHOTOMETRIC_INTERPRETATION: "photometricInterpretation",
|
|
28689
|
+
// For 3D volume rendering
|
|
28690
|
+
SPATIAL_RENDERING_MODE: "spatialRenderingMode",
|
|
28691
|
+
VOLUMETRIC_RENDERING_ALGORITHM: "volumetricRenderingAlgorithm",
|
|
28692
|
+
SPATIAL_TARGET_RESOLUTION: "spatialTargetResolution",
|
|
28693
|
+
// For clipping plane sliders
|
|
28694
|
+
SPATIAL_SLICE_X: "spatialSliceX",
|
|
28695
|
+
SPATIAL_SLICE_Y: "spatialSliceY",
|
|
28696
|
+
SPATIAL_SLICE_Z: "spatialSliceZ",
|
|
28697
|
+
// For spatial spot and point layers
|
|
28698
|
+
SPOT_LAYER: "spotLayer",
|
|
28699
|
+
POINT_LAYER: "pointLayer",
|
|
28700
|
+
SPATIAL_SPOT_RADIUS: "spatialSpotRadius",
|
|
28701
|
+
SPATIAL_SPOT_FILLED: "spatialSpotFilled",
|
|
28702
|
+
SPATIAL_SPOT_STROKE_WIDTH: "spatialSpotStrokeWidth",
|
|
28703
|
+
SPATIAL_LAYER_COLOR: "spatialLayerColor",
|
|
28704
|
+
PIXEL_HIGHLIGHT: "pixelHighlight",
|
|
28705
|
+
TOOLTIP_CROSSHAIRS_VISIBLE: "tooltipCrosshairsVisible",
|
|
28706
|
+
LEGEND_VISIBLE: "legendVisible",
|
|
28707
|
+
SPATIAL_CHANNEL_LABELS_VISIBLE: "spatialChannelLabelsVisible",
|
|
28708
|
+
SPATIAL_CHANNEL_LABELS_ORIENTATION: "spatialChannelLabelsOrientation",
|
|
28709
|
+
SPATIAL_CHANNEL_LABEL_SIZE: "spatialChannelLabelSize"
|
|
28575
28710
|
};
|
|
28576
28711
|
const ViewType = {
|
|
28577
28712
|
GENES: [
|
|
@@ -28832,6 +28967,8 @@ const annDataObsSets = z.array(z.object({
|
|
|
28832
28967
|
]),
|
|
28833
28968
|
scorePath: z.string().optional().describe("The location in the AnnData store for the set confidence scores, like 'obs/celltype_prediction_score.'")
|
|
28834
28969
|
}));
|
|
28970
|
+
const annDataObsSpots = annDataObsm;
|
|
28971
|
+
const annDataObsPoints = annDataObsm;
|
|
28835
28972
|
const annDataObsLocations = annDataObsm;
|
|
28836
28973
|
const annDataObsEmbedding = annDataObsm;
|
|
28837
28974
|
const annDataObsSegmentations = annDataObs;
|
|
@@ -28858,10 +28995,21 @@ z.object({
|
|
|
28858
28995
|
z.object({
|
|
28859
28996
|
obsIndex: z.string(),
|
|
28860
28997
|
obsEmbedding: z.array(z.string()).length(2)
|
|
28998
|
+
// TODO: support 3D?
|
|
28999
|
+
});
|
|
29000
|
+
z.object({
|
|
29001
|
+
obsIndex: z.string(),
|
|
29002
|
+
obsSpots: z.array(z.string()).length(2)
|
|
29003
|
+
// TODO: support 3D?
|
|
29004
|
+
});
|
|
29005
|
+
z.object({
|
|
29006
|
+
obsIndex: z.string(),
|
|
29007
|
+
obsPoints: z.array(z.string()).length(3)
|
|
28861
29008
|
});
|
|
28862
29009
|
z.object({
|
|
28863
29010
|
obsIndex: z.string(),
|
|
28864
29011
|
obsLocations: z.array(z.string()).length(2)
|
|
29012
|
+
// TODO: support 3D?
|
|
28865
29013
|
});
|
|
28866
29014
|
z.object({
|
|
28867
29015
|
obsIndex: z.string(),
|
|
@@ -28893,6 +29041,8 @@ z.object({
|
|
|
28893
29041
|
]),
|
|
28894
29042
|
obsFeatureMatrix: annDataObsFeatureMatrix,
|
|
28895
29043
|
obsSets: annDataObsSets,
|
|
29044
|
+
obsSpots: annDataObsSpots,
|
|
29045
|
+
obsPoints: annDataObsPoints,
|
|
28896
29046
|
obsLocations: annDataObsLocations,
|
|
28897
29047
|
obsSegmentations: annDataObsSegmentations,
|
|
28898
29048
|
obsEmbedding: z.union([
|
|
@@ -33975,7 +34125,7 @@ var json2csv_umd = { exports: {} };
|
|
|
33975
34125
|
var commonjsGlobal$1 = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof commonjsGlobal !== "undefined" ? commonjsGlobal : typeof self !== "undefined" ? self : {};
|
|
33976
34126
|
var FUNC_ERROR_TEXT2 = "Expected a function";
|
|
33977
34127
|
var HASH_UNDEFINED2 = "__lodash_hash_undefined__";
|
|
33978
|
-
var
|
|
34128
|
+
var INFINITY2 = 1 / 0;
|
|
33979
34129
|
var funcTag2 = "[object Function]", genTag2 = "[object GeneratorFunction]", symbolTag2 = "[object Symbol]";
|
|
33980
34130
|
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/, reLeadingDot = /^\./, rePropName2 = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
|
|
33981
34131
|
var reRegExpChar2 = /[\\^$.*+?()[\]{}|]/g;
|
|
@@ -34158,7 +34308,7 @@ var json2csv_umd = { exports: {} };
|
|
|
34158
34308
|
return symbolToString ? symbolToString.call(value) : "";
|
|
34159
34309
|
}
|
|
34160
34310
|
var result = value + "";
|
|
34161
|
-
return result == "0" && 1 / value == -
|
|
34311
|
+
return result == "0" && 1 / value == -INFINITY2 ? "-0" : result;
|
|
34162
34312
|
}
|
|
34163
34313
|
function castPath(value) {
|
|
34164
34314
|
return isArray$22(value) ? value : stringToPath3(value);
|
|
@@ -34204,7 +34354,7 @@ var json2csv_umd = { exports: {} };
|
|
|
34204
34354
|
return value;
|
|
34205
34355
|
}
|
|
34206
34356
|
var result = value + "";
|
|
34207
|
-
return result == "0" && 1 / value == -
|
|
34357
|
+
return result == "0" && 1 / value == -INFINITY2 ? "-0" : result;
|
|
34208
34358
|
}
|
|
34209
34359
|
function toSource2(func) {
|
|
34210
34360
|
if (func != null) {
|
|
@@ -36829,17 +36979,17 @@ let COLOR;
|
|
|
36829
36979
|
COLOR2[COLOR2["BRIGHT_CYAN"] = 96] = "BRIGHT_CYAN";
|
|
36830
36980
|
COLOR2[COLOR2["BRIGHT_WHITE"] = 97] = "BRIGHT_WHITE";
|
|
36831
36981
|
})(COLOR || (COLOR = {}));
|
|
36832
|
-
function getColor(color) {
|
|
36982
|
+
function getColor$1(color) {
|
|
36833
36983
|
return typeof color === "string" ? COLOR[color.toUpperCase()] || COLOR.WHITE : color;
|
|
36834
36984
|
}
|
|
36835
36985
|
function addColor(string, color, background) {
|
|
36836
36986
|
if (!isBrowser$1 && typeof string === "string") {
|
|
36837
36987
|
if (color) {
|
|
36838
|
-
color = getColor(color);
|
|
36988
|
+
color = getColor$1(color);
|
|
36839
36989
|
string = "\x1B[".concat(color, "m").concat(string, "\x1B[39m");
|
|
36840
36990
|
}
|
|
36841
36991
|
if (background) {
|
|
36842
|
-
color = getColor(background);
|
|
36992
|
+
color = getColor$1(background);
|
|
36843
36993
|
string = "\x1B[".concat(background + 10, "m").concat(string, "\x1B[49m");
|
|
36844
36994
|
}
|
|
36845
36995
|
}
|
|
@@ -66949,7 +67099,7 @@ function copyFlatRing(target, targetStartIndex, positions, size2, srcStartIndex
|
|
|
66949
67099
|
modifyPolygonWindingDirection(target, windingDirection, windingOptions);
|
|
66950
67100
|
return targetIndex;
|
|
66951
67101
|
}
|
|
66952
|
-
function normalize(polygon2, positionSize) {
|
|
67102
|
+
function normalize$1(polygon2, positionSize) {
|
|
66953
67103
|
validate(polygon2);
|
|
66954
67104
|
const positions = [];
|
|
66955
67105
|
const holeIndices = [];
|
|
@@ -67055,7 +67205,7 @@ class PolygonTesselator extends Tesselator {
|
|
|
67055
67205
|
}
|
|
67056
67206
|
normalizeGeometry(polygon2) {
|
|
67057
67207
|
if (this.normalize) {
|
|
67058
|
-
const normalizedPolygon = normalize(polygon2, this.positionSize);
|
|
67208
|
+
const normalizedPolygon = normalize$1(polygon2, this.positionSize);
|
|
67059
67209
|
if (this.opts.resolution) {
|
|
67060
67210
|
return cutPolygonByGrid(getPositions(normalizedPolygon), getHoleIndices(normalizedPolygon), {
|
|
67061
67211
|
size: this.positionSize,
|
|
@@ -67677,7 +67827,7 @@ class PolygonLayer extends CompositeLayer {
|
|
|
67677
67827
|
objectInfo.index++;
|
|
67678
67828
|
let polygon2 = getPolygon(object2, objectInfo);
|
|
67679
67829
|
if (_normalize) {
|
|
67680
|
-
polygon2 = normalize(polygon2, positionSize);
|
|
67830
|
+
polygon2 = normalize$1(polygon2, positionSize);
|
|
67681
67831
|
}
|
|
67682
67832
|
const {
|
|
67683
67833
|
holeIndices
|
|
@@ -111504,7 +111654,7 @@ function clipExtent(x02, y02, x12, y12) {
|
|
|
111504
111654
|
return clipStream;
|
|
111505
111655
|
};
|
|
111506
111656
|
}
|
|
111507
|
-
function extent() {
|
|
111657
|
+
function extent$1() {
|
|
111508
111658
|
var x02 = 0, y02 = 0, x12 = 960, y12 = 500, cache2, cacheStream, clip2;
|
|
111509
111659
|
return clip2 = {
|
|
111510
111660
|
stream: function(stream) {
|
|
@@ -112911,7 +113061,7 @@ const d3Geo$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
112911
113061
|
geoBounds: bounds,
|
|
112912
113062
|
geoCentroid: centroid$3,
|
|
112913
113063
|
geoCircle: circle$2,
|
|
112914
|
-
geoClipExtent: extent,
|
|
113064
|
+
geoClipExtent: extent$1,
|
|
112915
113065
|
geoConicConformal: conicConformal,
|
|
112916
113066
|
geoConicConformalRaw: conicConformalRaw,
|
|
112917
113067
|
geoConicEqualArea: conicEqualArea,
|
|
@@ -132114,28 +132264,38 @@ const PASS_THROUGH_PROPS = [
|
|
|
132114
132264
|
];
|
|
132115
132265
|
class SelectionLayer extends CompositeLayer {
|
|
132116
132266
|
_selectPolygonObjects(coordinates2) {
|
|
132117
|
-
const {
|
|
132267
|
+
const { flipY, obsLayers } = this.props;
|
|
132118
132268
|
const flippedCoordinates = flipY ? coordinates2.map((poly) => poly.map((p) => [p[0], -p[1]])) : coordinates2;
|
|
132119
132269
|
const selectedPolygon = polygon(flippedCoordinates);
|
|
132120
|
-
|
|
132121
|
-
|
|
132122
|
-
const
|
|
132123
|
-
|
|
132124
|
-
|
|
132125
|
-
|
|
132126
|
-
|
|
132127
|
-
|
|
132128
|
-
|
|
132129
|
-
|
|
132130
|
-
|
|
132131
|
-
|
|
132132
|
-
|
|
132133
|
-
|
|
132270
|
+
obsLayers.forEach((obsLayer) => {
|
|
132271
|
+
const { getObsCoords, obsQuadTree, obsIndex, onSelect: layerOnSelect } = obsLayer;
|
|
132272
|
+
const pickingInfos = [];
|
|
132273
|
+
obsQuadTree == null ? void 0 : obsQuadTree.visit((node2, x02, y02, x12, y12) => {
|
|
132274
|
+
const nodePoints = [[[x02, y02], [x12, y02], [x12, y12], [x02, y12], [x02, y02]]];
|
|
132275
|
+
const nodePolygon = polygon(nodePoints);
|
|
132276
|
+
const nodePolygonContainsSelectedPolygon = booleanContains(nodePolygon, selectedPolygon);
|
|
132277
|
+
const nodePolygonWithinSelectedPolygon = booleanWithin(nodePolygon, selectedPolygon);
|
|
132278
|
+
const nodePolygonOverlapsSelectedPolgyon = booleanOverlap(nodePolygon, selectedPolygon);
|
|
132279
|
+
if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
|
|
132280
|
+
return true;
|
|
132281
|
+
}
|
|
132282
|
+
if (node2.data && booleanPointInPolygon$1(point([].slice.call(getObsCoords(node2.data))), selectedPolygon)) {
|
|
132283
|
+
pickingInfos.push(node2.data);
|
|
132284
|
+
}
|
|
132285
|
+
return false;
|
|
132286
|
+
});
|
|
132287
|
+
const pickingIds = pickingInfos.map((obsI) => obsIndex[obsI]);
|
|
132288
|
+
layerOnSelect(pickingIds);
|
|
132289
|
+
});
|
|
132290
|
+
}
|
|
132291
|
+
_selectEmpty() {
|
|
132292
|
+
const { obsLayers } = this.props;
|
|
132293
|
+
obsLayers.forEach((obsLayer) => {
|
|
132294
|
+
const { onSelect: layerOnSelect } = obsLayer;
|
|
132295
|
+
layerOnSelect([]);
|
|
132134
132296
|
});
|
|
132135
|
-
onSelect({ pickingInfos });
|
|
132136
132297
|
}
|
|
132137
132298
|
renderLayers() {
|
|
132138
|
-
const { onSelect } = this.props;
|
|
132139
132299
|
const mode = MODE_MAP[this.props.selectionType] || distEs6.ViewMode;
|
|
132140
132300
|
const inheritedProps = {};
|
|
132141
132301
|
PASS_THROUGH_PROPS.forEach((p) => {
|
|
@@ -132157,7 +132317,7 @@ class SelectionLayer extends CompositeLayer {
|
|
|
132157
132317
|
const { coordinates: coordinates2 } = updatedData.features[0].geometry;
|
|
132158
132318
|
this._selectPolygonObjects(coordinates2);
|
|
132159
132319
|
} else if (editType === EDIT_TYPE_CLEAR) {
|
|
132160
|
-
|
|
132320
|
+
this._selectEmpty();
|
|
132161
132321
|
}
|
|
132162
132322
|
},
|
|
132163
132323
|
_subLayerProps: {
|
|
@@ -133297,16 +133457,16 @@ function addDecoder(cases, importFn) {
|
|
|
133297
133457
|
}
|
|
133298
133458
|
cases.forEach((c) => registry$1.set(c, importFn));
|
|
133299
133459
|
}
|
|
133300
|
-
addDecoder([void 0, 1], () => import("./raw-
|
|
133301
|
-
addDecoder(5, () => import("./lzw-
|
|
133460
|
+
addDecoder([void 0, 1], () => import("./raw-446b6beb.js").then((m) => m.default));
|
|
133461
|
+
addDecoder(5, () => import("./lzw-c5e8dff0.js").then((m) => m.default));
|
|
133302
133462
|
addDecoder(6, () => {
|
|
133303
133463
|
throw new Error("old style JPEG compression is not supported.");
|
|
133304
133464
|
});
|
|
133305
|
-
addDecoder(7, () => import("./jpeg-
|
|
133306
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
133307
|
-
addDecoder(32773, () => import("./packbits-
|
|
133308
|
-
addDecoder(34887, () => import("./lerc-
|
|
133309
|
-
addDecoder(50001, () => import("./webimage-
|
|
133465
|
+
addDecoder(7, () => import("./jpeg-76bff48f.js").then((m) => m.default));
|
|
133466
|
+
addDecoder([8, 32946], () => import("./deflate-3240dc7e.js").then((m) => m.default));
|
|
133467
|
+
addDecoder(32773, () => import("./packbits-ccf26149.js").then((m) => m.default));
|
|
133468
|
+
addDecoder(34887, () => import("./lerc-1ad8fc7c.js").then((m) => m.default));
|
|
133469
|
+
addDecoder(50001, () => import("./webimage-bf1c5425.js").then((m) => m.default));
|
|
133310
133470
|
function decodeRowAcc(row, stride) {
|
|
133311
133471
|
let length2 = row.length - stride;
|
|
133312
133472
|
let offset = 0;
|
|
@@ -140201,7 +140361,7 @@ const SIGNAL_ABORTED = "__vivSignalAborted";
|
|
|
140201
140361
|
addDecoder(5, () => LZWDecoder);
|
|
140202
140362
|
const MAX_COLOR_INTENSITY = 255;
|
|
140203
140363
|
const DEFAULT_COLOR_OFF = [0, 0, 0];
|
|
140204
|
-
const MAX_CHANNELS = 6;
|
|
140364
|
+
const MAX_CHANNELS$1 = 6;
|
|
140205
140365
|
const DEFAULT_FONT_FAMILY = "-apple-system, 'Helvetica Neue', Arial, sans-serif";
|
|
140206
140366
|
const DTYPE_VALUES = {
|
|
140207
140367
|
Uint8: {
|
|
@@ -141723,7 +141883,7 @@ const AdditiveColormapExtension = class extends LayerExtension {
|
|
|
141723
141883
|
};
|
|
141724
141884
|
AdditiveColormapExtension.extensionName = "AdditiveColormapExtension";
|
|
141725
141885
|
AdditiveColormapExtension.defaultProps = defaultProps$4$1;
|
|
141726
|
-
const fs$1$
|
|
141886
|
+
const fs$1$2 = `uniform vec3 transparentColor;
|
|
141727
141887
|
uniform bool useTransparentColor;
|
|
141728
141888
|
uniform float opacity;
|
|
141729
141889
|
|
|
@@ -141750,12 +141910,12 @@ rgba = apply_opacity(rgb);
|
|
|
141750
141910
|
`;
|
|
141751
141911
|
const colorPalette = {
|
|
141752
141912
|
name: "color-palette-module",
|
|
141753
|
-
fs: fs$1$
|
|
141913
|
+
fs: fs$1$2,
|
|
141754
141914
|
inject: {
|
|
141755
141915
|
"fs:DECKGL_MUTATE_COLOR": DECKGL_MUTATE_COLOR
|
|
141756
141916
|
}
|
|
141757
141917
|
};
|
|
141758
|
-
function padWithDefault$
|
|
141918
|
+
function padWithDefault$3(arr, defaultValue2, padWidth) {
|
|
141759
141919
|
for (let i2 = 0; i2 < padWidth; i2 += 1) {
|
|
141760
141920
|
arr.push(defaultValue2);
|
|
141761
141921
|
}
|
|
@@ -141781,8 +141941,8 @@ function padColors({ colors, channelsVisible }) {
|
|
|
141781
141941
|
const newColors = colors.map(
|
|
141782
141942
|
(color, i2) => channelsVisible[i2] ? color.map((c) => c / MAX_COLOR_INTENSITY) : DEFAULT_COLOR_OFF
|
|
141783
141943
|
);
|
|
141784
|
-
const padSize = MAX_CHANNELS - newColors.length;
|
|
141785
|
-
const paddedColors = padWithDefault$
|
|
141944
|
+
const padSize = MAX_CHANNELS$1 - newColors.length;
|
|
141945
|
+
const paddedColors = padWithDefault$3(
|
|
141786
141946
|
newColors,
|
|
141787
141947
|
DEFAULT_COLOR_OFF,
|
|
141788
141948
|
padSize
|
|
@@ -142026,7 +142186,7 @@ vec4 colormap(float intensity, float opacity) {
|
|
|
142026
142186
|
fs: fs2
|
|
142027
142187
|
};
|
|
142028
142188
|
}
|
|
142029
|
-
const defaultProps$1$
|
|
142189
|
+
const defaultProps$1$2 = {
|
|
142030
142190
|
colormap: { type: "string", value: "viridis", compare: true }
|
|
142031
142191
|
};
|
|
142032
142192
|
const BaseExtension$1 = class extends LayerExtension {
|
|
@@ -142036,7 +142196,7 @@ const BaseExtension$1 = class extends LayerExtension {
|
|
|
142036
142196
|
}
|
|
142037
142197
|
getShaders() {
|
|
142038
142198
|
var _a2;
|
|
142039
|
-
const name2 = ((_a2 = this == null ? void 0 : this.props) == null ? void 0 : _a2.colormap) || defaultProps$1$
|
|
142199
|
+
const name2 = ((_a2 = this == null ? void 0 : this.props) == null ? void 0 : _a2.colormap) || defaultProps$1$2.colormap.value;
|
|
142040
142200
|
const apply_cmap = cmaps[name2];
|
|
142041
142201
|
return {
|
|
142042
142202
|
...super.getShaders(),
|
|
@@ -142055,7 +142215,7 @@ const BaseExtension$1 = class extends LayerExtension {
|
|
|
142055
142215
|
}
|
|
142056
142216
|
};
|
|
142057
142217
|
BaseExtension$1.extensionName = "BaseExtension";
|
|
142058
|
-
BaseExtension$1.defaultProps = defaultProps$1$
|
|
142218
|
+
BaseExtension$1.defaultProps = defaultProps$1$2;
|
|
142059
142219
|
const _BEFORE_RENDER$5 = "";
|
|
142060
142220
|
const _RENDER$5 = ` float intensityArray[6] = float[6](intensityValue0, intensityValue1, intensityValue2, intensityValue3, intensityValue4, intensityValue5);
|
|
142061
142221
|
float total = 0.0;
|
|
@@ -142254,7 +142414,7 @@ const channels = {
|
|
|
142254
142414
|
function range(len2) {
|
|
142255
142415
|
return [...Array(len2).keys()];
|
|
142256
142416
|
}
|
|
142257
|
-
function padWithDefault$
|
|
142417
|
+
function padWithDefault$2(arr, defaultValue2, padWidth) {
|
|
142258
142418
|
for (let i2 = 0; i2 < padWidth; i2 += 1) {
|
|
142259
142419
|
arr.push(defaultValue2);
|
|
142260
142420
|
}
|
|
@@ -142278,20 +142438,20 @@ function padContrastLimits({
|
|
|
142278
142438
|
const newContrastLimits = contrastLimits.map(
|
|
142279
142439
|
(slider, i2) => channelsVisible[i2] ? slider : [maxSliderValue, maxSliderValue]
|
|
142280
142440
|
);
|
|
142281
|
-
const padSize = MAX_CHANNELS - newContrastLimits.length;
|
|
142441
|
+
const padSize = MAX_CHANNELS$1 - newContrastLimits.length;
|
|
142282
142442
|
if (padSize < 0) {
|
|
142283
142443
|
throw Error(
|
|
142284
142444
|
`${newContrastLimits.lengths} channels passed in, but only 6 are allowed.`
|
|
142285
142445
|
);
|
|
142286
142446
|
}
|
|
142287
|
-
const paddedContrastLimits = padWithDefault$
|
|
142447
|
+
const paddedContrastLimits = padWithDefault$2(
|
|
142288
142448
|
newContrastLimits,
|
|
142289
142449
|
[maxSliderValue, maxSliderValue],
|
|
142290
142450
|
padSize
|
|
142291
142451
|
).reduce((acc, val) => acc.concat(val), []);
|
|
142292
142452
|
return paddedContrastLimits;
|
|
142293
142453
|
}
|
|
142294
|
-
function getPhysicalSizeScalingMatrix(loader) {
|
|
142454
|
+
function getPhysicalSizeScalingMatrix$1(loader) {
|
|
142295
142455
|
var _a2;
|
|
142296
142456
|
const { x: x2, y: y2, z: z2 } = ((_a2 = loader == null ? void 0 : loader.meta) == null ? void 0 : _a2.physicalSizes) ?? {};
|
|
142297
142457
|
if ((x2 == null ? void 0 : x2.size) && (y2 == null ? void 0 : y2.size) && (z2 == null ? void 0 : z2.size)) {
|
|
@@ -142314,7 +142474,7 @@ function makeBoundingBox(viewState) {
|
|
|
142314
142474
|
viewport.unproject([0, viewport.height])
|
|
142315
142475
|
];
|
|
142316
142476
|
}
|
|
142317
|
-
const fs$1 = `#define SHADER_NAME xr-layer-fragment-shader
|
|
142477
|
+
const fs$1$1 = `#define SHADER_NAME xr-layer-fragment-shader
|
|
142318
142478
|
|
|
142319
142479
|
precision highp float;
|
|
142320
142480
|
precision highp int;
|
|
@@ -142355,7 +142515,7 @@ void main() {
|
|
|
142355
142515
|
DECKGL_FILTER_COLOR(gl_FragColor, geometry);
|
|
142356
142516
|
}
|
|
142357
142517
|
`;
|
|
142358
|
-
const vs$1 = `#define SHADER_NAME xr-layer-vertex-shader
|
|
142518
|
+
const vs$1$1 = `#define SHADER_NAME xr-layer-vertex-shader
|
|
142359
142519
|
|
|
142360
142520
|
attribute vec2 texCoords;
|
|
142361
142521
|
attribute vec3 positions;
|
|
@@ -142374,7 +142534,7 @@ void main(void) {
|
|
|
142374
142534
|
DECKGL_FILTER_COLOR(color, geometry);
|
|
142375
142535
|
}
|
|
142376
142536
|
`;
|
|
142377
|
-
const coreShaderModule = { fs: fs$1, vs: vs$1 };
|
|
142537
|
+
const coreShaderModule = { fs: fs$1$1, vs: vs$1$1 };
|
|
142378
142538
|
function validateWebGL2Filter(gl, interpolation) {
|
|
142379
142539
|
const canShowFloat = hasFeature(gl, FEATURES$1.TEXTURE_FLOAT);
|
|
142380
142540
|
const canShowLinear = hasFeature(gl, FEATURES$1.TEXTURE_FILTER_LINEAR_FLOAT);
|
|
@@ -143465,7 +143625,7 @@ const CUBE_STRIP = [
|
|
|
143465
143625
|
0
|
|
143466
143626
|
];
|
|
143467
143627
|
const NUM_PLANES_DEFAULT = 1;
|
|
143468
|
-
const defaultProps$1 = {
|
|
143628
|
+
const defaultProps$1$1 = {
|
|
143469
143629
|
pickable: false,
|
|
143470
143630
|
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
|
|
143471
143631
|
channelData: { type: "object", value: {}, compare: true },
|
|
@@ -143607,7 +143767,7 @@ const XR3DLayer = class extends Layer {
|
|
|
143607
143767
|
});
|
|
143608
143768
|
const invertedScaleMatrix = scaleMatrix.clone().invert();
|
|
143609
143769
|
const invertedResolutionMatrix = resolutionMatrix.clone().invert();
|
|
143610
|
-
const paddedClippingPlanes = padWithDefault$
|
|
143770
|
+
const paddedClippingPlanes = padWithDefault$2(
|
|
143611
143771
|
clippingPlanes.map(
|
|
143612
143772
|
(p) => p.clone().transform(invertedScaleMatrix).transform(invertedResolutionMatrix)
|
|
143613
143773
|
),
|
|
@@ -143697,7 +143857,7 @@ const XR3DLayer = class extends Layer {
|
|
|
143697
143857
|
}
|
|
143698
143858
|
};
|
|
143699
143859
|
XR3DLayer.layerName = "XR3DLayer";
|
|
143700
|
-
XR3DLayer.defaultProps = defaultProps$1;
|
|
143860
|
+
XR3DLayer.defaultProps = defaultProps$1$1;
|
|
143701
143861
|
async function getVolume({
|
|
143702
143862
|
source,
|
|
143703
143863
|
selection,
|
|
@@ -143845,7 +144005,7 @@ const VolumeLayer = class extends CompositeLayer {
|
|
|
143845
144005
|
signal
|
|
143846
144006
|
})
|
|
143847
144007
|
);
|
|
143848
|
-
const physicalSizeScalingMatrix = getPhysicalSizeScalingMatrix(
|
|
144008
|
+
const physicalSizeScalingMatrix = getPhysicalSizeScalingMatrix$1(
|
|
143849
144009
|
loader[resolution]
|
|
143850
144010
|
);
|
|
143851
144011
|
Promise.all(volumePromises).then((volumes) => {
|
|
@@ -143919,7 +144079,7 @@ const VolumeLayer = class extends CompositeLayer {
|
|
|
143919
144079
|
};
|
|
143920
144080
|
VolumeLayer.layerName = "VolumeLayer";
|
|
143921
144081
|
VolumeLayer.defaultProps = defaultProps$9;
|
|
143922
|
-
const vs = `
|
|
144082
|
+
const vs$1 = `
|
|
143923
144083
|
#define SHADER_NAME bitmask-layer-vertex-shader
|
|
143924
144084
|
|
|
143925
144085
|
attribute vec2 texCoords;
|
|
@@ -143940,7 +144100,7 @@ void main(void) {
|
|
|
143940
144100
|
DECKGL_FILTER_COLOR(color, geometry);
|
|
143941
144101
|
}
|
|
143942
144102
|
`;
|
|
143943
|
-
const fs = `
|
|
144103
|
+
const fs$1 = `
|
|
143944
144104
|
#define SHADER_NAME bitmask-layer-fragment-shader
|
|
143945
144105
|
precision highp float;
|
|
143946
144106
|
|
|
@@ -144008,14 +144168,14 @@ void main() {
|
|
|
144008
144168
|
DECKGL_FILTER_COLOR(gl_FragColor, geometry);
|
|
144009
144169
|
}
|
|
144010
144170
|
`;
|
|
144011
|
-
function padWithDefault(arr, defaultValue2, padWidth) {
|
|
144171
|
+
function padWithDefault$1(arr, defaultValue2, padWidth) {
|
|
144012
144172
|
const newArr = [...arr];
|
|
144013
144173
|
for (let i2 = 0; i2 < padWidth; i2 += 1) {
|
|
144014
144174
|
newArr.push(defaultValue2);
|
|
144015
144175
|
}
|
|
144016
144176
|
return newArr;
|
|
144017
144177
|
}
|
|
144018
|
-
const defaultProps = {
|
|
144178
|
+
const defaultProps$1 = {
|
|
144019
144179
|
hoveredCell: { type: "number", value: null, compare: true },
|
|
144020
144180
|
// We do not want to deep-compare cellColorData,
|
|
144021
144181
|
// as it is potentially a TypedArray with millions of elements.
|
|
@@ -144027,13 +144187,13 @@ const defaultProps = {
|
|
|
144027
144187
|
// Same as with cellColorData, we do not want to deep-compare expressionData.
|
|
144028
144188
|
expressionData: { type: "object", value: null, compare: 0 }
|
|
144029
144189
|
};
|
|
144030
|
-
class BitmaskLayer extends XRLayer {
|
|
144190
|
+
let BitmaskLayer$1 = class BitmaskLayer extends XRLayer {
|
|
144031
144191
|
// eslint-disable-next-line class-methods-use-this
|
|
144032
144192
|
getShaders() {
|
|
144033
144193
|
const { colormap } = this.props;
|
|
144034
144194
|
return {
|
|
144035
|
-
fs,
|
|
144036
|
-
vs,
|
|
144195
|
+
fs: fs$1,
|
|
144196
|
+
vs: vs$1,
|
|
144037
144197
|
modules: [project32, picking],
|
|
144038
144198
|
defines: {
|
|
144039
144199
|
[COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT
|
|
@@ -144093,7 +144253,7 @@ class BitmaskLayer extends XRLayer {
|
|
|
144093
144253
|
expressionTex,
|
|
144094
144254
|
colorTexHeight: colorTex.height,
|
|
144095
144255
|
colorTexWidth: colorTex.width,
|
|
144096
|
-
channelsVisible: padWithDefault(
|
|
144256
|
+
channelsVisible: padWithDefault$1(
|
|
144097
144257
|
channelsVisible,
|
|
144098
144258
|
false,
|
|
144099
144259
|
// There are six texture entries on the shaders
|
|
@@ -144130,28 +144290,632 @@ class BitmaskLayer extends XRLayer {
|
|
|
144130
144290
|
type: GL$1.FLOAT
|
|
144131
144291
|
});
|
|
144132
144292
|
}
|
|
144293
|
+
};
|
|
144294
|
+
BitmaskLayer$1.layerName = "BitmaskLayer";
|
|
144295
|
+
BitmaskLayer$1.defaultProps = defaultProps$1;
|
|
144296
|
+
const vs = `
|
|
144297
|
+
#define SHADER_NAME bitmask-layer-vertex-shader
|
|
144298
|
+
|
|
144299
|
+
attribute vec2 texCoords;
|
|
144300
|
+
attribute vec3 positions;
|
|
144301
|
+
attribute vec3 positions64Low;
|
|
144302
|
+
attribute vec3 instancePickingColors;
|
|
144303
|
+
|
|
144304
|
+
varying vec2 vTexCoord;
|
|
144305
|
+
|
|
144306
|
+
void main(void) {
|
|
144307
|
+
geometry.worldPosition = positions;
|
|
144308
|
+
geometry.uv = texCoords;
|
|
144309
|
+
geometry.pickingColor = instancePickingColors;
|
|
144310
|
+
gl_Position = project_position_to_clipspace(positions, positions64Low, vec3(0.0), geometry.position);
|
|
144311
|
+
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
|
|
144312
|
+
vTexCoord = texCoords;
|
|
144313
|
+
vec4 color = vec4(0.0);
|
|
144314
|
+
DECKGL_FILTER_COLOR(color, geometry);
|
|
144315
|
+
}
|
|
144316
|
+
`;
|
|
144317
|
+
const fs = `
|
|
144318
|
+
#define SHADER_NAME bitmask-layer-fragment-shader
|
|
144319
|
+
precision highp float;
|
|
144320
|
+
|
|
144321
|
+
${colormaps}
|
|
144322
|
+
|
|
144323
|
+
// Note: can have a maximum of 16 textures in most browsers
|
|
144324
|
+
// Reference: https://webglreport.com/
|
|
144325
|
+
|
|
144326
|
+
// Data (mask) texture
|
|
144327
|
+
uniform sampler2D channel0;
|
|
144328
|
+
uniform sampler2D channel1;
|
|
144329
|
+
uniform sampler2D channel2;
|
|
144330
|
+
uniform sampler2D channel3;
|
|
144331
|
+
uniform sampler2D channel4;
|
|
144332
|
+
uniform sampler2D channel5;
|
|
144333
|
+
uniform sampler2D channel6;
|
|
144334
|
+
|
|
144335
|
+
// Color texture
|
|
144336
|
+
uniform float hovered;
|
|
144337
|
+
|
|
144338
|
+
// Channel-specific properties
|
|
144339
|
+
uniform bool channelsVisible[7];
|
|
144340
|
+
uniform float channelOpacities[7];
|
|
144341
|
+
uniform bool channelIsStaticColorMode[7]; // TODO: should this be a single float?
|
|
144342
|
+
uniform bool channelIsSetColorMode[7]; // TODO: should this be a single float?
|
|
144343
|
+
|
|
144344
|
+
// TODO: can array of tuples/vec2 be used?
|
|
144345
|
+
uniform float channelColormapRangeStarts[7];
|
|
144346
|
+
uniform float channelColormapRangeEnds[7];
|
|
144347
|
+
|
|
144348
|
+
uniform float multiFeatureTexSize;
|
|
144349
|
+
|
|
144350
|
+
// Use one expressionTex for all channels, using an offset mechanism.
|
|
144351
|
+
uniform sampler2D valueTex;
|
|
144352
|
+
uniform float valueTexOffsets[7];
|
|
144353
|
+
uniform float valueTexHeight;
|
|
144354
|
+
|
|
144355
|
+
// Textures for set colors, using the same offset mechanism.
|
|
144356
|
+
uniform sampler2D colorTex;
|
|
144357
|
+
uniform float colorTexOffsets[7];
|
|
144358
|
+
uniform float colorTexHeight;
|
|
144359
|
+
|
|
144360
|
+
|
|
144361
|
+
// Static colors
|
|
144362
|
+
// TODO: For some reason I cannot use uniform vec3 colors[7]; and i cannot figure out why.
|
|
144363
|
+
uniform vec3 color0;
|
|
144364
|
+
uniform vec3 color1;
|
|
144365
|
+
uniform vec3 color2;
|
|
144366
|
+
uniform vec3 color3;
|
|
144367
|
+
uniform vec3 color4;
|
|
144368
|
+
uniform vec3 color5;
|
|
144369
|
+
uniform vec3 color6;
|
|
144370
|
+
|
|
144371
|
+
// Info for edge-only mode
|
|
144372
|
+
uniform float scaleFactor;
|
|
144373
|
+
uniform bool channelsFilled[7];
|
|
144374
|
+
uniform float channelStrokeWidths[7];
|
|
144375
|
+
|
|
144376
|
+
// opacity
|
|
144377
|
+
uniform float opacity;
|
|
144378
|
+
|
|
144379
|
+
varying vec2 vTexCoord;
|
|
144380
|
+
|
|
144381
|
+
vec3 sampleAndGetData(sampler2D dataTex, vec2 coord, bool isFilled, float strokeWidth, bool isOn) {
|
|
144382
|
+
float sampledData = texture(dataTex, coord).r;
|
|
144383
|
+
float clampedSampledData = max(0., min(sampledData, 1.));
|
|
144384
|
+
|
|
144385
|
+
bool isEdge = true;
|
|
144386
|
+
|
|
144387
|
+
if(!isFilled) {
|
|
144388
|
+
vec2 uTextureSize = vec2(2048.0, 2048.0);
|
|
144389
|
+
vec2 onePixel = vec2(1.0, 1.0) / uTextureSize;
|
|
144390
|
+
|
|
144391
|
+
// Vary the edgeSize based on user-defined stroke width.
|
|
144392
|
+
float edgeSize = 150.0 * strokeWidth * scaleFactor;
|
|
144393
|
+
|
|
144394
|
+
float pixN = texture(dataTex, coord + vec2(0.0, onePixel.y * edgeSize)).r;
|
|
144395
|
+
float pixS = texture(dataTex, coord - vec2(0.0, onePixel.y * edgeSize)).r;
|
|
144396
|
+
float pixW = texture(dataTex, coord + vec2(onePixel.x * edgeSize, 0.0)).r;
|
|
144397
|
+
float pixE = texture(dataTex, coord - vec2(onePixel.x * edgeSize, 0.0)).r;
|
|
144398
|
+
|
|
144399
|
+
float pixNW = texture(dataTex, coord + vec2(onePixel.y * edgeSize, onePixel.y * edgeSize)).r;
|
|
144400
|
+
float pixNE = texture(dataTex, coord + vec2(-1.0 * onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
|
|
144401
|
+
float pixSW = texture(dataTex, coord - vec2(onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
|
|
144402
|
+
float pixSE = texture(dataTex, coord - vec2(-1.0 * onePixel.x * edgeSize, onePixel.y * edgeSize)).r;
|
|
144403
|
+
|
|
144404
|
+
isEdge = (pixN != sampledData || pixS != sampledData || pixW != sampledData || pixE != sampledData || pixNW != sampledData || pixNE != sampledData || pixSW != sampledData || pixSE != sampledData);
|
|
144405
|
+
}
|
|
144406
|
+
// Return a tuple of (sampledData, isEdge)
|
|
144407
|
+
return vec3(clampedSampledData * float(isOn), sampledData, float(isEdge));
|
|
144408
|
+
}
|
|
144409
|
+
|
|
144410
|
+
vec4 dataToColor(vec3 sampledDataAndIsEdge, bool isStaticColorMode, vec3 channelColor, float channelOpacity, float valueOffset, float rangeStart, float rangeEnd, bool isSetColorMode, float setColorOffset) {
|
|
144411
|
+
float clampedSampledDataAndIsOn = sampledDataAndIsEdge.x;
|
|
144412
|
+
float sampledData = sampledDataAndIsEdge.y;
|
|
144413
|
+
float isEdge = sampledDataAndIsEdge.z;
|
|
144414
|
+
|
|
144415
|
+
|
|
144416
|
+
vec4 hoveredColor = float(sampledData == hovered && sampledData > 0. && hovered > 0.) * vec4(0., 0., 1., 1.);
|
|
144417
|
+
|
|
144418
|
+
// Colors are laid out corresponding to ids in row-major order in the texture. So if width of the texture is 10, and you want ID 25,
|
|
144419
|
+
// you need coordinate (1, 4) (i.e 2 rows down, and 5 columns over indexed from 0 for a total of 25 units covered in row major order).
|
|
144420
|
+
float offsetSampledData = sampledData + valueOffset - 1.0;
|
|
144421
|
+
vec2 colorTexCoord = vec2(mod(offsetSampledData, multiFeatureTexSize) / multiFeatureTexSize, floor(offsetSampledData / multiFeatureTexSize) / (valueTexHeight - 1.));
|
|
144422
|
+
|
|
144423
|
+
// Get expression value
|
|
144424
|
+
float expressionValue = texture(valueTex, colorTexCoord).r / 255.;
|
|
144425
|
+
float scaledExpressionValue = (expressionValue - rangeStart) / max(0.005, (rangeEnd - rangeStart));
|
|
144426
|
+
|
|
144427
|
+
|
|
144428
|
+
// Get set color index value
|
|
144429
|
+
vec2 setIndicesTexCoord = vec2(mod(offsetSampledData, multiFeatureTexSize) / multiFeatureTexSize, floor(offsetSampledData / multiFeatureTexSize) / (valueTexHeight - 1.));
|
|
144430
|
+
float setColorIndex = texture(valueTex, setIndicesTexCoord).r;
|
|
144431
|
+
|
|
144432
|
+
// Initialize to the default "null" color.
|
|
144433
|
+
vec3 setColor = vec3(200. / 255., 200. / 255., 200. / 255.);
|
|
144434
|
+
if(setColorIndex != 0.) {
|
|
144435
|
+
// Subtract one from setColorIndex because we have already checked for the "null" value.
|
|
144436
|
+
setColorIndex = setColorIndex - 1.;
|
|
144437
|
+
|
|
144438
|
+
float setColorOffsetR = (setColorIndex + setColorOffset) * 3.0 + 0.0;
|
|
144439
|
+
vec2 setColorTexCoordR = vec2(mod(setColorOffsetR, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetR / multiFeatureTexSize) / (colorTexHeight - 1.));
|
|
144440
|
+
float setColorR = texture(colorTex, setColorTexCoordR).r / 255.;
|
|
144441
|
+
|
|
144442
|
+
float setColorOffsetG = (setColorIndex + setColorOffset) * 3.0 + 1.0;
|
|
144443
|
+
vec2 setColorTexCoordG = vec2(mod(setColorOffsetG, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetG / multiFeatureTexSize) / (colorTexHeight - 1.));
|
|
144444
|
+
float setColorG = texture(colorTex, setColorTexCoordG).r / 255.;
|
|
144445
|
+
|
|
144446
|
+
float setColorOffsetB = (setColorIndex + setColorOffset) * 3.0 + 2.0;
|
|
144447
|
+
vec2 setColorTexCoordB = vec2(mod(setColorOffsetB, multiFeatureTexSize) / multiFeatureTexSize, floor(setColorOffsetB / multiFeatureTexSize) / (colorTexHeight - 1.));
|
|
144448
|
+
float setColorB = texture(colorTex, setColorTexCoordB).r / 255.;
|
|
144449
|
+
|
|
144450
|
+
setColor = vec3(setColorR, setColorG, setColorB);
|
|
144451
|
+
}
|
|
144452
|
+
|
|
144453
|
+
|
|
144454
|
+
vec4 sampledColor = (1. - (float(isStaticColorMode) + float(isSetColorMode))) * vec4(COLORMAP_FUNC(clamp(scaledExpressionValue, 0.0, 1.0)).rgb, channelOpacity) + float(isStaticColorMode) * vec4(channelColor.rgb, channelOpacity) + float(isSetColorMode) * vec4(setColor, channelOpacity);
|
|
144455
|
+
// Only return a color if the data is non-zero.
|
|
144456
|
+
|
|
144457
|
+
return clampedSampledDataAndIsOn * isEdge * sampledColor;
|
|
144458
|
+
}
|
|
144459
|
+
|
|
144460
|
+
void main() {
|
|
144461
|
+
|
|
144462
|
+
// Get the color and alpha value for each channel.
|
|
144463
|
+
vec3 dat0 = sampleAndGetData(channel0, vTexCoord, channelsFilled[0], channelStrokeWidths[0], channelsVisible[0]);
|
|
144464
|
+
vec3 dat1 = sampleAndGetData(channel1, vTexCoord, channelsFilled[1], channelStrokeWidths[1], channelsVisible[1]);
|
|
144465
|
+
vec3 dat2 = sampleAndGetData(channel2, vTexCoord, channelsFilled[2], channelStrokeWidths[2], channelsVisible[2]);
|
|
144466
|
+
vec3 dat3 = sampleAndGetData(channel3, vTexCoord, channelsFilled[3], channelStrokeWidths[3], channelsVisible[3]);
|
|
144467
|
+
vec3 dat4 = sampleAndGetData(channel4, vTexCoord, channelsFilled[4], channelStrokeWidths[4], channelsVisible[4]);
|
|
144468
|
+
vec3 dat5 = sampleAndGetData(channel5, vTexCoord, channelsFilled[5], channelStrokeWidths[5], channelsVisible[5]);
|
|
144469
|
+
vec3 dat6 = sampleAndGetData(channel6, vTexCoord, channelsFilled[6], channelStrokeWidths[6], channelsVisible[6]);
|
|
144470
|
+
|
|
144471
|
+
vec4 val0 = dataToColor(dat0, channelIsStaticColorMode[0], color0, channelOpacities[0], valueTexOffsets[0], channelColormapRangeStarts[0], channelColormapRangeEnds[0], channelIsSetColorMode[0], colorTexOffsets[0]);
|
|
144472
|
+
vec4 val1 = dataToColor(dat1, channelIsStaticColorMode[1], color1, channelOpacities[1], valueTexOffsets[1], channelColormapRangeStarts[1], channelColormapRangeEnds[1], channelIsSetColorMode[1], colorTexOffsets[1]);
|
|
144473
|
+
vec4 val2 = dataToColor(dat2, channelIsStaticColorMode[2], color2, channelOpacities[2], valueTexOffsets[2], channelColormapRangeStarts[2], channelColormapRangeEnds[2], channelIsSetColorMode[2], colorTexOffsets[2]);
|
|
144474
|
+
vec4 val3 = dataToColor(dat3, channelIsStaticColorMode[3], color3, channelOpacities[3], valueTexOffsets[3], channelColormapRangeStarts[3], channelColormapRangeEnds[3], channelIsSetColorMode[3], colorTexOffsets[3]);
|
|
144475
|
+
vec4 val4 = dataToColor(dat4, channelIsStaticColorMode[4], color4, channelOpacities[4], valueTexOffsets[4], channelColormapRangeStarts[4], channelColormapRangeEnds[4], channelIsSetColorMode[4], colorTexOffsets[4]);
|
|
144476
|
+
vec4 val5 = dataToColor(dat5, channelIsStaticColorMode[5], color5, channelOpacities[5], valueTexOffsets[5], channelColormapRangeStarts[5], channelColormapRangeEnds[5], channelIsSetColorMode[5], colorTexOffsets[5]);
|
|
144477
|
+
vec4 val6 = dataToColor(dat6, channelIsStaticColorMode[6], color6, channelOpacities[6], valueTexOffsets[6], channelColormapRangeStarts[6], channelColormapRangeEnds[6], channelIsSetColorMode[6], colorTexOffsets[6]);
|
|
144478
|
+
|
|
144479
|
+
// If all of the channels are "empty", then discard this pixel so that it is not considered during picking.
|
|
144480
|
+
float emptyDat = 0.;
|
|
144481
|
+
if(dat0.x == emptyDat && dat1.x == emptyDat && dat2.x == emptyDat && dat3.x == emptyDat && dat4.x == emptyDat && dat5.x == emptyDat && dat6.x == emptyDat) {
|
|
144482
|
+
discard;
|
|
144483
|
+
}
|
|
144484
|
+
|
|
144485
|
+
// If the next channel color and the currently stored color (gl_FragColor) are identical,
|
|
144486
|
+
// or the next channel color is transparent black,
|
|
144487
|
+
// just use the currently stored color. Repeat this for all channels.
|
|
144488
|
+
|
|
144489
|
+
// Mix colors where necessary, using the alpha value of the next channel as the weight.
|
|
144490
|
+
// Use the maximum alpha value as the resulting alpha value.
|
|
144491
|
+
gl_FragColor = val0;
|
|
144492
|
+
gl_FragColor = (val1 == gl_FragColor || val1 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val1, val1.a).rgb, max(gl_FragColor.a, val1.a));
|
|
144493
|
+
gl_FragColor = (val2 == gl_FragColor || val2 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val2, val2.a).rgb, max(gl_FragColor.a, val2.a));
|
|
144494
|
+
gl_FragColor = (val3 == gl_FragColor || val3 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val3, val3.a).rgb, max(gl_FragColor.a, val3.a));
|
|
144495
|
+
gl_FragColor = (val4 == gl_FragColor || val4 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val4, val4.a).rgb, max(gl_FragColor.a, val4.a));
|
|
144496
|
+
gl_FragColor = (val5 == gl_FragColor || val5 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val5, val5.a).rgb, max(gl_FragColor.a, val5.a));
|
|
144497
|
+
gl_FragColor = (val6 == gl_FragColor || val6 == vec4(0.)) ? gl_FragColor : vec4(mix(gl_FragColor, val6, val6.a).rgb, max(gl_FragColor.a, val6.a));
|
|
144498
|
+
|
|
144499
|
+
|
|
144500
|
+
|
|
144501
|
+
// TODO: multiply the resulting channel-level opacity value by the layer-level opacity value.
|
|
144502
|
+
|
|
144503
|
+
geometry.uv = vTexCoord;
|
|
144504
|
+
DECKGL_FILTER_COLOR(gl_FragColor, geometry);
|
|
144505
|
+
}
|
|
144506
|
+
`;
|
|
144507
|
+
function extent(values, valueof) {
|
|
144508
|
+
let min2;
|
|
144509
|
+
let max2;
|
|
144510
|
+
if (valueof === void 0) {
|
|
144511
|
+
for (const value of values) {
|
|
144512
|
+
if (value != null) {
|
|
144513
|
+
if (min2 === void 0) {
|
|
144514
|
+
if (value >= value)
|
|
144515
|
+
min2 = max2 = value;
|
|
144516
|
+
} else {
|
|
144517
|
+
if (min2 > value)
|
|
144518
|
+
min2 = value;
|
|
144519
|
+
if (max2 < value)
|
|
144520
|
+
max2 = value;
|
|
144521
|
+
}
|
|
144522
|
+
}
|
|
144523
|
+
}
|
|
144524
|
+
} else {
|
|
144525
|
+
let index2 = -1;
|
|
144526
|
+
for (let value of values) {
|
|
144527
|
+
if ((value = valueof(value, ++index2, values)) != null) {
|
|
144528
|
+
if (min2 === void 0) {
|
|
144529
|
+
if (value >= value)
|
|
144530
|
+
min2 = max2 = value;
|
|
144531
|
+
} else {
|
|
144532
|
+
if (min2 > value)
|
|
144533
|
+
min2 = value;
|
|
144534
|
+
if (max2 < value)
|
|
144535
|
+
max2 = value;
|
|
144536
|
+
}
|
|
144537
|
+
}
|
|
144538
|
+
}
|
|
144539
|
+
}
|
|
144540
|
+
return [min2, max2];
|
|
144541
|
+
}
|
|
144542
|
+
function normalize(arr) {
|
|
144543
|
+
const [min2, max2] = extent(arr);
|
|
144544
|
+
const ratio = 255 / (max2 - min2);
|
|
144545
|
+
const data = new Uint8Array(arr.map((i2) => Math.floor((i2 - min2) * ratio)));
|
|
144546
|
+
return data;
|
|
144547
|
+
}
|
|
144548
|
+
function multiSetsToTextureData(multiFeatureValues, setColorValues, channelIsSetColorMode, texSize) {
|
|
144549
|
+
let totalValuesLength = 0;
|
|
144550
|
+
let totalColorsLength = 0;
|
|
144551
|
+
channelIsSetColorMode.forEach((isSetColorMode, channelIndex) => {
|
|
144552
|
+
var _a2, _b, _c, _d, _e;
|
|
144553
|
+
if (isSetColorMode) {
|
|
144554
|
+
totalValuesLength += ((_b = (_a2 = setColorValues[channelIndex]) == null ? void 0 : _a2.obsIndex) == null ? void 0 : _b.length) || 0;
|
|
144555
|
+
totalColorsLength += (((_d = (_c = setColorValues[channelIndex]) == null ? void 0 : _c.setColors) == null ? void 0 : _d.length) || 0) * 3;
|
|
144556
|
+
} else {
|
|
144557
|
+
totalValuesLength += ((_e = multiFeatureValues[channelIndex]) == null ? void 0 : _e.length) || 0;
|
|
144558
|
+
}
|
|
144559
|
+
});
|
|
144560
|
+
const valueTexHeight = Math.max(2, Math.ceil(totalValuesLength / texSize));
|
|
144561
|
+
const colorTexHeight = Math.max(2, Math.ceil(totalColorsLength / texSize));
|
|
144562
|
+
if (valueTexHeight > texSize) {
|
|
144563
|
+
console.error("Error: length of concatenated quantitative feature values larger than maximum texture size");
|
|
144564
|
+
}
|
|
144565
|
+
if (colorTexHeight > texSize) {
|
|
144566
|
+
console.error("Error: length of concatenated quantitative feature values larger than maximum texture size");
|
|
144567
|
+
}
|
|
144568
|
+
const totalData = new Uint8Array(texSize * valueTexHeight);
|
|
144569
|
+
const totalColors = new Uint8Array(texSize * colorTexHeight);
|
|
144570
|
+
const indicesOffsets = [];
|
|
144571
|
+
const colorsOffsets = [];
|
|
144572
|
+
let indexOffset = 0;
|
|
144573
|
+
let colorOffset = 0;
|
|
144574
|
+
channelIsSetColorMode.forEach((isSetColorMode, channelIndex) => {
|
|
144575
|
+
if (isSetColorMode) {
|
|
144576
|
+
const { setColorIndices, setColors, obsIndex } = setColorValues[channelIndex] || {};
|
|
144577
|
+
if (setColorIndices && setColors && obsIndex) {
|
|
144578
|
+
for (let i2 = 0; i2 < obsIndex.length; i2++) {
|
|
144579
|
+
const colorIndex = setColorIndices.get(String(i2 + 1));
|
|
144580
|
+
totalData[indexOffset + i2] = colorIndex === void 0 ? 0 : colorIndex + 1;
|
|
144581
|
+
}
|
|
144582
|
+
for (let i2 = 0; i2 < setColors.length; i2++) {
|
|
144583
|
+
const { color: [r2, g2, b] } = setColors[i2];
|
|
144584
|
+
totalColors[(colorOffset + i2) * 3 + 0] = r2;
|
|
144585
|
+
totalColors[(colorOffset + i2) * 3 + 1] = g2;
|
|
144586
|
+
totalColors[(colorOffset + i2) * 3 + 2] = b;
|
|
144587
|
+
}
|
|
144588
|
+
}
|
|
144589
|
+
indicesOffsets.push(indexOffset);
|
|
144590
|
+
colorsOffsets.push(colorOffset);
|
|
144591
|
+
indexOffset += (obsIndex == null ? void 0 : obsIndex.length) || 0;
|
|
144592
|
+
colorOffset += (setColors == null ? void 0 : setColors.length) || 0;
|
|
144593
|
+
} else {
|
|
144594
|
+
const featureArr = multiFeatureValues[channelIndex];
|
|
144595
|
+
totalData.set(normalize(featureArr), indexOffset);
|
|
144596
|
+
indicesOffsets.push(indexOffset);
|
|
144597
|
+
indexOffset += featureArr.length;
|
|
144598
|
+
colorsOffsets.push(colorOffset);
|
|
144599
|
+
}
|
|
144600
|
+
});
|
|
144601
|
+
return [
|
|
144602
|
+
totalData,
|
|
144603
|
+
valueTexHeight,
|
|
144604
|
+
indicesOffsets,
|
|
144605
|
+
totalColors,
|
|
144606
|
+
colorTexHeight,
|
|
144607
|
+
colorsOffsets
|
|
144608
|
+
];
|
|
144609
|
+
}
|
|
144610
|
+
const MAX_CHANNELS = 7;
|
|
144611
|
+
const MULTI_FEATURE_TEX_SIZE = 2048;
|
|
144612
|
+
function padWithDefault(arr, defaultValue2, padWidth) {
|
|
144613
|
+
const newArr = [...arr];
|
|
144614
|
+
for (let i2 = 0; i2 < padWidth; i2 += 1) {
|
|
144615
|
+
newArr.push(defaultValue2);
|
|
144616
|
+
}
|
|
144617
|
+
return newArr;
|
|
144618
|
+
}
|
|
144619
|
+
function getColor(arr) {
|
|
144620
|
+
return arr ? arr.map((v) => v / 255) : [0, 0, 0];
|
|
144621
|
+
}
|
|
144622
|
+
const defaultProps = {
|
|
144623
|
+
channelStrokeWidths: { type: "array", value: null, compare: true },
|
|
144624
|
+
channelsFilled: { type: "array", value: null, compare: true },
|
|
144625
|
+
channelOpacities: { type: "array", value: null, compare: true },
|
|
144626
|
+
channelColors: { type: "array", value: null, compare: true },
|
|
144627
|
+
hoveredCell: { type: "number", value: null, compare: true },
|
|
144628
|
+
colormap: { type: "string", value: GLSL_COLORMAP_DEFAULT, compare: true },
|
|
144629
|
+
expressionData: { type: "object", value: null, compare: true },
|
|
144630
|
+
multiFeatureValues: { type: "array", value: null, compare: true },
|
|
144631
|
+
setColorValues: { type: "array", value: null, compare: true },
|
|
144632
|
+
channelFeatureValueColormaps: { type: "array", value: null, compare: true },
|
|
144633
|
+
channelFeatureValueColormapRanges: { type: "array", value: null, compare: true },
|
|
144634
|
+
channelIsStaticColorMode: { type: "array", value: null, compare: true },
|
|
144635
|
+
channelIsSetColorMode: { type: "array", value: null, compare: true }
|
|
144636
|
+
};
|
|
144637
|
+
class BitmaskLayer2 extends XRLayer {
|
|
144638
|
+
// eslint-disable-next-line class-methods-use-this
|
|
144639
|
+
getShaders() {
|
|
144640
|
+
const { colormap } = this.props;
|
|
144641
|
+
return {
|
|
144642
|
+
fs,
|
|
144643
|
+
vs,
|
|
144644
|
+
modules: [project32, picking],
|
|
144645
|
+
defines: {
|
|
144646
|
+
[COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap) ? colormap : GLSL_COLORMAP_DEFAULT
|
|
144647
|
+
}
|
|
144648
|
+
};
|
|
144649
|
+
}
|
|
144650
|
+
/**
|
|
144651
|
+
* Override the parent loadChannelTextures to enable
|
|
144652
|
+
* up to eight channels (rather than six).
|
|
144653
|
+
* Reference: https://github.com/hms-dbmi/viv/blob/v0.13.3/packages/layers/src/xr-layer/xr-layer.js#L316
|
|
144654
|
+
*/
|
|
144655
|
+
loadChannelTextures(channelData) {
|
|
144656
|
+
const textures = {
|
|
144657
|
+
channel0: null,
|
|
144658
|
+
channel1: null,
|
|
144659
|
+
channel2: null,
|
|
144660
|
+
channel3: null,
|
|
144661
|
+
channel4: null,
|
|
144662
|
+
channel5: null,
|
|
144663
|
+
channel6: null
|
|
144664
|
+
};
|
|
144665
|
+
if (this.state.textures) {
|
|
144666
|
+
Object.values(this.state.textures).forEach((tex) => tex && tex.delete());
|
|
144667
|
+
}
|
|
144668
|
+
if (channelData && Object.keys(channelData).length > 0 && channelData.data) {
|
|
144669
|
+
channelData.data.forEach((d, i2) => {
|
|
144670
|
+
textures[`channel${i2}`] = this.dataToTexture(d, channelData.width, channelData.height);
|
|
144671
|
+
}, this);
|
|
144672
|
+
this.setState({ textures });
|
|
144673
|
+
}
|
|
144674
|
+
}
|
|
144675
|
+
updateState({ props: props2, oldProps, changeFlags }) {
|
|
144676
|
+
super.updateState({ props: props2, oldProps, changeFlags });
|
|
144677
|
+
if (props2.multiFeatureValues !== oldProps.multiFeatureValues || props2.setColorValues !== oldProps.setColorValues || props2.channelIsSetColorMode !== oldProps.channelIsSetColorMode) {
|
|
144678
|
+
const { multiFeatureValues, setColorValues, channelIsSetColorMode } = this.props;
|
|
144679
|
+
const [valueTex, colorTex, valueTexOffsets, colorTexOffsets, valueTexHeight, colorTexHeight] = this.multiSetsToTexture(multiFeatureValues, setColorValues, channelIsSetColorMode);
|
|
144680
|
+
this.setState({
|
|
144681
|
+
valueTex,
|
|
144682
|
+
colorTex,
|
|
144683
|
+
valueTexOffsets,
|
|
144684
|
+
colorTexOffsets,
|
|
144685
|
+
valueTexHeight,
|
|
144686
|
+
colorTexHeight
|
|
144687
|
+
});
|
|
144688
|
+
}
|
|
144689
|
+
if (props2.colormap !== oldProps.colormap) {
|
|
144690
|
+
const { gl } = this.context;
|
|
144691
|
+
if (this.state.model) {
|
|
144692
|
+
this.state.model.delete();
|
|
144693
|
+
}
|
|
144694
|
+
this.setState({ model: this._getModel(gl) });
|
|
144695
|
+
this.getAttributeManager().invalidateAll();
|
|
144696
|
+
}
|
|
144697
|
+
}
|
|
144698
|
+
draw(opts2) {
|
|
144699
|
+
const { uniforms } = opts2;
|
|
144700
|
+
const {
|
|
144701
|
+
channelStrokeWidths,
|
|
144702
|
+
channelsFilled,
|
|
144703
|
+
channelOpacities,
|
|
144704
|
+
channelColors,
|
|
144705
|
+
channelsVisible,
|
|
144706
|
+
// TODO: use `channelFeatureValueColormaps` in shader,
|
|
144707
|
+
// figure out how to call multiple GLSL colormap functions
|
|
144708
|
+
channelFeatureValueColormaps,
|
|
144709
|
+
channelFeatureValueColormapRanges,
|
|
144710
|
+
channelIsStaticColorMode,
|
|
144711
|
+
channelIsSetColorMode,
|
|
144712
|
+
hoveredCell,
|
|
144713
|
+
colorScaleLo,
|
|
144714
|
+
colorScaleHi,
|
|
144715
|
+
isExpressionMode,
|
|
144716
|
+
zoom,
|
|
144717
|
+
minZoom,
|
|
144718
|
+
maxZoom,
|
|
144719
|
+
zoomOffset
|
|
144720
|
+
// TODO: figure out if this needs to be used or not
|
|
144721
|
+
} = this.props;
|
|
144722
|
+
const {
|
|
144723
|
+
textures,
|
|
144724
|
+
model,
|
|
144725
|
+
// Expression and set index (and colors) textures with offsets
|
|
144726
|
+
valueTex,
|
|
144727
|
+
colorTex,
|
|
144728
|
+
valueTexOffsets,
|
|
144729
|
+
colorTexOffsets,
|
|
144730
|
+
valueTexHeight,
|
|
144731
|
+
colorTexHeight
|
|
144732
|
+
} = this.state;
|
|
144733
|
+
if (textures && model) {
|
|
144734
|
+
const scaleFactor = 1 / 2 ** (maxZoom - zoom);
|
|
144735
|
+
const colors = fromEntries(range$5(MAX_CHANNELS).map((i2) => [`color${i2}`, getColor(channelColors[i2])]));
|
|
144736
|
+
model.setUniforms(Object.assign({}, uniforms, {
|
|
144737
|
+
...colors,
|
|
144738
|
+
// Bitmask image channel data textures
|
|
144739
|
+
...textures,
|
|
144740
|
+
multiFeatureTexSize: MULTI_FEATURE_TEX_SIZE,
|
|
144741
|
+
// Expression textures with offsets
|
|
144742
|
+
valueTex,
|
|
144743
|
+
valueTexOffsets: padWithDefault(valueTexOffsets, 0, MAX_CHANNELS - valueTexOffsets.length),
|
|
144744
|
+
valueTexHeight,
|
|
144745
|
+
// Set indices and colors textures with offsets
|
|
144746
|
+
colorTex,
|
|
144747
|
+
colorTexOffsets: padWithDefault(colorTexOffsets, 0, MAX_CHANNELS - colorTexOffsets.length),
|
|
144748
|
+
colorTexHeight,
|
|
144749
|
+
// Visualization properties
|
|
144750
|
+
channelsFilled: padWithDefault(
|
|
144751
|
+
channelsFilled,
|
|
144752
|
+
true,
|
|
144753
|
+
// There are six texture entries on the shaders
|
|
144754
|
+
MAX_CHANNELS - channelsFilled.length
|
|
144755
|
+
),
|
|
144756
|
+
channelOpacities: padWithDefault(
|
|
144757
|
+
channelOpacities,
|
|
144758
|
+
0,
|
|
144759
|
+
// There are six texture entries on the shaders
|
|
144760
|
+
MAX_CHANNELS - channelOpacities.length
|
|
144761
|
+
),
|
|
144762
|
+
channelStrokeWidths: padWithDefault(
|
|
144763
|
+
channelStrokeWidths,
|
|
144764
|
+
1,
|
|
144765
|
+
// There are six texture entries on the shaders
|
|
144766
|
+
MAX_CHANNELS - channelStrokeWidths.length
|
|
144767
|
+
),
|
|
144768
|
+
channelColormapRangeStarts: padWithDefault(
|
|
144769
|
+
channelFeatureValueColormapRanges.map((r2) => (r2 == null ? void 0 : r2[0]) || 0),
|
|
144770
|
+
0,
|
|
144771
|
+
// There are six texture entries on the shaders
|
|
144772
|
+
MAX_CHANNELS - channelFeatureValueColormapRanges.length
|
|
144773
|
+
),
|
|
144774
|
+
channelColormapRangeEnds: padWithDefault(
|
|
144775
|
+
channelFeatureValueColormapRanges.map((r2) => (r2 == null ? void 0 : r2[1]) || 1),
|
|
144776
|
+
1,
|
|
144777
|
+
// There are six texture entries on the shaders
|
|
144778
|
+
MAX_CHANNELS - channelFeatureValueColormapRanges.length
|
|
144779
|
+
),
|
|
144780
|
+
channelIsStaticColorMode: padWithDefault(
|
|
144781
|
+
channelIsStaticColorMode,
|
|
144782
|
+
true,
|
|
144783
|
+
// There are six texture entries on the shaders
|
|
144784
|
+
MAX_CHANNELS - channelIsStaticColorMode.length
|
|
144785
|
+
),
|
|
144786
|
+
channelIsSetColorMode: padWithDefault(
|
|
144787
|
+
channelIsSetColorMode,
|
|
144788
|
+
false,
|
|
144789
|
+
// There are six texture entries on the shaders
|
|
144790
|
+
MAX_CHANNELS - channelIsSetColorMode.length
|
|
144791
|
+
),
|
|
144792
|
+
hovered: hoveredCell || 0,
|
|
144793
|
+
channelsVisible: padWithDefault(
|
|
144794
|
+
channelsVisible,
|
|
144795
|
+
false,
|
|
144796
|
+
// There are six texture entries on the shaders
|
|
144797
|
+
MAX_CHANNELS - channelsVisible.length
|
|
144798
|
+
),
|
|
144799
|
+
// uColorScaleRange: [colorScaleLo, colorScaleHi],
|
|
144800
|
+
// uIsExpressionMode: isExpressionMode,
|
|
144801
|
+
// uIsOutlined: false,
|
|
144802
|
+
scaleFactor
|
|
144803
|
+
})).draw();
|
|
144804
|
+
}
|
|
144805
|
+
}
|
|
144806
|
+
/**
|
|
144807
|
+
* This function creates textures from the data
|
|
144808
|
+
*/
|
|
144809
|
+
dataToTexture(data, width, height) {
|
|
144810
|
+
const isWebGL2On = isWebGL2$1(this.context.gl);
|
|
144811
|
+
return new Texture2D(this.context.gl, {
|
|
144812
|
+
width,
|
|
144813
|
+
height,
|
|
144814
|
+
// Only use Float32 so we don't have to write two shaders
|
|
144815
|
+
data: new Float32Array(data),
|
|
144816
|
+
// we don't want or need mimaps
|
|
144817
|
+
mipmaps: false,
|
|
144818
|
+
parameters: {
|
|
144819
|
+
// NEAREST for integer data
|
|
144820
|
+
[GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
|
|
144821
|
+
[GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
|
|
144822
|
+
// CLAMP_TO_EDGE to remove tile artifacts
|
|
144823
|
+
[GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
|
|
144824
|
+
[GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
|
|
144825
|
+
},
|
|
144826
|
+
format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
|
|
144827
|
+
dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
|
|
144828
|
+
type: GL$1.FLOAT
|
|
144829
|
+
});
|
|
144830
|
+
}
|
|
144831
|
+
multiSetsToTexture(multiFeatureValues, setColorValues, channelIsSetColorMode) {
|
|
144832
|
+
const isWebGL2On = isWebGL2$1(this.context.gl);
|
|
144833
|
+
const [totalData, valueTexHeight, indicesOffsets, totalColors, colorTexHeight, colorsOffsets] = multiSetsToTextureData(multiFeatureValues, setColorValues, channelIsSetColorMode, MULTI_FEATURE_TEX_SIZE);
|
|
144834
|
+
return [
|
|
144835
|
+
// Color indices texture
|
|
144836
|
+
new Texture2D(this.context.gl, {
|
|
144837
|
+
width: MULTI_FEATURE_TEX_SIZE,
|
|
144838
|
+
height: valueTexHeight,
|
|
144839
|
+
// Only use Float32 so we don't have to write two shaders
|
|
144840
|
+
data: new Float32Array(totalData),
|
|
144841
|
+
// we don't want or need mimaps
|
|
144842
|
+
mipmaps: false,
|
|
144843
|
+
parameters: {
|
|
144844
|
+
// NEAREST for integer data
|
|
144845
|
+
[GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
|
|
144846
|
+
[GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
|
|
144847
|
+
// CLAMP_TO_EDGE to remove tile artifacts
|
|
144848
|
+
[GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
|
|
144849
|
+
[GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
|
|
144850
|
+
},
|
|
144851
|
+
format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
|
|
144852
|
+
dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
|
|
144853
|
+
type: GL$1.FLOAT
|
|
144854
|
+
}),
|
|
144855
|
+
// Colors texture
|
|
144856
|
+
new Texture2D(this.context.gl, {
|
|
144857
|
+
width: MULTI_FEATURE_TEX_SIZE,
|
|
144858
|
+
height: colorTexHeight,
|
|
144859
|
+
// Only use Float32 so we don't have to write two shaders
|
|
144860
|
+
data: new Float32Array(totalColors),
|
|
144861
|
+
// we don't want or need mimaps
|
|
144862
|
+
mipmaps: false,
|
|
144863
|
+
parameters: {
|
|
144864
|
+
// NEAREST for integer data
|
|
144865
|
+
[GL$1.TEXTURE_MIN_FILTER]: GL$1.NEAREST,
|
|
144866
|
+
[GL$1.TEXTURE_MAG_FILTER]: GL$1.NEAREST,
|
|
144867
|
+
// CLAMP_TO_EDGE to remove tile artifacts
|
|
144868
|
+
[GL$1.TEXTURE_WRAP_S]: GL$1.CLAMP_TO_EDGE,
|
|
144869
|
+
[GL$1.TEXTURE_WRAP_T]: GL$1.CLAMP_TO_EDGE
|
|
144870
|
+
},
|
|
144871
|
+
format: isWebGL2On ? GL$1.R32F : GL$1.LUMINANCE,
|
|
144872
|
+
dataFormat: isWebGL2On ? GL$1.RED : GL$1.LUMINANCE,
|
|
144873
|
+
type: GL$1.FLOAT
|
|
144874
|
+
}),
|
|
144875
|
+
// Offsets
|
|
144876
|
+
indicesOffsets,
|
|
144877
|
+
colorsOffsets,
|
|
144878
|
+
// Texture heights
|
|
144879
|
+
valueTexHeight,
|
|
144880
|
+
colorTexHeight
|
|
144881
|
+
];
|
|
144882
|
+
}
|
|
144883
|
+
}
|
|
144884
|
+
BitmaskLayer2.layerName = "BitmaskLayer";
|
|
144885
|
+
BitmaskLayer2.defaultProps = defaultProps;
|
|
144886
|
+
const toRgbUIString = (on, arr, theme) => {
|
|
144887
|
+
const color = on || theme === "light" && (arr == null ? void 0 : arr.every((i2) => i2 === 255)) ? [220, 220, 220] : arr;
|
|
144888
|
+
return `rgb(${color})`;
|
|
144889
|
+
};
|
|
144890
|
+
function filterSelection(loader, selection) {
|
|
144891
|
+
if (!selection) {
|
|
144892
|
+
return selection;
|
|
144893
|
+
}
|
|
144894
|
+
const data = Array.isArray(loader) ? loader[loader.length - 1] : loader;
|
|
144895
|
+
const { labels } = data;
|
|
144896
|
+
return fromEntries(Object.entries(selection).filter(([key]) => labels.includes(key)));
|
|
144133
144897
|
}
|
|
144134
|
-
BitmaskLayer.layerName = "BitmaskLayer";
|
|
144135
|
-
BitmaskLayer.defaultProps = defaultProps;
|
|
144136
144898
|
async function getSingleSelectionStats2D({ loader, selection }) {
|
|
144137
144899
|
const data = Array.isArray(loader) ? loader[loader.length - 1] : loader;
|
|
144138
|
-
const
|
|
144900
|
+
const filteredSelection = filterSelection(loader, selection);
|
|
144901
|
+
const raster = await data.getRaster({ selection: filteredSelection });
|
|
144139
144902
|
const selectionStats = getChannelStats(raster.data);
|
|
144140
144903
|
const { domain, contrastLimits: slider } = selectionStats;
|
|
144141
144904
|
return { domain, slider };
|
|
144142
144905
|
}
|
|
144143
144906
|
async function getSingleSelectionStats3D({ loader, selection }) {
|
|
144144
144907
|
const lowResSource = loader[loader.length - 1];
|
|
144908
|
+
const filteredSelection = filterSelection(lowResSource, selection);
|
|
144145
144909
|
const { shape, labels } = lowResSource;
|
|
144146
144910
|
const sizeZ = shape[labels.indexOf("z")] >> loader.length - 1;
|
|
144147
144911
|
const raster0 = await lowResSource.getRaster({
|
|
144148
|
-
selection: { ...
|
|
144912
|
+
selection: { ...filteredSelection, z: 0 }
|
|
144149
144913
|
});
|
|
144150
144914
|
const rasterMid = await lowResSource.getRaster({
|
|
144151
|
-
selection: { ...
|
|
144915
|
+
selection: { ...filteredSelection, z: Math.floor(sizeZ / 2) }
|
|
144152
144916
|
});
|
|
144153
144917
|
const rasterTop = await lowResSource.getRaster({
|
|
144154
|
-
selection: { ...
|
|
144918
|
+
selection: { ...filteredSelection, z: Math.max(0, sizeZ - 1) }
|
|
144155
144919
|
});
|
|
144156
144920
|
const stats0 = getChannelStats(raster0.data);
|
|
144157
144921
|
const statsMid = getChannelStats(rasterMid.data);
|
|
@@ -144187,6 +144951,45 @@ const getMultiSelectionStats = async ({ loader, selections, use3d }) => {
|
|
|
144187
144951
|
const sliders = stats.map((stat) => stat.slider);
|
|
144188
144952
|
return { domains, sliders };
|
|
144189
144953
|
};
|
|
144954
|
+
function getPhysicalSizeScalingMatrix(loader) {
|
|
144955
|
+
var _a2;
|
|
144956
|
+
const { x: x2, y: y2, z: z2 } = ((_a2 = loader == null ? void 0 : loader.meta) == null ? void 0 : _a2.physicalSizes) ?? {};
|
|
144957
|
+
if ((x2 == null ? void 0 : x2.size) && (y2 == null ? void 0 : y2.size) && (z2 == null ? void 0 : z2.size)) {
|
|
144958
|
+
const min2 = Math.min(z2.size, x2.size, y2.size);
|
|
144959
|
+
const ratio = [x2.size / min2, y2.size / min2, z2.size / min2];
|
|
144960
|
+
return new Matrix4().scale(ratio);
|
|
144961
|
+
}
|
|
144962
|
+
return new Matrix4().identity();
|
|
144963
|
+
}
|
|
144964
|
+
function getBoundingCube(loader) {
|
|
144965
|
+
const source = Array.isArray(loader) ? loader[0] : loader;
|
|
144966
|
+
const { shape, labels } = source;
|
|
144967
|
+
const physicalSizeScalingMatrix = getPhysicalSizeScalingMatrix(source);
|
|
144968
|
+
const xSlice = [0, physicalSizeScalingMatrix[0] * shape[labels.indexOf("x")]];
|
|
144969
|
+
const ySlice = [0, physicalSizeScalingMatrix[5] * shape[labels.indexOf("y")]];
|
|
144970
|
+
const zSlice = [
|
|
144971
|
+
0,
|
|
144972
|
+
physicalSizeScalingMatrix[10] * shape[labels.indexOf("z")]
|
|
144973
|
+
];
|
|
144974
|
+
return [xSlice, ySlice, zSlice];
|
|
144975
|
+
}
|
|
144976
|
+
function abbreviateNumber(value) {
|
|
144977
|
+
const maxLength = 5;
|
|
144978
|
+
let maxNaiveDigits = maxLength;
|
|
144979
|
+
if (!Number.isInteger(value)) {
|
|
144980
|
+
--maxNaiveDigits;
|
|
144981
|
+
}
|
|
144982
|
+
if (value < 1) {
|
|
144983
|
+
--maxNaiveDigits;
|
|
144984
|
+
}
|
|
144985
|
+
const naive = Intl.NumberFormat("en-US", {
|
|
144986
|
+
maximumSignificantDigits: maxNaiveDigits,
|
|
144987
|
+
useGrouping: false
|
|
144988
|
+
}).format(value);
|
|
144989
|
+
if (naive.length <= maxLength)
|
|
144990
|
+
return naive;
|
|
144991
|
+
return value.toExponential(0);
|
|
144992
|
+
}
|
|
144190
144993
|
function square(x2, y2, r2) {
|
|
144191
144994
|
return [[x2, y2 + r2], [x2 + r2, y2], [x2, y2 - r2], [x2 - r2, y2]];
|
|
144192
144995
|
}
|
|
@@ -144226,6 +145029,35 @@ function getSourceFromLoader(loader, level) {
|
|
|
144226
145029
|
const source = Array.isArray(data) ? data[level || data.length - 1] : data;
|
|
144227
145030
|
return source;
|
|
144228
145031
|
}
|
|
145032
|
+
const getStatsForResolution = (loader, resolution) => {
|
|
145033
|
+
const { shape, labels } = loader[resolution];
|
|
145034
|
+
const height = shape[labels.indexOf("y")];
|
|
145035
|
+
const width = shape[labels.indexOf("x")];
|
|
145036
|
+
const depth = shape[labels.indexOf("z")];
|
|
145037
|
+
const depthDownsampled = Math.max(1, depth >> resolution);
|
|
145038
|
+
const totalBytes = 4 * height * width * depthDownsampled;
|
|
145039
|
+
return {
|
|
145040
|
+
height,
|
|
145041
|
+
width,
|
|
145042
|
+
depthDownsampled,
|
|
145043
|
+
totalBytes
|
|
145044
|
+
};
|
|
145045
|
+
};
|
|
145046
|
+
const canLoadResolution = (loader, resolution) => {
|
|
145047
|
+
var _a2, _b, _c;
|
|
145048
|
+
const {
|
|
145049
|
+
totalBytes,
|
|
145050
|
+
height,
|
|
145051
|
+
width,
|
|
145052
|
+
depthDownsampled
|
|
145053
|
+
} = getStatsForResolution(
|
|
145054
|
+
loader,
|
|
145055
|
+
resolution
|
|
145056
|
+
);
|
|
145057
|
+
const maxHeapSize = ((_a2 = window.performance) == null ? void 0 : _a2.memory) && ((_c = (_b = window.performance) == null ? void 0 : _b.memory) == null ? void 0 : _c.jsHeapSizeLimit) / 2;
|
|
145058
|
+
const maxSize = maxHeapSize || 2 ** 31 - 1;
|
|
145059
|
+
return totalBytes < maxSize && height <= 2048 && depthDownsampled <= 2048 && width <= 2048 && depthDownsampled > 1;
|
|
145060
|
+
};
|
|
144229
145061
|
function isRgb(loader, channels2) {
|
|
144230
145062
|
const source = getSourceFromLoader(loader);
|
|
144231
145063
|
const { shape, dtype, labels } = source;
|
|
@@ -144238,6 +145070,32 @@ function isRgb(loader, channels2) {
|
|
|
144238
145070
|
}
|
|
144239
145071
|
return false;
|
|
144240
145072
|
}
|
|
145073
|
+
function physicalSizeToMatrix(xSize, ySize, zSize, xUnit, yUnit, zUnit) {
|
|
145074
|
+
const hasZPhyscialSize = Boolean(zSize) && Boolean(zUnit);
|
|
145075
|
+
const hasYPhyscialSize = Boolean(ySize) && Boolean(yUnit);
|
|
145076
|
+
const hasXPhyscialSize = Boolean(xSize) && Boolean(xUnit);
|
|
145077
|
+
if (!hasXPhyscialSize || !hasYPhyscialSize) {
|
|
145078
|
+
return new Matrix4().identity();
|
|
145079
|
+
}
|
|
145080
|
+
const sizes = [
|
|
145081
|
+
unit(`${xSize} ${xUnit}`.replace("µ", "u")),
|
|
145082
|
+
unit(`${ySize} ${yUnit}`.replace("µ", "u"))
|
|
145083
|
+
];
|
|
145084
|
+
if (hasZPhyscialSize) {
|
|
145085
|
+
sizes.push(unit(`${zSize} ${zUnit}`.replace("µ", "u")));
|
|
145086
|
+
}
|
|
145087
|
+
const scale2 = sizes.map((i2) => divide(i2, unit("1 um")));
|
|
145088
|
+
if (!sizes[0].equals(sizes[1])) {
|
|
145089
|
+
scale2[1] = divide(sizes[1], sizes[0]);
|
|
145090
|
+
}
|
|
145091
|
+
if (!scale2[2]) {
|
|
145092
|
+
scale2[2] = 1;
|
|
145093
|
+
}
|
|
145094
|
+
if (isEqual$1(scale2, [1, 1, 1])) {
|
|
145095
|
+
return new Matrix4().identity();
|
|
145096
|
+
}
|
|
145097
|
+
return new Matrix4().scale([...scale2]);
|
|
145098
|
+
}
|
|
144241
145099
|
function getMetaWithTransformMatrices(imageMeta, imageLoaders) {
|
|
144242
145100
|
const sources = imageLoaders.map((loader) => getSourceFromLoader(loader));
|
|
144243
145101
|
if (imageMeta.map((meta2) => {
|
|
@@ -144475,8 +145333,64 @@ function coordinateTransformationsToMatrix(coordinateTransformations, axes) {
|
|
|
144475
145333
|
}
|
|
144476
145334
|
return mat;
|
|
144477
145335
|
}
|
|
145336
|
+
function hexToRgb(hex) {
|
|
145337
|
+
const result = /^#?([A-F\d]{2})([A-F\d]{2})([A-F\d]{2})$/i.exec(hex);
|
|
145338
|
+
return [
|
|
145339
|
+
parseInt(result[1].toLowerCase(), 16),
|
|
145340
|
+
parseInt(result[2].toLowerCase(), 16),
|
|
145341
|
+
parseInt(result[3].toLowerCase(), 16)
|
|
145342
|
+
];
|
|
145343
|
+
}
|
|
145344
|
+
function normalizeCoordinateTransformations(coordinateTransformations, datasets) {
|
|
145345
|
+
var _a2;
|
|
145346
|
+
let result = [];
|
|
145347
|
+
if (Array.isArray(coordinateTransformations)) {
|
|
145348
|
+
result = coordinateTransformations.map((transform2) => {
|
|
145349
|
+
if (transform2.input && transform2.output) {
|
|
145350
|
+
const { type } = transform2;
|
|
145351
|
+
if (type === "translation") {
|
|
145352
|
+
return {
|
|
145353
|
+
type,
|
|
145354
|
+
translation: transform2.translation
|
|
145355
|
+
};
|
|
145356
|
+
}
|
|
145357
|
+
if (type === "scale") {
|
|
145358
|
+
return {
|
|
145359
|
+
type,
|
|
145360
|
+
scale: transform2.scale
|
|
145361
|
+
};
|
|
145362
|
+
}
|
|
145363
|
+
if (type === "identity") {
|
|
145364
|
+
return { type };
|
|
145365
|
+
}
|
|
145366
|
+
console.warn(`Coordinate transformation type "${type}" is not supported.`);
|
|
145367
|
+
}
|
|
145368
|
+
return transform2;
|
|
145369
|
+
});
|
|
145370
|
+
}
|
|
145371
|
+
if (Array.isArray((_a2 = datasets == null ? void 0 : datasets[0]) == null ? void 0 : _a2.coordinateTransformations)) {
|
|
145372
|
+
result = [
|
|
145373
|
+
...datasets[0].coordinateTransformations,
|
|
145374
|
+
...result
|
|
145375
|
+
];
|
|
145376
|
+
}
|
|
145377
|
+
return result;
|
|
145378
|
+
}
|
|
145379
|
+
function getDomains() {
|
|
145380
|
+
const domains = {};
|
|
145381
|
+
const needMin = ["Int8", "Int16", "Int32"];
|
|
145382
|
+
Object.keys(DTYPE_VALUES).forEach((dtype) => {
|
|
145383
|
+
const { max: max2 } = DTYPE_VALUES[dtype];
|
|
145384
|
+
const min2 = needMin.includes(dtype) ? -(max2 + 1) : 0;
|
|
145385
|
+
domains[dtype] = [min2, max2];
|
|
145386
|
+
});
|
|
145387
|
+
return domains;
|
|
145388
|
+
}
|
|
145389
|
+
const DOMAINS = getDomains();
|
|
144478
145390
|
export {
|
|
145391
|
+
filterSelection as A,
|
|
144479
145392
|
BaseDecoder as B,
|
|
145393
|
+
DOMAINS as C,
|
|
144480
145394
|
DEFAULT_CELLS_LAYER as D,
|
|
144481
145395
|
GLOBAL_LABELS as G,
|
|
144482
145396
|
DEFAULT_MOLECULES_LAYER as a,
|
|
@@ -144493,5 +145407,16 @@ export {
|
|
|
144493
145407
|
getNgffAxes as l,
|
|
144494
145408
|
getNgffAxesForTiff as m,
|
|
144495
145409
|
coordinateTransformationsToMatrix as n,
|
|
144496
|
-
|
|
145410
|
+
hexToRgb as o,
|
|
145411
|
+
physicalSizeToMatrix as p,
|
|
145412
|
+
getStatsForResolution as q,
|
|
145413
|
+
canLoadResolution as r,
|
|
145414
|
+
square as s,
|
|
145415
|
+
normalizeCoordinateTransformations as t,
|
|
145416
|
+
toRgbUIString as u,
|
|
145417
|
+
getSingleSelectionStats as v,
|
|
145418
|
+
getMultiSelectionStats as w,
|
|
145419
|
+
getPhysicalSizeScalingMatrix as x,
|
|
145420
|
+
getBoundingCube as y,
|
|
145421
|
+
abbreviateNumber as z
|
|
144497
145422
|
};
|