51 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
52 "<function name=\"linear_scale\" version=\"1.0b1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#linear_scale\">\n" +
59 static double string_to_double(
const char *val)
67 double v = w32strtod(val, &ptr);
69 double v = strtod(val, &ptr);
72 if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
74 throw Error(malformed_expr,
string(
"Could not convert the string '") + val +
"' to a double.");
78 istringstream iss(val);
82 double abs_val = fabs(v);
83 if (abs_val > DODS_DBL_MAX || (abs_val != 0.0 && abs_val < DODS_DBL_MIN))
84 throw Error(malformed_expr,
string(
"Could not convert the string '") + val +
"' to a double.");
98 static double get_attribute_double_value(BaseType *var, vector<string> &attributes)
102 AttrTable &attr = var->get_attr_table();
103 string attribute_value =
"";
105 vector<string>::iterator i = attributes.begin();
106 while (attribute_value ==
"" && i != attributes.end()) {
110 attribute_value = attr.get_attr(*i++);
115 if (attribute_value.empty()) {
116 if (var->type() == dods_grid_c)
117 return get_attribute_double_value(dynamic_cast<Grid&>(*var).get_array(), attributes);
119 throw Error(malformed_expr,
string(
"No COARDS/CF '") + values.substr(0, values.length() - 2)
120 +
"' attribute was found for the variable '"
121 + var->name() +
"'.");
124 return string_to_double(remove_quotes(attribute_value).c_str());
127 static double get_attribute_double_value(BaseType *var,
const string &attribute)
129 AttrTable &attr = var->get_attr_table();
130 string attribute_value = attr.get_attr(attribute);
134 if (attribute_value.empty()) {
135 if (var->type() == dods_grid_c)
136 return get_attribute_double_value(dynamic_cast<Grid&>(*var).get_array(), attribute);
138 throw Error(malformed_expr,
string(
"No COARDS '") + attribute
139 +
"' attribute was found for the variable '"
140 + var->name() +
"'.");
143 return string_to_double(remove_quotes(attribute_value).c_str());
146 static double get_y_intercept(BaseType *var)
148 vector<string> attributes;
149 attributes.push_back(
"add_offset");
150 attributes.push_back(
"add_off");
151 return get_attribute_double_value(var, attributes);
154 static double get_slope(BaseType *var)
156 return get_attribute_double_value(var,
"scale_factor");
159 static double get_missing_value(BaseType *var)
161 return get_attribute_double_value(var,
"missing_value");
171 if (bt->type() == dods_grid_c) {
173 Grid &source =
dynamic_cast<Grid&
>(*bt);
175 BESDEBUG(
"function",
"function_linear_scale_worker() - Grid send_p: " << source.send_p() << endl);
176 BESDEBUG(
"function",
"function_linear_scale_worker() - Grid Array send_p: " << source.get_array()->send_p() << endl);
181 source.set_send_p(
true);
185 Array *a = source.get_array();
187 data = extract_double_array(a);
190 int length = a->length();
191 for (
int i = 0; i < length; ++i)
192 data[i] = data[i] * m + b;
197 Grid *result =
new Grid(source);
201 result->get_array()->add_var_nocopy(
new Float64(source.name()));
202 result->get_array()->set_value(data, length);
206 BESDEBUG(
"function",
"function_linear_scale_worker() - Grid send_p: " << source.send_p() << endl);
207 BESDEBUG(
"function",
"function_linear_scale_worker() - Grid Array send_p: " << source.get_array()->send_p() << endl);
211 else if (bt->is_vector_type()) {
212 Array &source =
dynamic_cast<Array&
>(*bt);
215 if (source.get_parent() && source.get_parent()->type() == dods_grid_c) {
216 source.get_parent()->set_send_p(
true);
217 source.get_parent()->read();
222 data = extract_double_array(&source);
223 int length = source.length();
224 for (
int i = 0; i < length; ++i)
225 data[i] = data[i] * m + b;
227 Array *result =
new Array(source);
229 result->add_var_nocopy(
new Float64(source.name()));
230 result->set_value(data, length);
236 else if (bt->is_simple_type() && !(bt->type() == dods_str_c || bt->type() == dods_url_c)) {
237 double data = extract_double_value(bt);
238 if (!use_missing || !double_eq(data, missing))
243 fdest->set_value(data);
247 throw Error(malformed_expr,
"The linear_scale() function works only for numeric Grids, Arrays and scalars.");
273 Str *response =
new Str(
"info");
274 response->set_value(linear_scale_info);
280 DBG(cerr <<
"argc = " << argc << endl);
281 if (!(argc == 1 || argc == 3 || argc == 4))
282 throw Error(malformed_expr,
"Wrong number of arguments to linear_scale(). See linear_scale() for more information");
285 bool use_missing =
false;
286 double m, b, missing = 0.0;
288 m = extract_double_value(argv[1]);
289 b = extract_double_value(argv[2]);
290 missing = extract_double_value(argv[3]);
292 }
else if (argc == 3) {
293 m = extract_double_value(argv[1]);
294 b = extract_double_value(argv[2]);
297 m = get_slope(argv[0]);
303 b = get_y_intercept(argv[0]);
313 missing = get_missing_value(argv[0]);
321 BESDEBUG(
"function",
"function_dap2_linear_scale() - m: " << m <<
", b: " << b <<
", use_missing: " << use_missing <<
", missing: " << missing << endl);
339 BESDEBUG(
"function",
"function_dap4_linear_scale() BEGIN " << endl);
342 if (args==0 || args->size() == 0) {
343 Str *response =
new Str(
"info");
344 response->set_value(linear_scale_info);
351 DBG(cerr <<
"args.size() = " << args.size() << endl);
352 if (!(args->size() == 1 || args->size() == 3 || args->size() == 4))
353 throw Error(malformed_expr,
"Wrong number of arguments to linear_scale(). See linear_scale() for more information");
356 bool use_missing =
false;
357 double m, b, missing = 0.0;
358 if (args->size() == 4) {
359 m = extract_double_value(args->get_rvalue(1)->value(dmr));
360 b = extract_double_value(args->get_rvalue(2)->value(dmr));
361 missing = extract_double_value(args->get_rvalue(3)->value(dmr));
363 }
else if (args->size() == 3) {
364 m = extract_double_value(args->get_rvalue(1)->value(dmr));
365 b = extract_double_value(args->get_rvalue(2)->value(dmr));
368 m = get_slope(args->get_rvalue(0)->value(dmr));
374 b = get_y_intercept(args->get_rvalue(0)->value(dmr));
384 missing = get_missing_value(args->get_rvalue(0)->value(dmr));
391 BESDEBUG(
"function",
"function_dap4_linear_scale() - m: " << m <<
", b: " << b <<
", use_missing: " << use_missing <<
", missing: " << missing << endl);
393 BESDEBUG(
"function",
"function_dap4_linear_scale() END " << endl);
BaseType * function_dap4_linear_scale(D4RValueList *args, DMR &dmr)
Given a BaseType, scale it using 'y = mx + b'.
BaseType * function_linear_scale_worker(BaseType *bt, double m, double b, double missing, bool use_missing)
static class NCMLUtil overview
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
void function_dap2_linear_scale(int argc, BaseType *argv[], DDS &, BaseType **btpp)
Given a BaseType, scale it using 'y = mx + b'.