/
wrappers_anndata.R
275 lines (264 loc) · 12.6 KB
/
wrappers_anndata.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
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#' AnnData object wrapper class
#' @title AnnDataWrapper Class
#' @docType class
#' @description
#' Class representing an AnnData object (saved to a Zarr store) in a Vitessce dataset.
#'
#' @rdname AnnDataWrapper
#' @export
AnnDataWrapper <- R6::R6Class("AnnDataWrapper",
inherit = AbstractWrapper,
public = list(
#' @field adata_path The object to wrap.
#' @keywords internal
adata_path = NULL,
#' @field adata_url The object to wrap.
#' @keywords internal
adata_url = NULL,
#' @field local_dir_uid The path to the local zarr store.
#' @keywords internal
local_dir_uid = NULL,
#' @field obs_feature_matrix_path The path to the observation-by-feature matrix within the Zarr store.
#' @keywords internal
obs_feature_matrix_path=NULL,
#' @field feature_filter_path The path to the a column of adata.var within the Zarr store.
#' Use this if obs_feature_matrix_path points to a subset of adata.X (relative to the full adata.var).
#' @keywords internal
feature_filter_path=NULL,
#' @field initial_feature_filter_path The path to the a column of adata.var within the Zarr store.
#' Use this to load a subset of the matrix at obs_feature_matrix_path initially.
#' @keywords internal
initial_feature_filter_path=NULL,
#' @field obs_set_paths A list of paths to the observation sets within the Zarr store.
#' @keywords internal
obs_set_paths=NULL,
#' @field obs_set_names A list of names for the observation sets.
#' @keywords internal
obs_set_names=NULL,
#' @field obs_locations_path The path to the observation locations within the Zarr store.
#' @keywords internal
obs_locations_path=NULL,
#' @field obs_segmentations_path The path to the observation segmentations within the Zarr store.
#' @keywords internal
obs_segmentations_path=NULL,
#' @field obs_embedding_paths A list of paths to the observation embeddings within the Zarr store.
#' @keywords internal
obs_embedding_paths=NULL,
#' @field obs_embedding_names A list of names for the observation embeddings.
#' @keywords internal
obs_embedding_names=NULL,
#' @field obs_embedding_dims A list of dimensions for the observation embeddings.
#' @keywords internal
obs_embedding_dims=NULL,
#' @field feature_labels_path The path to the feature labels within the Zarr store.
#' @keywords internal
feature_labels_path=NULL,
#' @field obs_labels_path The path to the observation labels within the Zarr store.
#' @keywords internal
obs_labels_path=NULL,
#' @field obs_labels_paths A list of paths to the observation labels within the Zarr store.
#' @keywords internal
obs_labels_paths=NULL,
#' @field obs_labels_names A list of names for the observation labels.
#' @keywords internal
obs_labels_names=NULL,
#' @field coordination_values A list of coordination values for the file definition.
#' @keywords internal
coordination_values=NULL,
#' @field request_init A list of requestInit options for the Zarr store.
#' @keywords internal
request_init=NULL,
#' @description
#' Create a wrapper around an AnnData object saved to a Zarr store.
#' @param adata_path The path to a local Zarr store.
#' @param adata_url The URL to a remote Zarr store.
#' @param obs_feature_matrix_path The path to the observation-by-feature matrix within the Zarr store.
#' @param feature_filter_path The path to the a column of adata.var within the Zarr store. Use this if obs_feature_matrix_path points to a subset of adata.X (relative to the full adata.var).
#' @param initial_feature_filter_path The path to the a column of adata.var within the Zarr store. Use this to load a subset of the matrix at obs_feature_matrix_path initially.
#' @param obs_set_paths A list of paths to the observation sets within the Zarr store.
#' @param obs_set_names A list of names for the observation sets.
#' @param obs_locations_path The path to the observation locations within the Zarr store.
#' @param obs_segmentations_path The path to the observation segmentations within the Zarr store.
#' @param obs_embedding_paths A list of paths to the observation embeddings within the Zarr store.
#' @param obs_embedding_names A list of names for the observation embeddings.
#' @param obs_embedding_dims A list of dimensions for the observation embeddings.
#' @param request_init A list of requestInit options for the Zarr store.
#' @param feature_labels_path The path to the feature labels within the Zarr store.
#' @param obs_labels_paths A list of paths to the observation labels within the Zarr store.
#' @param obs_labels_names A list of names for the observation labels.
#' @param coordination_values A list of coordination values for the file definition.
#' @param ... Parameters inherited from `AbstractWrapper`.
#' @return A new `AnnDataWrapper` object.
initialize = function(adata_path = NA, adata_url = NA, obs_feature_matrix_path = NA, feature_filter_path = NA, initial_feature_filter_path = NA, obs_set_paths = NA, obs_set_names = NA, obs_locations_path = NA, obs_segmentations_path = NA, obs_embedding_paths = NA, obs_embedding_names = NA, obs_embedding_dims = NA, request_init = NA, feature_labels_path = NA, coordination_values = NA, obs_labels_paths = NA, obs_labels_names = NA, ...) {
super$initialize(...)
self$adata_path <- adata_path
self$adata_url <- adata_url
if(!is.na(adata_url) && !is.na(adata_path)) {
stop("Did not expect adata_url to be provided with adata_path")
}
if(is.na(adata_url) && is.na(adata_path)) {
stop("Expected either adata_url or adata_path to be provided")
}
if(!is.na(adata_path)) {
self$is_remote <- FALSE
} else {
self$is_remote <- TRUE
}
self$local_dir_uid <- make_unique_filename(".adata.zarr")
self$obs_feature_matrix_path <- obs_feature_matrix_path
self$obs_set_names <- obs_set_names
self$obs_embedding_names <- obs_embedding_names
self$feature_filter_path <- feature_filter_path
self$initial_feature_filter_path <- initial_feature_filter_path
self$obs_set_paths <- obs_set_paths
self$obs_locations_path <- obs_locations_path
self$obs_segmentations_path <- obs_segmentations_path
self$obs_embedding_paths <- obs_embedding_paths
self$obs_embedding_dims <- obs_embedding_dims
self$request_init <- request_init
self$feature_labels_path <- feature_labels_path
self$obs_labels_paths <- obs_labels_paths
self$obs_labels_names <- obs_labels_names
self$coordination_values <- coordination_values
},
#' @description
#' Create the JSON output files, 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.
#' @param base_dir A base directory for local data.
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.
file_def_creator <- self$make_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, file_def_creator)
# Create a web server route object for the directory of JSON files.
new_routes <- self$make_routes(dataset_uid, obj_i)
for(route in new_routes) {
self$routes <- append(self$routes, route)
}
},
#' @description
#' Get a list of server route objects.
#' @param dataset_uid The ID for this dataset.
#' @param obj_i The index of this data object within the dataset.
make_routes = function(dataset_uid, obj_i) {
return(self$get_local_dir_route(dataset_uid, obj_i, self$adata_path, self$local_dir_uid))
},
#' @description
#' Get the URL to the Zarr store, to fill in the file URL in the file definitions.
#' @param base_url The base URL, on which the route will be served.
#' @param dataset_uid The ID for this dataset.
#' @param obj_i The index of this data object within the dataset.
#' @keywords internal
#' @return A URL as a string.
get_zarr_url = function(base_url, dataset_uid, obj_i) {
if(self$is_remote) {
return(self$adata_url)
} else {
return(self$get_local_dir_url(base_url, dataset_uid, obj_i, self$adata_path, self$local_dir_uid))
}
},
#' @description
#' Make the file definition creator function for the cells 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_file_def_creator = function(dataset_uid, obj_i) {
get_anndata_zarr <- function(base_url) {
options <- obj_list()
if(!is_na(self$obs_locations_path)) {
options[['obsLocations']] <- obj_list()
options[['obsLocations']][['path']] <- self$obs_locations_path
}
if(!is_na(self$obs_segmentations_path)) {
options[['obsSegmentations']] <- obj_list()
options[['obsSegmentations']][['path']] <- self$obs_segmentations_path
}
if(!is_na(self$obs_embedding_paths)) {
options[['obsEmbedding']] <- list()
for(i in seq_len(length(self$obs_embedding_paths))) {
embedding_path <- self$obs_embedding_paths[i]
if(!is_na(self$obs_embedding_names)) {
embedding_name <- self$obs_embedding_names[i]
} else {
segments <- stringr::str_split(embedding_path, "/")[[1]]
embedding_name <- segments[-1]
}
if(!is_na(self$obs_embedding_dims)) {
embedding_dims <- self$obs_embedding_dims[i]
} else {
embedding_dims <- c(0, 1)
}
options[['obsEmbedding']] <- append(options[['obsEmbedding']], list(obj_list(
path = embedding_path,
embeddingType = embedding_name,
dims = embedding_dims
)))
}
}
if(!is_na(self$obs_set_paths)) {
options[['obsSets']] <- list()
for(i in seq_len(length(self$obs_set_paths))) {
set_path <- self$obs_set_paths[i]
if(!is_na(self$obs_set_names)) {
set_name <- self$obs_set_names[i]
} else {
segments <- stringr::str_split(set_path, "/")[[1]]
set_name <- segments[-1]
}
options[['obsSets']] <- append(options[['obsSets']], list(obj_list(
path = set_path,
name = set_name
)))
}
}
if(!is_na(self$obs_feature_matrix_path)) {
options[['obsFeatureMatrix']] <- obj_list()
options[['obsFeatureMatrix']][['path']] <- self$obs_feature_matrix_path
if(!is_na(self$feature_filter_path)) {
options[['obsFeatureMatrix']][['featureFilterPath']] <- self$feature_filter_path
}
if(!is_na(self$initial_feature_filter_path)) {
options[['obsFeatureMatrix']][['initialFeatureFilterPath']] <- self$initial_feature_filter_path
}
}
if(!is_na(self$feature_labels_path)) {
options[['featureLabels']] <- obj_list()
options[['featureLabels']][['path']] <- self$feature_labels_path
}
if(!is_na(self$obs_labels_paths)) {
options[['obsLabels']] <- list()
for(i in seq_len(length(self$obs_labels_paths))) {
obs_labels_path <- self$obs_labels_paths[i]
if(!is_na(self$obs_labels_names)) {
obs_labels_name <- self$obs_labels_names[i]
} else {
segments <- stringr::str_split(obs_labels_path, "/")[[1]]
obs_labels_name <- segments[-1]
}
options[['obsLabels']] <- append(options[['obsLabels']], list(obj_list(
path = obs_labels_path,
obsLabelsType = obs_labels_name
)))
}
}
file_def <- list(
fileType = FileType$ANNDATA_ZARR,
url = self$get_zarr_url(base_url, dataset_uid, obj_i),
options = options
)
if(!is_na(self$request_init)) {
file_def[['requestInit']] <- self$request_init
}
if(!is_na(self$coordination_values)) {
file_def[['coordinationValues']] <- self$coordination_values
}
return(file_def)
}
return(get_anndata_zarr)
}
),
)