/
wrappers_images.R
250 lines (241 loc) · 9.89 KB
/
wrappers_images.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#' Image wrapper class
#' @title MultiImageWrapper Class
#' @docType class
#' @description
#' Class representing image objects in a Vitessce dataset.
#'
#' @rdname MultiImageWrapper
#' @export
MultiImageWrapper <- R6::R6Class("MultiImageWrapper",
inherit = AbstractWrapper,
public = list(
#' @field image_wrappers The object to wrap.
#' @keywords internal
image_wrappers = NULL,
#' @field use_physical_size_scaling Whether or not to scale the image based on the physical size metadata stored in the file.
#' @keywords internal
use_physical_size_scaling = NULL,
#' @description
#' Create a wrapper around multiple image objects.
#' @param image_wrappers A list of individual image wrapper objects.
#' @param use_physical_size_scaling Whether or not to scale the image based on the physical size metadata stored in the file.
#' @param ... Parameters inherited from `AbstractWrapper`.
#' @return A new `MultiImageWrapper` object.
initialize = function(image_wrappers, use_physical_size_scaling = FALSE, ...) {
super$initialize(...)
self$image_wrappers <- image_wrappers
self$use_physical_size_scaling <- use_physical_size_scaling
},
#' @description
#' Create the web server routes and file definition creators.
#' @param dataset_uid The ID for this dataset.
#' @param obj_i The index of this data object within the dataset.
convert_and_save = function(dataset_uid, obj_i) {
for(image in self$image_wrappers) {
image$convert_and_save(dataset_uid, obj_i)
}
# Get the file definition creator functions.
raster_file_creator <- self$make_raster_file_def_creator(dataset_uid, obj_i)
# Append the new file definition creators functions to the main list.
self$file_def_creators <- append(self$file_def_creators, raster_file_creator)
# Create a web server route object for the directory of JSON files.
routes <- self$make_raster_routes()
self$routes <- append(self$routes, routes)
},
#' @description
#' Create a list representing the image routes.
#' @return A list of server route objects.
#' @keywords internal
make_raster_routes = function() {
obj_routes <- list()
for(i in length(self$image_wrappers)) {
image <- self$image_wrappers[[i]]
image_routes <- image$get_routes()
obj_routes <- c(obj_routes, image_routes)
}
obj_routes
},
#' @description
#' Make the file definition creator function for the raster data type.
#' @param dataset_uid The ID for this dataset.
#' @param obj_i The index of this data object within the dataset.
#' @return A file definition creator function which takes a `base_url` parameter.
make_raster_file_def_creator = function(dataset_uid, obj_i) {
get_raster <- function(base_url) {
options_def <- list(
schemaVersion = "0.0.2",
usePhysicalSizeScaling = self$use_physical_size_scaling,
images = list(),
renderLayers = list()
)
for(image in self$image_wrappers) {
image_def <- image$make_image_def(dataset_uid, obj_i, base_url)
options_def$images <- append(options_def$images, list(image_def))
options_def$renderLayers <- append(options_def$renderLayers, image$name)
}
file_def <- list(
type = DataType$RASTER,
fileType = FileType$RASTER_JSON,
options = options_def
)
return(file_def)
}
return(get_raster)
}
),
)
#' OME-TIFF object wrapper class
#' @title OmeTiffWrapper Class
#' @docType class
#' @description
#' Class representing an OME-TIFF file in a Vitessce dataset.
#'
#' @rdname OmeTiffWrapper
#' @export
OmeTiffWrapper <- R6::R6Class("OmeTiffWrapper",
inherit = AbstractWrapper,
public = list(
#' @field img_path A local filepath to an OME-TIFF file.
#' @keywords internal
img_path = NULL,
#' @field img_url A remote URL of an OME-TIFF file.
#' @keywords internal
img_url = NULL,
#' @field name The display name for this OME-TIFF within Vitessce.
#' @keywords internal
name = NULL,
#' @field transformation_matrix A column-major ordered matrix for transforming
#' this image (see http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#homogeneous-coordinates for more information).
#' @keywords internal
transformation_matrix = NULL,
#' @field is_bitmask Whether or not this image is a bitmask.
#' @keywords internal
is_bitmask = NULL,
#' @field is_remote Whether or not this image is remote.
#' @keywords internal
is_remote = NULL,
#' @field local_img_uid
#' @keywords internal
local_img_uid = NULL,
#' @description
#' Create a wrapper around multiple image objects.
#' @param img_path A local filepath to an OME-TIFF file.
#' @param img_url A remote URL of an OME-TIFF file.
#' @param name The display name for this OME-TIFF within Vitessce.
#' @param transformation_matrix A column-major ordered matrix for transforming
#' this image (see http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#homogeneous-coordinates for more information).
#' @param is_bitmask Whether or not this image is a bitmask.
#' @param use_physical_size_scaling Whether or not to scale the image based on the physical size metadata stored in the file.
#' @param ... Parameters inherited from `AbstractWrapper`.
#' @return A new `OmeTiffWrapper` object.
initialize = function(img_path = NA, img_url = NA, name = "", transformation_matrix = NA, is_bitmask = FALSE, ...) {
super$initialize(...)
self$img_path <- img_path
self$img_url <- img_url
self$name <- name
self$transformation_matrix <- transformation_matrix
self$is_bitmask <- is_bitmask
self$local_img_uid <- make_unique_filename(".ome.tif")
if(!is.na(img_url) && !is.na(img_path)) {
warning("Expected either img_path or img_url to be provided, but not both.")
}
self$is_remote <- !is.na(img_url)
},
#' @description
#' Create the web server routes and file definition creators.
#' @param dataset_uid The ID for this dataset.
#' @param obj_i The index of this data object within the dataset.
convert_and_save = function(dataset_uid, obj_i, base_dir = NA) {
if(!self$is_remote) {
super$convert_and_save(dataset_uid, obj_i, base_dir = base_dir)
}
# Get the file definition creator functions.
raster_file_creator <- self$make_raster_file_def_creator(dataset_uid, obj_i)
self$file_def_creators <- append(self$file_def_creators, raster_file_creator)
routes <- self$make_raster_routes(dataset_uid, obj_i)
self$routes <- c(self$routes, routes)
},
#' @description
#' Create a list representing the server routes.
#' @param dataset_uid The ID for this dataset.
#' @param obj_i The index of this data object within the dataset.
#' @return A list of server route objects.
#' @keywords internal
make_raster_routes = function(dataset_uid, obj_i) {
if(self$is_remote) {
return(list())
} else {
if(is.na(self$base_dir)) {
local_img_path <- self$img_path
local_img_route_path <- self$get_route_str(dataset_uid, obj_i, self$local_img_uid)
} else {
local_img_path <- file.path(self$base_dir, self$img_path)
local_img_route_path <- file_path_to_url_path(self$img_path)
}
route <- VitessceConfigServerRangeRoute$new(
local_img_route_path,
local_img_path
)
return(list(route))
}
},
#' @description
#' Create an object representing a single image in a raster.json list of images.
#' @param dataset_uid The ID for this dataset.
#' @param obj_i The index of this data object within the dataset.
#' @param base_url The base URL for the server.
#' @return A list that can be converted to JSON.
#' @keywords internal
make_image_def = function(dataset_uid, obj_i, base_url) {
img_url <- self$get_img_url(base_url, dataset_uid, obj_i)
return(self$create_image_json(img_url))
},
#' @description
#' Make the file definition creator function for the raster data type.
#' @param dataset_uid The ID for this dataset.
#' @param obj_i The index of this data object within the dataset.
#' @return A file definition creator function which takes a `base_url` parameter.
make_raster_file_def_creator = function(dataset_uid, obj_i) {
get_raster <- function(base_url) {
options_def <- list(
schemaVersion = "0.0.2",
images = list(
self$make_image_def(dataset_uid, obj_i, base_url)
)
)
file_def <- list(
fileType = FileType$RASTER_JSON,
options = options_def
)
return(file_def)
}
return(get_raster)
},
create_image_json = function(img_url, offsets_url = NA) {
metadata <- obj_list()
img_def <- list(
name = self$name,
type = "ome-tiff",
url = img_url
)
# TODO: offsets_url
if(!is.na(self$transformation_matrix)) {
metadata[['transform']] = list(
matrix = self$transformation_matrix
)
}
metadata[['isBitmask']] = self$is_bitmask
img_def[['metadata']] = metadata
img_def
},
get_img_url = function(base_url = "", dataset_uid = "", obj_i = "") {
if(self$is_remote) {
return(self$img_url)
}
if(!is.na(self$base_dir)) {
return(self$get_url_simple(base_url, file_path_to_url_path(self$img_path, prepend_slash = FALSE)))
}
return(self$get_url(base_url, dataset_uid, obj_i, self$local_img_uid))
}
),
)