ARTS 2.5.0 (git: 9ee3ac6c)
xml_io_basic_types.cc
Go to the documentation of this file.
1/* Copyright (C) 2003-2012 Oliver Lemke <olemke@core-dump.info>
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2, or (at your option) any
6 later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 USA. */
17
19// File description
21
30#include "arts.h"
31#include "xml_io.h"
32
34// Overloaded functions for reading/writing data from/to XML stream
36
37//=== JacobianTarget ==================================================================
38
40
45void xml_read_from_stream(istream& is_xml,
47 bifstream* pbifs,
48 const Verbosity& verbosity) {
49 ArtsXMLTag tag(verbosity);
50
51 tag.read_from_stream(is_xml);
52 tag.check_name("JacobianTarget");
53
54 // Type information
55 String typestr, subtypestr;
56 tag.get_attribute_value("Type", typestr);
57 tag.get_attribute_value("SubType", subtypestr);
58 jt.TargetType(typestr);
59 jt.TargetSubType(subtypestr);
60
62 if (jt.needQuantumIdentity()) {
63 SpeciesTag spec;
64 tag.get_attribute_value("species", spec);
65
66 if (jt == Jacobian::Line::VMR) {
67 jt.QuantumIdentity() = QuantumIdentifier(spec.Isotopologue(), Quantum::IdentifierType::All);
68 } else if (jt == Jacobian::Line::NLTE) {
69 QuantumNumbers levelquanta;
70 tag.get_attribute_value("levelquanta", levelquanta);
71 jt.QuantumIdentity() = QuantumIdentifier(spec.Isotopologue(), levelquanta);
72 } else {
73 QuantumNumbers upperglobalquanta, lowerglobalquanta;
74 tag.get_attribute_value("upperglobalquanta", upperglobalquanta);
75 tag.get_attribute_value("lowerglobalquanta", lowerglobalquanta);
76 jt.QuantumIdentity() = QuantumIdentifier(spec.Isotopologue(), upperglobalquanta, lowerglobalquanta);
77 }
78 }
79
80 if (jt.needArrayOfSpeciesTag()) {
81 String key;
82 tag.get_attribute_value("species", key);
83 jt.SpeciesList() = ArrayOfSpeciesTag(key);
84 }
85
86 if (jt.needString()) {
87 tag.get_attribute_value("string_key", jt.StringKey());
88 }
89
90 if (pbifs) {
91 *pbifs >> jt.Perturbation();
92 if (pbifs->fail()) {
93 xml_data_parse_error(tag, "");
94 }
95 } else {
96 is_xml >> jt.Perturbation();
97 if (is_xml.fail()) {
98 xml_data_parse_error(tag, "");
99 }
100 }
101
102 tag.read_from_stream(is_xml);
103 tag.check_name("/JacobianTarget");
104
105 ARTS_USER_ERROR_IF (not jt.TargetSubTypeOK(),
106 "Bad input: ", typestr, " or ", subtypestr, '\n', "\tCannot be interpreted as a type or substype...\n")
107}
108
110
116void xml_write_to_stream(ostream& os_xml,
117 const JacobianTarget& jt,
118 bofstream* pbofs,
119 const String& name,
120 const Verbosity& verbosity) {
121 ArtsXMLTag open_tag(verbosity);
122 ArtsXMLTag close_tag(verbosity);
123
124 os_xml << '\n';
125 open_tag.set_name("JacobianTarget");
126 if (name.length()) open_tag.add_attribute("name", name);
127
128 // Type information
129 open_tag.add_attribute("Type", jt.TargetType());
130 open_tag.add_attribute("SubType", jt.TargetSubType());
131
133 if (jt.needQuantumIdentity()) {
134 open_tag.add_attribute("species", String(Species::toShortName(jt.QuantumIdentity().Species())));
135
136 if (jt == Jacobian::Line::VMR) {
137 } else if (jt == Jacobian::Line::NLTE) {
138 open_tag.add_attribute("levelquanta", jt.QuantumIdentity().Level().toString());
139 } else {
140 open_tag.add_attribute("upperglobalquanta", jt.QuantumIdentity().Upper().toString());
141 open_tag.add_attribute("lowerglobalquanta", jt.QuantumIdentity().Lower().toString());
142 }
143 }
144
145 if (jt.needArrayOfSpeciesTag()) {
146 open_tag.add_attribute("species", jt.SpeciesList().Name());
147 }
148
149 if (jt.needString()) {
150 open_tag.add_attribute("string_key", jt.StringKey());
151 }
152 open_tag.write_to_stream(os_xml);
153
154 if (pbofs)
155 *pbofs << jt.Perturbation();
156 else
157 os_xml << ' ' << jt.Perturbation() << ' ';
158
159 close_tag.set_name("/JacobianTarget");
160 close_tag.write_to_stream(os_xml);
161 os_xml << '\n';
162}
163
164//=== Rational =========================================================
165
167
172void xml_read_from_stream(istream& is_xml,
173 Rational& rational,
174 bifstream* pbifs,
175 const Verbosity& verbosity) {
176 ArtsXMLTag tag(verbosity);
177
178 tag.read_from_stream(is_xml);
179 tag.check_name("Rational");
180
181 if (pbifs) {
182 *pbifs >> rational;
183 if (pbifs->fail()) {
184 xml_data_parse_error(tag, "");
185 }
186 } else {
187 is_xml >> rational;
188 if (is_xml.fail()) {
189 xml_data_parse_error(tag, "");
190 }
191 }
192
193 tag.read_from_stream(is_xml);
194 tag.check_name("/Rational");
195}
196
198
204void xml_write_to_stream(ostream& os_xml,
205 const Rational& rational,
206 bofstream* pbofs,
207 const String& name,
208 const Verbosity& verbosity) {
209 ArtsXMLTag open_tag(verbosity);
210 ArtsXMLTag close_tag(verbosity);
211
212 open_tag.set_name("Rational");
213 if (name.length()) open_tag.add_attribute("name", name);
214
215 open_tag.write_to_stream(os_xml);
216
217 if (pbofs)
218 *pbofs << rational;
219 else
220 os_xml << rational;
221
222 close_tag.set_name("/Rational");
223 close_tag.write_to_stream(os_xml);
224 os_xml << '\n';
225}
226
227//=== TransmissionMatrix ================================================================
228
230
235void xml_read_from_stream(istream& is_xml,
237 bifstream* pbifs,
238 const Verbosity& verbosity) {
239 ArtsXMLTag tag(verbosity);
240 Index stokes_dim, nf;
241
242 tag.read_from_stream(is_xml);
243 tag.check_name("TransmissionMatrix");
244
245 tag.get_attribute_value("Stokes", stokes_dim);
246 tag.get_attribute_value("Freqs", nf);
247 tm = TransmissionMatrix(nf, stokes_dim);
248 if (pbifs) {
249 *pbifs >> tm;
250 if (pbifs->fail()) {
251 ostringstream os;
252 os << "TransmissionMatrix has wrong dimensions";
253 xml_data_parse_error(tag, os.str());
254 }
255 } else {
256 is_xml >> tm;
257 if (is_xml.fail()) {
258 ostringstream os;
259 os << "TransmissionMatrix has wrong dimensions";
260 xml_data_parse_error(tag, os.str());
261 }
262 }
263
264 tag.read_from_stream(is_xml);
265 tag.check_name("/TransmissionMatrix");
266}
267
269
275void xml_write_to_stream(ostream& os_xml,
276 const TransmissionMatrix& tm,
277 bofstream* pbofs,
278 const String& name,
279 const Verbosity& verbosity) {
280 ArtsXMLTag open_tag(verbosity);
281 ArtsXMLTag close_tag(verbosity);
282
283 open_tag.set_name("TransmissionMatrix");
284 if (name.length()) open_tag.add_attribute("name", name);
285 open_tag.add_attribute("Stokes", tm.StokesDim());
286 open_tag.add_attribute("Freqs", tm.Frequencies());
287
288 open_tag.write_to_stream(os_xml);
289 os_xml << '\n';
290
292 if (pbofs)
293 *pbofs << tm;
294 else
295 os_xml << tm;
296
297 close_tag.set_name("/TransmissionMatrix");
298 close_tag.write_to_stream(os_xml);
299
300 os_xml << '\n';
301}
302
303//=== RadiationVector ================================================================
304
306
311void xml_read_from_stream(istream& is_xml,
312 RadiationVector& rv,
313 bifstream* pbifs,
314 const Verbosity& verbosity) {
315 ArtsXMLTag tag(verbosity);
316 Index stokes_dim, nf;
317
318 tag.read_from_stream(is_xml);
319 tag.check_name("RadiationVector");
320
321 tag.get_attribute_value("Stokes", stokes_dim);
322 tag.get_attribute_value("Freqs", nf);
323 rv = RadiationVector(nf, stokes_dim);
324 if (pbifs) {
325 *pbifs >> rv;
326 if (pbifs->fail()) {
327 ostringstream os;
328 os << "RadiationVector has wrong dimensions";
329 xml_data_parse_error(tag, os.str());
330 }
331 } else {
332 is_xml >> rv;
333 if (is_xml.fail()) {
334 ostringstream os;
335 os << "RadiationVector has wrong dimensions";
336 xml_data_parse_error(tag, os.str());
337 }
338 }
339
340 tag.read_from_stream(is_xml);
341 tag.check_name("/RadiationVector");
342}
343
345
351void xml_write_to_stream(ostream& os_xml,
352 const RadiationVector& rv,
353 bofstream* pbofs,
354 const String& name,
355 const Verbosity& verbosity) {
356 ArtsXMLTag open_tag(verbosity);
357 ArtsXMLTag close_tag(verbosity);
358
359 open_tag.set_name("RadiationVector");
360 if (name.length()) open_tag.add_attribute("name", name);
361 open_tag.add_attribute("Stokes", rv.StokesDim());
362 open_tag.add_attribute("Freqs", rv.Frequencies());
363
364 open_tag.write_to_stream(os_xml);
365 os_xml << '\n';
366
368 if (pbofs)
369 *pbofs << rv;
370 else
371 os_xml << rv;
372
373 close_tag.set_name("/RadiationVector");
374 close_tag.write_to_stream(os_xml);
375
376 os_xml << '\n';
377}
378
379//=== Time ================================================================
380
382
387void xml_read_from_stream(istream& is_xml,
388 Time& t,
389 bifstream* pbifs [[maybe_unused]],
390 const Verbosity& verbosity) {
391 ArtsXMLTag tag(verbosity);
392
393 tag.read_from_stream(is_xml);
394 tag.check_name("Time");
395
396 Index version;
397 tag.get_attribute_value("version", version);
398 ARTS_USER_ERROR_IF (version not_eq 1,
399 "Your version of ARTS can only handle version 1 of Time");
400
401 is_xml >> t;
402 if (is_xml.fail()) {
403 xml_data_parse_error(tag, "Time is poorly formatted");
404 }
405
406 tag.read_from_stream(is_xml);
407 tag.check_name("/Time");
408}
409
411
417void xml_write_to_stream(ostream& os_xml,
418 const Time& t,
419 bofstream* pbofs [[maybe_unused]],
420 const String&,
421 const Verbosity& verbosity) {
422 ArtsXMLTag open_tag(verbosity);
423 ArtsXMLTag close_tag(verbosity);
424
425 open_tag.set_name("Time");
426 open_tag.add_attribute("version", t.Version());
427 open_tag.write_to_stream(os_xml);
428
430
431 os_xml << ' ' << t << ' ';
432
433 close_tag.set_name("/Time");
434 close_tag.write_to_stream(os_xml);
435 os_xml << '\n';
436}
437
438//=== AbsorptionLines ================================================================
439
441
446void xml_read_from_stream(istream& is_xml,
447 AbsorptionLines& al,
448 bifstream* pbifs,
449 const Verbosity& verbosity) {
450 static_assert(AbsorptionLines::version == 1, "The reading routine expects version 1 of the absorption lines data type to work");
451
452 ArtsXMLTag tag(verbosity);
453
454 tag.read_from_stream(is_xml);
455 tag.check_name("AbsorptionLines");
456
457 Index version;
458 if (tag.has_attribute("version")) {
459 tag.get_attribute_value("version", version);
460 } else {
461 version = 0;
462 }
463
464 // Number of lines
466 tag.get_attribute_value("nlines", nlines);
467
468 // Species of the lines
469 SpeciesTag spec;
470 if (version == 1) {
471 tag.get_attribute_value("species", spec);
472 } else {
473 String specname;
474 tag.get_attribute_value("species", specname);
475 specname = Species::update_isot_name(specname);
476
477 spec = SpeciesTag(specname);
478 }
479
480 // Cutoff type
481 String s_cutoff;
482 tag.get_attribute_value("cutofftype", s_cutoff);
483 const Absorption::CutoffType cutoff = Absorption::toCutoffType(s_cutoff);
484
485 // Mirroring type
486 String s_mirroring;
487 tag.get_attribute_value("mirroringtype", s_mirroring);
488 const Absorption::MirroringType mirroring = Absorption::toMirroringType(s_mirroring);
489
490 // Line population type
491 String s_population;
492 tag.get_attribute_value("populationtype", s_population);
493 const Absorption::PopulationType population = Absorption::toPopulationType(s_population);
494
495 // Normalization type
496 String s_normalization;
497 tag.get_attribute_value("normalizationtype", s_normalization);
498 const Absorption::NormalizationType normalization = Absorption::toNormalizationType(s_normalization);
499
500 // Shape type
501 String s_lineshapetype;
502 tag.get_attribute_value("lineshapetype", s_lineshapetype);
503 const LineShape::Type lineshapetype = LineShape::toType(s_lineshapetype);
504
506 Numeric T0;
507 tag.get_attribute_value("T0", T0);
508
510 Numeric cutofffreq;
511 tag.get_attribute_value("cutofffreq", cutofffreq);
512
514 Numeric linemixinglimit;
515 tag.get_attribute_value("linemixinglimit", linemixinglimit);
516
518 std::vector<QuantumNumberType> localquanta;
519 tag.get_attribute_value("localquanta", localquanta);
520
522 QuantumNumbers upperglobalquanta;
523 tag.get_attribute_value("upperglobalquanta", upperglobalquanta);
524 QuantumNumbers lowerglobalquanta;
525 tag.get_attribute_value("lowerglobalquanta", lowerglobalquanta);
526
528 ArrayOfSpecies broadeningspecies;
529 bool selfbroadening;
530 bool bathbroadening;
531 tag.get_attribute_value("broadeningspecies", broadeningspecies, selfbroadening, bathbroadening);
532 if (selfbroadening) broadeningspecies.front() = spec.Spec();
533
534 String temperaturemodes;
535 tag.get_attribute_value("temperaturemodes", temperaturemodes);
536 auto metamodel = LineShape::MetaData2ModelShape(temperaturemodes);
537
538 al = AbsorptionLines(selfbroadening, bathbroadening,
539 nlines, cutoff, mirroring,
540 population, normalization,
541 lineshapetype, T0, cutofffreq,
542 linemixinglimit, QuantumIdentifier(
543 spec.Isotopologue(), upperglobalquanta, lowerglobalquanta),
544 localquanta, broadeningspecies, metamodel);
545
546 if (pbifs) {
547 al.read(*pbifs);
548 if (pbifs->fail()) {
549 ostringstream os;
550 os << "AbsorptionLines has wrong dimensions";
551 xml_data_parse_error(tag, os.str());
552 }
553 } else {
554 is_xml >> al;
555 if (is_xml.fail()) {
556 ostringstream os;
557 os << "AbsorptionLines has wrong dimensions";
558 xml_data_parse_error(tag, os.str());
559 }
560 }
561
562 tag.read_from_stream(is_xml);
563 tag.check_name("/AbsorptionLines");
564}
565
567
573void xml_write_to_stream(ostream& os_xml,
574 const AbsorptionLines& al,
575 bofstream* pbofs,
576 const String&,
577 const Verbosity& verbosity) {
578 ArtsXMLTag open_comment_tag(verbosity);
579 ArtsXMLTag close_comment_tag(verbosity);
580 open_comment_tag.set_name("comment");
581 open_comment_tag.write_to_stream(os_xml);
582 os_xml << al.MetaData();
583 close_comment_tag.set_name("/comment");
584 close_comment_tag.write_to_stream(os_xml);
585 os_xml << '\n';
586
587 ArtsXMLTag open_tag(verbosity);
588 ArtsXMLTag close_tag(verbosity);
589
590 open_tag.set_name("AbsorptionLines");
591 open_tag.add_attribute("version", al.version);
592 open_tag.add_attribute("nlines", al.NumLines());
593 open_tag.add_attribute("species", al.SpeciesName());
594 open_tag.add_attribute("cutofftype", Absorption::toString(al.Cutoff()));
595 open_tag.add_attribute("mirroringtype", Absorption::toString(al.Mirroring()));
596 open_tag.add_attribute("populationtype", Absorption::toString(al.Population()));
597 open_tag.add_attribute("normalizationtype", Absorption::toString(al.Normalization()));
598 open_tag.add_attribute("lineshapetype", LineShape::toString(al.LineShapeType()));
599 open_tag.add_attribute("T0", al.T0());
600 open_tag.add_attribute("cutofffreq", al.CutoffFreqValue());
601 open_tag.add_attribute("linemixinglimit", al.LinemixingLimit());
602 open_tag.add_attribute("localquanta", al.LocalQuanta());
603 open_tag.add_attribute("upperglobalquanta", al.UpperQuantumNumbers());
604 open_tag.add_attribute("lowerglobalquanta", al.LowerQuantumNumbers());
605 open_tag.add_attribute("broadeningspecies", al.BroadeningSpecies(), al.Self(), al.Bath());
606 open_tag.add_attribute("temperaturemodes", al.LineShapeMetaData());
607
608 open_tag.write_to_stream(os_xml);
609 os_xml << '\n';
610
612 if (pbofs)
613 al.write(*pbofs);
614 else
615 os_xml << al;
616
617 close_tag.set_name("/AbsorptionLines");
618 close_tag.write_to_stream(os_xml);
619
620 os_xml << '\n';
621}
622
624// Dummy funtion for groups for which
625// IO function have not yet been implemented
627
628// FIXME: These should be implemented, sooner or later...
629
631 Timer&,
632 bifstream* /* pbifs */,
633 const Verbosity&) {
634 ARTS_USER_ERROR_IF(true, "Method not implemented!");
635}
636
638 const Timer&,
639 bofstream* /* pbofs */,
640 const String& /* name */,
641 const Verbosity&) {
642 ARTS_USER_ERROR_IF(true, "Method not implemented!");
643}
Absorption::Lines AbsorptionLines
The global header file for ARTS.
static constexpr Index version
MirroringType Mirroring() const noexcept
Returns mirroring style.
LineShape::Type LineShapeType() const noexcept
Returns lineshapetype style.
const std::vector< QuantumNumberType > & LocalQuanta() const noexcept
Returns local quantum numbers.
NormalizationType Normalization() const noexcept
Returns normalization style.
PopulationType Population() const noexcept
Returns population style.
Index NumLines() const noexcept
Number of lines.
bofstream & write(bofstream &os) const
Binary write for Lines.
Numeric CutoffFreqValue() const noexcept
Returns internal cutoff frequency value.
String LowerQuantumNumbers() const noexcept
Lower quantum numbers string.
const ArrayOfSpecies & BroadeningSpecies() const noexcept
Returns the broadening species.
bool Bath() const noexcept
Returns bath broadening status.
Numeric T0() const noexcept
Returns reference temperature.
bifstream & read(bifstream &is)
Binary read for Lines.
CutoffType Cutoff() const noexcept
Returns cutoff style.
bool Self() const noexcept
Returns self broadening status.
String LineShapeMetaData() const noexcept
Meta data for the line shape if it exists.
String SpeciesName() const noexcept
Species Name.
String UpperQuantumNumbers() const noexcept
Upper quantum numbers string.
String MetaData() const
Returns a printable statement about the lines.
Numeric LinemixingLimit() const noexcept
Returns line mixing limit.
The ARTS XML tag class.
Definition: xml_io.h:45
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:42
void get_attribute_value(const String &aname, SpeciesTag &value)
Returns value of attribute as type SpeciesTag.
Definition: xml_io.cc:70
Container class for Quantum Numbers.
Definition: quantum.h:112
Radiation Vector for Stokes dimension 1-4.
Index Frequencies() const
Get frequency count.
Index StokesDim() const
Get Stokes dimension.
Implements rational numbers to work with other ARTS types.
Definition: rational.h:52
Class to handle time in ARTS.
Definition: artstime.h:41
Index Version() const noexcept
Definition: artstime.h:49
Class to keep track of Transmission Matrices for Stokes Dim 1-4.
Index StokesDim() const
Stokes dimensionaility.
Index Frequencies() const
Number of frequencies.
bool has_attribute(const String &aname) const
Returns if the attribute exists or not.
Definition: xml_io_base.cc:111
void write_to_stream(ostream &os)
Write XML tag.
Definition: xml_io_base.cc:300
void check_name(const String &expected_name)
Check tag name.
Definition: xml_io_base.cc:48
void read_from_stream(istream &is)
Reads next XML tag.
Definition: xml_io_base.cc:179
void set_name(const String &new_name)
Definition: xml_io_base.h:76
Binary output file stream class.
Definition: bifstream.h:42
Binary output file stream class.
Definition: bofstream.h:42
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:134
Jacobian::Target JacobianTarget
Definition: jacobian.h:340
#define nlines
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:287
Numeric cutoff
Model MetaData2ModelShape(const String &s)
String update_isot_name(const String &old_name)
Updates the name of the isotopologue based on updates of the isotopologues.
Quantum::Identifier QuantumIdentifier
Definition: quantum.h:471
Species::Tag SpeciesTag
Definition: species_tags.h:99
void xml_data_parse_error(ArtsXMLTag &tag, String str_error)
Throws XML parser runtime error.
Definition: xml_io.cc:197
This file contains basic functions to handle XML data files.
void xml_set_stream_precision(ostream &os)
Definition: xml_io_base.cc:683
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.