ARTS 2.5.11 (git: 6827797f)
xml_io_basic_types.cc
Go to the documentation of this file.
1
2// File description
4
13#include "absorptionlines.h"
14#include "arts.h"
15#include "debug.h"
16#include "isotopologues.h"
17#include "messages.h"
18#include "quantum_numbers.h"
19#include "xml_io.h"
20#include <algorithm>
21#include <vector>
22
24// Overloaded functions for reading/writing data from/to XML stream
26
27//=== JacobianTarget ==================================================================
28
30
35void xml_read_from_stream(istream& is_xml,
37 bifstream* pbifs,
38 const Verbosity& verbosity) {
39 ArtsXMLTag tag(verbosity);
40
41 tag.read_from_stream(is_xml);
42 tag.check_name("JacobianTarget");
43
44 // Type information
45 String typestr, subtypestr;
46 tag.get_attribute_value("Type", typestr);
47 tag.get_attribute_value("SubType", subtypestr);
48 jt.TargetType(typestr);
49 jt.TargetSubType(subtypestr);
50
52 if (jt.needQuantumIdentity()) {
53 String qid;
54 tag.get_attribute_value("id", qid);
55 jt.qid = QuantumIdentifier(qid);
56 }
57
58 if (jt.needArrayOfSpeciesTag()) {
59 String key;
60 tag.get_attribute_value("species", key);
62 }
63
64 if (jt.needString()) {
65 tag.get_attribute_value("string_key", jt.string_id);
66 }
67
68 if (pbifs) {
69 *pbifs >> jt.perturbation;
70 if (pbifs->fail()) {
71 xml_data_parse_error(tag, "");
72 }
73 } else {
74 is_xml >> double_imanip() >> jt.perturbation;
75 if (is_xml.fail()) {
76 xml_data_parse_error(tag, "");
77 }
78 }
79
80 tag.read_from_stream(is_xml);
81 tag.check_name("/JacobianTarget");
82
84 "Bad input: ", typestr, " or ", subtypestr, '\n', "\tCannot be interpreted as a type or substype...\n")
85}
86
88
94void xml_write_to_stream(ostream& os_xml,
95 const JacobianTarget& jt,
96 bofstream* pbofs,
97 const String& name,
98 const Verbosity& verbosity) {
99 ArtsXMLTag open_tag(verbosity);
100 ArtsXMLTag close_tag(verbosity);
101
102 os_xml << '\n';
103 open_tag.set_name("JacobianTarget");
104 if (name.length()) open_tag.add_attribute("name", name);
105
106 // Type information
107 open_tag.add_attribute("Type", jt.TargetType());
108 open_tag.add_attribute("SubType", jt.TargetSubType());
109
111 if (jt.needQuantumIdentity()) {
112 open_tag.add_attribute("id", var_string(jt.qid));
113 }
114
115 if (jt.needArrayOfSpeciesTag()) {
116 open_tag.add_attribute("species", jt.species_array_id.Name());
117 }
118
119 if (jt.needString()) {
120 open_tag.add_attribute("string_key", jt.string_id);
121 }
122 open_tag.write_to_stream(os_xml);
123
124 if (pbofs)
125 *pbofs << jt.perturbation;
126 else
127 os_xml << ' ' << jt.perturbation << ' ';
128
129 close_tag.set_name("/JacobianTarget");
130 close_tag.write_to_stream(os_xml);
131 os_xml << '\n';
132}
133
134//=== Rational =========================================================
135
137
142void xml_read_from_stream(istream& is_xml,
143 Rational& rational,
144 bifstream* pbifs,
145 const Verbosity& verbosity) {
146 ArtsXMLTag tag(verbosity);
147
148 tag.read_from_stream(is_xml);
149 tag.check_name("Rational");
150
151 if (pbifs) {
152 *pbifs >> rational;
153 if (pbifs->fail()) {
154 xml_data_parse_error(tag, "");
155 }
156 } else {
157 is_xml >> rational;
158 if (is_xml.fail()) {
159 xml_data_parse_error(tag, "");
160 }
161 }
162
163 tag.read_from_stream(is_xml);
164 tag.check_name("/Rational");
165}
166
168
174void xml_write_to_stream(ostream& os_xml,
175 const Rational& rational,
176 bofstream* pbofs,
177 const String& name,
178 const Verbosity& verbosity) {
179 ArtsXMLTag open_tag(verbosity);
180 ArtsXMLTag close_tag(verbosity);
181
182 open_tag.set_name("Rational");
183 if (name.length()) open_tag.add_attribute("name", name);
184
185 open_tag.write_to_stream(os_xml);
186
187 if (pbofs)
188 *pbofs << rational;
189 else
190 os_xml << ' ' << rational << ' ';
191
192 close_tag.set_name("/Rational");
193 close_tag.write_to_stream(os_xml);
194 os_xml << '\n';
195}
196
197//=== TransmissionMatrix ================================================================
198
200
205void xml_read_from_stream(istream& is_xml,
207 bifstream* pbifs,
208 const Verbosity& verbosity) {
209 ArtsXMLTag tag(verbosity);
210 Index stokes_dim, nf;
211
212 tag.read_from_stream(is_xml);
213 tag.check_name("TransmissionMatrix");
214
215 tag.get_attribute_value("Stokes", stokes_dim);
216 tag.get_attribute_value("Freqs", nf);
217 tm = TransmissionMatrix(nf, stokes_dim);
218 if (pbifs) {
219 *pbifs >> tm;
220 if (pbifs->fail()) {
221 ostringstream os;
222 os << "TransmissionMatrix has wrong dimensions";
223 xml_data_parse_error(tag, os.str());
224 }
225 } else {
226 is_xml >> tm;
227 if (is_xml.fail()) {
228 ostringstream os;
229 os << "TransmissionMatrix has wrong dimensions";
230 xml_data_parse_error(tag, os.str());
231 }
232 }
233
234 tag.read_from_stream(is_xml);
235 tag.check_name("/TransmissionMatrix");
236}
237
239
245void xml_write_to_stream(ostream& os_xml,
246 const TransmissionMatrix& tm,
247 bofstream* pbofs,
248 const String& name,
249 const Verbosity& verbosity) {
250 ArtsXMLTag open_tag(verbosity);
251 ArtsXMLTag close_tag(verbosity);
252
253 open_tag.set_name("TransmissionMatrix");
254 if (name.length()) open_tag.add_attribute("name", name);
255 open_tag.add_attribute("Stokes", tm.stokes_dim);
256 open_tag.add_attribute("Freqs", tm.Frequencies());
257
258 open_tag.write_to_stream(os_xml);
259 os_xml << '\n';
260
262 if (pbofs)
263 *pbofs << tm;
264 else
265 os_xml << tm;
266
267 close_tag.set_name("/TransmissionMatrix");
268 close_tag.write_to_stream(os_xml);
269
270 os_xml << '\n';
271}
272
273//=== RadiationVector ================================================================
274
276
281void xml_read_from_stream(istream& is_xml,
282 RadiationVector& rv,
283 bifstream* pbifs,
284 const Verbosity& verbosity) {
285 ArtsXMLTag tag(verbosity);
286 Index stokes_dim, nf;
287
288 tag.read_from_stream(is_xml);
289 tag.check_name("RadiationVector");
290
291 tag.get_attribute_value("Stokes", stokes_dim);
292 tag.get_attribute_value("Freqs", nf);
293 rv = RadiationVector(nf, stokes_dim);
294 if (pbifs) {
295 *pbifs >> rv;
296 if (pbifs->fail()) {
297 ostringstream os;
298 os << "RadiationVector has wrong dimensions";
299 xml_data_parse_error(tag, os.str());
300 }
301 } else {
302 is_xml >> rv;
303 if (is_xml.fail()) {
304 ostringstream os;
305 os << "RadiationVector has wrong dimensions";
306 xml_data_parse_error(tag, os.str());
307 }
308 }
309
310 tag.read_from_stream(is_xml);
311 tag.check_name("/RadiationVector");
312}
313
315
321void xml_write_to_stream(ostream& os_xml,
322 const RadiationVector& rv,
323 bofstream* pbofs,
324 const String& name,
325 const Verbosity& verbosity) {
326 ArtsXMLTag open_tag(verbosity);
327 ArtsXMLTag close_tag(verbosity);
328
329 open_tag.set_name("RadiationVector");
330 if (name.length()) open_tag.add_attribute("name", name);
331 open_tag.add_attribute("Stokes", rv.stokes_dim);
332 open_tag.add_attribute("Freqs", rv.Frequencies());
333
334 open_tag.write_to_stream(os_xml);
335 os_xml << '\n';
336
338 if (pbofs)
339 *pbofs << rv;
340 else
341 os_xml << rv;
342
343 close_tag.set_name("/RadiationVector");
344 close_tag.write_to_stream(os_xml);
345
346 os_xml << '\n';
347}
348
349//=== Time ================================================================
350
352
357void xml_read_from_stream(istream& is_xml,
358 Time& t,
359 bifstream* pbifs [[maybe_unused]],
360 const Verbosity& verbosity) {
361 ArtsXMLTag tag(verbosity);
362
363 tag.read_from_stream(is_xml);
364 tag.check_name("Time");
365
366 Index version;
367 tag.get_attribute_value("version", version);
368 ARTS_USER_ERROR_IF (version not_eq 1,
369 "Your version of ARTS can only handle version 1 of Time");
370
371 is_xml >> t;
372 if (is_xml.fail()) {
373 xml_data_parse_error(tag, "Time is poorly formatted");
374 }
375
376 tag.read_from_stream(is_xml);
377 tag.check_name("/Time");
378}
379
381
387void xml_write_to_stream(ostream& os_xml,
388 const Time& t,
389 bofstream* pbofs [[maybe_unused]],
390 const String&,
391 const Verbosity& verbosity) {
392 ArtsXMLTag open_tag(verbosity);
393 ArtsXMLTag close_tag(verbosity);
394
395 open_tag.set_name("Time");
396 open_tag.add_attribute("version", t.Version());
397 open_tag.write_to_stream(os_xml);
398
400
401 os_xml << ' ' << t << ' ';
402
403 close_tag.set_name("/Time");
404 close_tag.write_to_stream(os_xml);
405 os_xml << '\n';
406}
407
408//=== AbsorptionLines ================================================================
409
411
416void xml_read_from_stream(istream& is_xml,
417 AbsorptionLines& al,
418 bifstream* pbifs,
419 const Verbosity& verbosity) {
420 static_assert(AbsorptionLines::version == 2, "The reading routine expects version 1 of the absorption lines data type to work");
421
422 ArtsXMLTag tag(verbosity);
423
424 tag.read_from_stream(is_xml);
425 tag.check_name("AbsorptionLines");
426
427 Index version;
428 if (tag.has_attribute("version")) {
429 tag.get_attribute_value("version", version);
430 } else {
431 version = 0;
432 }
433
435 AbsorptionLines::version < version,
436 "The version of this catalog is too new. You need to upgrade ARTS to use it.")
437
439 version < AbsorptionLines::version - 1 or
440 (pbifs and version not_eq AbsorptionLines::version),
441 "Using descoped version of the catalog; version: ",
442 version,
443 '\n',
444 "We only ever support limited number of versions. Your compilation supports versions ",
446 " and ",
448 " in ascii but only version ",
450 " in binary\n\n",
451 "To update from versions, please check-out the following branch, compile, and save your catalog again (as ascii):\n"
452 "0 to 1: 3b6565fb93702308c4cdd660ec63c71d63dcaf26\n"
453 "1 to 2: Current version\n")
454
455 // Number of lines
456 Index nlines;
457 tag.get_attribute_value("nlines", nlines);
458
459 // Identity of the lines (Changes between versions)
461 if (version == 2) {
462 String id_str;
463 tag.get_attribute_value("id", id_str);
464 id = QuantumIdentifier(id_str);
465 } else if (version == 1) {
466 String spec;
467 tag.get_attribute_value("species", spec);
468
469 Index spec_ind = Species::find_species_index(spec);
470 ARTS_USER_ERROR_IF(spec_ind < 0, "Bad species index for: ", spec)
471 id.isotopologue_index = spec_ind;
472 }
473
474 // Cutoff type
475 String s_cutoff;
476 tag.get_attribute_value("cutofftype", s_cutoff);
477 const Absorption::CutoffType cutoff = Absorption::toCutoffTypeOrThrow(s_cutoff);
478
479 // Mirroring type
480 String s_mirroring;
481 tag.get_attribute_value("mirroringtype", s_mirroring);
482 const Absorption::MirroringType mirroring = Absorption::toMirroringTypeOrThrow(s_mirroring);
483
484 // Line population type
485 String s_population;
486 tag.get_attribute_value("populationtype", s_population);
487 const Absorption::PopulationType population = Absorption::toPopulationTypeOrThrow(s_population);
488
489 // Normalization type
490 String s_normalization;
491 tag.get_attribute_value("normalizationtype", s_normalization);
492 const Absorption::NormalizationType normalization = Absorption::toNormalizationTypeOrThrow(s_normalization);
493
494 // Shape type
495 String s_lineshapetype;
496 tag.get_attribute_value("lineshapetype", s_lineshapetype);
497 const LineShape::Type lineshapetype = LineShape::toTypeOrThrow(s_lineshapetype);
498
500 Numeric T0;
501 tag.get_attribute_value("T0", T0);
502
504 Numeric cutofffreq;
505 tag.get_attribute_value("cutofffreq", cutofffreq);
506
508 Numeric linemixinglimit;
509 tag.get_attribute_value("linemixinglimit", linemixinglimit);
510
512 Quantum::Number::LocalState meta_localstate;
513 String localquanta_str;
514 tag.get_attribute_value("localquanta", localquanta_str);
515 const Index nlocal = Quantum::Number::count_items(localquanta_str);
517 for (Index i = 0; i < nlocal; i++)
518 qn_key.push_back(
519 Quantum::Number::toType(Quantum::Number::items(localquanta_str, i)));
521 std::any_of(qn_key.begin(),
522 qn_key.end(),
523 [](auto& qn) {
524 return Quantum::Number::common_value_type(
525 Quantum::Number::common_value_type(qn),
526 Quantum::Number::ValueType::H) not_eq
527 Quantum::Number::ValueType::H;
528 }),
529 "Quantum number list contains a string type, this is not allowed: [",
530 qn_key,
531 ']')
532 meta_localstate.set_unsorted_qns(qn_key);
533
535 if (version == 1) {
536 String uid, lid;
537 tag.get_attribute_value("upperglobalquanta", uid);
538 tag.get_attribute_value("lowerglobalquanta", lid);
539 id.val = Quantum::Number::ValueList(uid, lid);
540 }
541
543 ArrayOfSpecies broadeningspecies;
544 bool selfbroadening;
545 bool bathbroadening;
546 tag.get_attribute_value("broadeningspecies", broadeningspecies, selfbroadening, bathbroadening);
547 if (selfbroadening) broadeningspecies.front() = id.Species();
548
549 String temperaturemodes;
550 tag.get_attribute_value("temperaturemodes", temperaturemodes);
551 auto metamodel = LineShape::MetaData2ModelShape(temperaturemodes);
552
553 al = AbsorptionLines(selfbroadening, bathbroadening,
554 nlines, cutoff, mirroring,
555 population, normalization,
556 lineshapetype, T0, cutofffreq,
557 linemixinglimit, id,
558 broadeningspecies, meta_localstate, metamodel);
559
560 if (pbifs) {
561 al.read(*pbifs);
562 if (pbifs->fail()) {
563 ostringstream os;
564 os << "AbsorptionLines has wrong dimensions";
565 xml_data_parse_error(tag, os.str());
566 }
567 } else {
568 is_xml >> al;
569 if (is_xml.fail()) {
570 ostringstream os;
571 os << "AbsorptionLines has wrong dimensions";
572 xml_data_parse_error(tag, os.str());
573 }
574 }
575
576 // Finalize the sorting because we have to
577 for (auto& line: al.lines) line.localquanta.val.finalize();
578
579 tag.read_from_stream(is_xml);
580 tag.check_name("/AbsorptionLines");
581
583 if (out3.sufficient_priority_screen()) {
584 if (not al.quantumidentity.good()) {
585 out3 << "Bad data in absorption band " << al.MetaData() << '\n';
586 }
587 for (auto& line : al.lines) {
588 if (not line.localquanta.good()) {
589 out3 << "Bad data in absorption band " << al.MetaData() << '\n'
590 << "Line: " << line << '\n';
591 }
592 }
593 }
594}
595
597
603void xml_write_to_stream(ostream& os_xml,
604 const AbsorptionLines& al,
605 bofstream* pbofs,
606 const String&,
607 const Verbosity& verbosity) {
608 ArtsXMLTag open_comment_tag(verbosity);
609 ArtsXMLTag close_comment_tag(verbosity);
610 open_comment_tag.set_name("comment");
611 open_comment_tag.write_to_stream(os_xml);
612 os_xml << al.MetaData();
613 close_comment_tag.set_name("/comment");
614 close_comment_tag.write_to_stream(os_xml);
615 os_xml << '\n';
616
617 ArtsXMLTag open_tag(verbosity);
618 ArtsXMLTag close_tag(verbosity);
619
620 open_tag.set_name("AbsorptionLines");
621 open_tag.add_attribute("version", al.version);
622 open_tag.add_attribute("id", var_string(al.quantumidentity));
623 open_tag.add_attribute("nlines", al.NumLines());
624 open_tag.add_attribute("cutofftype", Absorption::toString(al.cutoff));
625 open_tag.add_attribute("mirroringtype", Absorption::toString(al.mirroring));
626 open_tag.add_attribute("populationtype", Absorption::toString(al.population));
627 open_tag.add_attribute("normalizationtype", Absorption::toString(al.normalization));
628 open_tag.add_attribute("lineshapetype", LineShape::toString(al.lineshapetype));
629 open_tag.add_attribute("T0", al.T0);
630 open_tag.add_attribute("cutofffreq", al.cutofffreq);
631 open_tag.add_attribute("linemixinglimit", al.linemixinglimit);
632
633 const String localquanta_str =
634 al.NumLines() ? al.lines.front().localquanta.keys() : "";
635 open_tag.add_attribute("localquanta", localquanta_str);
636
637 open_tag.add_attribute("broadeningspecies", al.broadeningspecies, al.selfbroadening, al.bathbroadening);
638 open_tag.add_attribute("temperaturemodes", al.LineShapeMetaData());
639
640 open_tag.write_to_stream(os_xml);
641 os_xml << '\n';
642
644 if (pbofs)
645 al.write(*pbofs);
646 else
647 os_xml << al;
648
649 close_tag.set_name("/AbsorptionLines");
650 close_tag.write_to_stream(os_xml);
651
652 os_xml << '\n';
653}
654
656// Dummy funtion for groups for which
657// IO function have not yet been implemented
659
660// FIXME: These should be implemented, sooner or later...
661
663 Timer&,
664 bifstream* /* pbifs */,
665 const Verbosity&) {
666 ARTS_USER_ERROR_IF(true, "Method not implemented!");
667}
668
670 const Timer&,
671 bofstream* /* pbofs */,
672 const String& /* name */,
673 const Verbosity&) {
674 ARTS_USER_ERROR_IF(true, "Method not implemented!");
675}
Contains the absorption namespace.
Absorption::Lines AbsorptionLines
The global header file for ARTS.
This can be used to make arrays out of anything.
Definition: array.h:31
The ARTS XML tag class.
Definition: xml_io.h:28
void add_attribute(const String &aname, const std::vector< QuantumNumberType > &value)
Adds value of attribute as type std::vector<QuantumNumberType> to tag.
Definition: xml_io.cc:25
void get_attribute_value(const String &aname, SpeciesTag &value)
Returns value of attribute as type SpeciesTag.
Definition: xml_io.cc:53
A list of many quantum numbers. Should always remain sorted.
bool has_attribute(const String &aname) const
Returns if the attribute exists or not.
Definition: xml_io_base.cc:108
void write_to_stream(ostream &os)
Write XML tag.
Definition: xml_io_base.cc:305
void check_name(const String &expected_name)
Check tag name.
Definition: xml_io_base.cc:37
void read_from_stream(istream &is)
Reads next XML tag.
Definition: xml_io_base.cc:184
void set_name(const String &new_name)
Definition: xml_io_base.h:61
Binary output file stream class.
Definition: bifstream.h:26
Binary output file stream class.
Definition: bofstream.h:25
Input manipulator class for doubles to enable nan and inf parsing.
Definition: double_imanip.h:25
Helper macros for debugging.
std::string var_string(Args &&... args)
Definition: debug.h:18
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:135
Declarations having to do with the four output streams.
#define CREATE_OUT3
Definition: messages.h:189
Model MetaData2ModelShape(const String &s)
constexpr std::string_view items(std::string_view s, std::size_t i) noexcept
Get a view of a number of space-separated items from the list.
constexpr Index count_items(std::string_view s) noexcept
Count all space-separated items in s.
constexpr Index find_species_index(const Species spec, const std::string_view isot) noexcept
Quantum::Number::GlobalState QuantumIdentifier
Numeric T0
Reference temperature for all parameters of the lines.
PopulationType population
Line population distribution.
static constexpr Index version
bool bathbroadening
Does the line broadening have bath broadening.
Array< SingleLine > lines
A list of individual lines.
Index NumLines() const noexcept
Number of lines.
bofstream & write(bofstream &os) const
Binary write for Lines.
Numeric linemixinglimit
linemixing limit
NormalizationType normalization
Line normalization type.
bifstream & read(bifstream &is)
Binary read for Lines.
String LineShapeMetaData() const noexcept
Meta data for the line shape if it exists.
LineShape::Type lineshapetype
Type of line shape.
Numeric cutofffreq
cutoff frequency
MirroringType mirroring
Mirroring type.
CutoffType cutoff
cutoff type, by band or by line
ArrayOfSpecies broadeningspecies
A list of broadening species.
String MetaData() const
Returns a printable statement about the lines.
bool selfbroadening
Does the line broadening have self broadening.
QuantumIdentifier quantumidentity
Catalog ID.
Holds all information required for individual partial derivatives.
Definition: jacobian.h:93
Numeric perturbation
Perturbations for methods where theoretical computations are impossible or plain slow.
Definition: jacobian.h:110
String string_id
ID for some of the Special types of partial derivatives.
Definition: jacobian.h:119
bool needArrayOfSpeciesTag() const noexcept
Does this type need the ArrayOfSpeciesTag?
Definition: jacobian.h:292
void TargetSubType(const std::string_view &s) noexcept
Sets sub target based on a string.
Definition: jacobian.h:192
bool TargetSubTypeOK() const noexcept
Are we good?
Definition: jacobian.h:236
ArrayOfSpeciesTag species_array_id
ID for some of the Special types of partial derivatives.
Definition: jacobian.h:116
std::string_view TargetType() const noexcept
Return type as string.
Definition: jacobian.h:184
bool needString() const noexcept
Does this type need the String?
Definition: jacobian.h:297
QuantumIdentifier qid
ID for the Line types of partial derivatives.
Definition: jacobian.h:113
bool needQuantumIdentity() const noexcept
Does this type need the QuantumIdentifier?
Definition: jacobian.h:287
A logical struct for global quantum numbers with species identifiers.
bool good() const
Test if there are bad quantum numbers (undefined ones) or if the isotopologue is not a normal target.
A logical struct for local quantum numbers.
void set_unsorted_qns(const Array< Type > &vals)
Radiation Vector for Stokes dimension 1-4.
Index Frequencies() const
Get frequency count.
Class to handle time in ARTS.
Definition: artstime.h:25
Index Version() const noexcept
Definition: artstime.h:30
Class to keep track of Transmission Matrices for Stokes Dim 1-4.
Index Frequencies() const
Number of frequencies.
void xml_data_parse_error(ArtsXMLTag &tag, String str_error)
Throws XML parser runtime error.
Definition: xml_io.cc:162
This file contains basic functions to handle XML data files.
void xml_set_stream_precision(ostream &os)
Definition: xml_io_base.cc:688
void xml_write_to_stream(ostream &os_xml, const JacobianTarget &jt, bofstream *pbofs, const String &name, const Verbosity &verbosity)
Writes JacobianTarget to XML output stream.
void xml_read_from_stream(istream &is_xml, JacobianTarget &jt, bifstream *pbifs, const Verbosity &verbosity)
Reads JacobianTarget from XML input stream.