IODA Bundle
ObsFilters.h
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 #ifndef OOPS_BASE_OBSFILTERS_H_
9 #define OOPS_BASE_OBSFILTERS_H_
10 
11 #include <memory>
12 #include <set>
13 #include <vector>
14 
15 #include <boost/noncopyable.hpp>
16 
17 #include "eckit/config/LocalConfiguration.h"
19 #include "oops/base/Variables.h"
20 #include "oops/interface/GeoVaLs.h"
25 #include "oops/util/IntSetParser.h"
26 #include "oops/util/Printable.h"
27 
28 namespace oops {
29 
30 /// Holds observation filters (usually QC) for one observation type
31 
32 // -----------------------------------------------------------------------------
33 
34 template <typename OBS>
35 class ObsFilters : public util::Printable,
36  private boost::noncopyable {
41  typedef std::shared_ptr<ObsFilterBase<OBS> > ObsFilterPtr_;
42  typedef std::shared_ptr<ObsDataVector<OBS, int> > ObsDataPtr_;
43 
44  public:
45  /// Initialize all filters for \p obspace, from parameters, using
46  /// \p qcflags and \p obserr (observation error variances)
47  /// \p iteration argument indicates outer loop iteration in the variational
48  /// assimilation
49  ObsFilters(const ObsSpace_ &, const std::vector<ObsFilterParametersWrapper<OBS>> &,
50  ObsDataPtr_ qcflags, ObsVector_ & obserr, const int iteration = 0);
51 
52  void preProcess() const;
53  void priorFilter(const GeoVaLs_ &) const;
54  void postFilter(const ObsVector_ &, const ObsDiags_ &) const;
55 
56  Variables requiredVars() const {return geovars_;}
58 
59  private:
60  void print(std::ostream &) const override;
61 
62  std::vector<ObsFilterPtr_> filters_;
67  std::shared_ptr<ObsDataVector<OBS, float> > obserrtmp_;
68 };
69 
70 // -----------------------------------------------------------------------------
71 
72 template <typename OBS>
74  const std::vector<ObsFilterParametersWrapper<OBS>> & filtersParams,
75  ObsDataPtr_ qcflags, ObsVector_ & obserr, const int iteration)
76  : filters_(), geovars_(), diagvars_(), qcflags_(qcflags), obserr_(obserr),
77  obserrtmp_(new ObsDataVector<OBS, float>(obserr)) {
78  Log::trace() << "ObsFilters::ObsFilters starting:\n";
79  for (const ObsFilterParametersWrapper<OBS> &filterParams : filtersParams)
80  Log::trace() << " " << filterParams << std::endl;
81 
82 // Prepare QC handling and statistics if any filters are present
83  if (filtersParams.size() > 0) {
84  eckit::LocalConfiguration preconf;
85  preconf.set("filter", "QCmanager");
86  filters_.push_back(FilterFactory<OBS>::create(os, preconf, qcflags_, obserrtmp_));
87  }
88 
89 // Create the filters, only at 0-th iteration, or at iterations specified in "apply at iterations"
90  for (const ObsFilterParametersWrapper<OBS> &filterParams : filtersParams) {
91  // Only create filters for the 0-th iteration by default
92  bool apply = (iteration == 0);
93  // If "apply at iterations" is set, check if this is the right iteration
94  if (filterParams.applyAtIterations.value() != boost::none) {
95  std::set<int> iters = parseIntSet(*filterParams.applyAtIterations.value());
96  apply = contains(iters, iteration);
97  }
98  if (apply) {
99  ObsFilterPtr_ tmp(FilterFactory<OBS>::create(os, filterParams.filterParameters,
100  qcflags_, obserrtmp_));
101  geovars_ += tmp->requiredVars();
102  diagvars_ += tmp->requiredHdiagnostics();
103  filters_.push_back(tmp);
104  }
105  }
106 
107 // Create the final filter run at the end of the pipeline
108  if (filtersParams.size() > 0) {
109  eckit::LocalConfiguration preconf;
110  preconf.set("filter", "Final Check");
111  filters_.push_back(FilterFactory<OBS>::create(os, preconf, qcflags_, obserrtmp_));
112  }
113 
114  Log::trace() << "ObsFilters::ObsFilters done" << std::endl;
115 }
116 
117 // -----------------------------------------------------------------------------
118 
119 template<typename OBS>
121  for (const auto & filter : filters_) {
122  filter->preProcess();
123  }
124  obserrtmp_->mask(*qcflags_);
125  obserr_ = *obserrtmp_;
126 }
127 
128 // -----------------------------------------------------------------------------
129 
130 template<typename OBS>
131 void ObsFilters<OBS>::priorFilter(const GeoVaLs_ & gv) const {
132  for (const auto & filter : filters_) {
133  filter->priorFilter(gv);
134  }
135  obserrtmp_->mask(*qcflags_);
136  obserr_ = *obserrtmp_;
137 }
138 
139 // -----------------------------------------------------------------------------
140 
141 template<typename OBS>
142 void ObsFilters<OBS>::postFilter(const ObsVector_ & hofx, const ObsDiags_ & diags) const {
143  for (const auto & filter : filters_) {
144  filter->postFilter(hofx, diags);
145  }
146  obserrtmp_->mask(*qcflags_);
147  obserr_ = *obserrtmp_;
148 }
149 
150 // -----------------------------------------------------------------------------
151 
152 template <typename OBS>
153 void ObsFilters<OBS>::print(std::ostream & os) const {
154  os << "ObsFilters: " << filters_.size() << " elements:" << std::endl;
155  for (const auto & filter : filters_) {
156  os << *filter << std::endl;
157  }
158 }
159 
160 // -----------------------------------------------------------------------------
161 
162 } // namespace oops
163 
164 #endif // OOPS_BASE_OBSFILTERS_H_
ObsFilter Factory.
Contains a polymorphic parameter holding an instance of a subclass of ObsFilterParametersBase.
Definition: ObsFilterBase.h:89
Holds observation filters (usually QC) for one observation type.
Definition: ObsFilters.h:36
void postFilter(const ObsVector_ &, const ObsDiags_ &) const
Definition: ObsFilters.h:142
void priorFilter(const GeoVaLs_ &) const
Definition: ObsFilters.h:131
GeoVaLs< OBS > GeoVaLs_
Definition: ObsFilters.h:37
std::vector< ObsFilterPtr_ > filters_
Definition: ObsFilters.h:62
ObsDataPtr_ qcflags_
Definition: ObsFilters.h:65
void preProcess() const
Definition: ObsFilters.h:120
std::shared_ptr< ObsDataVector< OBS, float > > obserrtmp_
Definition: ObsFilters.h:67
std::shared_ptr< ObsFilterBase< OBS > > ObsFilterPtr_
Definition: ObsFilters.h:41
ObsDiagnostics< OBS > ObsDiags_
Definition: ObsFilters.h:38
Variables requiredHdiagnostics() const
Definition: ObsFilters.h:57
ObsSpace< OBS > ObsSpace_
Definition: ObsFilters.h:39
ObsVector< OBS > ObsVector_
Definition: ObsFilters.h:40
ObsVector_ & obserr_
Definition: ObsFilters.h:66
Variables geovars_
Definition: ObsFilters.h:63
std::shared_ptr< ObsDataVector< OBS, int > > ObsDataPtr_
Definition: ObsFilters.h:42
ObsFilters(const ObsSpace_ &, const std::vector< ObsFilterParametersWrapper< OBS >> &, ObsDataPtr_ qcflags, ObsVector_ &obserr, const int iteration=0)
Definition: ObsFilters.h:73
Variables requiredVars() const
Definition: ObsFilters.h:56
Variables diagvars_
Definition: ObsFilters.h:64
void print(std::ostream &) const override
Definition: ObsFilters.h:153
The namespace for the main oops code.
subroutine apply(self, field_in, field_out, field_nn_out)