UFO
CLWRetMW.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 "ufo/filters/Variable.h"
21 #include "ufo/utils/Constants.h"
22 
23 namespace ufo {
24 
26 
27 CLWRetMW::CLWRetMW(const eckit::LocalConfiguration & conf)
28  : invars_() {
29  // Initialize options
30  options_.deserialize(conf);
31 
32  // Check required parameters
33  // Get variable group types for CLW retrieval from option
34  ASSERT(options_.varGroup.value().size() == 1 || options_.varGroup.value().size() == 2);
35 
36  // Get channels for CLW retrieval from options
37  const std::vector<int> channels_ = {options_.ch238.value(), options_.ch314.value()};
38  ASSERT(options_.ch238 != 0 && options_.ch314 != 0 && channels_.size() == 2);
39 
40  // Include list of required data from ObsSpace
41  for (size_t igrp = 0; igrp < options_.varGroup.value().size(); ++igrp) {
42  invars_ += Variable("brightness_temperature@" + options_.varGroup.value()[igrp], channels_);
43  }
44  invars_ += Variable("brightness_temperature@" + options_.testBias.value(), channels_);
45  invars_ += Variable("sensor_zenith_angle@MetaData");
46 
47  // Include list of required data from GeoVaLs
48  invars_ += Variable("average_surface_temperature_within_field_of_view@GeoVaLs");
49  invars_ += Variable("water_area_fraction@GeoVaLs");
50  invars_ += Variable("surface_temperature_where_sea@GeoVaLs");
51 }
52 
53 // -----------------------------------------------------------------------------
54 
56 
57 // -----------------------------------------------------------------------------
58 
60  ioda::ObsDataVector<float> & out) const {
61  // Get required parameters
62  const std::vector<std::string> &vargrp = options_.varGroup.value();
63  const std::vector<int> channels_ = {options_.ch238.value(), options_.ch314.value()};
64 
65  // Get dimension
66  const size_t nlocs = in.nlocs();
67  const size_t ngrps = vargrp.size();
68 
69  // Get variables from ObsSpace
70  // Get sensor zenith angle
71  std::vector<float> szas(nlocs);
72  in.get(Variable("sensor_zenith_angle@MetaData"), szas);
73 
74  // Get variables from GeoVaLs
75  // Get average surface temperature in FOV
76  std::vector<float> tsavg(nlocs);
77  in.get(Variable("average_surface_temperature_within_field_of_view@GeoVaLs"), tsavg);
78 
79  // Get area fraction of each surface type
80  std::vector<float> water_frac(nlocs);
81  in.get(Variable("water_area_fraction@GeoVaLs"), water_frac);
82 
83  // Calculate retrieved cloud liquid water
84  std::vector<float> bt238(nlocs), bt314(nlocs);
85  for (size_t igrp = 0; igrp < ngrps; ++igrp) {
86  // Get data based on group type
87  in.get(Variable("brightness_temperature@" + vargrp[igrp], channels_)[channels_[0]-1], bt238);
88  in.get(Variable("brightness_temperature@" + vargrp[igrp], channels_)[channels_[1]-1], bt314);
89  // Get bias based on group type
90  if (options_.addBias.value() == vargrp[igrp]) {
91  std::vector<float> bias238(nlocs), bias314(nlocs);
92  if (in.has(Variable("brightness_temperature@" + options_.testBias.value(), channels_)[0])) {
93  in.get(Variable("brightness_temperature@" + options_.testBias.value(), channels_)
94  [channels_[0]-1], bias238);
95  in.get(Variable("brightness_temperature@" + options_.testBias.value(), channels_)
96  [channels_[1]-1], bias314);
97  } else {
98  bias238.assign(nlocs, 0.0f);
99  bias314.assign(nlocs, 0.0f);
100  }
101  // Add bias correction to the assigned group
102  if (options_.addBias.value() == "ObsValue") {
103  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
104  bt238[iloc] = bt238[iloc] - bias238[iloc];
105  bt314[iloc] = bt314[iloc] - bias314[iloc];
106  }
107  } else {
108  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
109  bt238[iloc] = bt238[iloc] + bias238[iloc];
110  bt314[iloc] = bt314[iloc] + bias314[iloc];
111  }
112  }
113  }
114 
115  // Compute the cloud liquid qater
116  cloudLiquidWater(szas, tsavg, water_frac, bt238, bt314, out[igrp], nlocs);
117  }
118 }
119 
120 // -----------------------------------------------------------------------------
121 
122 void CLWRetMW::cloudLiquidWater(const std::vector<float> & szas,
123  const std::vector<float> & tsavg,
124  const std::vector<float> & water_frac,
125  const std::vector<float> & bt238,
126  const std::vector<float> & bt314,
127  std::vector<float> & out,
128  const std::size_t nlocs) {
129  ///
130  /// \brief Retrieve cloud liquid water from AMSU-A 23.8 GHz and 31.4 GHz channels.
131  ///
132  /// Reference: Grody et al. (2001)
133  /// Determination of precipitable water and cloud liquid water over oceans from
134  /// the NOAA 15 advanced microwave sounding unit
135  ///
136  const float t0c = Constants::t0c;
137  const float d1 = 0.754, d2 = -2.265;
138  const float c1 = 8.240, c2 = 2.622, c3 = 1.846;
139  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
140  if (water_frac[iloc] >= 0.99) {
141  float cossza = cos(Constants::deg2rad * szas[iloc]);
142  float d0 = c1 - (c2 - c3 * cossza) * cossza;
143  if (tsavg[iloc] > t0c - 1.0 && bt238[iloc] <= 284.0 && bt314[iloc] <= 284.0
144  && bt238[iloc] > 0.0 && bt314[iloc] > 0.0) {
145  out[iloc] = cossza * (d0 + d1 * std::log(285.0 - bt238[iloc])
146  + d2 * std::log(285.0 - bt314[iloc]));
147  out[iloc] = std::max(0.f, out[iloc]);
148  } else {
149  out[iloc] = getBadValue();
150  }
151  }
152  }
153 }
154 
155 // -----------------------------------------------------------------------------
156 
158  return invars_;
159 }
160 
161 // -----------------------------------------------------------------------------
162 
163 } // namespace ufo
ufo::CLWRetMW::~CLWRetMW
~CLWRetMW()
Definition: CLWRetMW.cc:55
ufo::CLWRetMWParameters::ch238
oops::RequiredParameter< int > ch238
Definition: CLWRetMW.h:36
ufo::CLWRetMWParameters::addBias
oops::Parameter< std::string > addBias
Definition: CLWRetMW.h:57
ufo::ObsFilterData::nlocs
size_t nlocs() const
Returns number of locations.
Definition: ObsFilterData.cc:66
ufo::CLWRetMW::cloudLiquidWater
static void cloudLiquidWater(const std::vector< float > &, const std::vector< float > &, const std::vector< float > &, const std::vector< float > &, const std::vector< float > &, std::vector< float > &, const std::size_t)
Definition: CLWRetMW.cc:122
ufo::Variables
Definition: src/ufo/filters/Variables.h:24
ufo::CLWRetMW::CLWRetMW
CLWRetMW(const eckit::LocalConfiguration &=eckit::LocalConfiguration())
Definition: CLWRetMW.cc:27
ufo::Constants::t0c
static constexpr double t0c
Definition: Constants.h:24
ufo::CLWRetMW::compute
void compute(const ObsFilterData &, ioda::ObsDataVector< float > &) const
compute the result of the function
Definition: CLWRetMW.cc:59
CLWRetMW.h
ufo::CLWRetMW::invars_
ufo::Variables invars_
Definition: CLWRetMW.h:94
ufo::CLWRetMWParameters::varGroup
oops::RequiredParameter< std::vector< std::string > > varGroup
Definition: CLWRetMW.h:50
ufo::CLWRetMW::options_
CLWRetMWParameters options_
Definition: CLWRetMW.h:95
ufo
Definition: RunCRTM.h:27
ufo::ObsFunctionMaker
Definition: ObsFunctionBase.h:60
ufo::ObsFilterData::has
bool has(const Variable &) const
Checks if requested data exists in ObsFilterData.
Definition: ObsFilterData.cc:76
ufo::CLWRetMW::getBadValue
static float getBadValue()
Definition: CLWRetMW.h:92
ufo_constants_mod::t0c
real(kind_real), parameter, public t0c
Definition: ufo_constants_mod.F90:11
ufo::makerCLWRetMW_
static ObsFunctionMaker< CLWRetMW > makerCLWRetMW_("CLWRetMW")
ufo::Constants::deg2rad
static constexpr double deg2rad
Definition: Constants.h:21
ioda::ObsDataVector
Definition: BackgroundCheck.h:26
ufo::CLWRetMWParameters::ch314
oops::RequiredParameter< int > ch314
Definition: CLWRetMW.h:42
ufo::CLWRetMWParameters::testBias
oops::Parameter< std::string > testBias
Definition: CLWRetMW.h:62
ufo::CLWRetMW::requiredVariables
const ufo::Variables & requiredVariables() const
geovals required to compute the function
Definition: CLWRetMW.cc:157
Constants.h
ufo::ObsFilterData::get
void get(const Variable &, std::vector< float > &) const
Gets requested data from ObsFilterData.
Definition: ObsFilterData.cc:130
ufo::Variable
Definition: Variable.h:23
ufo::ObsFilterData
ObsFilterData provides access to all data related to an ObsFilter.
Definition: src/ufo/filters/ObsFilterData.h:40
conf
Definition: conf.py:1
Variable.h