UFO
Legendre.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 
8 #include <string>
9 #include "ioda/ObsSpace.h"
10 #include "oops/util/Logger.h"
12 #include "ufo/utils/Constants.h"
13 
14 namespace ufo {
15 
17 
18 // -----------------------------------------------------------------------------
19 
20 Legendre::Legendre(const Parameters_ & parameters, const oops::Variables & vars)
21  : PredictorBase(parameters, vars),
22  order_(parameters.order.value().value_or(1)),
23  nscan_(parameters.numScanPositions) {
24  if (parameters.order.value() != boost::none) {
25  // override the predictor name to distinguish between Legendre predictors of different orders
26  name() = name() + "_order_" + std::to_string(order_);
27  }
28 }
29 
30 // -----------------------------------------------------------------------------
31 
32 void Legendre::compute(const ioda::ObsSpace & odb,
33  const GeoVaLs &,
34  const ObsDiagnostics &,
35  ioda::ObsVector & out) const {
36  const std::size_t nlocs = odb.nlocs();
37 
38  // assure shape of out
39  ASSERT(out.nlocs() == nlocs);
40 
41  // retrieve the sensor scan position and total number of scan positions (const for inst type)
42  std::vector<int> scan_position(nlocs, 0);
43  std::vector<double> LegPoly(order_+1, 0);
44 
45  odb.get_db("MetaData", "scan_position", scan_position);
46  const std::size_t nvars = vars_.size();
47  for (std::size_t jl = 0; jl < nlocs; ++jl) {
48  double xscan{-1.0 + 2.0 * (scan_position[jl] - 1) / (nscan_ - 1)};
49  // Transformed variable for the scan position in the range -1 to 1.
50  // Calculate Legendre Polynomial for current scan position
51  LegPoly[0] = 1.0;
52  LegPoly[1] = xscan;
53  for (std::size_t iorder=1; iorder < order_; ++iorder) {
54  LegPoly[iorder+1] = ((2*iorder+1)*xscan*LegPoly[iorder]
55  -iorder*LegPoly[iorder-1])/(iorder+1);
56  }
57  for (std::size_t iorder=0; iorder < order_+1; ++iorder) {
58  LegPoly[iorder] = sqrt(2*iorder+1)*LegPoly[iorder];
59  }
60  for (std::size_t jb = 0; jb < nvars; ++jb) {
61  out[jl*nvars+jb] = LegPoly[order_];
62  }
63  }
64 }
65 
66 // -----------------------------------------------------------------------------
67 
68 } // namespace ufo
GeoVaLs: geophysical values at locations.
Legendre(const Parameters_ &, const oops::Variables &)
Definition: Legendre.cc:20
void compute(const ioda::ObsSpace &, const GeoVaLs &, const ObsDiagnostics &, ioda::ObsVector &) const override
compute the predictor
Definition: Legendre.cc:32
Configuration parameters of the Legendre predictor.
Definition: Legendre.h:29
oops::OptionalParameter< int > order
Definition: Legendre.h:40
std::string & name()
predictor name
Definition: PredictorBase.h:80
oops::Variables vars_
variables that will be bias-corrected using this predictor
Definition: PredictorBase.h:84
integer function nlocs(this)
Return the number of observational locations in this Locations object.
Definition: RunCRTM.h:27
static PredictorMaker< Legendre > makerFuncLegendre_("Legendre")