/** * @file RadxAppSweeData.cc */ #include #include #include #include #include #include #include #include const std::string RadxAppSweepData::_variance2dStr = "Variance2d"; //------------------------------------------------------------------ RadxAppSweepData::RadxAppSweepData(void) : MathData(), _rays(NULL), _lookup(NULL) { } //------------------------------------------------------------------ RadxAppSweepData::RadxAppSweepData(const RadxAppVolume &r, int index, const RadxAppCircularLookupHandler *lookup) : MathData(), _rays(r._rays), _lookup(lookup) { const vector sweeps = r._vol.getSweeps(); _i0 = sweeps[index]->getStartRayIndex(); _i1 = sweeps[index]->getEndRayIndex(); } //------------------------------------------------------------------ RadxAppSweepData::~RadxAppSweepData(void) { // nothing owned by this class } //------------------------------------------------------------------ std::vector RadxAppSweepData::userUnaryOperators(void) const { std::vector ret; ret.push_back(FunctionDef(_variance2dStr, "v", "field", "2d Variance of input field, " " uses variance_radius_km parameter")); radxappAppendUnaryOperators(ret); return ret; } //------------------------------------------------------------------ // virtual int RadxAppSweepData::numData(void) const { if (_outputSweep == NULL) { LOG(ERROR) << " No sweep to look at"; return 0; } return _outputSweep->numData(); } //------------------------------------------------------------------ // virtual void RadxAppSweepData::finishProcessingNode(int index, VolumeData *vol) { // add all the derived data to this sweep _updateSweep(); // clear out derived data _data.clear(); } //------------------------------------------------------------------ // virtual bool RadxAppSweepData::synchInputsAndOutputs(const std::string &output, const std::vector &inputs) { // look for input data and return false if one or more missing RadxAppSweepLoopData *m=NULL; for (size_t i=0; i &names) { // if (!_needToSynch(userKey)) // { // return true; // } // for (size_t i=0; i &args) const { LOG(ERROR) << "Not implemented"; return false; } // virtual //------------------------------------------------------------------ bool RadxAppSweepData::smoothDBZ(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } //------------------------------------------------------------------ // virtual bool RadxAppSweepData::stddev(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } //------------------------------------------------------------------ // virtual bool RadxAppSweepData::fuzzy(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } //------------------------------------------------------------------ // virtual bool RadxAppSweepData::average(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } //------------------------------------------------------------------ // virtual bool RadxAppSweepData::max_expand(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } //------------------------------------------------------------------ // virtual bool RadxAppSweepData::weighted_average(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::mask(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::median(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::weighted_angle_average(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::expand_angles_laterally(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::clump(MathLoopData *l, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::mask_missing_to_missing(MathLoopData *out, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::trapezoid(MathLoopData *out, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::s_remap(MathLoopData *out, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } bool RadxAppSweepData::max(MathLoopData *out, std::vector &args) const { LOG(ERROR) << "Not implemented"; return false; } //------------------------------------------------------------------ RadxAppSweepLoopData *RadxAppSweepData::_refToData(const std::string &name, bool suppressWarn) { // try to pull out of existing data for (size_t i=0; i<_data.size(); ++i) { if (name == _data[i].getName()) { return &_data[i]; } } // try to pull out of input data RadxAppSweepLoopData r; if (_newLoopData(name, r, !suppressWarn)) { _data.push_back(r); size_t k = _data.size(); return &(_data[k-1]); } // can't pull out of state, not in input data and not in _data if (!suppressWarn) { printf("ERROR retrieving data for %s\n", name.c_str()); } return NULL; } //------------------------------------------------------------------ RadxAppSweepLoopData *RadxAppSweepData::_exampleData(const std::string &name) { RadxAppSweepLoopData *s = _refToData(name, true); if (s == NULL) { RadxAppSweepLoopData r; if (_anyLoopData(r)) { r.modifyForOutput(name, "units"); _data.push_back(r); s = _refToData(name, true); } } if (s != NULL) { return s; } else { LOG(ERROR) << "No data created for " << name; return NULL; } } //------------------------------------------------------------------ bool RadxAppSweepData::_processVariance2d(std::vector &args) { if (_lookup == NULL) { LOG(ERROR) << "No lookup, cannot compute variance"; return false; } const MathLoopData *data = loadData(args, 0); if (data == NULL) { LOG(ERROR) << "Wrong interface"; return false; } const RadxAppSweepLoopData * rdata = dynamic_cast(data); // the output should already be in place, so just go for it return _outputSweep->variance2d(*rdata, *_lookup); } //------------------------------------------------------------------ RadxAppSweepLoopData *RadxAppSweepData::_match(const std::string &n) { // try to pull out of existing rays in data for (size_t i=0; i<_data.size(); ++i) { if (n == _data[i].getName()) { return &_data[i]; } } return NULL; } //------------------------------------------------------------------ const RadxAppSweepLoopData * RadxAppSweepData::_matchConst(const std::string &n) const { // try to pull out of existing rays in data for (size_t i=0; i<_data.size(); ++i) { if (n == _data[i].getName()) { return &_data[i]; } } return NULL; } // //------------------------------------------------------------------ // bool RadxAppSweepData ::_needToSynch(const std::string &userKey) const // { // if (userKey == _variance2dStr) // { // // this loop filter has inputs // return true; // } // // everything else has inputs // return true; // } //--------------------------------------------------------------- void RadxAppSweepData::_updateSweep(void) { // take all the local data and add to the sweep. // note that here should make sure not deleting a result (check names) if (_data.empty()) { return; } for (size_t k=0; k<_data.size(); ++k) { _updateSweepOneDataset(k); } } //------------------------------------------------------------------ void RadxAppSweepData::_updateSweepOneDataset(int k) { // get the name of the 0th data, and number of gates, which can change string name = _data[k].getName(); int nGatesPrimary = _data[k].getNGates(); Radx::fl32 *data = new Radx::fl32[nGatesPrimary]; int j=0; for (int i=_i0; i<=_i1; ++i) { _data[k].retrieveRayData(j, data, nGatesPrimary); (*_rays)[i]->addField(name, _data[k].getUnits(), _data[k].getNpoints(j), _data[k].getMissing(), data, true); j++; } delete [] data; } //------------------------------------------------------------------ bool RadxAppSweepData::_newLoopData(const std::string &name, RadxAppSweepLoopData &ret, bool warn) const { vector rays; for (int i=_i0; i<=_i1; ++i) { RayxData r; if (RadxApp::retrieveRay(name, *(*_rays)[i], r, false)) { rays.push_back(r); } else { if (warn) LOG(ERROR) << "No data for " << name; return false; } } ret = RadxAppSweepLoopData(name, _i0, _i1, rays); return true; } //------------------------------------------------------------------ bool RadxAppSweepData::_anyLoopData(RadxAppSweepLoopData &ret) const { RayxData r; string name; if (RadxApp::retrieveAnyRay(*(*_rays)[_i0], r)) { name = r.getName(); return _newLoopData(name, ret, true); } else { LOG(ERROR) << "No data"; return false; } }