UFO
ObsErrorBoundIR.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2019 UCAR
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  */
7 
9 
10 #include <algorithm>
11 #include <cmath>
12 #include <iomanip>
13 #include <iostream>
14 #include <set>
15 #include <string>
16 #include <vector>
17 
18 #include "ioda/ObsDataVector.h"
19 #include "oops/util/IntSetParser.h"
20 #include "oops/util/missingValues.h"
23 #include "ufo/filters/Variable.h"
24 #include "ufo/utils/Constants.h"
25 
26 namespace ufo {
27 
29 
30 // -----------------------------------------------------------------------------
31 
32 ObsErrorBoundIR::ObsErrorBoundIR(const eckit::LocalConfiguration & conf)
33  : invars_() {
34  // Check options
35  options_.deserialize(conf);
36 
37  // Get channels from options
38  std::set<int> channelset = oops::parseIntSet(options_.channelList);
39  std::copy(channelset.begin(), channelset.end(), std::back_inserter(channels_));
40  ASSERT(channels_.size() > 0);
41 
42  const Variable &obserrlat = options_.obserrBoundLat.value();
43  invars_ += obserrlat;
44 
45  const Variable &obserrtaotop = options_.obserrBoundTransmittop.value();
46 
47  invars_ += obserrtaotop;
48 
49  // Get test groups from options
50  const std::string &errgrp = options_.testObserr.value();
51  const std::string &flaggrp = options_.testQCflag.value();
52 
53  // Include list of required data from ObsSpace
54  invars_ += Variable("brightness_temperature@"+flaggrp, channels_);
55  invars_ += Variable("brightness_temperature@"+errgrp, channels_);
56  invars_ += Variable("brightness_temperature@ObsError", channels_);
57 }
58 
59 // -----------------------------------------------------------------------------
60 
62 
63 // -----------------------------------------------------------------------------
64 
66  ioda::ObsDataVector<float> & out) const {
67  // Get observation error bounds from options
68  const std::vector<float> &obserr_bound_max = options_.obserrBoundMax.value();
69  // Get dimensions
70  size_t nlocs = in.nlocs();
71  size_t nchans = channels_.size();
72 
73  // Get error factor from ObsFunction
74  const Variable &obserrlat = options_.obserrBoundLat.value();
75  ioda::ObsDataVector<float> errflat(in.obsspace(), obserrlat.toOopsVariables());
76  in.get(obserrlat, errflat);
77 
78  // Get error factor from ObsFunction
79  const Variable &obserrtaotop = options_.obserrBoundTransmittop.value();
80  ioda::ObsDataVector<float> errftaotop(in.obsspace(), obserrtaotop.toOopsVariables());
81  in.get(obserrtaotop, errftaotop);
82 
83  // Output integrated error bound for gross check
84  std::vector<float> obserr(nlocs); //!< original obs error
85  std::vector<float> obserrdata(nlocs); //!< effective obs err
86  std::vector<int> qcflagdata(nlocs); //!< effective qcflag
87  const std::string &errgrp = options_.testObserr.value();
88  const std::string &flaggrp = options_.testQCflag.value();
89  const float missing = util::missingValue(missing);
90  float varinv = 0.0;
91  for (size_t ichan = 0; ichan < nchans; ++ichan) {
92  in.get(Variable("brightness_temperature@"+flaggrp, channels_)[ichan], qcflagdata);
93  in.get(Variable("brightness_temperature@"+errgrp, channels_)[ichan], obserrdata);
94  in.get(Variable("brightness_temperature@ObsError", channels_)[ichan], obserr);
95  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
96  if (flaggrp == "PreQC") obserrdata[iloc] == missing ? qcflagdata[iloc] = 100
97  : qcflagdata[iloc] = 0;
98  (qcflagdata[iloc] == 0) ? (varinv = 1.0 / pow(obserrdata[iloc], 2)) : (varinv = 0.0);
99  out[ichan][iloc] = obserr[iloc];
100  if (varinv > 0.0) {
101  out[ichan][iloc] = std::fmin(3.0 * obserr[iloc]
102  * (1.0 / pow(errflat[0][iloc], 2))
103  * (1.0 / pow(errftaotop[ichan][iloc], 2)), obserr_bound_max[ichan]);
104  }
105  }
106  }
107 }
108 
109 // -----------------------------------------------------------------------------
110 
112  return invars_;
113 }
114 
115 // -----------------------------------------------------------------------------
116 
117 } // namespace ufo
ObsErrorBoundIRParameters options_
const ufo::Variables & requiredVariables() const
geovals required to compute the function
ObsErrorBoundIR(const eckit::LocalConfiguration &)
std::vector< int > channels_
ufo::Variables invars_
void compute(const ObsFilterData &, ioda::ObsDataVector< float > &) const
compute the result of the function
oops::RequiredParameter< Variable > obserrBoundLat
Function used to set the observation bound based on Latitude (ObsErrorFactorLatRad)
oops::RequiredParameter< std::string > channelList
List of channels available for assimilation.
oops::Parameter< std::string > testQCflag
Name of the data group to which the QC flag is applied (default is QCflagsData)
oops::RequiredParameter< Variable > obserrBoundTransmittop
oops::RequiredParameter< std::vector< float > > obserrBoundMax
Maximum value of the observation error bound for each channel in channelList.
oops::Parameter< std::string > testObserr
Name of the data group to which the observation error is applied (default: ObsErrorData)
ObsFilterData provides access to all data related to an ObsFilter.
size_t nlocs() const
Returns the number of locations in the associated ObsSpace.
ioda::ObsSpace & obsspace() const
Returns reference to ObsSpace associated with ObsFilterData.
void get(const Variable &varname, std::vector< float > &values) const
Fills a std::vector with values of the specified variable.
oops::Variables toOopsVariables() const
Definition: Variable.cc:139
constexpr int missing
Definition: QCflags.h:20
integer function nlocs(this)
Return the number of observational locations in this Locations object.
Definition: RunCRTM.h:27
static ObsFunctionMaker< ObsErrorBoundIR > makerObsErrorBoundIR_("ObsErrorBoundIR")