ARTS 2.5.11 (git: 725533f0)
quantum_numbers.cc
Go to the documentation of this file.
1#include "quantum_numbers.h"
2
3#include <algorithm>
4#include <string_view>
5#include <utility>
6
7#include "debug.h"
8#include "species.h"
9
10namespace Quantum::Number {
11std::ostream& operator<<(std::ostream& os, ValueDescription x) {
12 os << x.type << ' ';
13 switch (x.type) {
14 case ValueType::S:
15 return os << x.val.s.val();
16 case ValueType::I:
17 return os << x.val.i.x;
18 case ValueType::H:
19 return os << Rational(x.val.h.x, 2);
20 case ValueType::FINAL: {
21 }
22 }
23 return os;
24}
25
26String Value::str_upp() const noexcept {
27 if (ValueType::S == common_value_type(type)) return qn.upp.s.val();
28 return var_string(upp());
29}
30String Value::str_low() const noexcept {
31 if (ValueType::S == common_value_type(type)) return qn.low.s.val();
32 return var_string(low());
33}
34
35std::ostream& operator<<(std::ostream& os, Value x) {
36 return os << x.type << ' ' << x.str_upp() << ' ' << x.str_low();
37}
38
39std::istream& operator>>(std::istream& is, Value& x) {
40 std::string upp, low;
41 is >> x.type >> upp >> low;
42
44 value_holder(upp, x.type), value_holder(low, x.type), x.type);
45
46 return is;
47}
48
50 std::sort(begin(), end(), [](auto& a, auto& b) { return a.type < b.type; });
51}
52
54 return std::adjacent_find(begin(), end(), [](auto& a, auto& b) {
55 return a.type >= b.type;
56 }) == values.end();
57}
58
60std::pair<std::string_view, String> fix_legacy(std::string_view key,
61 std::string_view val) {
62 if (key == "ElectronState") {
63 if (val == "X") return {"ElecStateLabel", "X"};
64 if (val == "a") return {"ElecStateLabel", "a"};
65 if (val == "b") return {"ElecStateLabel", "b"};
66 if (val == "c") return {"ElecStateLabel", "c"};
67 if (val == "A") return {"ElecStateLabel", "A"};
68 if (val == "'") return {"ElecStateLabel", "'"};
69 if (val == "B") return {"ElecStateLabel", "B"};
70 if (val == "88") return {"ElecStateLabel", "X"};
71 if (val == "97") return {"ElecStateLabel", "a"};
72 if (val == "98") return {"ElecStateLabel", "b"};
73 if (val == "99") return {"ElecStateLabel", "c"};
74 if (val == "65") return {"ElecStateLabel", "A"};
75 if (val == "39") return {"ElecStateLabel", "'"};
76 if (val == "66") return {"ElecStateLabel", "B"};
77 goto error;
78 }
79
80 if (key == "parity") {
81 if (val == "-") return {key, "-"};
82 if (val == "+") return {key, "+"};
83 if (val == "-1") return {key, "-"};
84 if (val == "1") return {key, "+"};
85 goto error;
86 }
87
88 if (key == "Hund") return {"config", val};
89
90 if (key == "kronigParity") {
91 if (val == "e") return {key, "e"};
92 if (val == "f") return {key, "f"};
93 if (val == "101") return {key, "e"};
94 if (val == "102") return {key, "f"};
95 goto error;
96 }
97
98 return {key, val};
99
100error:
101 ARTS_USER_ERROR("Cannot read combination ", key, ' ', val)
102}
103
104ValueList::ValueList(std::string_view s, bool legacy) : values(0) {
105 const Index n = count_items(s);
106
107 if (not legacy) {
109 n % 3, "Must have multiple of three items, got ", n, " in:\n", s)
110 for (Index i = 0; i < n; i += 3) values.emplace_back(Value(items<3>(s, i)));
111 } else {
112 ARTS_USER_ERROR_IF(n < 2, "Must have two items:\n", s)
113 Index i = 0;
114 auto key_type = items(s, i);
115 if (key_type == "ALL") return;
116 if (key_type == "NONE") return;
117
118 if (key_type == "TR") {
119 // Transition type, will look like SPEC TR UP QN VAL QN VAL QN VAL LO QN VAL QN VAL QN VAL
120 ARTS_USER_ERROR_IF(n < 4, "Must have at least four items")
121
122 i++;
124 items(s, i) not_eq "UP", "Bad legacy quantum numbers in:\n", s)
125 i++;
126
127 bool upp = true;
128 for (; i < n; i += 2) {
129 auto key = items(s, i);
130 if (key == "LO") {
131 i++;
132 key = items(s, i);
133 upp = false;
134 }
135
136 auto [k, val] = fix_legacy(key, items(s, i + 1));
137
138 auto t = toTypeOrThrow(k);
139 if (has(t)) {
140 std::find_if(begin(), end(), [t](auto& x) {
141 return x.type == t;
142 })->set(val, upp);
143 } else {
144 Value value = add(t);
145 value.set(val, upp);
146 set(value);
147 }
148 }
149 return;
150 }
151
152 if (key_type == "EN") {
153 // Transition type, will look like SPEC EN QN VAL QN VAL QN VAL
154 i++;
155
156 for (; i < n; i += 2) {
157 auto [key, val] = fix_legacy(items(s, i), items(s, i + 1));
158 auto t = toTypeOrThrow(key);
159
160 if (has(t)) {
161 auto valptr = std::find_if(
162 begin(), end(), [t](auto& x) { return x.type == t; });
163 valptr->set(val, true);
164 valptr->set(val, false);
165 } else {
166 Value& value = add(t);
167 value.set(val, true);
168 value.set(val, false);
169 }
170 }
171 return;
172 }
173 }
174 finalize();
175}
176
177ValueList::ValueList(std::string_view upp, std::string_view low) {
178 const Index nu = count_items(upp);
179 const Index nl = count_items(low);
180
182 nu % 2,
183 "Uneven count of items for legacy upper quantum number list: ",
184 upp)
186 nl % 2,
187 "Uneven count of items for legacy lower quantum number list: ",
188 low)
189
190 for (Index i = 0; i < nu; i += 2) {
191 auto [k, val] = fix_legacy(items(upp, i), items(upp, i + 1));
192 auto key = toTypeOrThrow(k);
193
194 auto ptr =
195 std::find_if(begin(), end(), [key](auto& a) { return a.type == key; });
196 if (ptr == end()) {
197 add(key);
198 ptr = std::find_if(
199 begin(), end(), [key](auto& a) { return a.type == key; });
200 }
201
202 ptr->set(val, true);
203 }
204
205 for (Index i = 0; i < nl; i += 2) {
206 auto [k, val] = fix_legacy(items(low, i), items(low, i + 1));
207 auto key = toTypeOrThrow(k);
208
209 auto ptr =
210 std::find_if(begin(), end(), [key](auto& a) { return a.type == key; });
211 if (ptr == end()) {
212 add(key);
213 ptr = std::find_if(
214 begin(), end(), [key](auto& a) { return a.type == key; });
215 }
216
217 ptr->set(val, false);
218 }
219}
220
228constexpr std::pair<std::string_view, std::string_view> split_hitran_qn(
229 std::string_view x) {
230 auto eq = x.find('=');
231 std::pair<std::string_view, std::string_view> out{strip(x.substr(0, eq)),
232 strip(x.substr(eq + 1))};
233
234 if (x.size() > 1 and 'F' == out.first.front() and '#' == out.first[1])
235 out.first = out.first.substr(0, 1);
236
237 return out;
238}
239
240ValueList from_hitran(std::string_view upp, std::string_view low) {
241 ValueList out;
242
243 upp = strip(upp);
244 while (not upp.empty()) {
245 auto sep = upp.find(';');
246 auto [t, v] = split_hitran_qn(upp.substr(0, sep));
247 auto type = toTypeOrThrow(t);
249 out.has(type),
250 "Type ",
251 t,
252 " already exist, this is a problem, there should be only one per level!")
253 out.add(type).set(v, true);
254
255 if (sep == upp.npos) break;
256 upp = upp.substr(sep + 1);
257 }
258
259 low = strip(low);
260 while (not low.empty()) {
261 auto sep = low.find(';');
262 auto [t, v] = split_hitran_qn(low.substr(0, sep));
263 auto type = toTypeOrThrow(t);
264 if (out.has(type)) {
265 Value val = out[type];
266 val.set(v, false);
267 out.set(val);
268 } else {
269 out.add(type).set(v, false);
270 }
271
272 if (sep == low.npos) break;
273 low = low.substr(sep + 1);
274 }
275
276 return out;
277}
278
280 sort_by_type();
282 "The quantum number list: [",
283 *this,
284 "] contains copies of types")
285}
286
288 ARTS_ASSERT(has_unique_increasing_types())
289 ARTS_ASSERT(that.has_unique_increasing_types())
290
291 auto this_val = cbegin();
292 auto that_val = that.cbegin();
293 while (that_val not_eq that.cend() and this_val not_eq cend()) {
294 if (that_val->type < this_val->type)
295 that_val++;
296 else if (this_val->type < that_val->type)
297 this_val++;
298 else
299 return false;
300 }
301 return true;
302}
303
305 CheckMatch status = {CheckValue::Full, CheckValue::Full};
306
307 for (Type const t : enumtyps::TypeTypes) {
308 const bool ahas = has(t), bhas = other.has(t);
309
310 if (ahas and bhas) {
311 const LevelMatch levels = operator[](t).level_match(other[t]);
312 if (not levels.upp) status.upp = CheckValue::Miss;
313 if (not levels.low) status.low = CheckValue::Miss;
314 } else if (ahas and not bhas) {
315 status = update(status, CheckValue::BinA);
316 } else if (not ahas and bhas) {
317 status = update(status, CheckValue::AinB);
318 }
319 }
320 return status;
321}
322
324 auto val =
325 std::find_if(cbegin(), cend(), [t](auto& x) { return x.type == t; });
326 ARTS_ASSERT(val not_eq cend())
327 return *val;
328}
329
331 Value v{t};
332 values.push_back(v);
333 finalize();
334
335 // We have the value, it is unique, so no need to check this pointer (we still need to find it, since we sort things)
336 return *std::find_if(begin(), end(), [t](auto& x) { return x.type == t; });
337}
338
340 values.push_back(v);
341 finalize();
342
343 // We have the value, it is unique, so no need to check this pointer (we still need to find it, since we sort things)
344 return *std::find_if(
345 begin(), end(), [t = v.type](auto& x) { return x.type == t; });
346}
347
349 if (has(v.type))
350 *std::find_if(
351 begin(), end(), [t = v.type](auto& x) { return x.type == t; }) = v;
352 else
353 add(v);
354}
355
356void ValueList::set(Index i, std::string_view upp, std::string_view low) {
357 values[i] = Value(var_string(values[i].type, ' ', upp, ' ', low));
358}
359
360std::ostream& operator<<(std::ostream& os, const ValueList& vl) {
361 for (Index i = 0; i < vl.values.nelem(); i++) {
362 if (i) os << ' ';
363 os << vl.values[i];
364 }
365 return os;
366}
367
368std::istream& operator>>(std::istream& is, ValueList& vl) {
369 for (auto& x : vl.values) is >> x;
370 vl.finalize();
371 return is;
372}
373
375 std::ostringstream os;
376
377 bool has = false;
378 for (auto& qn : val) {
379 if (has) os << ' ';
380 has = true;
381 os << qn.type;
382 }
383 return os.str();
384}
385
387 std::ostringstream os;
388
389 bool first = true;
390 for (auto& x : val) {
391 if (first)
392 first = false;
393 else
394 os << ' ';
395 os << x.str_low();
396 }
397
398 for (auto& x : val) {
399 os << ' ' << x.str_upp();
400 }
401
402 return os.str();
403}
404
407}
408
409Species::Species GlobalState::Species() const noexcept {
410 return Isotopologue().spec;
411}
412
413std::ostream& operator<<(std::ostream& os, const GlobalState& gs) {
414 return os << gs.Isotopologue().FullName() << ' ' << gs.val;
415}
416
417std::istream& operator>>(std::istream& is, GlobalState& gs) {
418 String spec;
419 is >> spec >> gs.val;
421 ARTS_USER_ERROR_IF(gs.isotopologue_index < 0, "Cannot read species: ", spec)
422 return is;
423}
424
425bool vamdcCheck(const ValueList& l, VAMDC type) ARTS_NOEXCEPT {
426 switch (type) {
427 case VAMDC::asymcs:
428 if (l.has(Type::K)) return false;
429 if (l.has(Type::Lambda)) return false;
430 if (l.has(Type::N)) return false;
431 if (l.has(Type::Omega)) return false;
432 if (l.has(Type::S)) return false;
433 if (l.has(Type::Sigma)) return false;
434 if (l.has(Type::SpinComponentLabel)) return false;
435 if (l.has(Type::asSym)) return false;
436 if (l.has(Type::elecInv)) return false;
437 if (l.has(Type::elecRefl)) return false;
438 if (l.has(Type::elecSym)) return false;
439 if (l.has(Type::kronigParity)) return false;
440 if (l.has(Type::l)) return false;
441 if (l.has(Type::l1)) return false;
442 if (l.has(Type::l10)) return false;
443 if (l.has(Type::l11)) return false;
444 if (l.has(Type::l12)) return false;
445 if (l.has(Type::l2)) return false;
446 if (l.has(Type::l3)) return false;
447 if (l.has(Type::l4)) return false;
448 if (l.has(Type::l5)) return false;
449 if (l.has(Type::l6)) return false;
450 if (l.has(Type::l7)) return false;
451 if (l.has(Type::l8)) return false;
452 if (l.has(Type::l9)) return false;
453 if (l.has(Type::sym)) return false;
454 if (l.has(Type::v)) return false;
455 if (l.has(Type::vibRefl)) return false;
456 return true;
457 case VAMDC::asymos:
458 if (l.has(Type::K)) return false;
459 if (l.has(Type::Lambda)) return false;
460 if (l.has(Type::Omega)) return false;
461 if (l.has(Type::Sigma)) return false;
462 if (l.has(Type::SpinComponentLabel)) return false;
463 if (l.has(Type::asSym)) return false;
464 if (l.has(Type::elecRefl)) return false;
465 if (l.has(Type::kronigParity)) return false;
466 if (l.has(Type::l)) return false;
467 if (l.has(Type::l1)) return false;
468 if (l.has(Type::l10)) return false;
469 if (l.has(Type::l11)) return false;
470 if (l.has(Type::l12)) return false;
471 if (l.has(Type::l2)) return false;
472 if (l.has(Type::l3)) return false;
473 if (l.has(Type::l4)) return false;
474 if (l.has(Type::l5)) return false;
475 if (l.has(Type::l6)) return false;
476 if (l.has(Type::l7)) return false;
477 if (l.has(Type::l8)) return false;
478 if (l.has(Type::l9)) return false;
479 if (l.has(Type::sym)) return false;
480 if (l.has(Type::v)) return false;
481 if (l.has(Type::vibRefl)) return false;
482 return true;
483 case VAMDC::dcs:
484 if (l.has(Type::F10)) return false;
485 if (l.has(Type::F11)) return false;
486 if (l.has(Type::F12)) return false;
487 if (l.has(Type::F2)) return false;
488 if (l.has(Type::F3)) return false;
489 if (l.has(Type::F4)) return false;
490 if (l.has(Type::F5)) return false;
491 if (l.has(Type::F6)) return false;
492 if (l.has(Type::F7)) return false;
493 if (l.has(Type::F8)) return false;
494 if (l.has(Type::F9)) return false;
495 if (l.has(Type::K)) return false;
496 if (l.has(Type::Ka)) return false;
497 if (l.has(Type::Kc)) return false;
498 if (l.has(Type::Lambda)) return false;
499 if (l.has(Type::N)) return false;
500 if (l.has(Type::Omega)) return false;
501 if (l.has(Type::S)) return false;
502 if (l.has(Type::Sigma)) return false;
503 if (l.has(Type::SpinComponentLabel)) return false;
504 if (l.has(Type::elecInv)) return false;
505 if (l.has(Type::elecRefl)) return false;
506 if (l.has(Type::elecSym)) return false;
507 if (l.has(Type::l)) return false;
508 if (l.has(Type::l1)) return false;
509 if (l.has(Type::l10)) return false;
510 if (l.has(Type::l11)) return false;
511 if (l.has(Type::l12)) return false;
512 if (l.has(Type::l2)) return false;
513 if (l.has(Type::l3)) return false;
514 if (l.has(Type::l4)) return false;
515 if (l.has(Type::l5)) return false;
516 if (l.has(Type::l6)) return false;
517 if (l.has(Type::l7)) return false;
518 if (l.has(Type::l8)) return false;
519 if (l.has(Type::l9)) return false;
520 if (l.has(Type::rotSym)) return false;
521 if (l.has(Type::rovibSym)) return false;
522 if (l.has(Type::sym)) return false;
523 if (l.has(Type::v1)) return false;
524 if (l.has(Type::v10)) return false;
525 if (l.has(Type::v11)) return false;
526 if (l.has(Type::v12)) return false;
527 if (l.has(Type::v2)) return false;
528 if (l.has(Type::v3)) return false;
529 if (l.has(Type::v4)) return false;
530 if (l.has(Type::v5)) return false;
531 if (l.has(Type::v6)) return false;
532 if (l.has(Type::v7)) return false;
533 if (l.has(Type::v8)) return false;
534 if (l.has(Type::v9)) return false;
535 if (l.has(Type::vibInv)) return false;
536 if (l.has(Type::vibRefl)) return false;
537 if (l.has(Type::vibSym)) return false;
538 return true;
539 case VAMDC::hunda:
540 if (l.has(Type::F10)) return false;
541 if (l.has(Type::F11)) return false;
542 if (l.has(Type::F12)) return false;
543 if (l.has(Type::F2)) return false;
544 if (l.has(Type::F3)) return false;
545 if (l.has(Type::F4)) return false;
546 if (l.has(Type::F5)) return false;
547 if (l.has(Type::F6)) return false;
548 if (l.has(Type::F7)) return false;
549 if (l.has(Type::F8)) return false;
550 if (l.has(Type::F9)) return false;
551 if (l.has(Type::K)) return false;
552 if (l.has(Type::Ka)) return false;
553 if (l.has(Type::Kc)) return false;
554 if (l.has(Type::N)) return false;
555 if (l.has(Type::SpinComponentLabel)) return false;
556 if (l.has(Type::elecSym)) return false;
557 if (l.has(Type::l)) return false;
558 if (l.has(Type::l1)) return false;
559 if (l.has(Type::l10)) return false;
560 if (l.has(Type::l11)) return false;
561 if (l.has(Type::l12)) return false;
562 if (l.has(Type::l2)) return false;
563 if (l.has(Type::l3)) return false;
564 if (l.has(Type::l4)) return false;
565 if (l.has(Type::l5)) return false;
566 if (l.has(Type::l6)) return false;
567 if (l.has(Type::l7)) return false;
568 if (l.has(Type::l8)) return false;
569 if (l.has(Type::l9)) return false;
570 if (l.has(Type::rotSym)) return false;
571 if (l.has(Type::rovibSym)) return false;
572 if (l.has(Type::sym)) return false;
573 if (l.has(Type::v1)) return false;
574 if (l.has(Type::v10)) return false;
575 if (l.has(Type::v11)) return false;
576 if (l.has(Type::v12)) return false;
577 if (l.has(Type::v2)) return false;
578 if (l.has(Type::v3)) return false;
579 if (l.has(Type::v4)) return false;
580 if (l.has(Type::v5)) return false;
581 if (l.has(Type::v6)) return false;
582 if (l.has(Type::v7)) return false;
583 if (l.has(Type::v8)) return false;
584 if (l.has(Type::v9)) return false;
585 if (l.has(Type::vibInv)) return false;
586 if (l.has(Type::vibRefl)) return false;
587 if (l.has(Type::vibSym)) return false;
588 return true;
589 case VAMDC::hundb:
590 if (l.has(Type::F10)) return false;
591 if (l.has(Type::F11)) return false;
592 if (l.has(Type::F12)) return false;
593 if (l.has(Type::F2)) return false;
594 if (l.has(Type::F3)) return false;
595 if (l.has(Type::F4)) return false;
596 if (l.has(Type::F5)) return false;
597 if (l.has(Type::F6)) return false;
598 if (l.has(Type::F7)) return false;
599 if (l.has(Type::F8)) return false;
600 if (l.has(Type::F9)) return false;
601 if (l.has(Type::K)) return false;
602 if (l.has(Type::Ka)) return false;
603 if (l.has(Type::Kc)) return false;
604 if (l.has(Type::Omega)) return false;
605 if (l.has(Type::Sigma)) return false;
606 if (l.has(Type::elecSym)) return false;
607 if (l.has(Type::l)) return false;
608 if (l.has(Type::l1)) return false;
609 if (l.has(Type::l10)) return false;
610 if (l.has(Type::l11)) return false;
611 if (l.has(Type::l12)) return false;
612 if (l.has(Type::l2)) return false;
613 if (l.has(Type::l3)) return false;
614 if (l.has(Type::l4)) return false;
615 if (l.has(Type::l5)) return false;
616 if (l.has(Type::l6)) return false;
617 if (l.has(Type::l7)) return false;
618 if (l.has(Type::l8)) return false;
619 if (l.has(Type::l9)) return false;
620 if (l.has(Type::rotSym)) return false;
621 if (l.has(Type::rovibSym)) return false;
622 if (l.has(Type::sym)) return false;
623 if (l.has(Type::v1)) return false;
624 if (l.has(Type::v10)) return false;
625 if (l.has(Type::v11)) return false;
626 if (l.has(Type::v12)) return false;
627 if (l.has(Type::v2)) return false;
628 if (l.has(Type::v3)) return false;
629 if (l.has(Type::v4)) return false;
630 if (l.has(Type::v5)) return false;
631 if (l.has(Type::v6)) return false;
632 if (l.has(Type::v7)) return false;
633 if (l.has(Type::v8)) return false;
634 if (l.has(Type::v9)) return false;
635 if (l.has(Type::vibInv)) return false;
636 if (l.has(Type::vibRefl)) return false;
637 if (l.has(Type::vibSym)) return false;
638 return true;
639 case VAMDC::lpcs:
640 if (l.has(Type::K)) return false;
641 if (l.has(Type::Ka)) return false;
642 if (l.has(Type::Kc)) return false;
643 if (l.has(Type::Lambda)) return false;
644 if (l.has(Type::N)) return false;
645 if (l.has(Type::Omega)) return false;
646 if (l.has(Type::S)) return false;
647 if (l.has(Type::Sigma)) return false;
648 if (l.has(Type::SpinComponentLabel)) return false;
649 if (l.has(Type::elecInv)) return false;
650 if (l.has(Type::elecRefl)) return false;
651 if (l.has(Type::elecSym)) return false;
652 if (l.has(Type::rotSym)) return false;
653 if (l.has(Type::rovibSym)) return false;
654 if (l.has(Type::sym)) return false;
655 if (l.has(Type::v)) return false;
656 return true;
657 case VAMDC::lpos:
658 if (l.has(Type::K)) return false;
659 if (l.has(Type::Ka)) return false;
660 if (l.has(Type::Kc)) return false;
661 if (l.has(Type::Omega)) return false;
662 if (l.has(Type::Sigma)) return false;
663 if (l.has(Type::SpinComponentLabel)) return false;
664 if (l.has(Type::elecSym)) return false;
665 if (l.has(Type::rotSym)) return false;
666 if (l.has(Type::rovibSym)) return false;
667 if (l.has(Type::sym)) return false;
668 if (l.has(Type::v)) return false;
669 if (l.has(Type::vibSym)) return false;
670 return true;
671 case VAMDC::ltcs:
672 if (l.has(Type::F10)) return false;
673 if (l.has(Type::F11)) return false;
674 if (l.has(Type::F12)) return false;
675 if (l.has(Type::F3)) return false;
676 if (l.has(Type::F4)) return false;
677 if (l.has(Type::F5)) return false;
678 if (l.has(Type::F6)) return false;
679 if (l.has(Type::F7)) return false;
680 if (l.has(Type::F8)) return false;
681 if (l.has(Type::F9)) return false;
682 if (l.has(Type::K)) return false;
683 if (l.has(Type::Ka)) return false;
684 if (l.has(Type::Kc)) return false;
685 if (l.has(Type::Lambda)) return false;
686 if (l.has(Type::N)) return false;
687 if (l.has(Type::Omega)) return false;
688 if (l.has(Type::S)) return false;
689 if (l.has(Type::Sigma)) return false;
690 if (l.has(Type::SpinComponentLabel)) return false;
691 if (l.has(Type::elecInv)) return false;
692 if (l.has(Type::elecRefl)) return false;
693 if (l.has(Type::elecSym)) return false;
694 if (l.has(Type::l)) return false;
695 if (l.has(Type::l1)) return false;
696 if (l.has(Type::l10)) return false;
697 if (l.has(Type::l11)) return false;
698 if (l.has(Type::l12)) return false;
699 if (l.has(Type::l3)) return false;
700 if (l.has(Type::l4)) return false;
701 if (l.has(Type::l5)) return false;
702 if (l.has(Type::l6)) return false;
703 if (l.has(Type::l7)) return false;
704 if (l.has(Type::l8)) return false;
705 if (l.has(Type::l9)) return false;
706 if (l.has(Type::rotSym)) return false;
707 if (l.has(Type::rovibSym)) return false;
708 if (l.has(Type::sym)) return false;
709 if (l.has(Type::v)) return false;
710 if (l.has(Type::v10)) return false;
711 if (l.has(Type::v11)) return false;
712 if (l.has(Type::v12)) return false;
713 if (l.has(Type::v4)) return false;
714 if (l.has(Type::v5)) return false;
715 if (l.has(Type::v6)) return false;
716 if (l.has(Type::v7)) return false;
717 if (l.has(Type::v8)) return false;
718 if (l.has(Type::v9)) return false;
719 if (l.has(Type::vibInv)) return false;
720 if (l.has(Type::vibRefl)) return false;
721 if (l.has(Type::vibSym)) return false;
722 return true;
723 case VAMDC::ltos:
724 if (l.has(Type::F10)) return false;
725 if (l.has(Type::F11)) return false;
726 if (l.has(Type::F12)) return false;
727 if (l.has(Type::F3)) return false;
728 if (l.has(Type::F4)) return false;
729 if (l.has(Type::F5)) return false;
730 if (l.has(Type::F6)) return false;
731 if (l.has(Type::F7)) return false;
732 if (l.has(Type::F8)) return false;
733 if (l.has(Type::F9)) return false;
734 if (l.has(Type::K)) return false;
735 if (l.has(Type::Ka)) return false;
736 if (l.has(Type::Kc)) return false;
737 if (l.has(Type::Omega)) return false;
738 if (l.has(Type::Sigma)) return false;
739 if (l.has(Type::SpinComponentLabel)) return false;
740 if (l.has(Type::elecSym)) return false;
741 if (l.has(Type::l)) return false;
742 if (l.has(Type::l1)) return false;
743 if (l.has(Type::l10)) return false;
744 if (l.has(Type::l11)) return false;
745 if (l.has(Type::l12)) return false;
746 if (l.has(Type::l3)) return false;
747 if (l.has(Type::l4)) return false;
748 if (l.has(Type::l5)) return false;
749 if (l.has(Type::l6)) return false;
750 if (l.has(Type::l7)) return false;
751 if (l.has(Type::l8)) return false;
752 if (l.has(Type::l9)) return false;
753 if (l.has(Type::rotSym)) return false;
754 if (l.has(Type::rovibSym)) return false;
755 if (l.has(Type::sym)) return false;
756 if (l.has(Type::v)) return false;
757 if (l.has(Type::v10)) return false;
758 if (l.has(Type::v11)) return false;
759 if (l.has(Type::v12)) return false;
760 if (l.has(Type::v4)) return false;
761 if (l.has(Type::v5)) return false;
762 if (l.has(Type::v6)) return false;
763 if (l.has(Type::v7)) return false;
764 if (l.has(Type::v8)) return false;
765 if (l.has(Type::v9)) return false;
766 if (l.has(Type::vibInv)) return false;
767 if (l.has(Type::vibRefl)) return false;
768 if (l.has(Type::vibSym)) return false;
769 return true;
770 case VAMDC::nltcs:
771 if (l.has(Type::F10)) return false;
772 if (l.has(Type::F11)) return false;
773 if (l.has(Type::F12)) return false;
774 if (l.has(Type::F3)) return false;
775 if (l.has(Type::F4)) return false;
776 if (l.has(Type::F5)) return false;
777 if (l.has(Type::F6)) return false;
778 if (l.has(Type::F7)) return false;
779 if (l.has(Type::F8)) return false;
780 if (l.has(Type::F9)) return false;
781 if (l.has(Type::K)) return false;
782 if (l.has(Type::Lambda)) return false;
783 if (l.has(Type::N)) return false;
784 if (l.has(Type::Omega)) return false;
785 if (l.has(Type::S)) return false;
786 if (l.has(Type::Sigma)) return false;
787 if (l.has(Type::SpinComponentLabel)) return false;
788 if (l.has(Type::elecInv)) return false;
789 if (l.has(Type::elecRefl)) return false;
790 if (l.has(Type::elecSym)) return false;
791 if (l.has(Type::l)) return false;
792 if (l.has(Type::l1)) return false;
793 if (l.has(Type::l10)) return false;
794 if (l.has(Type::l11)) return false;
795 if (l.has(Type::l12)) return false;
796 if (l.has(Type::l2)) return false;
797 if (l.has(Type::l3)) return false;
798 if (l.has(Type::l4)) return false;
799 if (l.has(Type::l5)) return false;
800 if (l.has(Type::l6)) return false;
801 if (l.has(Type::l7)) return false;
802 if (l.has(Type::l8)) return false;
803 if (l.has(Type::l9)) return false;
804 if (l.has(Type::rotSym)) return false;
805 if (l.has(Type::rovibSym)) return false;
806 if (l.has(Type::sym)) return false;
807 if (l.has(Type::v)) return false;
808 if (l.has(Type::v10)) return false;
809 if (l.has(Type::v11)) return false;
810 if (l.has(Type::v12)) return false;
811 if (l.has(Type::v4)) return false;
812 if (l.has(Type::v5)) return false;
813 if (l.has(Type::v6)) return false;
814 if (l.has(Type::v7)) return false;
815 if (l.has(Type::v8)) return false;
816 if (l.has(Type::v9)) return false;
817 if (l.has(Type::vibInv)) return false;
818 if (l.has(Type::vibRefl)) return false;
819 if (l.has(Type::vibSym)) return false;
820 return true;
821 case VAMDC::nltos:
822 if (l.has(Type::F10)) return false;
823 if (l.has(Type::F11)) return false;
824 if (l.has(Type::F12)) return false;
825 if (l.has(Type::F3)) return false;
826 if (l.has(Type::F4)) return false;
827 if (l.has(Type::F5)) return false;
828 if (l.has(Type::F6)) return false;
829 if (l.has(Type::F7)) return false;
830 if (l.has(Type::F8)) return false;
831 if (l.has(Type::F9)) return false;
832 if (l.has(Type::K)) return false;
833 if (l.has(Type::Lambda)) return false;
834 if (l.has(Type::Omega)) return false;
835 if (l.has(Type::Sigma)) return false;
836 if (l.has(Type::SpinComponentLabel)) return false;
837 if (l.has(Type::elecInv)) return false;
838 if (l.has(Type::elecRefl)) return false;
839 if (l.has(Type::l)) return false;
840 if (l.has(Type::l1)) return false;
841 if (l.has(Type::l10)) return false;
842 if (l.has(Type::l11)) return false;
843 if (l.has(Type::l12)) return false;
844 if (l.has(Type::l2)) return false;
845 if (l.has(Type::l3)) return false;
846 if (l.has(Type::l4)) return false;
847 if (l.has(Type::l5)) return false;
848 if (l.has(Type::l6)) return false;
849 if (l.has(Type::l7)) return false;
850 if (l.has(Type::l8)) return false;
851 if (l.has(Type::l9)) return false;
852 if (l.has(Type::rotSym)) return false;
853 if (l.has(Type::rovibSym)) return false;
854 if (l.has(Type::sym)) return false;
855 if (l.has(Type::v)) return false;
856 if (l.has(Type::v10)) return false;
857 if (l.has(Type::v11)) return false;
858 if (l.has(Type::v12)) return false;
859 if (l.has(Type::v4)) return false;
860 if (l.has(Type::v5)) return false;
861 if (l.has(Type::v6)) return false;
862 if (l.has(Type::v7)) return false;
863 if (l.has(Type::v8)) return false;
864 if (l.has(Type::v9)) return false;
865 if (l.has(Type::vibInv)) return false;
866 if (l.has(Type::vibRefl)) return false;
867 if (l.has(Type::vibSym)) return false;
868 return true;
869 case VAMDC::sphcs:
870 if (l.has(Type::K)) return false;
871 if (l.has(Type::Ka)) return false;
872 if (l.has(Type::Kc)) return false;
873 if (l.has(Type::Lambda)) return false;
874 if (l.has(Type::N)) return false;
875 if (l.has(Type::Omega)) return false;
876 if (l.has(Type::S)) return false;
877 if (l.has(Type::Sigma)) return false;
878 if (l.has(Type::SpinComponentLabel)) return false;
879 if (l.has(Type::asSym)) return false;
880 if (l.has(Type::elecInv)) return false;
881 if (l.has(Type::elecRefl)) return false;
882 if (l.has(Type::elecSym)) return false;
883 if (l.has(Type::kronigParity)) return false;
884 if (l.has(Type::l)) return false;
885 if (l.has(Type::v)) return false;
886 if (l.has(Type::vibInv)) return false;
887 if (l.has(Type::vibRefl)) return false;
888 return true;
889 case VAMDC::sphos:
890 if (l.has(Type::K)) return false;
891 if (l.has(Type::Ka)) return false;
892 if (l.has(Type::Kc)) return false;
893 if (l.has(Type::Lambda)) return false;
894 if (l.has(Type::Omega)) return false;
895 if (l.has(Type::Sigma)) return false;
896 if (l.has(Type::SpinComponentLabel)) return false;
897 if (l.has(Type::asSym)) return false;
898 if (l.has(Type::elecRefl)) return false;
899 if (l.has(Type::kronigParity)) return false;
900 if (l.has(Type::l)) return false;
901 if (l.has(Type::v)) return false;
902 if (l.has(Type::vibInv)) return false;
903 if (l.has(Type::vibRefl)) return false;
904 return true;
905 case VAMDC::stcs:
906 if (l.has(Type::Ka)) return false;
907 if (l.has(Type::Kc)) return false;
908 if (l.has(Type::Lambda)) return false;
909 if (l.has(Type::N)) return false;
910 if (l.has(Type::Omega)) return false;
911 if (l.has(Type::S)) return false;
912 if (l.has(Type::Sigma)) return false;
913 if (l.has(Type::SpinComponentLabel)) return false;
914 if (l.has(Type::asSym)) return false;
915 if (l.has(Type::elecInv)) return false;
916 if (l.has(Type::elecRefl)) return false;
917 if (l.has(Type::elecSym)) return false;
918 if (l.has(Type::kronigParity)) return false;
919 if (l.has(Type::sym)) return false;
920 if (l.has(Type::v)) return false;
921 if (l.has(Type::vibRefl)) return false;
922 return true;
923 case VAMDC::FINAL: {
924 }
925 }
926 return false;
927}
928
930 const LocalState& local,
931 const GlobalState& global) {
932 if (target.isotopologue_index == global.isotopologue_index)
933 type = StateMatchType::Isotopologue;
934 else if (target.Species() == global.Species())
935 type = StateMatchType::Species;
936
937 if (type == StateMatchType::Isotopologue) {
938 auto g = target.val.check_match(global.val);
939 auto l = target.val.check_match(local.val);
940
941 bool ug = g.upp == CheckValue::Full or g.upp == CheckValue::BinA;
942 bool ul = l.upp == CheckValue::Full or l.upp == CheckValue::BinA;
943 bool lg = g.low == CheckValue::Full or g.low == CheckValue::BinA;
944 bool ll = l.low == CheckValue::Full or l.low == CheckValue::BinA;
945
946 upp = ug and ul;
947 low = lg and ll;
948
949 if (upp and low)
950 type = StateMatchType::Full;
951 else if (upp or low)
952 type = StateMatchType::Level;
953 }
954}
955
957 if (target.isotopologue_index == key.isotopologue_index)
958 type = StateMatchType::Isotopologue;
959 else if (target.Species() == key.Species())
960 type = StateMatchType::Species;
961
962 if (type == StateMatchType::Isotopologue) {
963 auto m = target.val.check_match(key.val);
964
965 upp = m.upp == CheckValue::Full or m.upp == CheckValue::BinA;
966 low = m.low == CheckValue::Full or m.low == CheckValue::BinA;
967 if (upp and low)
968 type = StateMatchType::Full;
969 else if (upp or low)
970 type = StateMatchType::Level;
971 }
972}
973
974bool GlobalState::part_of(const GlobalState& other) const {
975 if (other.isotopologue_index not_eq isotopologue_index) return false;
976
977 auto test = other.val.check_match(val);
978 return (test.upp == CheckValue::Full or test.upp == CheckValue::AinB) and
979 (test.low == CheckValue::Full or test.low == CheckValue::AinB);
980}
981
982std::ostream& operator<<(std::ostream& os, const LocalState& vl) {
983 return os << vl.values();
984}
985
986std::istream& operator>>(std::istream& is, LocalState& vl) {
987 String val;
988 for (auto& v : vl.val) {
989 is >> val;
990 v.set(val, false);
991 }
992 for (auto& v : vl.val) {
993 is >> val;
994 v.set(val, true);
995 }
996 return is;
997}
998
999bool LocalState::same_types_as(const LocalState& that) const {
1000 return std::equal(val.begin(),
1001 val.end(),
1002 that.val.begin(),
1003 that.val.end(),
1004 [](auto& a, auto& b) { return a.type == b.type; });
1005}
1006
1008 GlobalState out = *this;
1009 for (auto& value : out.val) value.qn.upp = value.qn.low;
1010 return out;
1011}
1012
1014 GlobalState out = *this;
1015 for (auto& value : out.val) value.qn.low = value.qn.upp;
1016 return out;
1017}
1018
1020 // Make copies
1021 Value _this = *this;
1022 Value _x = x;
1023
1024 // Copy values from the other part
1025 _this.qn = x.qn;
1026 _x.qn = qn;
1027
1028 // Assign by reinterpreting the data using standard operations
1029 *this = Value(var_string(_this));
1030 x = Value(var_string(_x));
1031}
1032
1033GlobalState::GlobalState(std::string_view s, Index v) {
1034 auto n = count_items(s);
1035 auto specname = items(s, 0);
1037 ARTS_USER_ERROR_IF(isotopologue_index < 0, "Bad species in: ", s)
1038
1039 if (version == v) {
1040 if (n > 1) val = ValueList(s.substr(specname.length() + 1));
1041 } else if (v == 0 or v == 1) {
1042 val = ValueList(s.substr(specname.length() + 1), true);
1043 } else {
1044 ARTS_USER_ERROR("Unknown version: ", v)
1045 }
1046}
1047
1048void ValueList::add_type_wo_sort(Type t) { values.emplace_back().type = t; }
1049
1051 val = ValueList("");
1052 for (auto qn : vals) val.add_type_wo_sort(qn);
1053}
1054
1056 const LocalState& l) const {
1057 bool upp = true, low = true;
1058 if (isotopologue_index not_eq g.isotopologue_index) return {false, false};
1059
1060 for (auto& qn : val) {
1061 bool any = false;
1062
1063 if (g.val.has(qn.type)) {
1064 auto& v = g.val[qn.type];
1065
1066 upp = upp and v.str_upp() == qn.str_upp();
1067 low = low and v.str_low() == qn.str_low();
1068 any = true;
1069 }
1070
1071 if (l.val.has(qn.type)) {
1072 auto& v = l.val[qn.type];
1073
1074 upp = upp and v.str_upp() == qn.str_upp();
1075 low = low and v.str_low() == qn.str_low();
1077 "Repeated type: ",
1078 qn.type,
1079 '\n',
1080 "From original key: ",
1081 *this,
1082 '\n',
1083 "With global key: ",
1084 g,
1085 '\n',
1086 "With local key: ",
1087 l.val)
1088 any = true;
1089 }
1090
1091 if (not any) return {false, false};
1092 }
1093 return {upp, low};
1094}
1095
1097 switch (common_value_type(type)) {
1098 case ValueType::I:
1099 bof << qn.upp.i.x << qn.low.i.x;
1100 break;
1101 case ValueType::H:
1102 bof << qn.upp.h.x << qn.low.h.x;
1103 break;
1104 case ValueType::S:
1105 bof.writeString(qn.upp.s.x.data(), StringValue::N);
1106 bof.writeString(qn.low.s.x.data(), StringValue::N);
1107 break;
1108 case ValueType::FINAL: {
1109 }
1110 }
1111 return bof;
1112}
1113
1115 switch (common_value_type(type)) {
1116 case ValueType::I:
1117 bif >> qn.upp.i.x >> qn.low.i.x;
1118 break;
1119 case ValueType::H:
1120 bif >> qn.upp.h.x >> qn.low.h.x;
1121 break;
1122 case ValueType::S:
1123 bif.readString(qn.upp.s.x.data(), StringValue::N);
1124 bif.readString(qn.low.s.x.data(), StringValue::N);
1125 break;
1126 case ValueType::FINAL: {
1127 }
1128 }
1129 return bif;
1130}
1131
1133 {
1134 for (auto& qn : values)
1135 if (not qn.good()) {
1136 return false;
1137 }
1138 }
1139 return true;
1140}
1141
1142bool Quantum::Number::LocalState::good() const { return val.good(); }
1143
1145 return Species::is_normal_isotopologue(Isotopologue()) and val.good();
1146}
1147} // namespace Quantum::Number
This can be used to make arrays out of anything.
Definition array.h:31
A list of many quantum numbers. Should always remain sorted.
void set(Value v)
Sets the value if it exists or adds it otherwise.
void finalize()
Should always be called before this object is handed to another user.
CheckMatch check_match(const ValueList &other) const ARTS_NOEXCEPT
Returns upper and lower matching status.
bool has_unique_increasing_types() const
Internal check function. Remember to sort by type before calling this.
void sort_by_type()
Internal sort function. Should be called whenever new items are created.
Array< Value >::iterator begin()
For iterators.
bool has(Types... ts) const ARTS_NOEXCEPT
Returns whether all the Types are part of the list, the types must be sorted.
Value & add(Type t)
Add for manipulation.
const Value & operator[](Type t) const ARTS_NOEXCEPT
Returns the value of the Type (assumes it exist)
bool perpendicular(const ValueList &that) const ARTS_NOEXCEPT
Finds whether two ValueList describe completely different sets of quantum numbers (e....
void add_type_wo_sort(Type)
Add a type without sorting (WARNING, many things might break if you don't sort in the end)
Array< Value >::iterator end()
Binary output file stream class.
Definition bifstream.h:26
unsigned long readString(char *str, unsigned long amount)
Definition binio.cc:192
unsigned long writeString(const char *str, unsigned long amount=0)
Definition binio.cc:351
Binary output file stream class.
Definition bofstream.h:25
Helper macros for debugging.
#define ARTS_ASSERT(condition,...)
Definition debug.h:86
#define ARTS_USER_ERROR(...)
Definition debug.h:153
std::string var_string(Args &&... args)
Definition debug.h:19
#define ARTS_USER_ERROR_IF(condition,...)
Definition debug.h:137
constexpr ValueType common_value_type(ValueType a, ValueType b) noexcept
Return a common type between a and b.
ValueList from_hitran(std::string_view upp, std::string_view low)
bool vamdcCheck(const ValueList &l, VAMDC type) ARTS_NOEXCEPT
std::ostream & operator<<(std::ostream &os, ValueDescription x)
constexpr ValueDescription value_holder(Rational r_)
Takes a rational and determine which type of quantum number it is, returning this information or thro...
constexpr std::pair< std::string_view, std::string_view > split_hitran_qn(std::string_view x)
Returns some input "ASDASDS=asdAS" as ["ASDASDS", "asdAS"] for Hitran online data.
std::istream & operator>>(std::istream &is, Value &x)
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 CheckValue update(CheckValue val, CheckValue res) noexcept
Updates old by what a new check says it should be.
std::pair< std::string_view, String > fix_legacy(std::string_view key, std::string_view val)
Fix legacy catalog, where some values are rationals even though they shouldn't be.
constexpr Index count_items(std::string_view s) noexcept
Count all space-separated items in s.
VAMDC type ARTS_NOEXCEPT
constexpr std::string_view strip(std::string_view x)
Strips spaces at the beginning and end of x before returning it.
constexpr std::array Isotopologues
A list of all ARTS isotopologues, note how the species enum class input HAS to be sorted.
constexpr bool is_normal_isotopologue(const IsotopeRecord &ir) noexcept
constexpr Index find_species_index(const Species spec, const std::string_view isot) noexcept
Status of comparing two lists that are supposedly of some type.
A logical struct for global quantum numbers with species identifiers.
Species::Species Species() const noexcept
bool part_of(const GlobalState &other) const
Checks wheter all of the LHS is part of RHS.
static constexpr Index version
Species::IsotopeRecord Isotopologue() const noexcept
bool good() const
Test if there are bad quantum numbers (undefined ones) or if the isotopologue is not a normal target.
Struct that converts to bool automatically but allows checking both energy levels matching status.
A logical struct for local quantum numbers.
void set_unsorted_qns(const Array< Type > &vals)
bool good() const
Test if there are bad quantum numbers (undefined ones)
bool same_types_as(const LocalState &that) const
constexpr StateMatch()=default
static constexpr std::size_t N
constexpr std::string_view val() const noexcept
Returns the value in such a way that no \0 remains in the view.
A complete description of a value, its type and value.
A complete quantum number value with type information.
bofstream & write(bofstream &bof) const
String str_upp() const noexcept
Returns the upper quantum number string copy.
bifstream & read(bifstream &bif)
constexpr Rational upp() const noexcept
Returns the upper quantum number rational if it exists or an undefined.
TwoLevelValueHolder qn
constexpr Rational low() const noexcept
Returns the lower quantum number rational if it exists or an undefined.
constexpr void set(std::string_view s, bool upp)
Set level value.
String str_low() const noexcept
Returns the lower quantum number string copy.
void swap_values(Value &x)
Legacy way to swap the values between two Values.
Struct containing all information needed about one isotope.
String FullName() const noexcept
Species spec
Species type as defined in species.h.
#define v
#define a
#define b