35#include <libdap/Type.h>
36#include <libdap/BaseType.h>
37#include <libdap/Byte.h>
38#include <libdap/Str.h>
40#include <libdap/Array.h>
41#include <libdap/Error.h>
42#include <libdap/DDS.h>
46#include <libdap/DMR.h>
47#include <libdap/D4Group.h>
48#include <libdap/D4RValue.h>
51#include <libdap/debug.h>
52#include <libdap/util.h>
56#include "MakeMaskFunction.h"
58#include "functions_util.h"
65vector<int> parse_dims(
const string &shape);
67string make_mask_info =
68 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
69 +
"<function name=\"make_array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#make_mask\">\n"
80find_value_index(
double value,
const vector<double> &map)
85 for (vector<double>::const_iterator i = map.begin(), e = map.end(); i != e; ++i) {
86 if (double_eq(*i, value, 0.1)) {
87 return i - map.begin();
106find_value_indices(
const vector<double> &values,
const vector< vector<double> > &maps)
108 assert(values.size() == maps.size());
111 vector <vector<double> >::const_iterator m = maps.begin();
112 for (vector<double>::const_iterator d = values.begin(), e = values.end(); d != e; ++d) {
113 indices.push_back(find_value_index(*d, *m++));
124bool all_indices_valid(vector<int> indices)
126 return find(indices.begin(), indices.end(), -1) == indices.end();
143void make_mask_helper(
const vector<Array*> dims, Array *tuples, vector<dods_byte> &mask)
145 vector< vector<double> > dim_value_vecs(dims.size());
147 for (vector<Array*>::const_iterator d = dims.begin(), e = dims.end(); d != e; ++d) {
150 extract_double_array(*d, dim_value_vecs.at(i++));
154 Odometer::shape shape(dims.size());
157 for (vector<Array*>::const_iterator d = dims.begin(), e = dims.end(); d != e; ++d) {
158 shape[j++] = (*d)->length();
164 vector<T> data(tuples->length());
165 tuples->value(data.data());
168 int nDims = dims.size();
169 int nTuples = data.size() / nDims;
174 for (
int n = 0; n < nTuples; ++n) {
175 vector<double> tuple(nDims);
177 for (
int dim = 0; dim < nDims; ++dim) {
179 tuple[dim] = data[n * nDims + dim];
182 DBG(cerr <<
"tuple: ");
183 DBGN(copy(tuple.begin(), tuple.end(), ostream_iterator<int>(std::cerr,
" ")));
188 vector<int> indices = find_value_indices(tuple, dim_value_vecs);
189 DBG(cerr <<
"indices: ");
190 DBGN(copy(indices.begin(), indices.end(), ostream_iterator<int>(std::cerr,
" ")));
194 if (all_indices_valid(indices)) {
200 odometer.set_indices(indices);
201 DBG(cerr <<
"odometer.offset(): " << odometer.offset() << endl);
202 mask[odometer.offset()] = 1;
216void function_dap2_make_mask(
int argc, BaseType * argv[], DDS &, BaseType **btpp)
219 Str *response =
new Str(
"info");
220 response->set_value(make_mask_info);
226 DBG(cerr <<
"argc = " << argc << endl);
228 throw Error(malformed_expr,
229 "make_mask(shape_string,[dim1,...],$TYPE(dim1_value0,dim2_value0,...)) requires at least four arguments.");
231 if (argv[0]->type() != dods_str_c)
232 throw Error(malformed_expr,
"make_mask(): first argument must point to a string variable.");
234 string shape_str = extract_string_argument(argv[0]);
235 vector<int> shape = parse_dims(shape_str);
239 for (vector<int>::iterator i = shape.begin(), e = shape.end(); i != e; ++i)
241 vector<dods_byte> mask(length, 0);
242 unsigned int nDims = shape.size();
247 assert(nDims == (
unsigned int)argc-2);
250 for (
unsigned int i = 0; i < nDims; i++) {
252 BaseType *btp = argv[1 + i];
253 if (btp->type() != dods_array_c) {
254 throw Error(malformed_expr,
255 "make_mask(): dimension-name arguments must point to Grid variable dimensions.");
258 Array *a =
static_cast<Array*
>(btp);
263 assert(a->dimension_size(a->dim_begin()) == shape.at(i));
270 BaseType *btp = argv[argc - 1];
271 if (btp->type() != dods_array_c) {
272 throw Error(malformed_expr,
"make_mask(): last argument must be an array.");
275 check_number_type_array(btp);
277 Array *tuples =
static_cast<Array*
>(btp);
279 switch (tuples->var()->type()) {
283 make_mask_helper<dods_byte>(dims, tuples, mask);
287 make_mask_helper<dods_int16>(dims, tuples, mask);
291 make_mask_helper<dods_uint16>(dims, tuples, mask);
295 make_mask_helper<dods_int32>(dims, tuples, mask);
299 make_mask_helper<dods_uint32>(dims, tuples, mask);
303 make_mask_helper<dods_float32>(dims, tuples, mask);
307 make_mask_helper<dods_float64>(dims, tuples, mask);
313 throw InternalErr(__FILE__, __LINE__,
314 "make_mask(): Expect an array of mask points (numbers) but found something else instead.");
317 Array *dest =
new Array(
"mask", 0);
319 dest->add_var_nocopy(
new Byte(
"mask"));
321 for (vector<int>::iterator i = shape.begin(), e = shape.end(); i != e; ++i)
322 dest->append_dim(*i);
324 dest->set_value(mask, length);
326 dest->set_read_p(
true);