bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
StareFunctions.h
1// This file is part of libdap, A C++ implementation of the OPeNDAP Data
2// Access Protocol.
3
4// Copyright (c) 2019 OPeNDAP, Inc.
5// Authors: Kodi Neumiller <kneumiller@opendap.org>
6//
7// This library is free software; you can redistribute it and/or
8// modify it under the terms of the GNU Lesser General Public
9// License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11//
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// Lesser General Public License for more details.
16//
17// You should have received a copy of the GNU Lesser General Public
18// License along with this library; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20//
21// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
22
23#include <string>
24#include <utility>
25
26#include <STARE.h>
27#include <hdf5.h>
28
29#include <libdap/BaseType.h>
30#include <libdap/dods-datatypes.h>
31
32#include <libdap/ServerFunction.h>
33
34#define STARE_STORAGE_PATH_KEY "FUNCTIONS.stareStoragePath"
35#define STARE_SIDECAR_SUFFIX_KEY "FUNCTIONS.stareSidecarSuffix"
36
37namespace libdap {
38class BaseType;
39class DDS;
40class D4RValueList;
41class DMR;
42}
43
44namespace functions {
45
46// These default values can be overridden using BES keys.
47// See DapFunctions.cc. jhrg 5/21/20
48extern string stare_storage_path;
49extern string stare_sidecar_suffix;
50
51bool target_in_dataset(const std::vector<STARE_ArrayIndexSpatialValue> &target_indices,
52 const std::vector<STARE_ArrayIndexSpatialValue> &data_stare_indices);
53
54unsigned int count(const std::vector<STARE_ArrayIndexSpatialValue> &target_indices,
55 const std::vector<STARE_ArrayIndexSpatialValue> &dataset_indices, bool all_target_matches = false);
56
71template <class T>
72void stare_subset_array_helper(vector<T> &result_data, const vector<T> &src_data,
73 const vector<STARE_ArrayIndexSpatialValue> &target_indices,
74 const vector<STARE_ArrayIndexSpatialValue> &dataset_indices)
75{
76 assert(dataset_indices.size() == src_data.size());
77 assert(dataset_indices.size() == result_data.size());
78
79 auto r = result_data.begin();
80 auto s = src_data.begin();
81 for (const auto &i : dataset_indices) {
82 for (const auto &j : target_indices) {
83 if (cmpSpatial(i, j) != 0) { // != 0 --> i is in j OR j is in i
84 *r = *s;
85 break;
86 }
87 }
88 ++r; ++s;
89 }
90}
91
109template<class T>
110void build_masked_data(libdap::Array *dependent_var,
111 const vector<STARE_ArrayIndexSpatialValue> &dep_var_stare_indices,
112 const vector<STARE_ArrayIndexSpatialValue> &target_s_indices,
113 T mask_value,
114 unique_ptr<libdap::Array> &result)
115{
116 vector<T> src_data(dependent_var->length());
117 dependent_var->read(); // TODO Do we need to call read() here? jhrg 6/16/20
118 dependent_var->value(src_data.data());
119
120 //T mask_value = 0; // TODO This should use the value in mask_val_var. jhrg 6/16/20
121 vector<T> result_data(dependent_var->length(), mask_value);
122
123 stare_subset_array_helper(result_data, src_data, target_s_indices, dep_var_stare_indices);
124
125 result->set_value(result_data, result_data.size());
126}
127
129struct stare_matches {
130 std::vector<libdap::dods_int32> row_indices;
131 std::vector<libdap::dods_int32> col_indices;
132
133 std::vector<STARE_ArrayIndexSpatialValue> stare_indices;
134 std::vector<STARE_ArrayIndexSpatialValue> target_indices;
135
136 // Pass by value and use move
137 stare_matches(std::vector<libdap::dods_int32> row, std::vector<libdap::dods_int32> col,
138 std::vector<STARE_ArrayIndexSpatialValue> si, std::vector<STARE_ArrayIndexSpatialValue> ti)
139 : row_indices(std::move(row)), col_indices(std::move(col)), stare_indices(std::move(si)),
140 target_indices(std::move(ti)) {}
141
142 stare_matches() = default;
143
144 void add(libdap::dods_int32 row, libdap::dods_int32 col, STARE_ArrayIndexSpatialValue si, STARE_ArrayIndexSpatialValue ti) {
145 row_indices.push_back(row);
146 col_indices.push_back(col);
147 stare_indices.push_back(si);
148 target_indices.push_back(ti);
149 }
150
151 friend std::ostream &operator<<(std::ostream &out, const stare_matches &m);
152};
153
154unique_ptr<stare_matches> stare_subset_helper(const std::vector<STARE_ArrayIndexSpatialValue> &target_indices,
155 const std::vector<STARE_ArrayIndexSpatialValue> &dataset_indices,
156 size_t row, size_t cols);
157
158class StareIntersectionFunction : public libdap::ServerFunction {
159public:
160 static libdap::BaseType *stare_intersection_dap4_function(libdap::D4RValueList *args, libdap::DMR &dmr);
161
162 friend class StareFunctionsTest;
163
164 StareIntersectionFunction() {
165 setName("stare_intersection");
166 setDescriptionString(
167 "The stare_intersection: Returns 1 if the coverage of the current dataset includes any of the given STARE indices, 0 otherwise.");
168 setUsageString(
169 "stare_intersection(var, STARE index [, STARE index ...]) | stare_intersection(var, $UInt64(<size hint>:STARE index [, STARE index ...]))");
170 setRole("http://services.opendap.org/dap4/server-side-function/stare_intersection");
171 setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#stare_intersection");
173 setVersion("0.3");
174 }
175
176 ~StareIntersectionFunction() override = default;
177};
178
179class StareCountFunction : public libdap::ServerFunction {
180public:
181 static libdap::BaseType *stare_count_dap4_function(libdap::D4RValueList *args, libdap::DMR &dmr);
182
183 friend class StareFunctionsTest;
184
185 StareCountFunction() {
186 setName("stare_count");
187 setDescriptionString(
188 "The stare_count: Returns the number of the STARE indices that are included in the coverage of this dataset.");
189 setUsageString(
190 "stare_count(var, STARE index [, STARE index ...]) | stare_count(var, $UInt64(<size hint>:STARE index [, STARE index ...]))");
191 setRole("http://services.opendap.org/dap4/server-side-function/stare_count");
192 setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#stare_count");
193 setFunction(stare_count_dap4_function);
194 setVersion("0.3");
195 }
196
197 ~StareCountFunction() override = default;
198};
199
200class StareSubsetFunction : public libdap::ServerFunction {
201public:
202 static libdap::BaseType *stare_subset_dap4_function(libdap::D4RValueList *args, libdap::DMR &dmr);
203
204 friend class StareFunctionsTest;
205
206 StareSubsetFunction() {
207 setName("stare_subset");
208 setDescriptionString(
209 "The stare_subset: Returns the set of the STARE indices that are included in the coverage of this dataset.");
210 setUsageString("stare_subset(var, $UInt64(<size hint>:STARE index [, STARE index ...]))");
211 setRole("http://services.opendap.org/dap4/server-side-function/stare_subset");
212 setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#stare_subset");
213 setFunction(stare_subset_dap4_function);
214 setVersion("0.3");
215 }
216
217 ~StareSubsetFunction() override = default;
218};
219
220class StareSubsetArrayFunction : public libdap::ServerFunction {
221public:
222 static libdap::BaseType *stare_subset_array_dap4_function(libdap::D4RValueList *args, libdap::DMR &dmr);
223
224 friend class StareFunctionsTest;
225
226 StareSubsetArrayFunction() {
227 setName("stare_subset_array");
228 setDescriptionString(
229 "The stare_subset: Returns a masked copy of 'var' for the subset given the set of STARE indices that are included in the coverage of this dataset.");
230 setUsageString("stare_subset_array(var, mask-val, $UInt64(<size hint>:STARE index [, STARE index ...]))");
231 setRole("http://services.opendap.org/dap4/server-side-function/stare_subset_array");
232 setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#stare_subset_array");
233 setFunction(stare_subset_array_dap4_function);
234 setVersion("0.1");
235 }
236
237 ~StareSubsetArrayFunction() override = default;
238};
239
243struct point {
244 double lat;
245 double lon;
246 point() = default;
247 point(double lat_, double lon_) : lat(lat_), lon(lon_) {}
248};
249
250STARE_SpatialIntervals stare_box_helper(const vector<point> &points, int resolution = 6);
251STARE_SpatialIntervals stare_box_helper(const point &top_left, const point &bottom_right, int resolution = 6);
252
253class StareBoxFunction : public libdap::ServerFunction {
254public:
255 static libdap::BaseType *stare_box_dap4_function(libdap::D4RValueList *args, libdap::DMR &dmr);
256
257 friend class StareFunctionsTest;
258
259 StareBoxFunction() {
260 setName("stare_box");
261 setDescriptionString(
262 "The stare_box() function: Returns a STARE cover for the region within the four lat/lon corner points.");
263 setUsageString("stare_box(tl_lat, tl_lon, br_lat, br_lon) or stare_box(p1_lat, p1_lon, ..., p4_lat, p4_lon)");
264 setRole("http://services.opendap.org/dap4/server-side-function/stare_box");
265 setDocUrl("http://docs.opendap.org/index.php/Server_Side_Processing_Functions#stare_box");
266 setFunction(stare_box_dap4_function);
267 setVersion("0.1");
268 }
269
270 ~StareBoxFunction() override = default;
271};
272
273} // functions namespace
static libdap::BaseType * stare_count_dap4_function(libdap::D4RValueList *args, libdap::DMR &dmr)
Count the number of STARE indices in the arg that overlap the indices of this dataset.
static libdap::BaseType * stare_intersection_dap4_function(libdap::D4RValueList *args, libdap::DMR &dmr)
Return true/false indicating that the given stare indices intersect the variables.
static libdap::BaseType * stare_subset_dap4_function(libdap::D4RValueList *args, libdap::DMR &dmr)
For the given target STARE indices, return the overlapping dataset X, Y, and STARE indices.
STL class.
STL class.
friend std::ostream & operator<<(std::ostream &out, const stare_matches &m)
Write a collection of STARE Matches to an ostream.