@@ -5,8 +5,20 @@ import com.scalableminds.util.geometry.{BoundingBox, Vec3Double, Vec3Int}
5
5
import com .scalableminds .util .objectid .ObjectId
6
6
import com .scalableminds .util .time .Instant
7
7
import com .scalableminds .util .tools .{Fox , JsonHelper }
8
+ import com .scalableminds .webknossos .datastore .dataformats .MagLocator
9
+ import com .scalableminds .webknossos .datastore .dataformats .layers .{
10
+ N5DataLayer ,
11
+ N5SegmentationLayer ,
12
+ PrecomputedDataLayer ,
13
+ PrecomputedSegmentationLayer ,
14
+ Zarr3DataLayer ,
15
+ Zarr3SegmentationLayer ,
16
+ ZarrDataLayer ,
17
+ ZarrSegmentationLayer
18
+ }
19
+ import com .scalableminds .webknossos .datastore .datareaders .AxisOrder
8
20
import com .scalableminds .webknossos .datastore .helpers .DataSourceMagInfo
9
- import com .scalableminds .webknossos .datastore .models .{LengthUnit , VoxelSize }
21
+ import com .scalableminds .webknossos .datastore .models .{LengthUnit , VoxelSize , datasource }
10
22
import com .scalableminds .webknossos .datastore .models .datasource .DatasetViewConfiguration .DatasetViewConfiguration
11
23
import com .scalableminds .webknossos .datastore .models .datasource .LayerViewConfiguration .LayerViewConfiguration
12
24
import com .scalableminds .webknossos .datastore .models .datasource .inbox .{InboxDataSourceLike => InboxDataSource }
@@ -17,8 +29,10 @@ import com.scalableminds.webknossos.datastore.models.datasource.{
17
29
Category ,
18
30
CoordinateTransformation ,
19
31
CoordinateTransformationType ,
32
+ DataFormat ,
20
33
DataSourceId ,
21
34
ElementClass ,
35
+ SegmentationLayerLike ,
22
36
ThinPlateSplineCorrespondences ,
23
37
DataLayerLike => DataLayer
24
38
}
@@ -839,6 +853,30 @@ class DatasetMagsDAO @Inject()(sqlClient: SqlClient)(implicit ec: ExecutionConte
839
853
magInfos <- rowsToMagInfos(rows)
840
854
} yield magInfos
841
855
856
+ def parseMagLocator (row : DatasetMagsRow ): Fox [MagLocator ] =
857
+ for {
858
+ mag <- parseMag(row.mag)
859
+ axisOrderParsed = row.axisorder match {
860
+ case Some (axisOrder) => JsonHelper .parseAs[AxisOrder ](axisOrder).toOption
861
+ case None => None
862
+ }
863
+ } yield
864
+ MagLocator (
865
+ mag,
866
+ row.path, // Does this make sense -> mag path may be something different than path in DB :/
867
+ None ,
868
+ axisOrderParsed,
869
+ row.channelindex,
870
+ row.credentialid
871
+ )
872
+
873
+ def findAllByDatasetId (datasetId : ObjectId ): Fox [Seq [(String , MagLocator )]] =
874
+ for {
875
+ // We assume non-WKW Datasets here (WKW Resolutions are not handled)
876
+ rows <- run(q """ SELECT * FROM webknossos.dataset_mags WHERE _dataset = $datasetId""" .as[DatasetMagsRow ])
877
+ mags <- Fox .combined(rows.map(parseMagLocator))
878
+ } yield rows.map(r => r.datalayername).zip(mags)
879
+
842
880
}
843
881
844
882
class DatasetLayerDAO @ Inject ()(
@@ -865,6 +903,7 @@ class DatasetLayerDAO @Inject()(
865
903
coordinateTransformationsOpt = if (coordinateTransformations.isEmpty) None else Some (coordinateTransformations)
866
904
additionalAxes <- datasetLayerAdditionalAxesDAO.findAllForDatasetAndDataLayerName(datasetId, row.name)
867
905
additionalAxesOpt = if (additionalAxes.isEmpty) None else Some (additionalAxes)
906
+ dataFormat = row.dataformat.flatMap(df => DataFormat .fromString(df))
868
907
} yield {
869
908
category match {
870
909
case Category .segmentation =>
@@ -881,7 +920,9 @@ class DatasetLayerDAO @Inject()(
881
920
defaultViewConfigurationOpt,
882
921
adminViewConfigurationOpt,
883
922
coordinateTransformationsOpt,
884
- additionalAxesOpt
923
+ additionalAxesOpt,
924
+ numChannels = row.numchannels,
925
+ dataFormat = dataFormat
885
926
))
886
927
case Category .color =>
887
928
Fox .successful(
@@ -894,7 +935,9 @@ class DatasetLayerDAO @Inject()(
894
935
defaultViewConfigurationOpt,
895
936
adminViewConfigurationOpt,
896
937
coordinateTransformationsOpt,
897
- additionalAxesOpt
938
+ additionalAxesOpt,
939
+ numChannels = row.numchannels,
940
+ dataFormat = dataFormat
898
941
))
899
942
case _ => Fox .failure(s " Could not match dataset layer with category $category" )
900
943
}
@@ -905,13 +948,174 @@ class DatasetLayerDAO @Inject()(
905
948
def findAllForDataset (datasetId : ObjectId ): Fox [List [DataLayer ]] =
906
949
for {
907
950
rows <- run(q """ SELECT _dataset, name, category, elementClass, boundingBox, largestSegmentId, mappings,
908
- defaultViewConfiguration, adminViewConfiguration
951
+ defaultViewConfiguration, adminViewConfiguration, numChannels, dataFormat
909
952
FROM webknossos.dataset_layers
910
953
WHERE _dataset = $datasetId
911
954
ORDER BY name """ .as[DatasetLayersRow ])
912
955
rowsParsed <- Fox .combined(rows.toList.map(parseRow(_, datasetId)))
913
956
} yield rowsParsed
914
957
958
+ def findAllForDatasetWithMags (datasetId : ObjectId ): Fox [List [DataLayer ]] =
959
+ for {
960
+ layers <- findAllForDataset(datasetId)
961
+ layerNamesAndMags <- datasetMagsDAO.findAllByDatasetId(datasetId)
962
+ layersWithMags = layers.map { layer =>
963
+ val mags = layerNamesAndMags.filter(_._1 == layer.name).map(_._2).toList
964
+ layer match {
965
+ // Maybe move this somewhere else?
966
+ case AbstractDataLayer (name,
967
+ category,
968
+ boundingBox,
969
+ resolutions,
970
+ elementClass,
971
+ defaultViewConfiguration,
972
+ adminViewConfiguration,
973
+ coordinateTransformations,
974
+ additionalAxes,
975
+ _,
976
+ numChannels,
977
+ dataFormat,
978
+ _) =>
979
+ dataFormat match {
980
+ case Some (df) =>
981
+ df match {
982
+ case DataFormat .wkw =>
983
+ throw new NotImplementedError (
984
+ " WKW data format not supported in this context, only datasets with MagLocators are supported" )
985
+ case DataFormat .neuroglancerPrecomputed =>
986
+ PrecomputedDataLayer (name,
987
+ boundingBox,
988
+ category,
989
+ elementClass,
990
+ mags,
991
+ defaultViewConfiguration,
992
+ adminViewConfiguration,
993
+ coordinateTransformations,
994
+ numChannels,
995
+ additionalAxes)
996
+ case DataFormat .n5 =>
997
+ N5DataLayer (name,
998
+ category,
999
+ boundingBox,
1000
+ elementClass,
1001
+ mags,
1002
+ defaultViewConfiguration,
1003
+ adminViewConfiguration,
1004
+ coordinateTransformations,
1005
+ numChannels,
1006
+ additionalAxes)
1007
+ case DataFormat .zarr =>
1008
+ ZarrDataLayer (name,
1009
+ category,
1010
+ boundingBox,
1011
+ elementClass,
1012
+ mags,
1013
+ defaultViewConfiguration,
1014
+ adminViewConfiguration,
1015
+ coordinateTransformations,
1016
+ numChannels,
1017
+ additionalAxes,
1018
+ df)
1019
+ case DataFormat .zarr3 =>
1020
+ Zarr3DataLayer (name,
1021
+ category,
1022
+ boundingBox,
1023
+ elementClass,
1024
+ mags,
1025
+ defaultViewConfiguration,
1026
+ adminViewConfiguration,
1027
+ coordinateTransformations,
1028
+ numChannels,
1029
+ additionalAxes)
1030
+ }
1031
+ case None => ???
1032
+ }
1033
+ case AbstractSegmentationLayer (name,
1034
+ category,
1035
+ boundingBox,
1036
+ resolutions,
1037
+ elementClass,
1038
+ largestSegmentId,
1039
+ mappings,
1040
+ defaultViewConfiguration,
1041
+ adminViewConfiguration,
1042
+ coordinateTransformations,
1043
+ additionalAxes,
1044
+ _,
1045
+ numChannels,
1046
+ dataFormat,
1047
+ _) =>
1048
+ dataFormat match {
1049
+ case Some (df) =>
1050
+ df match {
1051
+ case DataFormat .wkw =>
1052
+ throw new NotImplementedError (
1053
+ " WKW data format not supported in this context, only datasets with MagLocators are supported" )
1054
+ case DataFormat .neuroglancerPrecomputed =>
1055
+ PrecomputedSegmentationLayer (
1056
+ name,
1057
+ boundingBox,
1058
+ elementClass,
1059
+ mags,
1060
+ largestSegmentId,
1061
+ mappings,
1062
+ defaultViewConfiguration,
1063
+ adminViewConfiguration,
1064
+ coordinateTransformations,
1065
+ numChannels,
1066
+ additionalAxes,
1067
+ )
1068
+ case DataFormat .n5 =>
1069
+ N5SegmentationLayer (
1070
+ name,
1071
+ boundingBox,
1072
+ elementClass,
1073
+ mags,
1074
+ largestSegmentId,
1075
+ mappings,
1076
+ defaultViewConfiguration,
1077
+ adminViewConfiguration,
1078
+ coordinateTransformations,
1079
+ numChannels,
1080
+ additionalAxes
1081
+ )
1082
+ case DataFormat .zarr =>
1083
+ ZarrSegmentationLayer (
1084
+ name,
1085
+ boundingBox,
1086
+ elementClass,
1087
+ mags,
1088
+ largestSegmentId,
1089
+ mappings,
1090
+ defaultViewConfiguration,
1091
+ adminViewConfiguration,
1092
+ coordinateTransformations,
1093
+ numChannels,
1094
+ additionalAxes,
1095
+ df
1096
+ )
1097
+ case DataFormat .zarr3 =>
1098
+ Zarr3SegmentationLayer (
1099
+ name,
1100
+ boundingBox,
1101
+ elementClass,
1102
+ mags,
1103
+ largestSegmentId,
1104
+ mappings,
1105
+ defaultViewConfiguration,
1106
+ adminViewConfiguration,
1107
+ coordinateTransformations,
1108
+ numChannels,
1109
+ additionalAxes
1110
+ )
1111
+ }
1112
+ case None => ???
1113
+ }
1114
+ case _ => throw new NotImplementedError (" DataLayer type mismatch (unreachable)" )
1115
+ }
1116
+ }
1117
+ } yield layersWithMags
1118
+
915
1119
private def insertLayerQuery (datasetId : ObjectId , layer : DataLayer ): SqlAction [Int , NoStream , Effect ] =
916
1120
layer match {
917
1121
case s : AbstractSegmentationLayer =>
0 commit comments