UFO
InterChannelConsistencyCheck.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 <cmath>
11 
12 #include <algorithm>
13 #include <iomanip>
14 #include <iostream>
15 #include <set>
16 #include <string>
17 #include <vector>
18 
19 #include "ioda/ObsDataVector.h"
20 #include "oops/util/IntSetParser.h"
21 #include "oops/util/missingValues.h"
22 #include "ufo/filters/Variable.h"
23 #include "ufo/utils/Constants.h"
24 #include "ufo/utils/StringUtils.h"
25 
26 namespace ufo {
27 
28 static ObsFunctionMaker<InterChannelConsistencyCheck>
29  makerInterChannelConsistencyCheck_("InterChannelConsistencyCheck");
30 
31 // -----------------------------------------------------------------------------
32 
33 InterChannelConsistencyCheck::InterChannelConsistencyCheck(const eckit::LocalConfiguration & conf)
34  : invars_() {
35  // Initialize options
36  options_.deserialize(conf);
37 
38  // Get channels from options
39  std::set<int> channelset = oops::parseIntSet(options_.channelList);
40  std::copy(channelset.begin(), channelset.end(), std::back_inserter(channels_));
41  ASSERT(channels_.size() > 0);
42 
43  // TODO(EL) the following two lines will be removed when the revised filter behavior is in place
44  // Include required variables from ObsDiag (note: included here to trigger posterFilter)
45  invars_ += Variable("brightness_temperature_jacobian_surface_temperature@ObsDiag", channels_);
46 }
47 
48 // -----------------------------------------------------------------------------
49 
51 
52 // -----------------------------------------------------------------------------
53 
55  ioda::ObsDataVector<float> & out) const {
56  // Get sensor information from options
57  const std::string &sensor = options_.sensor.value();
58 
59  // Get instrument and satellite from sensor
60  std::string inst, sat;
61  splitInstSat(sensor, inst, sat);
62 
63  // Get dimension
64  const size_t nlocs = in.nlocs();
65  const size_t nchans = channels_.size();
66 
67  // Get channel use flags from options
68  const std::vector<int> &use_flag = options_.useflagChannel.value();
69 
70  // Get test groups from options
71  const std::string &flaggrp = options_.testQCflag.value();
72  const std::string &errgrp = options_.testObserr.value();
73 
74  // Get effective observation error and qcflag from ObsSpace
75  // Convert effective observation error to inverse of the error variance
76  const float missing = util::missingValue(missing);
77  std::vector<int> qcflagdata(nlocs);
78  std::vector<float> obserrdata(nlocs);
79  std::vector<std::vector<float>> varinv(nchans, std::vector<float>(nlocs, 0.0));
80  for (size_t ichan = 0; ichan < nchans; ++ichan) {
81  in.get(Variable("brightness_temperature@"+errgrp, channels_)[ichan], obserrdata);
82  in.get(Variable("brightness_temperature@"+flaggrp, channels_)[ichan], qcflagdata);
83  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
84  if (flaggrp == "PreQC") obserrdata[iloc] == missing ? qcflagdata[iloc] = 100
85  : qcflagdata[iloc] = 0;
86  (qcflagdata[iloc] == 0) ? (varinv[ichan][iloc] = 1.0 / pow(obserrdata[iloc], 2))
87  : (varinv[ichan][iloc] = 0.0);
88  }
89  }
90 
91  // Inter-channel consistency check
92  bool passive_bc = true;
93  bool channel_passive = false;
94  size_t ncheck = 6;
95  if (inst == "atms") ncheck = 7;
96  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
97  for (int ichan = 0; ichan < nchans; ++ichan) out[ichan][iloc] = 0;
98  int kval = 0;
99  for (int ichan = 1; ichan < ncheck; ++ichan) {
100  channel_passive = use_flag[ichan] == -1 || use_flag[ichan] == 0;
101  int channel = ichan + 1;
102  if (varinv[ichan][iloc] <= 0.0 &&
103  (use_flag[ichan] >= 1 || (passive_bc && channel_passive))) {
104  kval = std::max(channel-1, kval);
105  if ((inst == "amsua" || inst == "atms") && channel <= 3) kval = 0;
106  }
107  }
108  if (kval > 0) {
109  for (int ichan = 0; ichan < kval; ++ichan) out[ichan][iloc] = 1;
110  if (inst == "amsua") {
111  int channel = 15;
112  out[channel-1][iloc] = 1;
113  }
114  if (inst == "atms") {
115  int channel = 16;
116  out[channel-1][iloc] = 1;
117  channel = 17;
118  out[channel-1][iloc] = 1;
119  channel = 18;
120  out[channel-1][iloc] = 1;
121  }
122  }
123  }
124 }
125 
126 // -----------------------------------------------------------------------------
127 
129  return invars_;
130 }
131 
132 // -----------------------------------------------------------------------------
133 
134 } // namespace ufo
void compute(const ObsFilterData &, ioda::ObsDataVector< float > &) const
compute the result of the function
InterChannelConsistencyCheck(const eckit::LocalConfiguration &)
InterChannelConsistencyCheckParameters options_
const ufo::Variables & requiredVariables() const
geovals required to compute the function
oops::RequiredParameter< std::vector< int > > useflagChannel
Useflag (-1: not used; 0: monitoring; 1: used) for each channel in channelList.
oops::RequiredParameter< std::string > sensor
Name of the sensor for which the observation error factor applies.
oops::RequiredParameter< std::string > channelList
List of channels available for assimilation.
oops::Parameter< std::string > testObserr
Name of the data group to which the observation error is applied (default: ObsErrorData)
oops::Parameter< std::string > testQCflag
Name of the data group to which the QC flag is applied (default is QCflagsData)
ObsFilterData provides access to all data related to an ObsFilter.
size_t nlocs() const
Returns the number of locations in the associated ObsSpace.
void get(const Variable &varname, std::vector< float > &values) const
Fills a std::vector with values of the specified variable.
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< InterChannelConsistencyCheck > makerInterChannelConsistencyCheck_("InterChannelConsistencyCheck")
void splitInstSat(const std::string &instsat, std::string &inst, std::string &sat)
Definition: StringUtils.cc:51