ARTS  2.4.0(git:4fb77825)
quantum_parser_hitran.cc
Go to the documentation of this file.
1 /* Copyright (C) 2015, The ARTS Developers.
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 
25 #include "quantum_parser_hitran.h"
26 #include "absorption.h"
27 #include "global_data.h"
28 #include "messages.h"
29 
30 // Parsing functions for fields
31 void parse_space(Rational& qn, String& s, const Index species);
32 void parse_a1_br_hitran(Rational& qn, String& s, const Index species);
33 void parse_a1_pm_hitran(Rational& qn, String& s, const Index species);
34 void parse_a1_sym_hitran(Rational& qn, String& s, const Index species);
35 void parse_a1_s_hitran(Rational& qn, String& s, const Index species);
36 void parse_a1_x_hitran(Rational& qn, String& s, const Index species);
37 void parse_a2_hitran(Rational& qn, String& s, const Index species);
38 void parse_a3_hitran(Rational& qn, String& s, const Index species);
39 void parse_a4_hitran(Rational& qn, String& s, const Index species);
40 void parse_a5_hitran(Rational& qn, String& s, const Index species);
41 void parse_i1_hitran(Rational& qn, String& s, const Index species);
42 void parse_i2_hitran(Rational& qn, String& s, const Index species);
43 void parse_i3_hitran(Rational& qn, String& s, const Index species);
44 void parse_f51_hitran(Rational& qn, String& s, const Index species);
45 
46 // Postprocessing functions for calculation of implicit quantum numbers
52 
55 
56 #define SKIP_X_SPACES(container, nspaces) \
57  container.push_back_n( \
58  QuantumFieldDescription(QuantumNumberType::FINAL_ENTRY, parse_space), \
59  nspaces)
60 
61  // HITRAN Classes
62  mclass.resize(CI_FINAL);
63 
64  // Class 1
65  {
67  SKIP_X_SPACES(this_class, 13);
68  this_class.push_back(
70  }
71 
72  // Class 2
73  {
75  SKIP_X_SPACES(this_class, 7);
76  this_class.push_back(
77  QuantumFieldDescription(QuantumNumberType::ElectronState, parse_a1_x_hitran));
78  SKIP_X_SPACES(this_class, 5);
79  this_class.push_back(
81  }
82 
83  // Class 3
84  {
86  SKIP_X_SPACES(this_class, 7);
87  this_class.push_back(
88  QuantumFieldDescription(QuantumNumberType::ElectronState, parse_a1_x_hitran));
89  this_class.push_back(
90  QuantumFieldDescription(QuantumNumberType::Omega, parse_a3_hitran));
91  SKIP_X_SPACES(this_class, 2);
92  this_class.push_back(
94  }
95 
96  // Class 4
97  {
99  SKIP_X_SPACES(this_class, 7);
100  this_class.push_back(
102  this_class.push_back(
104  this_class.push_back(
105  QuantumFieldDescription(QuantumNumberType::l2, parse_i2_hitran));
106  this_class.push_back(
107  QuantumFieldDescription(QuantumNumberType::v3, parse_i2_hitran));
108  }
109 
110  // Class 5
111  {
113  SKIP_X_SPACES(this_class, 6);
114  this_class.push_back(
116  this_class.push_back(
118  this_class.push_back(
119  QuantumFieldDescription(QuantumNumberType::l2, parse_i2_hitran));
120  this_class.push_back(
121  QuantumFieldDescription(QuantumNumberType::v3, parse_i2_hitran));
122  this_class.push_back(
124  }
125 
126  // Class 6
127  {
129  SKIP_X_SPACES(this_class, 9);
130  this_class.push_back(
132  this_class.push_back(
134  this_class.push_back(
135  QuantumFieldDescription(QuantumNumberType::v3, parse_i2_hitran));
136  }
137 
138  // Class 7
139  {
141  this_class.push_back(
143  this_class.push_back(
145  this_class.push_back(
146  QuantumFieldDescription(QuantumNumberType::v3, parse_i2_hitran));
147  this_class.push_back(
148  QuantumFieldDescription(QuantumNumberType::v4, parse_i2_hitran));
149  this_class.push_back(
150  QuantumFieldDescription(QuantumNumberType::v5, parse_i2_hitran));
151  this_class.push_back(
152  QuantumFieldDescription(QuantumNumberType::l1, parse_i2_hitran));
153  this_class.push_back(
154  QuantumFieldDescription(QuantumNumberType::pm, parse_a1_pm_hitran));
155  this_class.push_back(
157  this_class.push_back(QuantumFieldDescription(QuantumNumberType::S_global,
159  }
160 
161  // Class 8
162  {
164  SKIP_X_SPACES(this_class, 5);
165  this_class.push_back(
167  this_class.push_back(
169  this_class.push_back(
170  QuantumFieldDescription(QuantumNumberType::v3, parse_i2_hitran));
171  this_class.push_back(
172  QuantumFieldDescription(QuantumNumberType::v4, parse_i2_hitran));
173  this_class.push_back(
174  QuantumFieldDescription(QuantumNumberType::S_global, parse_i2_hitran));
175  }
176 
177  // Class 9
178  {
180  SKIP_X_SPACES(this_class, 3);
181  this_class.push_back(
183  this_class.push_back(
185  this_class.push_back(
186  QuantumFieldDescription(QuantumNumberType::v3, parse_i2_hitran));
187  this_class.push_back(
188  QuantumFieldDescription(QuantumNumberType::v4, parse_i2_hitran));
189  this_class.push_back(
190  QuantumFieldDescription(QuantumNumberType::v5, parse_i2_hitran));
191  this_class.push_back(
192  QuantumFieldDescription(QuantumNumberType::v6, parse_i2_hitran));
193  }
194 
195  // Class 10
196  {
198  SKIP_X_SPACES(this_class, 3);
199  this_class.push_back(
201  this_class.push_back(
203  this_class.push_back(
204  QuantumFieldDescription(QuantumNumberType::v3, parse_i2_hitran));
205  this_class.push_back(
206  QuantumFieldDescription(QuantumNumberType::v4, parse_i2_hitran));
207  this_class.push_back(
208  QuantumFieldDescription(QuantumNumberType::n_global, parse_a2_hitran));
209  this_class.push_back(
210  QuantumFieldDescription(QuantumNumberType::C, parse_a2_hitran));
211  }
212 
213  // HITRAN Groups
214  mgroup.resize(GI_FINAL);
215 
216  // Group 1
217  {
218  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP1].upper;
219  this_group.push_back(
221  this_group.push_back(
222  QuantumFieldDescription(QuantumNumberType::Ka, parse_i3_hitran));
223  this_group.push_back(
224  QuantumFieldDescription(QuantumNumberType::Kc, parse_i3_hitran));
225  this_group.push_back(
227  this_group.push_back(
228  QuantumFieldDescription(QuantumNumberType::Sym, parse_a1_sym_hitran));
229  }
230 
231  {
232  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP1].lower;
233  this_group.push_back(
235  this_group.push_back(
236  QuantumFieldDescription(QuantumNumberType::Ka, parse_i3_hitran));
237  this_group.push_back(
238  QuantumFieldDescription(QuantumNumberType::Kc, parse_i3_hitran));
239  this_group.push_back(
241  this_group.push_back(
242  QuantumFieldDescription(QuantumNumberType::Sym, parse_a1_sym_hitran));
243  }
244 
245  // Group 2
246  {
247  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP2].upper;
248  SKIP_X_SPACES(this_group, 10);
249  this_group.push_back(
251  }
252 
253  {
254  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP2].lower;
255  SKIP_X_SPACES(this_group, 5);
256  this_group.push_back(
257  QuantumFieldDescription(QuantumNumberType::dJ, parse_a1_br_hitran));
258  this_group.push_back(
260  this_group.push_back(
261  QuantumFieldDescription(QuantumNumberType::Sym, parse_a1_sym_hitran));
262  this_group.push_back(
264  }
265 
266  // Group 3
267  {
268  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP3].upper;
269  SKIP_X_SPACES(this_group, 2);
270  this_group.push_back(
272  this_group.push_back(
273  QuantumFieldDescription(QuantumNumberType::C, parse_a2_hitran));
274  this_group.push_back(
275  QuantumFieldDescription(QuantumNumberType::alpha, parse_i3_hitran));
276  this_group.push_back(
278  }
279 
280  {
281  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP3].lower;
282  SKIP_X_SPACES(this_group, 2);
283  this_group.push_back(
285  this_group.push_back(
286  QuantumFieldDescription(QuantumNumberType::Ka, parse_a2_hitran));
287  this_group.push_back(
288  QuantumFieldDescription(QuantumNumberType::Kc, parse_i3_hitran));
289  this_group.push_back(
291  }
292 
293  // Group 4
294  {
295  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP4].upper;
296  this_group.push_back(
298  this_group.push_back(
299  QuantumFieldDescription(QuantumNumberType::Ka, parse_i3_hitran));
300  this_group.push_back(
301  QuantumFieldDescription(QuantumNumberType::l1, parse_i2_hitran));
302  this_group.push_back(
303  QuantumFieldDescription(QuantumNumberType::C, parse_a2_hitran));
304  this_group.push_back(
305  QuantumFieldDescription(QuantumNumberType::Sym, parse_a1_sym_hitran));
306  this_group.push_back(
308  }
309 
310  {
311  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP4].lower;
312  this_group.push_back(
314  this_group.push_back(
315  QuantumFieldDescription(QuantumNumberType::Ka, parse_i3_hitran));
316  this_group.push_back(
317  QuantumFieldDescription(QuantumNumberType::l1, parse_i2_hitran));
318  this_group.push_back(
319  QuantumFieldDescription(QuantumNumberType::C, parse_a2_hitran));
320  this_group.push_back(
321  QuantumFieldDescription(QuantumNumberType::Sym, parse_a1_sym_hitran));
322  this_group.push_back(
324  }
325 
326  // Group 5
327  {
328  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP5].upper;
329  SKIP_X_SPACES(this_group, 10);
330  this_group.push_back(
332  }
333 
334  {
335  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP5].lower;
336  SKIP_X_SPACES(this_group, 1);
337  this_group.push_back(
339  this_group.push_back(
341  this_group.push_back(
342  QuantumFieldDescription(QuantumNumberType::dJ, parse_a1_br_hitran));
343  this_group.push_back(
345  this_group.push_back(
347  this_group.push_back(
348  QuantumFieldDescription(QuantumNumberType::Sym, parse_a1_sym_hitran));
349  }
350 
351  // Group 6
352  {
353  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP6].upper;
354  SKIP_X_SPACES(this_group, 10);
355  this_group.push_back(
357  }
358 
359  {
360  Array<QuantumFieldDescription>& this_group = mgroup[GI_GROUP6].lower;
361  SKIP_X_SPACES(this_group, 3);
362  this_group.push_back(
363  QuantumFieldDescription(QuantumNumberType::dJ, parse_a1_br_hitran));
364  this_group.push_back(
366  this_group.push_back(
367  QuantumFieldDescription(QuantumNumberType::Sym, parse_a1_sym_hitran));
368  this_group.push_back(
370  }
371 
372  // Group 6 (OH)
373  {
375  SKIP_X_SPACES(this_group, 10);
376  this_group.push_back(
378  }
379 
380  {
382  SKIP_X_SPACES(this_group, 1);
383  this_group.push_back(
385  this_group.push_back(
386  QuantumFieldDescription(QuantumNumberType::dJ, parse_a1_br_hitran));
387  this_group.push_back(
389  this_group.push_back(
390  QuantumFieldDescription(QuantumNumberType::Sym, parse_a1_sym_hitran));
391  this_group.push_back(
393  }
394 
395  mspecies.resize(species_data.nelem());
396 
406 
407 #undef SKIP_X_SPACES
408 }
409 
411  const String& quantum_string) const {
412  qid.SetTransition();
413 
414  const QuantumClassGroup& qcg = mspecies[qid.Species()];
415  const Index qclass = mspecies[qid.Species()].iclass;
416  const Index qgroup = mspecies[qid.Species()].igroup;
417 
418  if (qcg.iclass == -1 || qcg.igroup == -1) return;
419 
420  String qstr;
421 
422  qstr = quantum_string.substr(0, 15);
423  for (Index i = 0; i < mclass[qclass].nelem(); i++) {
424  mclass[qclass][i].Parse(qid.UpperQuantumNumbers(), qstr, qid.Species());
425  }
426 
427  qstr = quantum_string.substr(15, 15);
428  for (Index i = 0; i < mclass[qclass].nelem(); i++) {
429  mclass[qclass][i].Parse(qid.LowerQuantumNumbers(), qstr, qid.Species());
430  }
431 
432  if (qgroup != GI_UNDEFINED) {
433  qstr = quantum_string.substr(30, 15);
434  for (Index i = 0; i < mgroup[qgroup].upper.nelem(); i++) {
435  mgroup[qgroup].upper[i].Parse(
436  qid.UpperQuantumNumbers(), qstr, qid.Species());
437  }
438  }
439 
440  if (qgroup != GI_UNDEFINED) {
441  qstr = quantum_string.substr(45, 15);
442  for (Index i = 0; i < mgroup[qgroup].lower.nelem(); i++) {
443  mgroup[qgroup].lower[i].Parse(
444  qid.LowerQuantumNumbers(), qstr, qid.Species());
445  }
446  }
447 
448  switch (qgroup) {
449  case GI_GROUP1:
451  break;
452  case GI_GROUP2:
454  break;
455  case GI_GROUP5:
457  break;
458  case GI_GROUP6:
460  break;
461  case GI_GROUP6OH:
463  break;
464  default:
465  break;
466  }
467 }
468 
470  const ClassIds iclass,
471  const GroupIds igroup) {
472  Index species = species_index_from_species_name(species_name);
473  mspecies[species].iclass = iclass;
474  mspecies[species].igroup = igroup;
475 }
476 
480 
481 void parse_space(Rational& qn, String& s, const Index /* species */) {
482  s.erase(0, 1);
483  qn = RATIONAL_UNDEFINED;
484 }
485 
486 void parse_a1_br_hitran(Rational& qn, String& s, const Index /* species */) {
487  qn = Rational('Q' - s[0]);
488  if (abs(qn) > 4) qn = RATIONAL_UNDEFINED;
489  s.erase(0, 1);
490 }
491 
492 void parse_a1_pm_hitran(Rational& qn, String& s, const Index /* species */) {
493  // FIXME: How to handle plus/minus?
494  s.erase(0, 1);
495  qn = RATIONAL_UNDEFINED;
496 }
497 
498 void parse_a1_sym_hitran(Rational& qn, String& s, const Index species) {
499  qn = RATIONAL_UNDEFINED;
500  const char ch = s[0];
501 
502  if ((ch == '+' || ch == '-') &&
503  (species == species_index_from_species_name("HO2") ||
504  species == species_index_from_species_name("NO2"))) {
505  if (ch == '+')
506  qn = Rational(1, 2);
507  else if (ch == '-')
508  qn = Rational(-1, 2);
509  else
510  throw std::runtime_error("Error parsing quantum number Sym");
511  } else if ((ch == 'd' || ch == 'q') &&
512  (species == species_index_from_species_name("O2") ||
513  species == species_index_from_species_name("N2"))) {
514  // FIXME: How to deal with symmetry parameter?
515  } else if (ch == 'g' && species == species_index_from_species_name("O2")) {
516  // FIXME: What does 'g' mean? Docs only talk about d and q for O2
517  } else if (ch == 'e' || ch == 'f') {
518  // FIXME: How to handle linedoubling values?
519  } else if (ch == '+' || ch == '-') {
520  // FIXME: How to handle symmetry parameter?
521  } else if (ch != ' ')
522  throw std::runtime_error("Error parsing quantum number Sym");
523 
524  s.erase(0, 1);
525 }
526 
527 void parse_a1_s_hitran(Rational& qn, String& s, const Index /* species */) {
528  // FIXME: How to handle S?
529  s.erase(0, 1);
530  qn = RATIONAL_UNDEFINED;
531 }
532 
533 void parse_a1_x_hitran(Rational& qn, String& s, const Index species) {
534  const char ch = s[0];
535 
536  if (species == species_index_from_species_name("O2")) {
537  if (ch == 'X')
538  qn = Rational(Index(QuantumNumberTypeLabelsHitran::O2_X_is_X));
539  else if (ch == 'a')
540  qn = Rational(Index(QuantumNumberTypeLabelsHitran::O2_X_is_a));
541  else if (ch == 'b')
542  qn = Rational(Index(QuantumNumberTypeLabelsHitran::O2_X_is_b));
543  else
544  throw std::runtime_error("Unidentified X for O2 in HITRAN parsing...");
545  } else if (species == species_index_from_species_name("NO")) {
546  if (ch == 'X')
547  qn = Rational(Index(QuantumNumberTypeLabelsHitran::NO_X_is_X));
548  else
549  throw std::runtime_error("Unidentified X for NO in HITRAN parsing...");
550 
551  } else if (species == species_index_from_species_name("OH")) {
552  if (ch == 'X')
553  qn = Rational(Index(QuantumNumberTypeLabelsHitran::OH_X_is_X));
554  else if (ch == 'A')
555  qn = Rational(Index(QuantumNumberTypeLabelsHitran::OH_X_is_A));
556  else
557  throw std::runtime_error("Unidentified X for OH in HITRAN parsing...");
558 
559  } else if (species == species_index_from_species_name("ClO")) {
560  if (ch == 'X')
562  else
563  throw std::runtime_error("Unidentified X for ClO in HITRAN parsing...");
564 
565  } else
566  qn = RATIONAL_UNDEFINED;
567 
568  s.erase(0, 1);
569 }
570 
571 void parse_a2_hitran(Rational& qn, String& s, const Index /* species */) {
572  // FIXME OLE
573  s.erase(0, 2);
574  qn = RATIONAL_UNDEFINED;
575 }
576 
577 void parse_a3_hitran(Rational& qn, String& s, const Index /* species */) {
578  extract(qn, s, 3);
579 }
580 
581 void parse_a4_hitran(Rational& qn, String& s, const Index /* species */) {
582  // FIXME OLE
583  s.erase(0, 4);
584  qn = RATIONAL_UNDEFINED;
585 }
586 
587 void parse_a5_hitran(Rational& qn, String& s, const Index /* species */) {
588  String qnf = s.substr(0, 5);
589  qn = RATIONAL_UNDEFINED;
590 
591  qnf.trim();
592  if (qnf.nelem()) {
593  ArrayOfString as;
594  qnf.split(as, ".");
595  if (as.nelem() == 2) {
596  Index nom;
597  char* endptr;
598 
599  nom = strtol(as[0].c_str(), &endptr, 10);
600  if (endptr != as[0].c_str() + as[0].nelem()) {
601  throw std::runtime_error("Error parsing quantum number of type A5");
602  }
603 
604  if (as[1] == "5")
605  qn = Rational(nom * 2 + 1, 2);
606  else if (as[1] == "0")
607  qn = Rational(nom);
608  else {
609  throw std::runtime_error("Error parsing quantum number of type A5");
610  }
611  }
612  }
613  s.erase(0, 5);
614 }
615 
616 void parse_i1_hitran(Rational& qn, String& s, const Index /* species */) {
617  Index i;
618  extract(i, s, 1);
619  qn = Rational(i);
620 }
621 
622 void parse_i2_hitran(Rational& qn, String& s, const Index /* species */) {
623  Index i;
624  extract(i, s, 2);
625  qn = Rational(i);
626 }
627 
628 void parse_i3_hitran(Rational& qn, String& s, const Index /* species */) {
629  Index i;
630  extract(i, s, 3);
631  qn = Rational(i);
632 }
633 
634 void parse_f51_hitran(Rational& qn, String& s, const Index /* species */) {
635  String qnf = s.substr(0, 5);
636  qn = RATIONAL_UNDEFINED;
637 
638  qnf.trim();
639  if (qnf.nelem()) {
640  ArrayOfString as;
641  qnf.split(as, ".");
642  if (as.nelem() == 2) {
643  Index nom;
644  char* endptr;
645 
646  nom = strtol(as[0].c_str(), &endptr, 10);
647  if (endptr != as[0].c_str() + as[0].nelem()) {
648  throw std::runtime_error("Error parsing quantum number of type F5.1");
649  }
650 
651  if (as[1] == "5")
652  qn = Rational(nom * 2 + 1, 2);
653  else if (as[1] == "0")
654  qn = Rational(nom);
655  else {
656  throw std::runtime_error("Error parsing quantum number of type F5.1");
657  }
658  s.erase(0, 5);
659  } else {
660  bool valid_num = true;
661  for (Index i = 0; valid_num && i < qnf.nelem(); i++)
662  if (qnf[i] < '0' || qnf[i] > '9') valid_num = false;
663  if (!valid_num)
664  throw std::runtime_error("Error parsing quantum number of type F5.1");
665 
666  Index q;
667  extract(q, s, qnf.nelem());
668  }
669  }
670 }
671 
675 
677  if (qid.Species() == species_index_from_species_name("HO2") ||
678  qid.Species() == species_index_from_species_name("NO2")) {
679  // For these species, N is stored in field J, so we copy it here
680  // to the correct quantum number
685  // Now we can calculate the correct J by using the Symmetry quantum
686  // number. However, it does not represent Symmetry for these
687  // species, but +1/2 or -1/2
688  qid.UpperQuantumNumbers().Set(
691  qid.UpperQuantumNumber(QuantumNumberType::Sym));
692  qid.LowerQuantumNumbers().Set(
695  qid.LowerQuantumNumber(QuantumNumberType::Sym));
696 
697  // We don't need Sym after this point
698  qid.UpperQuantumNumbers().Set(QuantumNumberType::Sym, RATIONAL_UNDEFINED);
699  qid.LowerQuantumNumbers().Set(QuantumNumberType::Sym, RATIONAL_UNDEFINED);
700  }
701 }
702 
704  qid.UpperQuantumNumbers().Set(
707  qid.LowerQuantumNumber(QuantumNumberType::dJ));
708 
709  // We don't need dN and dJ after this point
710  qid.LowerQuantumNumbers().Set(QuantumNumberType::dJ, RATIONAL_UNDEFINED);
711 }
712 
714  qid.UpperQuantumNumbers().Set(
718  qid.UpperQuantumNumbers().Set(
721  qid.LowerQuantumNumbers()[QuantumNumberType::dJ]);
722 
723  assert(qid.Species() == species_index_from_species_name("O2"));
724 
725  if (qid.LowerQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
726  Index(QuantumNumberTypeLabelsHitran::O2_X_is_X)) {
728  qid.LowerQuantumNumbers().Set(QuantumNumberType::S, Rational(1, 1));
729  qid.LowerQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(0, 1));
730  } else if (qid.LowerQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
731  Index(QuantumNumberTypeLabelsHitran::O2_X_is_a)) {
733  qid.LowerQuantumNumbers().Set(QuantumNumberType::S, Rational(0, 1));
734  qid.LowerQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(2, 1));
735  } else if (qid.LowerQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
736  Index(QuantumNumberTypeLabelsHitran::O2_X_is_b)) {
738  qid.LowerQuantumNumbers().Set(QuantumNumberType::S, Rational(0, 1));
739  qid.LowerQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(0, 1));
740  }
741 
742  if (qid.UpperQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
743  Index(QuantumNumberTypeLabelsHitran::O2_X_is_X)) {
745  qid.UpperQuantumNumbers().Set(QuantumNumberType::S, Rational(1, 1));
746  qid.UpperQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(0, 1));
747  } else if (qid.UpperQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
748  Index(QuantumNumberTypeLabelsHitran::O2_X_is_a)) {
750  qid.UpperQuantumNumbers().Set(QuantumNumberType::S, Rational(0, 1));
751  qid.UpperQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(2, 1));
752  } else if (qid.UpperQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
753  Index(QuantumNumberTypeLabelsHitran::O2_X_is_b)) {
755  qid.UpperQuantumNumbers().Set(QuantumNumberType::S, Rational(0, 1));
756  qid.UpperQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(0, 1));
757  }
758 
759  // We don't need these after this point
761  qid.LowerQuantumNumbers().Set(QuantumNumberType::dJ, RATIONAL_UNDEFINED);
762  qid.LowerQuantumNumbers().Set(QuantumNumberType::ElectronState, RATIONAL_UNDEFINED);
763  qid.UpperQuantumNumbers().Set(QuantumNumberType::ElectronState, RATIONAL_UNDEFINED);
764 }
765 
767  qid.UpperQuantumNumbers().Set(
770  qid.LowerQuantumNumbers()[QuantumNumberType::dJ]);
771 
772  if (qid.Species() == species_index_from_species_name("NO")) {
773  if (qid.LowerQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
774  Index(QuantumNumberTypeLabelsHitran::NO_X_is_X)) {
776  Rational(Index(Hund::CaseA)));
777  qid.LowerQuantumNumbers().Set(QuantumNumberType::S, Rational(1, 2));
778  qid.LowerQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(1, 1));
779  } else
780  throw std::runtime_error(
781  "Missing definition of NO... this is a developer bug because it should fail earlier...");
782 
783  if (qid.UpperQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
784  Index(QuantumNumberTypeLabelsHitran::NO_X_is_X)) {
786  Rational(Index(Hund::CaseA)));
787  qid.UpperQuantumNumbers().Set(QuantumNumberType::S, Rational(1, 2));
788  qid.UpperQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(1, 1));
789  } else
790  throw std::runtime_error(
791  "Missing definition of NO... this is a developer bug because it should fail earlier...");
792  } else if (qid.Species() == species_index_from_species_name("ClO")) {
793  if (qid.LowerQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
796  Rational(Index(Hund::CaseA)));
797  qid.LowerQuantumNumbers().Set(QuantumNumberType::S, Rational(1, 2));
798  qid.LowerQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(1, 1));
799  } else
800  throw std::runtime_error(
801  "Missing definition of ClO... this is a developer bug because it should fail earlier...");
802 
803  if (qid.UpperQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
806  Rational(Index(Hund::CaseA)));
807  qid.UpperQuantumNumbers().Set(QuantumNumberType::S, Rational(1, 2));
808  qid.UpperQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(1, 1));
809  } else
810  throw std::runtime_error(
811  "Missing definition of ClO... this is a developer bug because it should fail earlier...");
812  } else
813  throw std::runtime_error(
814  "Unknown species accessing postprocessing of Hitran data... this is a developer bug");
815 
816  // We don't need these after this point
817  qid.LowerQuantumNumbers().Set(QuantumNumberType::dJ, RATIONAL_UNDEFINED);
818  qid.LowerQuantumNumbers().Set(QuantumNumberType::ElectronState, RATIONAL_UNDEFINED);
819  qid.UpperQuantumNumbers().Set(QuantumNumberType::ElectronState, RATIONAL_UNDEFINED);
820 }
821 
823  assert(qid.Species() == species_index_from_species_name("OH"));
824 
825  qid.UpperQuantumNumbers().Set(
828  qid.LowerQuantumNumbers()[QuantumNumberType::dJ]);
829 
830  qid.LowerQuantumNumbers().Set(QuantumNumberType::S, Rational(1, 2));
831  if (qid.LowerQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
832  Index(QuantumNumberTypeLabelsHitran::OH_X_is_X)) {
834  qid.LowerQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(1, 1));
835  } else if (qid.LowerQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
836  Index(QuantumNumberTypeLabelsHitran::OH_X_is_A)) {
838  qid.LowerQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(0, 1));
839  if (qid.LowerQuantumNumber(QuantumNumberType::Omega) == 1)
840  qid.LowerQuantumNumbers().Set(
843  qid.LowerQuantumNumbers()[QuantumNumberType::S]);
844  else if (qid.LowerQuantumNumber(QuantumNumberType::Omega) == 2)
845  qid.LowerQuantumNumbers().Set(
848  qid.LowerQuantumNumbers()[QuantumNumberType::S]);
849  else
850  throw std::runtime_error("Cannot understand value for OH");
851  } else
852  throw std::runtime_error(
853  "Missing definition of OH... this is a developer bug because it should fail earlier...");
854 
855  qid.UpperQuantumNumbers().Set(QuantumNumberType::S, Rational(1, 2));
856  if (qid.UpperQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
857  Index(QuantumNumberTypeLabelsHitran::OH_X_is_X)) {
859  qid.UpperQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(1, 1));
860  } else if (qid.UpperQuantumNumber(QuantumNumberType::ElectronState).toIndex() ==
861  Index(QuantumNumberTypeLabelsHitran::OH_X_is_A)) {
863  qid.UpperQuantumNumbers().Set(QuantumNumberType::Lambda, Rational(0, 1));
864  if (qid.UpperQuantumNumber(QuantumNumberType::Omega) == 1)
865  qid.UpperQuantumNumbers().Set(
868  qid.UpperQuantumNumbers()[QuantumNumberType::S]);
869  else if (qid.UpperQuantumNumber(QuantumNumberType::Omega) == 2)
870  qid.UpperQuantumNumbers().Set(
873  qid.UpperQuantumNumbers()[QuantumNumberType::S]);
874  else
875  throw std::runtime_error("Cannot understand value for OH");
876 
877  qid.LowerQuantumNumbers().Set(QuantumNumberType::Omega, RATIONAL_UNDEFINED);
878  qid.UpperQuantumNumbers().Set(QuantumNumberType::Omega, RATIONAL_UNDEFINED);
879  } else
880  throw std::runtime_error(
881  "Missing definition of OH... this is a developer bug because it should fail earlier...");
882 
883  // We don't need these after this point
885  qid.LowerQuantumNumbers().Set(QuantumNumberType::dJ, RATIONAL_UNDEFINED);
886  qid.LowerQuantumNumbers().Set(QuantumNumberType::ElectronState, RATIONAL_UNDEFINED);
887  qid.UpperQuantumNumbers().Set(QuantumNumberType::ElectronState, RATIONAL_UNDEFINED);
888 }
QuantumParserHITRAN2004::GI_GROUP4
@ GI_GROUP4
Definition: quantum_parser_hitran.h:74
RATIONAL_UNDEFINED
#define RATIONAL_UNDEFINED
Definition: rational.h:361
QuantumNumberType::N
@ N
QuantumIdentifier
Class to identify and match lines by their quantum numbers.
Definition: quantum.h:390
Rational::toIndex
constexpr Index toIndex(int n=1) const
Converts the value to index by n-scaled division.
Definition: rational.h:136
absorption.h
Declarations required for the calculation of absorption coefficients.
parse_a1_pm_hitran
void parse_a1_pm_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:492
QuantumParserHITRAN2004::CI_CLASS9
@ CI_CLASS9
Definition: quantum_parser_hitran.h:65
parse_i2_hitran
void parse_i2_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:622
QuantumNumberType::F
@ F
QuantumNumberType::r
@ r
parse_a1_s_hitran
void parse_a1_s_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:527
postprocess_group2_hitran
void postprocess_group2_hitran(QuantumIdentifier &qnr)
Definition: quantum_parser_hitran.cc:703
QuantumParserHITRAN2004::CI_CLASS1
@ CI_CLASS1
Definition: quantum_parser_hitran.h:57
abs
#define abs(x)
Definition: legacy_continua.cc:20626
parse_a2_hitran
void parse_a2_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:571
parse_a1_x_hitran
void parse_a1_x_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:533
QuantumParserHITRAN2004::CI_CLASS5
@ CI_CLASS5
Definition: quantum_parser_hitran.h:61
QuantumNumberType::v2
@ v2
QuantumParserHITRAN2004::GI_GROUP2
@ GI_GROUP2
Definition: quantum_parser_hitran.h:72
SKIP_X_SPACES
#define SKIP_X_SPACES(container, nspaces)
QuantumParserHITRAN2004::GI_FINAL
@ GI_FINAL
Definition: quantum_parser_hitran.h:78
parse_i3_hitran
void parse_i3_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:628
QuantumParserHITRAN2004::CI_CLASS6
@ CI_CLASS6
Definition: quantum_parser_hitran.h:62
global_data::species_data
const Array< SpeciesRecord > species_data
Species Data.
Definition: partition_function_data.cc:42
QuantumNumberType::v1
@ v1
QuantumParserHITRAN2004::CI_CLASS10
@ CI_CLASS10
Definition: quantum_parser_hitran.h:66
QuantumParserHITRAN2004::CI_CLASS7
@ CI_CLASS7
Definition: quantum_parser_hitran.h:63
extract
void extract(T &x, String &line, Index n)
Extract something from the beginning of a string.
Definition: mystring.h:297
parse_f51_hitran
void parse_f51_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:634
QuantumParserHITRAN2004::GI_GROUP6OH
@ GI_GROUP6OH
Definition: quantum_parser_hitran.h:77
QuantumParserHITRAN2004::QuantumClassGroup
Definition: quantum_parser_hitran.h:48
Array< QuantumFieldDescription >
Absorption::nelem
Index nelem(const Lines &l)
Number of lines.
Definition: absorptionlines.h:1820
QuantumParserHITRAN2004::GI_UNDEFINED
@ GI_UNDEFINED
Definition: quantum_parser_hitran.h:79
species_index_from_species_name
Index species_index_from_species_name(String name)
Return species index for given species name.
Definition: absorption.cc:531
postprocess_group5_hitran
void postprocess_group5_hitran(QuantumIdentifier &qnr)
Definition: quantum_parser_hitran.cc:713
postprocess_group6_hitran
void postprocess_group6_hitran(QuantumIdentifier &qnr)
Definition: quantum_parser_hitran.cc:766
parse_a3_hitran
void parse_a3_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:577
QuantumIdentifier::Species
void Species(Index sp)
Set the Species.
Definition: quantum.h:481
Hund::CaseA
@ CaseA
messages.h
Declarations having to do with the four output streams.
my_basic_string< char >
QuantumParserHITRAN2004::GI_GROUP6
@ GI_GROUP6
Definition: quantum_parser_hitran.h:76
quantum_parser_hitran.h
Parser for quantum numbers from HITRAN 2004 and later.
postprocess_group6oh_hitran
void postprocess_group6oh_hitran(QuantumIdentifier &qnr)
Definition: quantum_parser_hitran.cc:822
QuantumParserHITRAN2004::QuantumClassGroup::igroup
Index igroup
Definition: quantum_parser_hitran.h:53
QuantumIdentifier::SetTransition
void SetTransition(const QuantumNumbers &upper, const QuantumNumbers &lower)
Set to transition type identifier.
Definition: quantum.cc:229
QuantumIdentifier::LowerQuantumNumber
constexpr Rational LowerQuantumNumber(QuantumNumberType X) const noexcept
Return a lower quantum number by copy.
Definition: quantum.h:602
Hund
Hund
Enum for Hund cases.
Definition: quantum.h:219
ARTS::Group::Rational
Rational Rational
Definition: autoarts.h:96
postprocess_group1_hitran
void postprocess_group1_hitran(QuantumIdentifier &qnr)
Post-processing functions.
Definition: quantum_parser_hitran.cc:676
QuantumParserHITRAN2004::QuantumClassGroup::iclass
Index iclass
Definition: quantum_parser_hitran.h:50
parse_a1_br_hitran
void parse_a1_br_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:486
parse_a1_sym_hitran
void parse_a1_sym_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:498
QuantumNumberTypeLabelsHitran::O2_X_is_X
@ O2_X_is_X
parse_space
void parse_space(Rational &qn, String &s, const Index species)
Parsing functions.
Definition: quantum_parser_hitran.cc:481
QuantumParserHITRAN2004::mclass
Array< QuantumClass > mclass
Definition: quantum_parser_hitran.h:97
global_data.h
my_basic_string::trim
void trim()
Trim leading and trailing whitespace.
Definition: mystring.h:225
QuantumFieldDescription
Class mapping quantum numbers to parsing functions.
Definition: quantum_parser.h:36
my_basic_string::nelem
Index nelem() const
Number of elements.
Definition: mystring.h:246
my_basic_string::split
void split(Array< my_basic_string< charT > > &aos, const my_basic_string< charT > &delim) const
Split string into substrings.
Definition: mystring.h:206
QuantumIdentifier::LowerQuantumNumbers
const QuantumNumbers & LowerQuantumNumbers() const noexcept
Return the lower quantum numbers by const reference.
Definition: quantum.h:592
q
#define q
Definition: legacy_continua.cc:21712
QuantumParserHITRAN2004::CI_CLASS3
@ CI_CLASS3
Definition: quantum_parser_hitran.h:59
QuantumIdentifier::UpperQuantumNumber
constexpr Rational UpperQuantumNumber(QuantumNumberType X) const noexcept
Return a upper quantum number by copy.
Definition: quantum.h:597
QuantumParserHITRAN2004::GI_GROUP5
@ GI_GROUP5
Definition: quantum_parser_hitran.h:75
QuantumParserHITRAN2004::ClassIds
ClassIds
Definition: quantum_parser_hitran.h:56
QuantumParserHITRAN2004::CI_FINAL
@ CI_FINAL
Definition: quantum_parser_hitran.h:67
QuantumParserHITRAN2004::mgroup
Array< QuantumGroup > mgroup
Definition: quantum_parser_hitran.h:98
QuantumParserHITRAN2004::CI_CLASS4
@ CI_CLASS4
Definition: quantum_parser_hitran.h:60
QuantumParserHITRAN2004::GI_GROUP1
@ GI_GROUP1
Definition: quantum_parser_hitran.h:71
QuantumParserHITRAN2004::Parse
void Parse(QuantumIdentifier &qid, const String &quantum_string) const
Parse quantum numbers from string.
Definition: quantum_parser_hitran.cc:410
QuantumParserHITRAN2004::mspecies
Array< QuantumClassGroup > mspecies
Definition: quantum_parser_hitran.h:99
QuantumParserHITRAN2004::CI_CLASS2
@ CI_CLASS2
Definition: quantum_parser_hitran.h:58
parse_a5_hitran
void parse_a5_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:587
parse_a4_hitran
void parse_a4_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:581
QuantumNumberType::dN
@ dN
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
QuantumParserHITRAN2004::GI_GROUP3
@ GI_GROUP3
Definition: quantum_parser_hitran.h:73
QuantumParserHITRAN2004::CI_CLASS8
@ CI_CLASS8
Definition: quantum_parser_hitran.h:64
QuantumParserHITRAN2004::SetClassGroup
void SetClassGroup(const String &species_name, const ClassIds iclass, const GroupIds igroup)
Definition: quantum_parser_hitran.cc:469
QuantumNumbers::Set
void Set(Index qn, Rational r)
Set quantum number at position.
Definition: quantum.h:310
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:195
parse_i1_hitran
void parse_i1_hitran(Rational &qn, String &s, const Index species)
Definition: quantum_parser_hitran.cc:616
QuantumParserHITRAN2004::GroupIds
GroupIds
Definition: quantum_parser_hitran.h:70
QuantumParserHITRAN2004::QuantumParserHITRAN2004
QuantumParserHITRAN2004()
Constructor initializing the parser.
Definition: quantum_parser_hitran.cc:53
Rational
Implements rational numbers to work with other ARTS types.
Definition: rational.h:54
QuantumIdentifier::UpperQuantumNumbers
const QuantumNumbers & UpperQuantumNumbers() const noexcept
Return the upper quantum numbers by const reference.
Definition: quantum.h:587
QuantumNumberType::J
@ J