UFO
ProfileStandardLevels.cc
Go to the documentation of this file.
1 /*
2  * (C) Crown copyright 2020, Met Office
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 namespace ufo {
13  : optionsSL_(options)
14  {
16  BigGaps_ = optionsSL_.BigGaps.value();
17  }
18 
19  void ProfileStandardLevels::calcStdLevels(const int numProfileLevels,
20  const std::vector <float> &pressures,
21  const std::vector <float> &tObs,
22  const std::vector <int> &tFlags)
23  {
24  oops::Log::debug() << " Finding standard levels" << std::endl;
25 
26  // Reset calculated values
27  NumSig_ = 0;
28  NumStd_ = 0;
29  StdLev_.assign(numProfileLevels, -1);
30  SigBelow_.assign(numProfileLevels, -1);
31  SigAbove_.assign(numProfileLevels, -1);
32  LogP_.assign(numProfileLevels, 0.0);
33  IndStd_.assign(numProfileLevels, -1);
34 
35  /// Missing value (float)
36  const float missingValueFloat = util::missingValue(1.0f);
37 
38  int SigPrev = -1; // Previous significant level
39  int jlevStdA = 0; // Standard level below previous significant level
40  for (int jlev = 0; jlev < numProfileLevels; ++jlev) {
41  // Ignore this level if it has been flagged as rejected.
42  if (tFlags[jlev] & ufo::MetOfficeQCFlags::Elem::FinalRejectFlag) continue;
43  if (tObs[jlev] != missingValueFloat &&
44  pressures[jlev] > optionsSL_.FS_MinP.value()) {
45  LogP_[jlev] = (pressures[jlev] > 0 ? std::log(pressures[jlev]) : 0.0);
47  // Surface
48  NumStd_++;
49  StdLev_[NumStd_ - 1] = jlev;
50  } else if (tFlags[jlev] & ufo::MetOfficeQCFlags::Profile::StandardLevelFlag) {
51  // Standard level
52  NumStd_++;
53  StdLev_[NumStd_ - 1] = jlev;
54  SigBelow_[NumStd_ - 1] = SigPrev;
55  } else {
56  NumSig_++;
57  for (int jlevStd = jlevStdA; jlevStd < NumStd_; ++jlevStd) {
58  SigAbove_[jlevStd] = jlev;
59  }
60  jlevStdA = NumStd_;
61  SigPrev = jlev;
62  }
63  }
64  }
65 
66  // Calculate IndStd_ (standard level indices)
67  for (int jlevstd = 0; jlevstd < NumStd_; ++jlevstd) {
68  int jlev = StdLev_[jlevstd]; // Standard level
69  if (tFlags[jlev] & ufo::MetOfficeQCFlags::Profile::SurfaceLevelFlag) continue;
70  int IPStd = std::round(pressures[jlev] * 0.01); // Pressure rounded to nearest hPa
71  for (size_t i = 0; i < StandardLevels_.size(); ++i) {
72  if (IPStd == StandardLevels_[i])
73  IndStd_[jlevstd] = static_cast<int> (i); // Index at which standard level appears
74  if (StandardLevels_[i] <= IPStd) break;
75  }
76  }
77  }
78 
80  {
81  // Find indices in StandardLevels that are closest to 925 and 100 hPa
82  // Required for hydrostatic check
83 
84  // StandardLevels_ must contain decreasing pressures
85  for (size_t jstdlev = 0; jstdlev < StandardLevels_.size() - 1; ++jstdlev) {
86  if (StandardLevels_[jstdlev] < StandardLevels_[jstdlev + 1]) {
87  throw eckit::BadValue("Standard levels in wrong order", Here());
88  }
89  }
90 
91  // Find indices using reverse iterators
92  auto it925 = std::lower_bound(StandardLevels_.rbegin(), StandardLevels_.rend(), 925.0);
93  Ind925_ = std::distance(StandardLevels_.begin(), it925.base()) - 1;
94  auto it100 = std::lower_bound(StandardLevels_.rbegin(), StandardLevels_.rend(), 100.0);
95  Ind100_ = std::distance(StandardLevels_.begin(), it100.base()) - 1;
96  }
97 
98  void ProfileStandardLevels::calcStdLevelsUV(const int numProfileLevels,
99  const std::vector <float> &pressures,
100  const std::vector <float> &uObs,
101  const std::vector <float> &vObs,
102  const std::vector <int> &uFlags)
103  {
104  oops::Log::debug() << " Finding standard levels for U and V data" << std::endl;
105 
106  // Reset calculated values
107  NumSig_ = 0;
108  NumStd_ = 0;
109  StdLev_.assign(numProfileLevels, -1);
110  SigBelow_.assign(numProfileLevels, -1);
111  SigAbove_.assign(numProfileLevels, -1);
112  LogP_.assign(numProfileLevels, 0.0);
113 
114  /// Missing value (float)
115  const float missingValueFloat = util::missingValue(1.0f);
116 
117  int SigPrev = -1; // Previous significant level
118  int jlevStdA = 0; // Standard level below previous significant level
119 
120  for (int jlev = 0; jlev < numProfileLevels; ++jlev) {
121  if (uObs[jlev] != missingValueFloat && vObs[jlev] != missingValueFloat) {
122  LogP_[jlev] = std::log(pressures[jlev]);
123  if (uFlags[jlev] & ufo::MetOfficeQCFlags::Profile::StandardLevelFlag) { // Standard level
124  NumStd_++;
125  StdLev_[NumStd_ - 1] = jlev;
126  SigBelow_[NumStd_ - 1] = SigPrev;
127  } else {
128  NumSig_++;
129  for (int jlevstd = jlevStdA; jlevstd < NumStd_; ++jlevstd) {
130  SigAbove_[jlevstd] = jlev;
131  }
132  jlevStdA = NumStd_;
133  SigPrev = jlev;
134  }
135  }
136  }
137  }
138 } // namespace ufo
Options controlling the operation of the ConventionalProfileProcessing filter.
oops::Parameter< std::vector< float > > BigGaps
Big gaps (hPa) used in interpolation check.
oops::Parameter< float > FS_MinP
Min P for finding standard levels (Pa)
oops::Parameter< std::vector< float > > StandardLevels
Standard Levels (hPa)
int Ind925_
Standard level index closest to 925 hPa.
void calcStdLevelsUV(const int numProfileLevels, const std::vector< float > &pressures, const std::vector< float > &uObs, const std::vector< float > &vObs, const std::vector< int > &uFlags)
Calculate standard levels for U and V data.
int Ind100_
Standard level index closest to 100 hPa.
std::vector< float > BigGaps_
Big gaps (hPa) used in interpolation check.
std::vector< int > StdLev_
Index of standard levels.
ProfileStandardLevels(const ConventionalProfileProcessingParameters &options)
void findHCheckStdLevs()
Compute indices of particular standard levels for the hydrostatic check.
const ConventionalProfileProcessingParameters & optionsSL_
Configurable parameters.
void calcStdLevels(const int numProfileLevels, const std::vector< float > &pressures, const std::vector< float > &tObs, const std::vector< int > &tFlags)
Calculate standard levels.
std::vector< float > StandardLevels_
Standard levels (hPa)
std::vector< float > LogP_
Log(Pressure) - used for vertical interpolation.
int NumStd_
Number of standard levels.
std::vector< int > IndStd_
Indices of standard levels.
std::vector< int > SigBelow_
Significant level below standard level.
std::vector< int > SigAbove_
Significant level above standard level.
int NumSig_
Number of significant levels.
@ SurfaceLevelFlag
Surface Level.
@ StandardLevelFlag
Standard Level.
@ FinalRejectFlag
Final QC flag.
float distance(const Point &a, const Point &b)
Returns the distance between the two cartesian-mapped Point arguments
Definition: RunCRTM.h:27