15 #include "ioda/ObsVector.h"
17 #include "oops/base/Variables.h"
18 #include "oops/util/IntSetParser.h"
19 #include "oops/util/Logger.h"
22 #include "ufo/ObsDiagnostics.h"
29 : predbases_(0), jobs_(0), odb_(odb), conf_(
conf) {
30 oops::Log::trace() <<
"ObsBias::create starting." << std::endl;
33 if (
conf_.has(
"obs bias.jobs")) {
34 const std::set<int> jobs = oops::parseIntSet(
conf_.getString(
"obs bias.jobs"));
35 jobs_.assign(jobs.begin(), jobs.end());
39 if (
conf_.has(
"obs bias.predictors")) {
40 std::vector<eckit::LocalConfiguration> confs;
41 conf_.get(
"obs bias.predictors", confs);
42 for (std::size_t j = 0; j < confs.size(); ++j) {
47 hdiags_ += pred->requiredHdiagnostics();
50 if (
jobs_.size() > 0) {
51 for (
auto & job :
jobs_) {
69 oops::Log::trace() <<
"ObsBias::create done." << std::endl;
75 : odb_(other.odb_), conf_(other.conf_), predbases_(other.predbases_),
76 prednames_(other.prednames_), jobs_(other.jobs_),
77 geovars_(other.geovars_), hdiags_(other.hdiags_) {
78 oops::Log::trace() <<
"ObsBias::copy ctor starting." << std::endl;
87 oops::Log::trace() <<
"ObsBias::copy ctor done." << std::endl;
93 for (std::size_t jj = 0; jj <
biascoeffs_.size(); ++jj)
101 if (rhs.
size() > 0 && this->size() == rhs.
size()) {
116 oops::Log::trace() <<
"ObsBias::read and initialize from file, starting "<< std::endl;
119 std::string input_filename;
120 if (
conf.has(
"obs bias.abias_in")) {
121 input_filename =
conf.getString(
"obs bias.abias_in");
123 << input_filename << std::endl;
127 const std::vector<std::string> gsi_predictors = {
"constant",
129 "cloud_liquid_water",
130 "lapse_rate_order_2",
132 "cosine_of_latitude_times_orbit_node",
135 "scan_angle_order_4",
136 "scan_angle_order_3",
137 "scan_angle_order_2",
140 std::ifstream infile(input_filename);
143 std::string sensor =
conf.getString(
"obs bias.sensor");
145 << sensor << std::endl;
151 std::size_t ntlapupdate;
153 if (infile.is_open())
157 while (infile >> ich)
163 infile >> ntlapupdate;
164 if (nusis == sensor) {
165 auto ijob = std::find(
jobs_.begin(),
jobs_.end(), nuchan);
166 if (ijob !=
jobs_.end()) {
169 for (
auto & item : gsi_predictors) {
178 for (
auto & item : gsi_predictors)
182 for (
auto & item : gsi_predictors)
187 oops::Log::debug() <<
"ObsBias:: read prior from " << input_filename << std::endl;
189 oops::Log::error() <<
"Unable to open file : " << input_filename << std::endl;
190 ABORT(
"Unable to open bias prior file ");
193 oops::Log::warning() <<
"ObsBias::prior file is NOT available, starting from ZERO"
197 oops::Log::trace() <<
"ObsBias::read and initilization done " << std::endl;
203 oops::Log::trace() <<
"ObsBias::write to file not implemented" << std::endl;
206 std::string output_filename;
207 if (
conf.has(
"ObsBias.abias_out")) {
208 output_filename =
conf.getString(
"ObsBias.abias_out");
211 oops::Log::trace() <<
"ObsBias::write to file done" << std::endl;
218 const std::vector<ioda::ObsVector> & predData)
const {
219 oops::Log::trace() <<
"ObsBias::computeObsBias starting" << std::endl;
221 if (this->
size() > 0) {
222 const std::size_t nlocs = ybias.nlocs();
224 const std::size_t njobs =
jobs_.size();
227 ASSERT(predData.size() == npreds);
228 ASSERT(ybias.nvars() == njobs);
264 Eigen::Map<const Eigen::MatrixXd> coeffs(
biascoeffs_.data(), npreds, njobs);
266 std::vector<double> biasTerm(nlocs, 0.0);
268 for (std::size_t jch = 0; jch < njobs; ++jch) {
269 for (std::size_t jp = 0; jp < npreds; ++jp) {
271 const double beta = coeffs(jp, jch);
272 for (std::size_t jl = 0; jl < nlocs; ++jl) {
273 biasTerm[jl] = predData[jp][jl*njobs+jch] * beta;
274 ybias[jl*njobs+jch] += biasTerm[jl];
277 const std::string varname =
predbases_[jp]->name() +
"_" + std::to_string(
jobs_[jch]);
278 if (ydiags.
has(varname)) {
279 ydiags.
save(biasTerm, varname, 1);
281 oops::Log::error() << varname <<
" is not reserved in ydiags !" << std::endl;
282 ABORT(
"ObsBiasTerm variable is not reserved in ydiags");
288 oops::Log::trace() <<
"ObsBias::computeObsBias done." << std::endl;
296 std::vector<ioda::ObsVector> predData(npreds, ioda::ObsVector(
odb_));
298 for (std::size_t p = 0; p < npreds; ++p) {
300 predData[p].save(
predbases_[p]->name() +
"Predictor");
303 oops::Log::trace() <<
"ObsBias::computePredictors done." << std::endl;
310 oops::Log::trace() <<
"ObsBias::norm starting." << std::endl;
312 for (std::size_t jj = 0; jj <
biascoeffs_.size(); ++jj) {
316 oops::Log::trace() <<
"ObsBias::norm done." << std::endl;
323 if (this->
size() > 0) {
325 Eigen::Map<const Eigen::MatrixXd>
328 os <<
"ObsBias::print " << std::endl;
329 os <<
"---------------------------------------------------------------" << std::endl;
330 auto njobs =
jobs_.size();
331 for (std::size_t p = 0; p <
prednames_.size(); ++p) {
332 os << std::fixed << std::setw(20) <<
prednames_[p]
333 <<
": Min= " << std::setw(15) << std::setprecision(8)
334 << coeffs.row(p).minCoeff()
335 <<
", Max= " << std::setw(15) << std::setprecision(8)
336 << coeffs.row(p).maxCoeff()
337 <<
", Norm= " << std::setw(15) << std::setprecision(8)
338 << coeffs.row(p).norm()
341 os <<
"---------------------------------------------------------------" << std::endl;
342 os <<
"ObsBias::print done" << std::endl;