1
1
#pragma once
2
2
3
3
#include < iostream>
4
- #include < map>
5
4
#include < string>
6
5
#include < vector>
7
6
17
16
#include " oops/util/Logger.h"
18
17
#include " oops/util/missingValues.h"
19
18
20
- namespace gdasapp {
21
- namespace testutils {
22
- template <typename Derived>
23
- std::string checksum (const Eigen::ArrayBase<Derived>& arr, const std::string varname) {
24
- std::stringstream result;
25
- if (arr.size () == 0 ) {
26
- result << varname << " is empty" << " \n " ;
27
- } else {
28
- auto minElement = arr.minCoeff ();
29
- auto maxElement = arr.maxCoeff ();
30
- auto sumElements = arr.sum ();
31
-
32
- result << varname << " :" << " \n " ;
33
- result << " Min: " << minElement << " \n " ;
34
- result << " Max: " << maxElement << " \n " ;
35
- result << " Sum: " << sumElements;
36
- }
37
- return result.str ();
38
- }
39
- } // namespace testutils
40
-
41
- // A simple data structure to organize the info to provide to the ioda
42
- // writter
43
- struct IodaVars {
44
- int location_; // Number of observation per variable
45
- int nVars_; // number of obs variables, should be set to
46
- // for now in the children classes
47
- int nfMetadata_; // number of float metadata fields
48
- int niMetadata_; // number of int metadata fields
49
-
50
- // Non optional metadata
51
- Eigen::ArrayXf longitude_; // geo-location_
52
- Eigen::ArrayXf latitude_; // "
53
- Eigen::Array<int64_t , Eigen::Dynamic, 1 > datetime_; // Epoch date in seconds
54
- std::string referenceDate_; // Reference date for epoch time
55
-
56
- // Obs info
57
- Eigen::ArrayXf obsVal_; // Observation value
58
- Eigen::ArrayXf obsError_; // " error
59
- Eigen::ArrayXi preQc_; // Quality control flag
60
-
61
- // Optional metadata
62
- Eigen::ArrayXXf floatMetadata_; // Optional array of float metadata
63
- std::vector<std::string> floatMetadataName_; // String descriptor of the float metadata
64
- Eigen::ArrayXXf intMetadata_; // Optional array of integer metadata
65
- std::vector<std::string> intMetadataName_; // String descriptor of the integer metadata
66
-
67
- // Optional global attributes
68
- std::map<std::string, std::string> strGlobalAttr_;
69
-
70
- // Constructor
71
- explicit IodaVars (const int nobs = 0 ,
72
- const std::vector<std::string> fmnames = {},
73
- const std::vector<std::string> imnames = {}) :
74
- location_(nobs), nVars_(1 ), nfMetadata_(fmnames.size()), niMetadata_(imnames.size()),
75
- longitude_(location_), latitude_(location_), datetime_(location_),
76
- obsVal_(location_),
77
- obsError_(location_),
78
- preQc_(location_),
79
- floatMetadata_(location_, fmnames.size()),
80
- floatMetadataName_(fmnames),
81
- intMetadata_(location_, imnames.size()),
82
- intMetadataName_(imnames)
83
- {
84
- oops::Log::trace () << " IodaVars::IodaVars created." << std::endl;
85
- }
86
-
87
- // Append an other instance of IodaVars
88
- void append (const IodaVars& other) {
89
- // Check if the two instances can be concatenated
90
- ASSERT (nVars_ == other.nVars_ );
91
- ASSERT (nfMetadata_ == other.nfMetadata_ );
92
- ASSERT (niMetadata_ == other.niMetadata_ );
93
- ASSERT (floatMetadataName_ == floatMetadataName_);
94
- ASSERT (intMetadataName_ == intMetadataName_);
95
-
96
- // Concatenate Eigen arrays and vectors
97
- longitude_.conservativeResize (location_ + other.location_ );
98
- latitude_.conservativeResize (location_ + other.location_ );
99
- datetime_.conservativeResize (location_ + other.location_ );
100
- obsVal_.conservativeResize (location_ + other.location_ );
101
- obsError_.conservativeResize (location_ + other.location_ );
102
- preQc_.conservativeResize (location_ + other.location_ );
103
- floatMetadata_.conservativeResize (location_ + other.location_ , nfMetadata_);
104
- intMetadata_.conservativeResize (location_ + other.location_ , niMetadata_);
105
-
106
- // Copy data from the 'other' object to this object
107
- longitude_.tail (other.location_ ) = other.longitude_ ;
108
- latitude_.tail (other.location_ ) = other.latitude_ ;
109
- datetime_.tail (other.location_ ) = other.datetime_ ;
110
- obsVal_.tail (other.location_ ) = other.obsVal_ ;
111
- obsError_.tail (other.location_ ) = other.obsError_ ;
112
- preQc_.tail (other.location_ ) = other.preQc_ ;
113
- floatMetadata_.bottomRows (other.location_ ) = other.floatMetadata_ ;
114
- intMetadata_.bottomRows (other.location_ ) = other.intMetadata_ ;
115
-
116
- // Update obs count
117
- location_ += other.location_ ;
118
- oops::Log::trace () << " IodaVars::IodaVars done appending." << std::endl;
119
- }
120
- void trim (const Eigen::Array<bool , Eigen::Dynamic, 1 >& mask ) {
121
- int newlocation = mask.count ();
122
-
123
- IodaVars iodaVarsMasked (newlocation, floatMetadataName_, intMetadataName_);
124
-
125
- // this feels downright crude, but apparently numpy-type masks are on the todo list for Eigen
126
- int j = 0 ;
127
- for (int i = 0 ; i < location_; i++) {
128
- if (mask (i)) {
129
- iodaVarsMasked.longitude_ (j) = longitude_ (i);
130
- iodaVarsMasked.latitude_ (j) = latitude_ (i);
131
- iodaVarsMasked.obsVal_ (j) = obsVal_ (i);
132
- iodaVarsMasked.obsError_ (j) = obsError_ (i);
133
- iodaVarsMasked.preQc_ (j) = preQc_ (i);
134
- iodaVarsMasked.datetime_ (j) = datetime_ (i);
135
- for (int k = 0 ; k < nfMetadata_; k++) {
136
- iodaVarsMasked.intMetadata_ (j, k) = intMetadata_ (i, k);
137
- }
138
- for (int k = 0 ; k < niMetadata_; k++) {
139
- iodaVarsMasked.intMetadata_ (j, k) = intMetadata_ (i, k);
140
- }
141
- j++;
142
- } // end if (mask(i))
143
- }
144
-
145
- longitude_ = iodaVarsMasked.longitude_ ;
146
- latitude_ = iodaVarsMasked.latitude_ ;
147
- datetime_ = iodaVarsMasked.datetime_ ;
148
- obsVal_ = iodaVarsMasked.obsVal_ ;
149
- obsError_ = iodaVarsMasked.obsError_ ;
150
- preQc_ = iodaVarsMasked.preQc_ ;
151
- floatMetadata_ = iodaVarsMasked.floatMetadata_ ;
152
- intMetadata_ = iodaVarsMasked.intMetadata_ ;
153
-
154
- // Update obs count
155
- location_ = iodaVarsMasked.location_ ;
156
- oops::Log::info () << " IodaVars::IodaVars done masking." << std::endl;
157
- }
19
+ # include " util.h"
158
20
159
- // Testing
160
- void testOutput () {
161
- oops::Log::test () << referenceDate_ << std::endl;
162
- oops::Log::test () <<
163
- gdasapp::testutils::checksum (obsVal_, " obsVal" ) << std::endl;
164
- oops::Log::test () <<
165
- gdasapp::testutils::checksum (obsError_, " obsError" ) << std::endl;
166
- oops::Log::test () <<
167
- gdasapp::testutils::checksum (preQc_, " preQc" ) << std::endl;
168
- oops::Log::test () <<
169
- gdasapp::testutils::checksum (longitude_, " longitude" ) << std::endl;
170
- oops::Log::test () <<
171
- gdasapp::testutils::checksum (latitude_, " latitude" ) << std::endl;
172
- oops::Log::test () <<
173
- gdasapp::testutils::checksum (datetime_, " datetime" ) << std::endl;
174
- }
175
- };
21
+ namespace gdasapp {
176
22
177
23
// Base class for the converters
178
24
class NetCDFToIodaConverter {
@@ -212,7 +58,7 @@ namespace gdasapp {
212
58
ASSERT (comm_.size () <= inputFilenames_.size ());
213
59
214
60
// Read the provider's netcdf file
215
- gdasapp::IodaVars iodaVars = providerToIodaVars (inputFilenames_[myrank]);
61
+ gdasapp::obsproc::iodavars:: IodaVars iodaVars = providerToIodaVars (inputFilenames_[myrank]);
216
62
for (int i = myrank + comm_.size (); i < inputFilenames_.size (); i += comm_.size ()) {
217
63
iodaVars.append (providerToIodaVars (inputFilenames_[i]));
218
64
oops::Log::info () << " appending: " << inputFilenames_[i] << std::endl;
@@ -223,7 +69,7 @@ namespace gdasapp {
223
69
// Get the total number of obs across pe's
224
70
int nobsAll (0 );
225
71
comm_.allReduce (nobs, nobsAll, eckit::mpi::sum ());
226
- gdasapp::IodaVars iodaVarsAll (nobsAll,
72
+ gdasapp::obsproc::iodavars:: IodaVars iodaVarsAll (nobsAll,
227
73
iodaVars.floatMetadataName_ ,
228
74
iodaVars.intMetadataName_ );
229
75
@@ -316,7 +162,8 @@ namespace gdasapp {
316
162
private:
317
163
// Virtual method that reads the provider's netcdf file and store the relevant
318
164
// info in a IodaVars struct
319
- virtual gdasapp::IodaVars providerToIodaVars (const std::string fileName) = 0;
165
+ virtual gdasapp::obsproc::iodavars::IodaVars providerToIodaVars (
166
+ const std::string fileName) = 0;
320
167
321
168
// Gather for eigen array
322
169
template <typename T>
0 commit comments