/** * @file MultiTileThresholds.cc */ //------------------------------------------------------------------ #include #include #include #include #include #include #include #include const std::string MultiTileThresholds::_tag = "Lt"; //------------------------------------------------------------------ MultiTileThresholds::MultiTileThresholds(void) : _ok(false) { } //------------------------------------------------------------------ MultiTileThresholds:: MultiTileThresholds(const std::string &xml, const std::vector &fields, const TileInfo &tiling) : _ok(true) { // read in tiles array, and compare to input. vector vstring; if (TaXml::readStringArray(xml, SingleTileThresholds::_tag, vstring)) { LOG(ERROR) << "Reading tag as array " << SingleTileThresholds::_tag; _ok = false; return; } if (static_cast(vstring.size()) != tiling.numTiles()) { LOG(ERROR) << "Inconsistent tiling " << "input:" << tiling.numTiles() << " xml:" << vstring.size(); _ok = false; return; } // for every element, // parse it as a SingleTileThresholds object. for (size_t i=0; i &fieldThresh) { for (int i=0; i::const_iterator i; for (i=_map.begin(); i!=_map.end(); ++i) { if (i->first == tileInd) { return &(i->second); } } return NULL; } //------------------------------------------------------------------ std::string MultiTileThresholds::toXml(int indent) const { string s = TaXml::writeStartTag(_tag, indent); std::map::const_iterator i; for (i=_map.begin(); i!=_map.end(); ++i) { s += i->second.toXml(i->first); } s += TaXml::writeEndTag(_tag, indent); return s; } //------------------------------------------------------------------ bool MultiTileThresholds:: checkColdstart(const time_t &t, int maxSecondsBeforeColdstart, const std::vector &coldstartThresh) { bool ret = true; std::map::iterator i; for (i = _map.begin(); i!= _map.end(); ++i) { if (!i->second.checkColdstart(t, maxSecondsBeforeColdstart, coldstartThresh)) { ret = false; } } return ret; } //------------------------------------------------------------------ bool MultiTileThresholds::update(const TileThreshInfo &item) { SingleTileThresholds *m = _mapFromTile(item.getTileIndex()); if (m == NULL) { LOG(ERROR) << "Tile index out of range " << item.getTileIndex(); return false; } return m->update(item); } //------------------------------------------------------------------ bool MultiTileThresholds::filterFields(const std::vector &fieldNames) { std::map::iterator i; for (i=_map.begin(); i!=_map.end(); ++i) { if (!i->second.filterFields(fieldNames)) { LOG(ERROR) << "Filtering fields for tile index " << i->first; return false; } } return true; } //------------------------------------------------------------------ bool MultiTileThresholds::replaceValues(const MultiTileThresholds &filtMap, const std::vector &filterFields) { if (_map.size() != filtMap._map.size()) { LOG(ERROR) << "Inconsistent number of tiles"; return false; } const SingleTileThresholds *inp; SingleTileThresholds *loc; // assumes tiles are indexed 0,1,... bool ret = true; for (int i=0; i(_map.size()); ++i) { inp = filtMap._constMapFromTile(i); loc = _mapFromTile(i); if (inp == NULL || loc == NULL) { LOG(ERROR) << "No tile at index " << i; ret = false; } else { loc->replaceValues(*inp, filterFields); } } return ret; } //------------------------------------------------------------------ void MultiTileThresholds::print(int leadTime, const TileInfo &info, bool verbose) const { std::map::const_iterator i; for (i=_map.begin(); i!=_map.end(); ++i) { i->second.print(leadTime, i->first, info, verbose); } } //------------------------------------------------------------------ void MultiTileThresholds::print(int leadTime, const std::vector &tiles, const TileInfo &info, bool verbose) const { if (tiles.empty()) { print(leadTime, info, verbose); } else { std::map::const_iterator i; for (i=_map.begin(); i!=_map.end(); ++i) { if (find(tiles.begin(), tiles.end(), i->first) != tiles.end()) { i->second.print(leadTime, i->first, info, verbose); } } } } //------------------------------------------------------------------ bool MultiTileThresholds::getDebugTiledGrids(const TileInfo &tiling, const std::string &field, double centerWeight, double edgeWeight, int nptSmooth, std::vector &item) const { const SingleTileThresholds *mt = _constMapFromTile(0); if (mt == NULL) { LOG(ERROR) << "No content, no grid"; return false; } int fieldIndex = mt->getThresholdIndex(field); if (fieldIndex < 0) { LOG(ERROR) << " Field not found " << field; return false; } // now construct non-overlapping return grids vector v = _tileThresh(fieldIndex, tiling.numTiles()); if (v.empty()) { return false; } Grid2d grid; if (!tiling.constructTiledGridNoOverlap("Thresh", v, grid)) { return false; } item.push_back(grid); if (!tiling.constructWeightedTiledGrid("WtThresh", v, centerWeight, edgeWeight, nptSmooth, grid)) { return false; } item.push_back(grid); v = _tileBias(tiling.numTiles()); if (!tiling.constructTiledGridNoOverlap("Bias", v, grid)) { return false; } item.push_back(grid); v = _tileObs(tiling.numTiles()); if (!tiling.constructTiledGridNoOverlap("Obs", v, grid)) { return false; } item.push_back(grid); v = _tileFcst(tiling.numTiles()); if (!tiling.constructTiledGridNoOverlap("Fcst", v, grid)) { return false; } item.push_back(grid); v = _tileIsMother(tiling.numTiles()); if (!tiling.constructTiledGridNoOverlap("Mother", v, grid)) { return false; } item.push_back(grid); return true; } //------------------------------------------------------------------ bool MultiTileThresholds::getTiledGrids(const TileInfo &tiling, double centerWeight, double edgeWeight, int nptSmooth, std::vector &item) const { item.clear(); // assume naming same for all tiles const SingleTileThresholds *mt = _constMapFromTile(0); if (mt == NULL) { LOG(ERROR) << "No content, no grid"; return false; } bool status = true; for (int i=0; inum(); ++i) { string name; if (mt->getIthName(i, name)) { Grid2d grid; if (constructTiledGrid(name, tiling, centerWeight, edgeWeight, nptSmooth, grid)) { item.push_back(grid); } else { LOG(ERROR) << "Could not construct grid"; status = false; } } else { LOG(ERROR) << "Name indexing error"; status = false; } } return status; } //------------------------------------------------------------------ bool MultiTileThresholds::constructTiledGrid(const std::string &fieldName, const TileInfo &tiling, double centerWeight, double edgeWeight, int nptSmooth, Grid2d &grid) const { // assume naming same for all tiles const SingleTileThresholds *mt = _constMapFromTile(0); if (mt == NULL) { LOG(ERROR) << "No content, no grid"; return false; } int fieldIndex = mt->getThresholdIndex(fieldName); if (fieldIndex < 0) { LOG(ERROR) << " Field not found " << fieldName; return false; } vector tileThresh = _tileThresh(fieldIndex, tiling.numTiles()); if (tileThresh.empty()) { return false; } return tiling.constructWeightedTiledGrid(fieldName, tileThresh, centerWeight, edgeWeight, nptSmooth, grid); } //------------------------------------------------------------------ std::vector MultiTileThresholds::getMotherStatus(void) const { vector ret; std::map::const_iterator i; for (i=_map.begin(); i!=_map.end(); ++i) { ret.push_back(i->second.getMotherStatus()); } return ret; } //------------------------------------------------------------------ SingleTileThresholds *MultiTileThresholds::_mapFromTile(int tileIndex) { std::map::iterator i; for (i=_map.begin(); i!=_map.end(); ++i) { if (i->first == tileIndex) { return &(i->second); } } return NULL; } //------------------------------------------------------------------ const SingleTileThresholds * MultiTileThresholds::_constMapFromTile(int tileIndex) const { std::map::const_iterator i; for (i=_map.begin(); i!=_map.end(); ++i) { if (i->first == tileIndex) { return &(i->second); } } return NULL; } //------------------------------------------------------------------ std::vector MultiTileThresholds::_tileThresh(int fieldIndex, int numTiles) const { vector ret; for (int tileIndex=0; tileIndexgetIthThreshold(fieldIndex, threshold)) { LOG(ERROR) << "Tiling mismatch no field " << fieldIndex; ret.clear(); return ret; } ret.push_back(threshold); } return ret; } //------------------------------------------------------------------ std::vector MultiTileThresholds::_tileBias(int numTiles) const { vector ret; for (int tileIndex=0; tileIndexgetBias()); } return ret; } //------------------------------------------------------------------ std::vector MultiTileThresholds::_tileObs(int numTiles) const { vector ret; for (int tileIndex=0; tileIndexgetObs()); } return ret; } //------------------------------------------------------------------ std::vector MultiTileThresholds::_tileFcst(int numTiles) const { vector ret; for (int tileIndex=0; tileIndexgetFcst()); } return ret; } //------------------------------------------------------------------ std::vector MultiTileThresholds::_tileIsMother(int numTiles) const { vector ret; for (int tileIndex=0; tileIndexgetIsMother(1, 0)); } return ret; }