ARTS 2.5.11 (git: 725533f0)
m_append.h
Go to the documentation of this file.
1
12#ifndef m_append_h
13#define m_append_h
14
15#include "agenda_class.h"
16#include "array.h"
17#include "exceptions.h"
18#include "matpack_data.h"
19
20/* Implementations for supported types follow. */
21
22/* Implementation for array types */
23template <class T>
24void Append( // WS Generic Output:
25 Array<T>& out,
26 const String& /* out_name */,
27 // WS Generic Input:
28 const Array<T>& in,
29 const String& direction _U_,
30 const String& /* in_name */,
31 const String& /* direction_name */,
32 const Verbosity&) {
33 const Array<T>* in_pnt;
34 Array<T> in_copy;
35
36 if (&in == &out) {
37 in_copy = in;
38 in_pnt = &in_copy;
39 } else
40 in_pnt = &in;
41
42 const Array<T>& in_ref = *in_pnt;
43
44 // Reserve memory in advance to avoid reallocations:
45 out.reserve(out.nelem() + in_ref.nelem());
46 // Append in to end of out:
47 for (Index i = 0; i < in_ref.nelem(); ++i) out.push_back(in_ref[i]);
48}
49
50inline void Append( // WS Generic Output:
52 const String& /* out_name */,
53 // WS Generic Input:
54 const ArrayOfSpeciesTag& in,
55 const String& direction _U_,
56 const String& /* in_name */,
57 const String& /* direction_name */,
58 const Verbosity&) {
59 const ArrayOfSpeciesTag* in_pnt;
60 ArrayOfSpeciesTag in_copy;
61
62 if (&in == &out) {
63 in_copy = in;
64 in_pnt = &in_copy;
65 } else
66 in_pnt = &in;
67
68 const ArrayOfSpeciesTag& in_ref = *in_pnt;
69
70 // Reserve memory in advance to avoid reallocations:
71 out.reserve(out.nelem() + in_ref.nelem());
72 // Append in to end of out:
73 for (Index i = 0; i < in_ref.nelem(); ++i) out.push_back(in_ref[i]);
74}
75
76/* Implementation for array types to append single element */
77template <class T>
78void Append( // WS Generic Output:
79 Array<T>& out,
80 const String& /* out_name */,
81 // WS Generic Input:
82 const T& in,
83 const String& direction _U_,
84 const String& /* in_name */,
85 const String& /* direction_name */,
86 const Verbosity&) {
87 // Append in to end of out:
88 out.push_back(in);
89}
90
91/* Implementation for array types to append single element */
92inline void Append( // WS Generic Output:
94 const String& /* out_name */,
95 // WS Generic Input:
96 const SpeciesTag& in,
97 const String& direction _U_,
98 const String& /* in_name */,
99 const String& /* direction_name */,
100 const Verbosity&) {
101 // Append in to end of out:
102 out.push_back(in);
103}
104
105/* Implementation for array types to append single element */
106inline void Append(Workspace& ws,
107 // WS Generic Output:
108 ArrayOfAgenda& out,
109 const String& out_name,
110 // WS Generic Input:
111 const Agenda& in,
112 const String& direction _U_,
113 const String& /* in_name */,
114 const String& /* direction_name */,
115 const Verbosity& verbosity) {
116 // Append in to end of out:
117 auto& newag = out.emplace_back(in);
118 newag.set_name(out_name);
119 newag.check(ws, verbosity);
120}
121
122/* Implementation for array types to append single element */
123inline void Append(Workspace& ws_in,
124 // WS Generic Output:
125 ArrayOfAgenda& out,
126 const String& out_name,
127 // WS Generic Input:
128 const ArrayOfAgenda& in,
129 const String& direction _U_,
130 const String& /* in_name */,
131 const String& /* direction_name */,
132 const Verbosity& verbosity) {
133 // Append in to end of out:
134 for (const auto & it : in) {
135 auto& newag = out.emplace_back(it);
136 newag.set_name(out_name);
137 newag.check(ws_in, verbosity);
138 }
139}
140
141/* Implementation for Vector */
142inline void Append( // WS Generic Output:
143 Vector& out,
144 const String& /* out_name */,
145 // WS Generic Input:
146 const Vector& in,
147 const String& direction _U_,
148 const String& /* in_name */,
149 const String& /* direction_name */,
150 const Verbosity&) {
151 const Vector* in_pnt;
152 Vector in_copy;
153
154 if (&in == &out) {
155 in_copy = in;
156 in_pnt = &in_copy;
157 } else
158 in_pnt = &in;
159
160 const Vector& in_ref = *in_pnt;
161
162 // Get backup of out:
163 Vector dummy = out;
164
165 // Make out the right size:
166 out.resize(dummy.nelem() + in_ref.nelem());
167
168 // Copy dummy to first part of out:
169 if (dummy.nelem()) out[Range(0, dummy.nelem())] = dummy;
170
171 // Copy in to last part of out:
172 if (in_ref.nelem()) out[Range(dummy.nelem(), in_ref.nelem())] = in_ref;
173}
174
175/* Implementation for Matrix */
176inline void Append( // WS Generic Output:
177 Matrix& out,
178 const String& /* out_name */,
179 // WS Generic Input:
180 const Matrix& in,
181 const String& direction,
182 const String& /* in_name */,
183 const String& /* direction_name */,
184 const Verbosity&) {
185 const Matrix* in_pnt;
186 Matrix in_copy;
187
188 if (&in == &out) {
189 in_copy = in;
190 in_pnt = &in_copy;
191 } else
192 in_pnt = &in;
193
194 const Matrix& in_ref = *in_pnt;
195
196 // Get backup of out:
197 Matrix dummy = out;
198
199 if (!out.nrows() || !out.ncols()) {
200 out = in_ref;
201 } else if (direction == "leading") {
202 if (out.ncols() != in_ref.ncols())
203 throw runtime_error(
204 "Input and output matrix must have the same number of columns.");
205
206 out.resize(dummy.nrows() + in_ref.nrows(), dummy.ncols());
207
208 if (dummy.nrows() && dummy.ncols())
209 out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
210 if (dummy.nrows() && in_ref.nrows() && in_ref.ncols())
211 out(Range(dummy.nrows(), in_ref.nrows()), Range(0, in_ref.ncols())) =
212 in_ref;
213 } else if (direction == "trailing") {
214 if (out.nrows() != in_ref.nrows())
215 throw runtime_error(
216 "Input and output matrix must have the same number of rows.");
217
218 out.resize(dummy.nrows(), dummy.ncols() + in_ref.ncols());
219
220 if (dummy.nrows() && dummy.ncols())
221 out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
222 if (dummy.ncols() && in_ref.nrows() && in_ref.ncols())
223 out(Range(0, in_ref.nrows()), Range(dummy.ncols(), in_ref.ncols())) =
224 in_ref;
225 } else
226 throw runtime_error(
227 R"(Dimension must be either "leading" or "trailing".)");
228}
229
230/* Implementation for Matrix/Vector */
231inline void Append( // WS Generic Output:
232 Matrix& out,
233 const String& /* out_name */,
234 // WS Generic Input:
235 const Vector& in,
236 const String& direction,
237 const String& /* in_name */,
238 const String& /* direction_name */,
239 const Verbosity&) {
240 // Get backup of out:
241 Matrix dummy = out;
242
243 if (direction == "leading") {
244 if (!out.nrows() || !out.ncols()) {
245 out = ExhaustiveMatrixView{in};
246 } else {
247 if (out.ncols() != in.nelem())
248 throw runtime_error(
249 "Number of elements in the input Vector has to match "
250 "the number of columns in the output Matrix.");
251
252 out.resize(dummy.nrows() + 1, dummy.ncols());
253 out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
254 out(Range(dummy.nrows(), 1), Range(0, in.nelem())) = transpose(ExhaustiveMatrixView{in});
255 }
256 } else if (direction == "trailing") {
257 if (!out.nrows() || !out.ncols()) {
258 out = transpose(ExhaustiveMatrixView{in});
259 } else if (in.nelem()) {
260 if (out.nrows() != in.nelem() && out.nrows() && out.ncols())
261 throw runtime_error(
262 "Number of elements in the input Vector has to match "
263 "the number of rows in the output Matrix.");
264
265 out.resize(dummy.nrows(), dummy.ncols() + 1);
266 out(Range(0, dummy.nrows()), Range(0, dummy.ncols())) = dummy;
267 out(Range(0, in.nelem()), Range(dummy.ncols(), 1)) = ExhaustiveMatrixView{in};
268 }
269 } else
270 throw runtime_error(
271 R"(Dimension must be either "leading" or "trailing".)");
272}
273
274/* Implementation for Vector/Numeric */
275inline void Append( // WS Generic Output:
276 Vector& out,
277 const String& /* out_name */,
278 // WS Generic Input:
279 const Numeric& in,
280 const String& direction _U_,
281 const String& /* in_name */,
282 const String& /* direction_name */,
283 const Verbosity&) {
284 // Get backup of out:
285 Vector dummy = out;
286
287 // Make out the right size:
288 out.resize(dummy.nelem() + 1);
289
290 // Copy dummy to first part of out:
291 if (dummy.nelem()) out[Range(0, dummy.nelem())] = dummy;
292
293 // Copy in to last part of out:
294 out[Range(dummy.nelem(), 1)] = in;
295}
296
297/* Implementation for Tensor3/Matrix */
298inline void Append( // WS Generic Output:
299 Tensor3& out,
300 const String& /* out_name */,
301 // WS Generic Input:
302 const Matrix& in,
303 // const String& direction,
304 const String& direction _U_,
305 const String& /* in_name */,
306 const String& /* direction_name */,
307 const Verbosity&) {
308 // Get backup of out:
309 Tensor3 dummy = out;
310
311 if (!out.npages() || !out.nrows() || !out.ncols()) {
312 out.resize(1, in.nrows(), in.ncols());
313 out(0, joker, joker) = in;
314 } else {
315 if (out.nrows() != in.nrows() || out.ncols() != in.ncols())
316 throw runtime_error(
317 "Number of rows and columns in the input Matrix have to match\n"
318 "the number of rows and columns in the output Tensor3.");
319
320 out.resize(dummy.npages() + 1, dummy.nrows(), dummy.ncols());
321 out(Range(0, dummy.npages()),
322 Range(0, dummy.nrows()),
323 Range(0, dummy.ncols())) = dummy;
324 out(dummy.npages(), Range(0, dummy.nrows()), Range(0, dummy.ncols())) = in;
325 }
326}
327
328/* Implementation for Tensor3 */
329inline void Append( // WS Generic Output:
330 Tensor3& out,
331 const String& /* out_name */,
332 // WS Generic Input:
333 const Tensor3& in,
334 // const String& direction,
335 const String& direction _U_,
336 const String& /* in_name */,
337 const String& /* direction_name */,
338 const Verbosity&) {
339 const Tensor3* in_pnt;
340 Tensor3 in_copy;
341
342 if (&in == &out) {
343 in_copy = in;
344 in_pnt = &in_copy;
345 } else
346 in_pnt = &in;
347
348 const Tensor3& in_ref = *in_pnt;
349
350 // Get backup of out:
351 Tensor3 dummy = out;
352
353 if (out.nrows() != in_ref.nrows() || out.ncols() != in_ref.ncols())
354 throw runtime_error(
355 "Tensor3 append is performed in pages dimension.\n"
356 "All other dimensions (rows, columns) must have identical\n"
357 "sizes in In and Out Tensor.");
358
359 out.resize(dummy.npages() + in_ref.npages(), dummy.nrows(), dummy.ncols());
360
361 if (dummy.npages() && dummy.nrows() && dummy.ncols())
362 out(Range(0, dummy.npages()),
363 Range(0, dummy.nrows()),
364 Range(0, dummy.ncols())) = dummy;
365 if (dummy.npages() && in_ref.npages() && in_ref.nrows() && in_ref.ncols())
366 out(Range(dummy.npages(), in_ref.npages()),
367 Range(0, in_ref.nrows()),
368 Range(0, in_ref.ncols())) = in_ref;
369}
370
371/* Implementation for Tensor4/Tensor3 */
372inline void Append( // WS Generic Output:
373 Tensor4& out,
374 const String& /* out_name */,
375 // WS Generic Input:
376 const Tensor3& in,
377 // const String& direction,
378 const String& direction _U_,
379 const String& /* in_name */,
380 const String& /* direction_name */,
381 const Verbosity&) {
382 // Get backup of out:
383 Tensor4 dummy = out;
384
385 if (!out.nbooks() || !out.npages() || !out.nrows() || !out.ncols()) {
386 out.resize(1, in.npages(), in.nrows(), in.ncols());
387 out(0, joker, joker, joker) = in;
388 } else {
389 if (out.npages() != in.npages() || out.nrows() != in.nrows() ||
390 out.ncols() != in.ncols())
391 throw runtime_error(
392 "Dimensions of input Tensor3 have to match corresponding\n"
393 "dimensions in the output Tensor4.");
394
395 out.resize(
396 dummy.nbooks() + 1, dummy.npages(), dummy.nrows(), dummy.ncols());
397 out(Range(0, dummy.nbooks()),
398 Range(0, dummy.npages()),
399 Range(0, dummy.nrows()),
400 Range(0, dummy.ncols())) = dummy;
401 out(dummy.nbooks(),
402 Range(0, dummy.npages()),
403 Range(0, dummy.nrows()),
404 Range(0, dummy.ncols())) = in;
405 }
406}
407
408/* Implementation for Tensor4 */
409inline void Append( // WS Generic Output:
410 Tensor4& out,
411 const String& /* out_name */,
412 // WS Generic Input:
413 const Tensor4& in,
414 // const String& direction,
415 const String& direction _U_,
416 const String& /* in_name */,
417 const String& /* direction_name */,
418 const Verbosity&) {
419 const Tensor4* in_pnt;
420 Tensor4 in_copy;
421
422 if (&in == &out) {
423 in_copy = in;
424 in_pnt = &in_copy;
425 } else
426 in_pnt = &in;
427
428 const Tensor4& in_ref = *in_pnt;
429
430 // Get backup of out:
431 Tensor4 dummy = out;
432
433 if (out.npages() != in_ref.npages() || out.nrows() != in_ref.nrows() ||
434 out.ncols() != in_ref.ncols())
435 throw runtime_error(
436 "Tensor4 append is performed in books dimension.\n"
437 "All other dimensions (pages, rows, columns) must have identical\n"
438 "sizes in In and Out Tensor.");
439
440 out.resize(dummy.nbooks() + in_ref.nbooks(),
441 dummy.npages(),
442 dummy.nrows(),
443 dummy.ncols());
444
445 if (dummy.nbooks() && dummy.npages() && dummy.nrows() && dummy.ncols())
446 out(Range(0, dummy.nbooks()),
447 Range(0, dummy.npages()),
448 Range(0, dummy.nrows()),
449 Range(0, dummy.ncols())) = dummy;
450 if (dummy.nbooks() && in_ref.nbooks() && in_ref.npages() && in_ref.nrows() &&
451 in_ref.ncols())
452 out(Range(dummy.nbooks(), in_ref.nbooks()),
453 Range(0, in_ref.npages()),
454 Range(0, in_ref.nrows()),
455 Range(0, in_ref.ncols())) = in_ref;
456}
457
458/* Implementation for String */
459inline void Append( // WS Generic Output:
460 String& out,
461 const String& /* out_name */,
462 // WS Generic Input:
463 const String& in,
464 const String& direction _U_,
465 const String& /* in_name */,
466 const String& /* direction_name */,
467 const Verbosity&) {
468 // String stream for easy string operations:
469 ostringstream os;
470
471 os << out << in;
472
473 out = os.str();
474}
475
476#endif // m_append_h
Declarations for agendas.
This file contains the definition of Array.
The Agenda class.
This can be used to make arrays out of anything.
Definition array.h:31
Index nelem() const ARTS_NOEXCEPT
Definition array.h:75
Workspace class.
#define _U_
Definition config.h:177
The declarations of all the exception classes.
void Append(Array< T > &out, const String &, const Array< T > &in, const String &direction, const String &, const String &, const Verbosity &)
Definition m_append.h:24
Species::Tag SpeciesTag