UFO
SIRetMW.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2020 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 SIRetMW::SIRetMW(const eckit::LocalConfiguration & conf)
28  : invars_() {
29  // Initialize options
30  options_.deserialize(conf);
31 
32  // Check required parameters
33  // Get variable group types for SI retrieval from option
34  ASSERT(options_.varGroup.value().size() == 1 || options_.varGroup.value().size() == 2);
35 
36  // Get channels for SI retrieval from options
37  const std::vector<int> channels_ = {options_.ch90.value(), options_.ch150.value()};
38  ASSERT(options_.ch90 != 0 && options_.ch150 != 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 
46  // Include list of required data from ObsDiag
47  invars_ += Variable("brightness_temperature_assuming_clear_sky@ObsDiag" , channels_);
48 
49  // Include list of required data from GeoVaLs
50  invars_ += Variable("water_area_fraction@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_.ch90.value(), options_.ch150.value()};
64 
65  // Get dimension
66  const size_t nlocs = in.nlocs();
67  const size_t ngrps = vargrp.size();
68 
69  // Get variables from GeoVaLs
70 
71  // Get brightness temperature assuming all pixels are in clear skies
72  std::vector<float> clr90(nlocs), clr150(nlocs);
73  in.get(Variable("brightness_temperature_assuming_clear_sky@ObsDiag", channels_)[0], clr90);
74  in.get(Variable("brightness_temperature_assuming_clear_sky@ObsDiag", channels_)[1], clr150);
75 
76  // Get area fraction of each surface type
77  std::vector<float> water_frac(nlocs);
78  in.get(Variable("water_area_fraction@GeoVaLs"), water_frac);
79 
80  // Calculate scattering index
81  std::vector<float> bt90(nlocs), bt150(nlocs);
82  for (size_t igrp = 0; igrp < ngrps; ++igrp) {
83  // Get data based on group type
84  in.get(Variable("brightness_temperature@" + vargrp[igrp], channels_)[0], bt90);
85  in.get(Variable("brightness_temperature@" + vargrp[igrp], channels_)[1], bt150);
86  // Get bias based on group type
87  if (options_.addBias.value() == vargrp[igrp]) {
88  std::vector<float> bias90(nlocs), bias150(nlocs);
89  if (in.has(Variable("brightness_temperature@" + options_.testBias.value(), channels_)[0])) {
90  in.get(Variable("brightness_temperature@" + options_.testBias.value(), channels_)
91  [0], bias90);
92  in.get(Variable("brightness_temperature@" + options_.testBias.value(), channels_)
93  [1], bias150);
94  } else {
95  bias90.assign(nlocs, 0.0f);
96  bias150.assign(nlocs, 0.0f);
97  }
98  // Add bias correction to the assigned group
99  if (options_.addBias.value() == "ObsValue") {
100  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
101  bt90[iloc] = bt90[iloc] - bias90[iloc];
102  bt150[iloc] = bt150[iloc] - bias150[iloc];
103  }
104  } else {
105  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
106  bt90[iloc] = bt90[iloc] + bias90[iloc];
107  bt150[iloc] = bt150[iloc] + bias150[iloc];
108  // Temporarily account for ZERO clear-sky BT output from CRTM
109  if (clr90[iloc] > -1.0f && clr90[iloc] < 1.0f) {
110  clr90[iloc] = bt90[iloc];
111  } else {
112  clr90[iloc] = clr90[iloc] + bias90[iloc];
113  }
114  if (clr150[iloc] > -1.0f && clr150[iloc] < 1.0f) {
115  clr150[iloc] = bt150[iloc];
116  } else {
117  clr150[iloc] = clr150[iloc] + bias150[iloc];
118  }
119  }
120  }
121  }
122 
123  // Retrieve scattering index
124  for (size_t iloc = 0; iloc < nlocs; ++iloc) {
125  if (water_frac[iloc] >= 0.99) {
126  float siclr = clr90[iloc] - clr150[iloc];
127  out[igrp][iloc] = bt90[iloc] - bt150[iloc] - siclr;
128  } else {
129  out[igrp][iloc] = bt90[iloc] - bt150[iloc];
130  }
131  }
132  }
133 }
134 
135 // -----------------------------------------------------------------------------
136 
138  return invars_;
139 }
140 
141 // -----------------------------------------------------------------------------
142 
143 } // namespace ufo
ufo::ObsFilterData::nlocs
size_t nlocs() const
Returns number of locations.
Definition: ObsFilterData.cc:66
ufo::SIRetMW::requiredVariables
const ufo::Variables & requiredVariables() const
geovals required to compute the function
Definition: SIRetMW.cc:137
ufo::Variables
Definition: src/ufo/filters/Variables.h:24
ufo::SIRetMW::SIRetMW
SIRetMW(const eckit::LocalConfiguration &=eckit::LocalConfiguration())
Definition: SIRetMW.cc:27
ufo::SIRetMW::~SIRetMW
~SIRetMW()
Definition: SIRetMW.cc:55
ufo::makerSIRetMW_
static ObsFunctionMaker< SIRetMW > makerSIRetMW_("SIRetMW")
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
SIRetMW.h
ufo::SIRetMW::invars_
ufo::Variables invars_
Definition: SIRetMW.h:86
ioda::ObsDataVector
Definition: BackgroundCheck.h:26
ufo::SIRetMW::compute
void compute(const ObsFilterData &, ioda::ObsDataVector< float > &) const
compute the result of the function
Definition: SIRetMW.cc:59
ufo::SIRetMWParameters::addBias
oops::Parameter< std::string > addBias
Definition: SIRetMW.h:57
ufo::SIRetMWParameters::varGroup
oops::RequiredParameter< std::vector< std::string > > varGroup
Definition: SIRetMW.h:50
Constants.h
ufo::ObsFilterData::get
void get(const Variable &, std::vector< float > &) const
Gets requested data from ObsFilterData.
Definition: ObsFilterData.cc:130
ufo::SIRetMWParameters::testBias
oops::Parameter< std::string > testBias
Definition: SIRetMW.h:62
ufo::SIRetMW::options_
SIRetMWParameters options_
Definition: SIRetMW.h:87
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
ufo::SIRetMWParameters::ch150
oops::RequiredParameter< int > ch150
Definition: SIRetMW.h:42
conf
Definition: conf.py:1
ufo::SIRetMWParameters::ch90
oops::RequiredParameter< int > ch90
Definition: SIRetMW.h:36
Variable.h