17 #include "eckit/config/Configuration.h"
19 #include "ioda/core/LocalObsSpaceParameters.h"
21 #include "oops/util/abor1_cpp.h"
22 #include "oops/util/DateTime.h"
23 #include "oops/util/Duration.h"
24 #include "oops/util/Logger.h"
26 #include "atlas/util/Earth.h"
43 const util::DateTime & bgn,
const util::DateTime & end,
44 const eckit::mpi::Comm & time)
45 :
oops::ObsSpaceBase(config, comm, bgn, end),
46 localopts_(), obsspace_(new
ObsData(config, comm, bgn, end, time)),
47 localobs_(obsspace_->nlocs()), isLocal_(false),
50 oops::Log::trace() <<
"ioda::ObsSpaces starting" << std::endl;
52 oops::Log::trace() <<
"ioda::ObsSpace done" << std::endl;
62 const eckit::geometry::Point2 & refPoint,
63 const eckit::Configuration & conf)
64 :
oops::ObsSpaceBase(
eckit::LocalConfiguration(), os.comm(), os.windowStart(), os.windowEnd()),
66 localobs_(), isLocal_(true),
69 oops::Log::trace() <<
"ioda::ObsSpace for LocalObs starting" << std::endl;
73 oops::Log::trace() <<
"ioda::ObsSpace searching via brute force" << std::endl;
76 std::vector<float> lats(
nlocs);
77 std::vector<float> lons(
nlocs);
83 for (
unsigned int jj = 0; jj <
nlocs; ++jj) {
84 eckit::geometry::Point2 searchPoint(lons[jj], lats[jj]);
85 double localDist =
localopts_->distance(refPoint, searchPoint);
86 if ( localDist < localopts_->lengthscale ) {
91 const boost::optional<int> & maxnobs =
localopts_->maxnobs;
92 if ( (maxnobs != boost::none) && (
localobs_.size() > *maxnobs ) ) {
93 for (
unsigned int jj = 0; jj <
localobs_.size(); ++jj) {
94 oops::Log::debug() <<
"Before sort [i, d]: " <<
localobs_[jj]
95 <<
" , " <<
obsdist_[jj] << std::endl;
98 std::vector<std::pair<std::size_t, double>> localObsIndDistPair;
99 for (
unsigned int jj = 0; jj <
obsdist_.size(); ++jj) {
104 sort(localObsIndDistPair.begin(), localObsIndDistPair.end(),
105 [](
const std::pair<std::size_t, double> & p1,
106 const std::pair<std::size_t, double> & p2){
107 return(p1.second < p2.second);
111 for (
unsigned int jj = 0; jj <
obsdist_.size(); ++jj) {
112 localobs_[jj] = localObsIndDistPair[jj].first;
113 obsdist_[jj] = localObsIndDistPair[jj].second;
121 oops::Log::trace() <<
"ioda::ObsSpace searching via KDTree" << std::endl;
124 ABORT(
"ObsSpace:: search method must be 'brute_force' when using 'cartesian' distance");
129 eckit::geometry::Point3 refPoint3D;
130 atlas::util::Earth::convertSphericalToCartesian(refPoint, refPoint3D);
132 double chordLength = 2.0*
localopts_->radius_earth * sin(alpha);
134 auto closePoints = kdtree.findInSphere(refPoint3D, chordLength);
137 for (
unsigned int jj = 0; jj < closePoints.size(); ++jj) {
138 localobs_.push_back(closePoints[jj].payload());
139 obsdist_.push_back(closePoints[jj].distance());
143 const boost::optional<int> & maxnobs =
localopts_->maxnobs;
144 if ( (maxnobs != boost::none) && (
localobs_.size() > *maxnobs ) ) {
150 oops::Log::trace() <<
"ioda::ObsSpace for LocalObs done" << std::endl;
162 oops::Log::trace() <<
"ioda::~ObsSpace done" << std::endl;
168 std::vector<int> & vdata)
const {
171 obsspace_->get_db(group, name, vdataTmp);
172 for (
unsigned int ii = 0; ii <
localobs_.size(); ++ii) {
183 std::vector<float> & vdata)
const {
185 std::vector<float> vdataTmp(
obsspace_->nlocs());
186 obsspace_->get_db(group, name, vdataTmp);
187 for (
unsigned int ii = 0; ii <
localobs_.size(); ++ii) {
198 std::vector<double> & vdata)
const {
200 std::vector<double> vdataTmp(
obsspace_->nlocs());
201 obsspace_->get_db(group, name, vdataTmp);
202 for (
unsigned int ii = 0; ii <
localobs_.size(); ++ii) {
213 std::vector<std::string> & vdata)
const {
215 std::vector<std::string> vdataTmp(
obsspace_->nlocs());
216 obsspace_->get_db(group, name, vdataTmp);
217 for (
unsigned int ii = 0; ii <
localobs_.size(); ++ii) {
228 std::vector<util::DateTime> & vdata)
const {
230 std::vector<util::DateTime> vdataTmp(
obsspace_->nlocs());
231 obsspace_->get_db(group, name, vdataTmp);
232 for (
unsigned int ii = 0; ii <
localobs_.size(); ++ii) {
243 const std::vector<int> & vdata) {
250 const std::vector<float> & vdata) {
257 const std::vector<double> & vdata) {
264 const std::vector<std::string> & vdata) {
271 const std::vector<util::DateTime> & vdata) {
282 bool ObsSpace::has(
const std::string & group,
const std::string & name)
const {