IODA
ObsFrameRead.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2017-2019 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 "oops/util/abor1_cpp.h"
9 
10 #include "oops/util/Logger.h"
11 
12 #include "ioda/distribution/DistributionFactory.h"
13 #include "ioda/io/ObsFrameRead.h"
14 #include "ioda/io/ObsIoFactory.h"
15 
16 namespace ioda {
17 
18 //--------------------------- public functions ---------------------------------------
19 //------------------------------------------------------------------------------------
21  ObsFrame(params) {
22  // Create the ObsIo object
24 
25  // Create an MPI distribution
26  each_process_reads_separate_obs_ = obs_io_->eachProcessGeneratesSeparateObs();
28  // On each process the obs_io_ object will produce a separate series of observations, so
29  // we need to use a non-overlapping distribution. The RoundRobin will do.
30  eckit::LocalConfiguration distConf;
31  distConf.set("distribution", "RoundRobin");
32  dist_ = DistributionFactory::create(params.comm(), distConf);
33  } else {
34  dist_ = DistributionFactory::create(params.comm(), params.top_level_.toConfiguration());
35  }
36 
37  max_frame_size_ = params.top_level_.obsIoInParameters().maxFrameSize;
38  oops::Log::debug() << "ObsFrameRead: maximum frame size: " << max_frame_size_ << std::endl;
39 }
40 
42 
43 //------------------------------------------------------------------------------------
45  // reset counters, etc.
46  frame_start_ = 0;
48  // Ensure record numbers assigned on different processes don't overlap
49  next_rec_num_ = params_.comm().rank();
50  rec_num_increment_ = params_.comm().size();
51  } else {
52  next_rec_num_ = 0;
54  }
55  unique_rec_nums_.clear();
56  max_var_size_ = obs_io_->maxVarSize();
57  nlocs_ = 0;
59  gnlocs_ = 0;
60 
61  // create an ObsGroup based frame with an in-memory backend
62  createFrameFromObsGroup(obs_io_->varList(), obs_io_->dimVarList(), obs_io_->varDimMap());
63 
64  // record the variable name <-> dim names associations.
66 }
67 
68 //------------------------------------------------------------------------------------
72 }
73 
74 //------------------------------------------------------------------------------------
76  bool haveAnotherFrame = (frame_start_ < max_var_size_);
77  // If there is another frame, then read it into obs_frame_
78  if (haveAnotherFrame) {
79  // Resize along the nlocs dimension
82  { std::pair<Variable, Dimensions_t>(nlocsVar, frameCount("nlocs")) });
83 
84  // Transfer all variable data
85  Dimensions_t frameStart = this->frameStart();
86  for (auto & varNameObject : obs_io_->varList()) {
87  std::string varName = varNameObject.first;
88  Variable sourceVar = varNameObject.second;
89  Dimensions_t frameCount = this->basicFrameCount(sourceVar);
90  if (frameCount > 0) {
91  // Transfer the variable data for this frame. Do this in two steps:
92  // ObsIo --> memory buffer --> frame storage
93 
94  // Selection objects for transfer;
95  std::vector<Dimensions_t> varShape = sourceVar.getDimensions().dimsCur;
96  Selection obsIoSelect = createObsIoSelection(varShape, frameStart, frameCount);
97  Selection memBufferSelect = createMemSelection(varShape, frameCount);
98  Selection obsFrameSelect = createEntireFrameSelection(varShape, frameCount);
99 
100  // Transfer the data
101  Variable destVar = obs_frame_.vars.open(varName);
102  if (destVar.isA<int>()) {
103  std::vector<int> varValues;
104  sourceVar.read<int>(varValues, memBufferSelect, obsIoSelect);
105  destVar.write<int>(varValues, memBufferSelect, obsFrameSelect);
106  } else if (destVar.isA<float>()) {
107  std::vector<float> varValues;
108  sourceVar.read<float>(varValues, memBufferSelect, obsIoSelect);
109  destVar.write<float>(varValues, memBufferSelect, obsFrameSelect);
110  } else if (destVar.isA<std::string>()) {
111  std::vector<std::string> varValues;
112  sourceVar.read<std::string>(varValues, memBufferSelect, obsIoSelect);
113  destVar.write<std::string>(varValues, memBufferSelect, obsFrameSelect);
114  }
115  }
116  }
117 
118  // generate the frame index and record numbers for this frame
120 
121  // clear the selection caches
122  known_frame_selections_.clear();
123  known_mem_selections_.clear();
124  } else {
125  if (obs_io_->eachProcessGeneratesSeparateObs()) {
126  // sum up global location counts on all PEs
127  params_.comm().allReduceInPlace(gnlocs_, eckit::mpi::sum());
128  params_.comm().allReduceInPlace(gnlocs_outside_timewindow_, eckit::mpi::sum());
129  }
130  // assign each record to the patch of a unique PE
131  dist_->computePatchLocs();
132  }
133  return (haveAnotherFrame);
134 }
135 
136 //------------------------------------------------------------------------------------
137 Dimensions_t ObsFrameRead::frameStart() {
138  return frame_start_;
139 }
140 
141 //------------------------------------------------------------------------------------
142 Dimensions_t ObsFrameRead::frameCount(const std::string & varName) {
143  Variable var = obs_io_->vars().open(varName);
144  Dimensions_t fCount;
145  if (var.isDimensionScale()) {
146  fCount = basicFrameCount(var);
147  } else {
148  if (obs_io_->isVarDimByNlocs(varName)) {
150  } else {
151  fCount = basicFrameCount(var);
152  }
153  }
154  return fCount;
155 }
156 
157 //-----------------------------------------------------------------------------------
158 bool ObsFrameRead::readFrameVar(const std::string & varName, std::vector<int> & varData) {
159  return readFrameVarHelper<int>(varName, varData);
160 }
161 bool ObsFrameRead::readFrameVar(const std::string & varName, std::vector<float> & varData) {
162  return readFrameVarHelper<float>(varName, varData);
163 }
164 bool ObsFrameRead::readFrameVar(const std::string & varName,
165  std::vector<std::string> & varData) {
166  return readFrameVarHelper<std::string>(varName, varData);
167 }
168 
169 //--------------------------- private functions --------------------------------------
170 //-----------------------------------------------------------------------------------
171 void ObsFrameRead::print(std::ostream & os) const {
172  os << "ObsFrameRead: " << std::endl;
173 }
174 
175 //------------------------------------------------------------------------------------
176 Dimensions_t ObsFrameRead::basicFrameCount(const Variable & var) {
177  Dimensions_t count;
178  Dimensions_t varSize0 = var.getDimensions().dimsCur[0];
179  if ((frame_start_ + max_frame_size_) > varSize0) {
180  count = varSize0 - frame_start_;
181  if (count < 0) { count = 0; }
182  } else {
183  count = max_frame_size_;
184  }
185  return count;
186 }
187 
188 //------------------------------------------------------------------------------------
189 Selection ObsFrameRead::createIndexedFrameSelection(const std::vector<Dimensions_t> & varShape) {
190  // frame_loc_index_ contains the indices for the first dimension. Subsequent
191  // dimensions, we want to select all indices.
192  Selection indexedFrameSelect;
193  indexedFrameSelect.extent(varShape)
195  for (std::size_t i = 1; i < varShape.size(); ++i) {
196  std::vector<Dimensions_t> dimIndex(varShape[i]);
197  std::iota(dimIndex.begin(), dimIndex.end(), 0);
198  indexedFrameSelect.extent(varShape).select({ SelectionOperator::AND, i, dimIndex });
199  }
200  return indexedFrameSelect;
201 }
202 
203 // -----------------------------------------------------------------------------
204 void ObsFrameRead::genFrameIndexRecNums(std::shared_ptr<Distribution> & dist) {
205  // Generate location indices relative to the obs source (locIndex) and relative
206  // to the current frame (frameIndex).
207  std::vector<Dimensions_t> locIndex;
208  std::vector<Dimensions_t> frameIndex;
209 
210  // Apply the timing window. Need to filter out locations that are outside the
211  // timing window before generating record numbers. This is because
212  // we are generating record numbers on the fly since we want to get to the point where
213  // we can do the MPI distribution without knowing how many obs (and records) we are going
214  // to encounter. Only apply the timing window in the case of reading from a file.
215  if (obs_io_->applyTimingWindow()) {
216  genFrameLocationsTimeWindow(locIndex, frameIndex);
217  } else {
218  genFrameLocationsAll(locIndex, frameIndex);
219  }
220 
221  // Generate record numbers for this frame. Consider obs grouping.
222  std::vector<Dimensions_t> records;
223  const std::vector<std::string> &obsGroupVarList = obs_io_->obsGroupingVars();
224  if (obsGroupVarList.empty()) {
225  genRecordNumbersAll(locIndex, records);
226  } else {
227  genRecordNumbersGrouping(obsGroupVarList, frameIndex, records);
228  }
229 
230  // Apply the MPI distribution to the records
231  applyMpiDistribution(dist, locIndex, records);
232 
233  // New frame count is the number of entries in the frame_loc_index_ vector
234  // This will be handed to callers through the frameCount function for all
235  // variables with nlocs as their first dimension.
237 }
238 
239 //------------------------------------------------------------------------------------
240 void ObsFrameRead::genFrameLocationsAll(std::vector<Dimensions_t> & locIndex,
241  std::vector<Dimensions_t> & frameIndex) {
242  Dimensions_t locSize = this->frameCount("nlocs");
243  gnlocs_ += locSize;
244 
245  locIndex.resize(locSize);
246  std::iota(locIndex.begin(), locIndex.end(), this->frameStart());
247 
248  frameIndex.resize(locSize);
249  std::iota(frameIndex.begin(), frameIndex.end(), 0);
250 }
251 
252 //------------------------------------------------------------------------------------
253 void ObsFrameRead::genFrameLocationsTimeWindow(std::vector<Dimensions_t> & locIndex,
254  std::vector<Dimensions_t> & frameIndex) {
255  Dimensions_t frameCount = this->frameCount("nlocs");
256  Dimensions_t frameStart = this->frameStart();
257 
258  // Prefer MetaData/datetime. Eventually "MetaData/time" will be obsoleted.
259  std::string dtVarName;
260  if (obs_frame_.vars.exists("MetaData/datetime")) {
261  dtVarName = std::string("MetaData/datetime");
262  } else if (obs_frame_.vars.exists("MetaData/time")) {
263  dtVarName = std::string("MetaData/time");
264  } else {
265  std::string ErrMsg =
266  std::string("ERROR: ObsFrameRead::genFrameLocationsTimeWindow: ") +
267  std::string("date time information does not exist, ") +
268  std::string("cannot perform time window filtering");
269  throw eckit::UserError(ErrMsg, Here());
270  }
271 
272  // Build the selection objects
273  Variable dtVar = obs_frame_.vars.open(dtVarName);
274  std::vector<Dimensions_t> varShape = dtVar.getDimensions().dimsCur;
275  Selection memSelect = createMemSelection(varShape, frameCount);
276  Selection frameSelect = createEntireFrameSelection(varShape, frameCount);
277 
278  // convert ref, offset time to datetime objects
279  std::vector<util::DateTime> dtimeVals;
280  if (dtVarName == "MetaData/datetime") {
281  std::vector<std::string> dtValues;
282  dtVar.read<std::string>(dtValues, memSelect, frameSelect);
283  dtValues.resize(frameCount);
284 
285  dtimeVals = convertDtStringsToDtime(dtValues);
286  } else {
287  std::vector<float> dtValues;
288  dtVar.read<float>(dtValues, memSelect, frameSelect);
289  dtValues.resize(frameCount);
290 
291  int refDtime;
292  this->obs_io_->atts().open("date_time").read<int>(refDtime);
293  dtimeVals = convertRefOffsetToDtime(refDtime, dtValues);
294  }
295 
296  // Keep all locations that fall inside the timing window. Note iloc will be set
297  // to the number of locations stored in the output vectors after exiting the
298  // following for loop.
299  locIndex.resize(frameCount);
300  frameIndex.resize(frameCount);
301  std::size_t iloc = 0;
302  for (std::size_t i = 0; i < frameCount; ++i) {
303  if (this->insideTimingWindow(dtimeVals[i])) {
304  locIndex[iloc] = frameStart + i;
305  frameIndex[iloc] = i;
306  iloc++;
307  } else {
309  }
310  }
311  locIndex.resize(iloc);
312  frameIndex.resize(iloc);
313  gnlocs_ += iloc;
314 }
315 
316 //------------------------------------------------------------------------------------
317 void ObsFrameRead::genRecordNumbersAll(const std::vector<Dimensions_t> & locIndex,
318  std::vector<Dimensions_t> & records) {
319  // No obs grouping. Assign each location to a separate record.
320  Dimensions_t locSize = locIndex.size();
321  records.assign(locSize, 0);
322  for (std::size_t i = 0; i < locSize; ++i) {
323  records[i] = next_rec_num_;
325  }
326 }
327 
328 //------------------------------------------------------------------------------------
329 void ObsFrameRead::genRecordNumbersGrouping(const std::vector<std::string> & obsGroupVarList,
330  const std::vector<Dimensions_t> & frameIndex,
331  std::vector<Dimensions_t> & records) {
332  // Form the selection objects for reading the variables
333 
334  // Applying obs grouping. First convert all of the group variable data values for this
335  // frame into string key values. This is done in one call to minimize accessing the
336  // frame data for the grouping variables.
337  std::size_t locSize = frameIndex.size();
338  records.assign(locSize, 0);
339  std::vector<std::string> obsGroupingKeys(locSize);
340  buildObsGroupingKeys(obsGroupVarList, frameIndex, obsGroupingKeys);
341 
342  for (std::size_t i = 0; i < locSize; ++i) {
343  if (obs_grouping_.find(obsGroupingKeys[i]) == obs_grouping_.end()) {
344  // key is not present in the map
345  // assign current record number to the current key, and move to the next record number
346  obs_grouping_.insert(
347  std::pair<std::string, std::size_t>(obsGroupingKeys[i], next_rec_num_));
349  }
350  records[i] = obs_grouping_.at(obsGroupingKeys[i]);
351  }
352 }
353 
354 //------------------------------------------------------------------------------------
355 void ObsFrameRead::buildObsGroupingKeys(const std::vector<std::string> & obsGroupVarList,
356  const std::vector<Dimensions_t> & frameIndex,
357  std::vector<std::string> & groupingKeys) {
358  // Walk though each variable and construct the segments of the key values (strings)
359  // Append the segments as each variable is encountered.
360  for (std::size_t i = 0; i < obsGroupVarList.size(); ++i) {
361  // Retrieve the variable values from the obs frame and convert
362  // those values to strings. Then append those "value" strings from each
363  // variable to form the grouping keys.
364  std::string obsGroupVarName = obsGroupVarList[i];
365  std::string varName = std::string("MetaData/") + obsGroupVarName;
366  Variable groupVar = obs_frame_.vars.open(varName);
367  if (!obs_io_->isVarDimByNlocs(varName)) {
368  std::string ErrMsg =
369  std::string("ERROR: ObsFrameRead::genRecordNumbersGrouping: ") +
370  std::string("obs grouping variable (") + obsGroupVarName +
371  std::string(") must have 'nlocs' as first dimension");
372  ABORT(ErrMsg);
373  }
374 
375  // Form selection objects to grab the current frame values
376  Dimensions_t frameStart = this->frameStart();
377  Dimensions_t frameCount = this->frameCount("nlocs");
378 
379  std::vector<Dimensions_t> varShape = groupVar.getDimensions().dimsCur;
380  Selection memSelect = createMemSelection(varShape, frameCount);
381  Selection frameSelect = createEntireFrameSelection(varShape, frameCount);
382 
383  std::string keySegment;
384  if (groupVar.isA<int>()) {
385  std::vector<int> groupVarValues;
386  groupVar.read<int>(groupVarValues, memSelect, frameSelect);
387  groupVarValues.resize(frameCount);
388  for (std::size_t j = 0; j < frameIndex.size(); ++j) {
389  keySegment = std::to_string(groupVarValues[frameIndex[j]]);
390  if (i == 0) {
391  groupingKeys[j] = keySegment;
392  } else {
393  groupingKeys[j] += ":";
394  groupingKeys[j] += keySegment;
395  }
396  }
397  } else if (groupVar.isA<float>()) {
398  std::vector<float> groupVarValues;
399  groupVar.read<float>(groupVarValues, memSelect, frameSelect);
400  groupVarValues.resize(frameCount);
401  for (std::size_t j = 0; j < frameIndex.size(); ++j) {
402  keySegment = std::to_string(groupVarValues[frameIndex[j]]);
403  if (i == 0) {
404  groupingKeys[j] = keySegment;
405  } else {
406  groupingKeys[j] += ":";
407  groupingKeys[j] += keySegment;
408  }
409  }
410  } else if (groupVar.isA<std::string>()) {
411  std::vector<std::string> groupVarValues;
412  groupVar.read<std::string>(groupVarValues, memSelect, frameSelect);
413  groupVarValues.resize(frameCount);
414  for (std::size_t j = 0; j < frameIndex.size(); ++j) {
415  keySegment = groupVarValues[frameIndex[j]];
416  if (i == 0) {
417  groupingKeys[j] = keySegment;
418  } else {
419  groupingKeys[j] += ":";
420  groupingKeys[j] += keySegment;
421  }
422  }
423  }
424  }
425 }
426 
427 //------------------------------------------------------------------------------------
428 void ObsFrameRead::applyMpiDistribution(const std::shared_ptr<Distribution> & dist,
429  const std::vector<Dimensions_t> & locIndex,
430  const std::vector<Dimensions_t> & records) {
431  // Read lat/lon for this frame
432  Dimensions_t locSize = locIndex.size();
433  std::vector<float> lats(locSize, 0);
434  std::vector<float> lons(locSize, 0);
435  Dimensions_t frameStart = this->frameStart();
436  // Form selection objects to grab the current frame values
437  Dimensions_t frameCount = this->frameCount("nlocs");
438 
439  // Assume that lat and lon variables are shaped the same
440  if (!obs_frame_.vars.exists("MetaData/longitude")) {
441  throw eckit::UserError("MetaData/longitude not found in observations file", Here());
442  }
443  Variable latLonVar = obs_frame_.vars.open("MetaData/longitude");
444  std::vector<Dimensions_t> varShape = latLonVar.getDimensions().dimsCur;
445  Selection memSelect = createMemSelection(varShape, frameCount);
446  Selection frameSelect = createEntireFrameSelection(varShape, frameCount);
447 
448  latLonVar.read(lons, memSelect, frameSelect);
449  lons.resize(frameCount);
450 
451  if (!obs_frame_.vars.exists("MetaData/latitude")) {
452  throw eckit::UserError("MetaData/latitude not found in observations file", Here());
453  }
454  latLonVar = obs_frame_.vars.open("MetaData/latitude");
455  latLonVar.read(lats, memSelect, frameSelect);
456  lats.resize(frameCount);
457 
458  // Generate the index and recnums for this frame.
459  const std::size_t commSize = params_.comm().size();
460  const std::size_t commRank = params_.comm().rank();
461  frame_loc_index_.clear();
462  for (std::size_t i = 0; i < locSize; ++i) {
463  std::size_t rowNum = locIndex[i];
464  std::size_t recNum = records[i];
465  // The current frame storage always starts at zero so frameIndex
466  // needs to be the offset from the ObsIo frame start.
467  std::size_t frameIndex = rowNum - frameStart;
468  eckit::geometry::Point2 point(lons[frameIndex], lats[frameIndex]);
469 
470  std::size_t globalLocIndex = rowNum;
472  // Each process reads a different set of observations. Make sure all of them are assigned
473  // different global location indices
474  globalLocIndex = rowNum * commSize + commRank;
475  }
476  dist_->assignRecord(recNum, globalLocIndex, point);
477 
478  if (dist->isMyRecord(recNum)) {
479  indx_.push_back(globalLocIndex);
480  recnums_.push_back(recNum);
481  unique_rec_nums_.insert(recNum);
482  frame_loc_index_.push_back(frameIndex);
483  nlocs_++;
484  }
485  }
486  nrecs_ = unique_rec_nums_.size();
487 }
488 
489 // -----------------------------------------------------------------------------
490 bool ObsFrameRead::insideTimingWindow(const util::DateTime & obsDt) {
491  return ((obsDt > params_.windowStart()) && (obsDt <= params_.windowEnd()));
492 }
493 
494 } // namespace ioda
static std::unique_ptr< Distribution > create(const eckit::mpi::Comm &comm, const eckit::Configuration &config)
Create a Distribution object implementing a particular method of distributing observations across mul...
Dimensions_t nlocs_
number of locations from source (file or generator)
Definition: ObsFrame.h:170
std::shared_ptr< ObsIo > obs_io_
ObsIo object.
Definition: ObsFrame.h:161
Selection createMemSelection(const std::vector< Dimensions_t > &varShape, const Dimensions_t frameCount)
create selection object for accessing a memory buffer
Definition: ObsFrame.cc:26
void createFrameFromObsGroup(const VarNameObjectList &varList, const VarNameObjectList &dimVarList, const VarDimMap &varDimMap)
create a frame object based on dimensions and variables from a source ObsGroup
Definition: ObsFrame.cc:109
Dimensions_t max_frame_size_
maximum frame size
Definition: ObsFrame.h:183
Dimensions_t max_var_size_
maximum variable size
Definition: ObsFrame.h:186
VarDimMap ioVarDimMap() const
return map from variables to their attached dimension scales
Definition: ObsFrame.h:70
Selection createEntireFrameSelection(const std::vector< Dimensions_t > &varShape, const Dimensions_t frameCount)
create selection object for accessing the entire frame variable
Definition: ObsFrame.cc:49
Dimensions_t frame_start_
current frame starting index
Definition: ObsFrame.h:189
Selection createObsIoSelection(const std::vector< Dimensions_t > &varShape, const Dimensions_t frameStart, const Dimensions_t frameCount)
create selection object for accessing an ObsIo variable
Definition: ObsFrame.cc:91
Dimensions_t gnlocs_outside_timewindow_
number of nlocs from the file (gnlocs) that are outside the time window
Definition: ObsFrame.h:177
Dimensions_t gnlocs_
total number of locations from source (file or generator) that were selected after the timing window ...
Definition: ObsFrame.h:174
Dimensions_t nrecs_
number of records from source (file or generator)
Definition: ObsFrame.h:167
ObsSpaceParameters params_
ObsIo parameter specs.
Definition: ObsFrame.h:180
ObsGroup obs_frame_
ObsGroup object (temporary storage for a single frame)
Definition: ObsFrame.h:164
std::map< std::string, std::size_t > obs_grouping_
map for obs grouping via string keys
Dimensions_t adjusted_nlocs_frame_start_
current frame start for variable dimensioned along nlocs
Selection createIndexedFrameSelection(const std::vector< Dimensions_t > &varShape)
set up frontend and backend selection objects for the given variable
void frameNext() override
move to the next frame
Definition: ObsFrameRead.cc:69
void applyMpiDistribution(const std::shared_ptr< Distribution > &dist, const std::vector< Dimensions_t > &locIndex, const std::vector< Dimensions_t > &records)
apply MPI distribution
Dimensions_t adjusted_nlocs_frame_count_
current frame count for variable dimensioned along nlocs
Dimensions_t frameCount(const std::string &varName) override
return current frame count for variable
std::size_t rec_num_increment_
spacing between record numbers assigned on this process.
VarDimMap dims_attached_to_vars_
map showing association of dim names with each variable name
std::size_t next_rec_num_
next available record number
bool frameAvailable() override
true if a frame is available (not past end of frames)
Definition: ObsFrameRead.cc:75
void frameInit() override
initialize for walking through the frames
Definition: ObsFrameRead.cc:44
bool each_process_reads_separate_obs_
true if obs_io_ produces a different series of observations on each process, false if they are all th...
Dimensions_t basicFrameCount(const Variable &var)
return current frame count for variable
std::set< std::size_t > unique_rec_nums_
unique record numbers
bool readFrameVar(const std::string &varName, std::vector< int > &varData)
read a frame variable
void print(std::ostream &os) const override
print routine for oops::Printable base class
std::shared_ptr< Distribution > dist_
MPI distribution object.
void buildObsGroupingKeys(const std::vector< std::string > &obsGroupVarList, const std::vector< Dimensions_t > &frameIndex, std::vector< std::string > &groupingKeys)
generate string keys for record number assignment
void genRecordNumbersGrouping(const std::vector< std::string > &obsGroupVarList, const std::vector< Dimensions_t > &frameIndex, std::vector< Dimensions_t > &records)
generate record numbers considering obs grouping
std::map< std::vector< std::string >, Selection > known_frame_selections_
cache for frame selection
void genRecordNumbersAll(const std::vector< Dimensions_t > &locIndex, std::vector< Dimensions_t > &records)
generate record numbers where each location is a unique record (no grouping)
std::map< std::vector< std::string >, Selection > known_mem_selections_
cache for memory buffer selection
ObsFrameRead(const ObsSpaceParameters &params)
Definition: ObsFrameRead.cc:20
Dimensions_t frameStart() override
return current frame starting index
void genFrameLocationsAll(std::vector< Dimensions_t > &locIndex, std::vector< Dimensions_t > &frameIndex)
generate indices for all locations in current frame
bool insideTimingWindow(const util::DateTime &ObsDt)
std::vector< std::size_t > recnums_
record numbers associated with the location indexes
std::vector< std::size_t > indx_
indexes of locations to extract from the input obs file
void genFrameLocationsTimeWindow(std::vector< Dimensions_t > &locIndex, std::vector< Dimensions_t > &frameIndex)
generate indices for locations in current frame after filtering out obs outside DA timing window
std::vector< Dimensions_t > frame_loc_index_
location indices for current frame
void genFrameIndexRecNums(std::shared_ptr< Distribution > &dist)
generate frame indices and corresponding record numbers
void resize(const std::vector< std::pair< Variable, ioda::Dimensions_t >> &newDims)
Resize a Dimension and every Variable that depends on it.
Definition: ObsGroup.cpp:85
static std::shared_ptr< ObsIo > create(ObsIoModes mode, const ObsSpaceParameters &parameters)
Create and return a new instance of an ObsIo subclass.
Definition: ObsIoFactory.cc:24
const util::DateTime & windowEnd() const
return the end of the DA timing window
const util::DateTime & windowStart() const
return the start of the DA timing window
const eckit::mpi::Comm & comm() const
return the associated MPI group communicator
A Selection represents the bounds of the data, in ioda or in userspace, that you are reading or writi...
Definition: Selection.h:48
Variables store data!
Definition: Variable.h:680
Has_Variables vars
Use this to access variables.
Definition: Group.h:123
virtual Variable open(const std::string &name) const
Open a Variable by name.
virtual bool exists(const std::string &name) const
Does a Variable with the specified name exist?
bool isA() const
Convenience function to check a Variable's storage type.
Definition: Variable.h:99
virtual bool isDimensionScale() const
Is this Variable used as a dimension scale?
Definition: Variable.cpp:251
virtual Dimensions getDimensions() const
Definition: Variable.cpp:160
virtual Variable read(gsl::span< char > data, const Type &in_memory_dataType, const Selection &mem_selection=Selection::all, const Selection &file_selection=Selection::all) const
Read the Variable - as char array. Ordering is row-major.
Definition: Variable.cpp:330
virtual Variable write(gsl::span< char > data, const Type &in_memory_dataType, const Selection &mem_selection=Selection::all, const Selection &file_selection=Selection::all)
The fundamental write function. Backends overload this function to implement all write operations.
Definition: Variable.cpp:317
virtual Variable resize(const std::vector< Dimensions_t > &newDims)
Resize the variable.
Definition: Variable.cpp:172
Selection & extent(const VecDimensions_t &sz)
Provide the dimensions of the object that you are selecting from.
Definition: Selection.h:111
Selection & select(const SingleSelection &s)
Append a new selection.
Definition: Selection.h:103
std::vector< util::DateTime > convertDtStringsToDtime(const std::vector< std::string > &dtStrings)
convert datetime strings to DateTime object
Definition: IodaUtils.cc:239
std::vector< util::DateTime > convertRefOffsetToDtime(const int refIntDtime, const std::vector< float > &timeOffsets)
convert reference, time to DateTime object
Definition: IodaUtils.cc:251
std::vector< Dimensions_t > dimsCur
The dimensions of the data.
Definition: Dimensions.h:23