FV3 Bundle
src/lorenz95/ObsTable.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
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  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #include "lorenz95/ObsTable.h"
12 
13 #include <algorithm>
14 #include <fstream>
15 #include <iostream>
16 #include <map>
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "eckit/config/LocalConfiguration.h"
23 #include "lorenz95/LocsL95.h"
24 #include "lorenz95/ObsVec1D.h"
25 #include "oops/util/abor1_cpp.h"
26 #include "oops/util/DateTime.h"
27 #include "oops/util/Duration.h"
28 #include "oops/util/Logger.h"
29 
30 // -----------------------------------------------------------------------------
31 namespace lorenz95 {
32 // -----------------------------------------------------------------------------
33 
34 ObsTable::ObsTable(const eckit::Configuration & config,
35  const util::DateTime & bgn, const util::DateTime & end)
36  : oops::ObsSpaceBase(config, bgn, end), winbgn_(bgn), winend_(end)
37 {
38  nameIn_.clear();
39  nameOut_.clear();
40  if (config.has("ObsData")) {
41  const eckit::LocalConfiguration dataConfig(config, "ObsData");
42  if (dataConfig.has("ObsDataIn")) {
43  nameIn_ = dataConfig.getString("ObsDataIn.filename");
44  otOpen(nameIn_);
45  }
46  if (dataConfig.has("ObsDataOut")) {
47  nameOut_ = dataConfig.getString("ObsDataOut.filename");
48  }
49  }
50  oops::Log::trace() << "ObsTable::ObsTable created" << std::endl;
51 }
52 
53 // -----------------------------------------------------------------------------
54 
56  if (!nameOut_.empty()) {
58  }
59  oops::Log::trace() << "ObsTable::ObsTable destructed" << std::endl;
60 }
61 
62 // -----------------------------------------------------------------------------
63 
64 void ObsTable::putdb(const std::string & col, const std::vector<double> & vec) const {
65  ASSERT(vec.size() == nobs());
66  ASSERT(data_.find(col) == data_.end());
67  data_.insert(std::pair<std::string, std::vector<double> >(col, vec));
68 }
69 
70 // -----------------------------------------------------------------------------
71 
72 void ObsTable::getdb(const std::string & col, std::vector<double> & vec) const {
73  std::map<std::string, std::vector<double> >::const_iterator ic = data_.find(col);
74  ASSERT(ic != data_.end());
75  vec.resize(nobs());
76  for (unsigned int jobs = 0; jobs < nobs(); ++jobs) {
77  vec[jobs] = ic->second[jobs];
78  }
79 }
80 
81 // -----------------------------------------------------------------------------
82 
83 LocsL95 * ObsTable::locations(const util::DateTime & t1, const util::DateTime & t2) const {
84  std::vector<int> olist = timeSelect(t1, t2);
85  const int nobs = olist.size();
86  std::vector<double> locs(nobs);
87  for (int jobs = 0; jobs < nobs; ++jobs) locs[jobs]=locations_[olist[jobs]];
88  return new LocsL95(olist, locs);
89 }
90 
91 // -----------------------------------------------------------------------------
92 
93 std::vector<int> ObsTable::timeSelect(const util::DateTime & t1,
94  const util::DateTime & t2) const {
95  std::vector<int> mask;
96  for (unsigned int jobs = 0; jobs < nobs(); ++jobs)
97  if (times_[jobs] > t1 && times_[jobs] <= t2) mask.push_back(jobs);
98  return mask;
99 }
100 
101 // -----------------------------------------------------------------------------
102 
103 void ObsTable::generateDistribution(const eckit::Configuration & config) {
104  oops::Log::trace() << "ObsTable::generateDistribution starting" << std::endl;
105 
106  util::Duration first(config.getString("begin"));
107  util::Duration last(winend_-winbgn_);
108  if (config.has("end")) {
109  last = util::Duration(config.getString("end"));
110  }
111  util::Duration freq(config.getString("obs_frequency"));
112 
113  int nobstimes = 0;
114  util::Duration step(first);
115  while (step <= last) {
116  ++nobstimes;
117  step += freq;
118  }
119 
120  const unsigned int nobs_locations = config.getInt("obs_density");
121  const unsigned int nobs = nobs_locations*nobstimes;
122  double dx = 1.0/static_cast<double>(nobs_locations);
123 
124  times_.resize(nobs);
125  locations_.resize(nobs);
126 
127  unsigned int iobs = 0;
128  util::DateTime now(winbgn_);
129  step = first;
130  while (step <= last) {
131  now = winbgn_ + step;
132  for (unsigned int jobs = 0; jobs < nobs_locations; ++jobs) {
133  double xpos = jobs*dx;
134  times_[iobs] = now;
135  locations_[iobs] = xpos;
136  ++iobs;
137  }
138  step += freq;
139  }
140  ASSERT(iobs == nobs);
141 
142 // Generate obs error
143  const double err = config.getDouble("obs_error");
144  std::vector<double> obserr(nobs);
145  for (unsigned int jj = 0; jj < nobs; ++jj) {
146  obserr[jj] = err;
147  }
148  this->putdb("ObsErr", obserr);
149 
150  oops::Log::trace() << "ObsTable::generateDistribution done" << std::endl;
151 }
152 
153 // -----------------------------------------------------------------------------
154 
155 void ObsTable::printJo(const ObsVec1D & ydep, const ObsVec1D & grad) {
156  oops::Log::info() << "ObsTable::printJo not implemented" << std::endl;
157 }
158 
159 // -----------------------------------------------------------------------------
160 // ObsTable Private Methods
161 // -----------------------------------------------------------------------------
162 
163 void ObsTable::otOpen(const std::string & filename) {
164  oops::Log::trace() << "ObsTable::ot_read starting" << std::endl;
165  std::ifstream fin(filename.c_str());
166  if (!fin.is_open()) ABORT("ObsTable::otOpen: Error opening file");
167 
168  int ncol, nobs;
169  fin >> ncol;
170 
171  std::vector<std::string> colnames;
172  for (int jc = 0; jc < ncol; ++jc) {
173  std::string col;
174  fin >> col;
175  colnames.push_back(col);
176  }
177 
178  fin >> nobs;
179  locations_.resize(nobs);
180  std::vector<double> newcol(nobs);
181  for (int jc = 0; jc < ncol; ++jc) {
182  ASSERT(data_.find(colnames[jc]) == data_.end());
183  data_.insert(std::pair<std::string, std::vector<double> >(colnames[jc], newcol));
184  }
185 
186  times_.clear();
187  int jjj;
188  for (int jobs = 0; jobs < nobs; ++jobs) {
189  fin >> jjj;
190  ASSERT(jjj == jobs);
191  std::string sss;
192  fin >> sss;
193  util::DateTime ttt(sss);
194  times_.push_back(ttt);
195  fin >> locations_[jobs];
196  for (std::map<std::string, std::vector<double> >::iterator jo = data_.begin();
197  jo != data_.end(); ++jo)
198  fin >> jo->second[jobs];
199  }
200 
201  fin.close();
202  oops::Log::trace() << "ObsTable::ot_read done" << std::endl;
203 }
204 
205 // -----------------------------------------------------------------------------
206 
207 void ObsTable::otWrite(const std::string & filename) const {
208  oops::Log::trace() << "ObsTable::otWrite writing " << filename << std::endl;
209  std::ofstream fout(filename.c_str());
210  if (!fout.is_open()) ABORT("ObsTable::otWrite: Error opening file");
211 
212  int ncol = data_.size();
213  fout << ncol << std::endl;
214 
215  for (std::map<std::string, std::vector<double> >::const_iterator jo = data_.begin();
216  jo != data_.end(); ++jo)
217  fout << jo->first << std::endl;
218 
219  int nobs = times_.size();
220  fout << nobs << std::endl;
221  for (int jobs = 0; jobs < nobs; ++jobs) {
222  fout << jobs;
223  fout << " " << times_[jobs];
224  fout << " " << locations_[jobs];
225  for (std::map<std::string, std::vector<double> >::const_iterator jo = data_.begin();
226  jo != data_.end(); ++jo)
227  fout << " " << jo->second[jobs];
228  fout << std::endl;
229  }
230 
231  fout.close();
232  oops::Log::trace() << "ObsTable::otWrite done" << std::endl;
233 }
234 
235 // -----------------------------------------------------------------------------
236 
237 void ObsTable::print(std::ostream & os) const {
238  os << "ObsTable: assimilation window = " << winbgn_ << " to " << winend_ << std::endl;
239  os << "ObsTable: file in = " << nameIn_ << ", file out = " << nameOut_ << std::endl;
240 }
241 
242 // -----------------------------------------------------------------------------
243 
244 } // namespace lorenz95
void otWrite(const std::string &) const
std::map< std::string, std::vector< double > > data_
Definition: ObsTable.h:66
std::vector< util::DateTime > times_
Definition: ObsTable.h:64
std::vector< int > timeSelect(const util::DateTime &, const util::DateTime &) const
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT end
void putdb(const std::string &, const std::vector< double > &) const
real, parameter t2
void print(std::ostream &) const
std::string nameOut_
Definition: ObsTable.h:69
LocsL95 * locations(const util::DateTime &t1, const util::DateTime &t2) const
LocsL95 class to handle locations for L95 model.
Definition: LocsL95.h:28
The namespace for the main oops code.
Vector in observation space.
Definition: ObsVec1D.h:32
void getdb(const std::string &, std::vector< double > &) const
const util::DateTime winbgn_
Definition: ObsTable.h:61
void otOpen(const std::string &)
std::vector< double > locations_
Definition: ObsTable.h:65
unsigned int nobs() const
Definition: ObsTable.h:54
subroutine, public info(self)
std::string nameIn_
Definition: ObsTable.h:68
The namespace for the L95 model.
real, parameter t1
enddo ! cludge for now
subroutine, public step(x, g)
void printJo(const ObsVec1D &, const ObsVec1D &)
type(tms), dimension(nblks), private last
const eckit::Configuration & config() const
Access information.
Definition: ObsSpaceBase.h:34
void generateDistribution(const eckit::Configuration &)
Pure virtual methods.
ObsTable(const eckit::Configuration &, const util::DateTime &, const util::DateTime &)
const util::DateTime winend_
Definition: ObsTable.h:62