cartesian-create.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 
32 
33 #ifndef RACK_CART_CREATE
34 #define RACK_CART_CREATE
35 
36 
37 
38 #include <drain/prog/CommandInstaller.h>
39 #include "resources.h"
40 
41 #include "composite.h"
42 
43 namespace rack {
44 
45 
46 
48 
54 class CartesianCreate : public Compositor {
55 
56 public:
57 
58 
59  CartesianCreate() : Compositor(__FUNCTION__, "Maps the current polar product to a Cartesian product."){
60  }
61 
62 
63  inline
64  void exec() const {
65 
66  RackContext & ctx = getContext<RackContext>();
67  drain::Logger mout(ctx.log, __FILE__, __FUNCTION__);
68 
69  Composite & composite = ctx.getComposite(RackContext::PRIVATE);
70 
71  mout.attention<LOG_DEBUG>("composite*: ", &composite, " accArray: ", composite.accArray);
72 
73  //composite.reset();
74  composite.accArray.reset(); // Not frame, otherwise --cSize spoiled
75  composite.dataSelector.reset();
76  composite.odim.clear();
77  composite.nodeMap.clear();
78 
79  //composite.odim.source.clear();
80 
81  // mout.attention("Composite counter N=", composite.odim.ACCnum, ")");
82 
83  if (composite.odim.ACCnum > 0){ // .counter
84  // mout.experimental("Clearing previous composite? N=", composite.counter, ")");
85  // mout.experimental("Clearing previous composite? N=", composite.odim.ACCnum, ")");
86  mout.hint<LOG_DEBUG>("Clearing previous composite. If that was not meant, use --cAdd to add, instead.");
87  composite.accArray.clear();
88  // clear metadata?
89  }
90 
91  // mout.attention("start add: ", composite.getTargetEncoding(), " odim.quantity=", composite.odim.quantity, " sel:", composite.dataSelector);
92  composite.odim.quantity = "";
93 
94  add(composite, RackContext::POLAR|RackContext::CURRENT, true);
95 
96  if (ctx.statusFlags.value > 0){
97  mout.warn("errors (", ctx.statusFlags, "), skipping extraction");
98  return;
99  }
100 
101  const drain::StringMatcher qualityMatcher("QIND"); // coming op: other
102 
103  mout.accept<LOG_NOTICE>("EPSG_A: ", composite.odim.epsg);
104  if (qualityMatcher.test(composite.odim.quantity)){
105  mout.note("Quality [", composite.odim.quantity, "] as input: extracting data only");
106  extract(composite, "d");
107  }
108  else {
109  extract(composite, "dw");
110  }
111  mout.accept<LOG_NOTICE>("EPSG: ", composite.odim.epsg);
112  // mout.attention("extract dw");
113 
114 
115  // When are these needed? Upon one-liner DBZH, VRAD singles?
116  composite.dataSelector.setQuantities(""); // why quantity only?
117  // mout.experimental("quantity ["," clearance removed");
118  composite.odim.quantity.clear();
119 
120  // mout.attention("angles: ", drain::sprinter(composite.odim.angles, "<>"));
121 
122  // better without...
123  // ctx.cartesianHi5[ODIMPathElem::WHAT].data.attributes["source2"] = (*ctx.currentPolarHi5)["what"].data.attributes["source"];
124  }
125 
126 };
127 
128 
130 
131 public:
132 
133  inline
134  CompositeCreateTile() : Compositor(__FUNCTION__, "Maps the current polar product to a tile to be used in compositing."){
135  }
136 
137  inline
138  void exec() const {
139 
140  RackContext & ctx = getContext<RackContext>();
141  drain::Logger mout(ctx.log, __FILE__, __FUNCTION__);
142 
143  //Composite & composite = getComposite();
144  Composite & composite = ctx.composite;
145 
146  if (!composite.geometryIsSet())
147  mout.error("Composite geometry undefined, cannot create tile");
148 
149  if (! composite.bboxIsSet())
150  mout.error("Bounding box undefined, cannot create tile");
151 
152  if (! composite.projectionIsSet()) // or use first input (bbox reset)
153  mout.error("Projection undefined, cannot create tile");
154 
155  if ((composite.odim.ACCnum > 0) || (!composite.odim.quantity.empty())){
156  mout.debug("Clearing previous composite...");
157  // Consider: composite.clear() ?
158  composite.accArray.clear();
159  composite.odim.quantity.clear();
160  composite.odim.ACCnum = 0;
161  composite.odim.scaling.set(0,0);
162  composite.odim.type.clear(); // ? risky
163  mout.info("Cleared previous composite");
164  }
165 
166 
167  composite.setCropping(true);
168  //add(composite, RackContext::POLAR|RackContext::CURRENT);
169  add(composite, RackContext::POLAR|RackContext::CURRENT, true); // updateSelector
170  extract(composite, "dw");
171 
172  // "Debugging"
173  if (!composite.isCropping()){
174  mout.warn("Composite cropping switched off during op");
175  mout.error("? Programming error in parallel comp design");
176  }
177 
178  composite.setCropping(false);
179 
180  }
181 
182 private:
183 
184 
185  // const CompositeAdd & addCmd;
186  // const CompositeExtract & extractCmd;
187 };
188 
189 
190 class CartesianRange : public drain::BasicCommand { //SimpleCommand<double> {
191 
192 public:
193 
194  inline
195  CartesianRange() : drain::BasicCommand(__FUNCTION__, "Force a range for single-radar cartesian products (0=use-metadata)."){
196  getParameters().link("range", PolarODIM::defaultRange, "km");
197  };
198 
199  inline
200  CartesianRange(const CartesianRange & cmd) : drain::BasicCommand(__FUNCTION__, cmd.getDescription()) {
201  getParameters().link("range", PolarODIM::defaultRange, "km");
202  };
203 
204 };
205 
207 
214 
215 public:
216 
217 
218  CartesianCreateLookup() : drain::BasicCommand(__FUNCTION__, "Creates lookup objects"){
219  }
220 
221 
222  inline
223  void exec() const {
224 
225  RackContext & ctx = getContext<RackContext>();
226  drain::Logger mout(ctx.log, __FILE__, __FUNCTION__);
227 
228  Composite & composite = ctx.getComposite(RackContext::PRIVATE);
229 
230  mout.debug("composite*: ", &composite, "accArray: ", composite.accArray);
231 
232  if (!ctx.polarInputHi5.empty())
233  mout.warn("polar input not empty");
234 
235  composite.createBinIndex(ctx.polarInputHi5);
236 
237 
238  }
239 
240 };
241 
243 
250 
251 public:
252 
253  CartesianReset() : drain::BasicCommand(__FUNCTION__, "Clears the current Cartesian product."){
254  }
255 
256  inline
257  void exec() const override {
258 
259  RackContext & ctx = getContext<RackContext>();
260 
261  ctx.composite.reset();
263  ctx.composite.odim.source.clear();
264  ctx.composite.nodeMap.clear();
265  ctx.composite.odim.clear(); // 2022/12
266  ctx.unsetCurrentImages();
267 
268  // Consider including in reset:
269  // ctx.composite.metadataMap.clear();
270 
271  }
272 
273 };
274 
275 } // rack::
276 
277 
278 
279 #endif
280 
281 // Rack
Simple implementation of Command: adds name , description and parameters .
Definition: Command.h:385
StatusFlags statusFlags
Optional log filename (syntax): when defined, automatically opened by CommandBank::run()
Definition: Context.h:98
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:310
Logger & error(const TT &... args)
Echoes.
Definition: Log.h:414
Logger & accept(const TT &... args)
Some input has been accepted, for example by a syntax.
Definition: Log.h:580
Logger & attention(const TT &... args)
Possible error, but execution can continue. Special type of Logger::warn().
Definition: Log.h:474
Logger & note(const TT &... args)
For top-level information.
Definition: Log.h:487
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:428
Logger & debug(const TT &... args)
Public, yet typically used "internally", when TIMING=true.
Definition: Log.h:678
Logger & hint(const TT &... args)
Like advice, but weaker.
Definition: Log.h:632
General-purpose key matcher: tests string equality, or regExp, if defined as such.
Definition: StringMatcher.h:58
bool test(const std::string &s) const
Test with direct string matching or regExp, if defined.
Definition: StringMatcher.cpp:70
void clear()
Resets the accumulation array values to undetectValue. Does not change the geometry.
Definition: AccumulationArray.cpp:63
void reset()
Collapses the accumulation geometries to zero area.
Definition: AccumulationArray.h:151
AccumulationArray accArray
Todo: export.
Definition: Accumulator.h:80
bool bboxIsSet() const
Returns true, if the bounding box (geographical extent) has been set.
Definition: GeoFrame.h:99
bool geometryIsSet() const
Return true, if array area is greater than zero.
Definition: GeoFrame.h:89
bool projectionIsSet() const
Returns true, if the geographical extent has been set.
Definition: GeoFrame.h:83
Creates a single-radar Cartesian data set (2D data of both quantity and quality).
Definition: cartesian-create.h:213
void exec() const
Run the command with current parameter values.
Definition: cartesian-create.h:223
Creates a single-radar Cartesian data set (2D data of both quantity and quality).
Definition: cartesian-create.h:54
void exec() const
Run the command with current parameter values.
Definition: cartesian-create.h:64
int epsg
This is needed for palette operations (of single-radar Cartesian products).
Definition: CartesianODIM.h:119
Definition: cartesian-create.h:190
Creates a single-radar Cartesian data set (2D data of both quantity and quality).
Definition: cartesian-create.h:249
void exec() const override
Run the command with current parameter values.
Definition: cartesian-create.h:257
Definition: cartesian-create.h:129
void exec() const
Run the command with current parameter values.
Definition: cartesian-create.h:138
Cartesian composite (mosaic) of data from several radars.
Definition: Composite.h:105
void setCropping(bool cropping=true)
If cropping is set, calling addPolar() also crops the bounding box to intersection of radar area and ...
Definition: Composite.h:148
void createBinIndex(Hi5Tree &dst)
Definition: Composite.cpp:442
drain::VariableMap nodeMap
Node keys (like "fivan") associated with upper left corner pixel coordinates [int] of the "tile".
Definition: Composite.h:192
Definition: composite.h:58
void add(Composite &composite, int inputFilter, bool updateSelector=true) const
Definition: composite.cpp:112
void extract(Composite &composite, const std::string &channels, const std::string &crop="") const
Definition: composite.cpp:669
void setQuantities(const std::string &s)
Sets basic quantities and quality quantities. These sets are separated by '/'.
Definition: DataSelector.cpp:282
void reset()
Restore default values.
Definition: DataSelector.cpp:156
std::string type
This is non-standard (not in ODIM), but a practical means of handling storage type of datasets.
Definition: EncodingODIM.h:146
void clear()
Resets the values.
Definition: EncodingODIM.cpp:171
Hi5Tree polarInputHi5
The last input file read, typically a volume. May be concatenated ie. read in incrementally.
Definition: resources-base.h:86
std::string quantity
dataX/what (obligatory)
Definition: ODIM.h:181
Resources provided separately for each thread.
Definition: resources.h:67
Composite & getComposite(Hi5RoleFlagger::ivalue_t filter)
Definition: resources.cpp:149
Composite composite
TODO: inherit from ProductBase.
Definition: resources.h:118
OD odim
For storing the scaling and encoding of (1st) input or user-defined values. Also for bookkeeping of d...
Definition: RadarAccumulator.h:111
DataSelector dataSelector
Input data selector.
Definition: RadarAccumulator.h:102
void setTargetEncoding(const std::string &encoding)
Not critical. If set, needed to warn if input data does not match the expected / potential targetEnco...
Definition: RadarAccumulator.h:125
Definition: DataSelector.cpp:44