FV3 Bundle
Locations.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2017 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 "ioda/Locations.h"
9 
10 #include <memory>
11 #include <random>
12 #include <vector>
13 
14 #include "oops/util/Logger.h"
15 
16 #include "ioda/Fortran.h"
17 
18 namespace ioda {
19 
20 // -----------------------------------------------------------------------------
21 /*! UFO Locations Constructor with Configuration
22  *
23  * \details This constructor can be used to generate user-specified
24  * and/or random locations for use with interpolation or other tests
25  *
26  * To generate random locations, the relevant parameters specified in
27  * **StateTest.Locations** section of the config file are:
28  *
29  * * **lats** user-specified latitudes (degrees)
30  * * **lons** user-specified longitudes (degrees)
31  * * **Nrandom** number of random locations desired
32  * * **random_seed** (optional) random seed for reproducibility of results
33  *
34  * \date May, 2018 Created (M. Miesch, JCSDA)
35  *
36  * \sa ioda::ioda_locs_create() ioda::ioda_loc_test() test::testStateInterpolation()
37  *
38  */
39 
40 Locations::Locations(const eckit::Configuration & conf) {
41  std::vector<double> lats = conf.getDoubleVector("lats");
42  std::vector<double> lons = conf.getDoubleVector("lons");
43 
44  ASSERT(lats.size() == lons.size());
45  int nloc = lats.size();
46 
47  int rdist = 0;
48 
49  if (conf.has("Nrandom")) {
50  int Nrandom = conf.getInt("Nrandom");
51 
52  std::unique_ptr<std::mt19937> generator;
53 
54  if (conf.has("random_seed")) {
55  int rseed = conf.getInt("random_seed");
56  generator.reset(new std::mt19937(rseed));
57  } else {
58  generator.reset(new std::mt19937(time(0)));
59  }
60 
61  static std::uniform_real_distribution<double> distribution(-90, 90);
62 
63  // random latitudes range from -90 to 90 degrees
64  // random longitudes range from 0 to 360 degrees
65  std::vector<double> xx(Nrandom, 0.0);
66  for (size_t jj=0; jj < Nrandom; ++jj) xx[jj] = distribution(*generator);
67  lats.insert(lats.end(), xx.begin(), xx.end());
68  for (size_t jj=0; jj < Nrandom; ++jj) xx[jj] = 2.0*distribution(*generator) + 180.0;
69  lons.insert(lons.end(), xx.begin(), xx.end());
70 
71  nloc += Nrandom;
72 
73  if (conf.has("Rdist")) {
74  rdist = conf.getInt("Rdist");
75  }
76  }
77 
78  ioda_locs_create_f90(keyLoc_, nloc, &lats[0], &lons[0], rdist);
79 }
80 
81 // -----------------------------------------------------------------------------
82 
85 }
86 
87 // -----------------------------------------------------------------------------
88 
89 int Locations::nobs() const {
90  int nobs;
92  return nobs;
93 }
94 
95 // -----------------------------------------------------------------------------
96 
97 void Locations::print(std::ostream & os) const {
98  int nobs;
100  os << "Locations: " << nobs << " locations: ";
101 
102  // Write lat and lon to debug stream
103  double lat, lon;
104 
105  for (int i=0; i < nobs; ++i) {
107  oops::Log::debug() << "obs " << i << ": " << std::setprecision(2) << std::fixed
108  << "lat = " << lat << ", lon = " << lon << std::endl;
109  }
110 }
111 
112 // -----------------------------------------------------------------------------
113 
114 } // namespace ioda
115 
void ioda_locs_create_f90(F90locs &, const int &, const double *, const double *, const int &)
Interface to Fortran IODA routines.
l_size ! loop over number of fields ke do je do i
real(fvprc), dimension(:), allocatable lon
Definition: conf.py:1
void ioda_locs_coords_f90(const F90locs &, int &, double &, double &)
Locations(const F90locs key)
logical debug
Definition: mpp.F90:1297
int nobs() const
Definition: Locations.cc:89
real(fvprc), dimension(:), allocatable lat
void ioda_locs_nobs_f90(const F90locs &, int &)
void print(std::ostream &os) const
Definition: Locations.cc:97
void ioda_locs_delete_f90(F90locs &)