ARTS 2.5.4 (git: bcd8c674)
quantum_numbers.h
Go to the documentation of this file.
1#ifndef quantun_numbers_h
2#define quantun_numbers_h
3
4#include <algorithm>
5#include <cstddef>
6#include <istream>
7#include <limits>
8#include <ostream>
9#include <sstream>
10#include <string>
11#include <string_view>
12#include <utility>
13#include <variant>
14#include <vector>
15
16#include "debug.h"
17#include "enums.h"
18#include "isotopologues.h"
19#include "matpack.h"
20#include "nonstd.h"
21#include "rational.h"
22
23constexpr Index quantum_number_error_value = -999'999'999;
24
25namespace Quantum::Number {
26
29 static constexpr std::size_t N = 16;
30 std::array<char, N> x{'\0'}; // First is \0 to be "empty"
31
33 [[nodiscard]] constexpr std::string_view val() const noexcept {
34 // Look for the first \0 or return everything
35 for (std::size_t i = 0; i < N; i++)
36 if (x[i] == '\0') return {x.data(), i};
37 return {x.data(), N};
38 }
39
41 constexpr StringValue() = default;
42
44 explicit constexpr StringValue(std::string_view s) {
45 const std::size_t n = s.size();
46
51 "The value \"",
52 s,
53 "\" is too long. Can be only ",
54 N,
55 " chars but is ",
56 n)
57
58 // Fill with correct values or zero characters
59 std::size_t i = 0;
60 for (; i < n; i++) x[i] = s[i];
61 if (i < N) x[i] = '\0';
62 }
63};
64
67 Index x{std::numeric_limits<Index>::lowest()};
68
70 [[nodiscard]] constexpr Rational val() const noexcept { return x; }
71};
72
75 Index x{std::numeric_limits<Index>::lowest()};
76
78 [[nodiscard]] constexpr Rational val() const noexcept {
79 return Rational(x, 2);
80 }
81};
82
84ENUMCLASS(ValueType, char, S, I, H)
85
86
88 char,
89 alpha, // FIXME: Not in VAMDC
90 config, // FIXME: Not in VAMDC
91 ElecStateLabel,
92 F,
93 F1,
94 F10,
95 F11,
96 F12,
97 F2,
98 F3,
99 F4,
100 F5,
101 F6,
102 F7,
103 F8,
104 F9,
105 I,
106 J,
107 K,
108 Ka,
109 Kc,
110 L, // FIXME: Not in VAMDC
111 Lambda,
112 N,
113 Omega,
114 S,
115 Sigma,
116 SpinComponentLabel,
117 asSym,
118 elecInv,
119 elecRefl,
120 elecSym,
121 kronigParity,
122 l,
123 l1,
124 l10,
125 l11,
126 l12,
127 l2,
128 l3,
129 l4,
130 l5,
131 l6,
132 l7,
133 l8,
134 l9,
135 n, // FIXME: Not in VAMDC
136 parity,
137 r,
138 rotSym,
139 rovibSym,
140 sym,
141 tau, // FIXME: Not in VAMDC
142 term, // FIXME: Not in VAMDC
143 v,
144 v1,
145 v10,
146 v11,
147 v12,
148 v2,
149 v3,
150 v4,
151 v5,
152 v6,
153 v7,
154 v8,
155 v9,
156 vibInv,
157 vibRefl,
158 vibSym)
159
170constexpr ValueType common_value_type(Type type) noexcept {
171 switch (type) {
172 case Type::alpha:
173 return ValueType::S;
174 case Type::config:
175 return ValueType::S;
176 case Type::ElecStateLabel:
177 return ValueType::S;
178 case Type::F:
179 return ValueType::H;
180 case Type::F1:
181 return ValueType::H;
182 case Type::F10:
183 return ValueType::H;
184 case Type::F11:
185 return ValueType::H;
186 case Type::F12:
187 return ValueType::H;
188 case Type::F2:
189 return ValueType::H;
190 case Type::F3:
191 return ValueType::H;
192 case Type::F4:
193 return ValueType::H;
194 case Type::F5:
195 return ValueType::H;
196 case Type::F6:
197 return ValueType::H;
198 case Type::F7:
199 return ValueType::H;
200 case Type::F8:
201 return ValueType::H;
202 case Type::F9:
203 return ValueType::H;
204 case Type::I:
205 return ValueType::I;
206 case Type::J:
207 return ValueType::H;
208 case Type::K:
209 return ValueType::I;
210 case Type::Ka:
211 return ValueType::I;
212 case Type::Kc:
213 return ValueType::I;
214 case Type::L:
215 return ValueType::I;
216 case Type::Lambda:
217 return ValueType::I;
218 case Type::N:
219 return ValueType::I;
220 case Type::Omega:
221 return ValueType::H;
222 case Type::S:
223 return ValueType::H;
224 case Type::Sigma:
225 return ValueType::H;
226 case Type::SpinComponentLabel:
227 return ValueType::I;
228 case Type::asSym:
229 return ValueType::S;
230 case Type::elecInv:
231 return ValueType::S;
232 case Type::elecRefl:
233 return ValueType::S;
234 case Type::elecSym:
235 return ValueType::S;
236 case Type::kronigParity:
237 return ValueType::S;
238 case Type::l:
239 return ValueType::I;
240 case Type::l1:
241 return ValueType::I;
242 case Type::l10:
243 return ValueType::I;
244 case Type::l11:
245 return ValueType::I;
246 case Type::l12:
247 return ValueType::I;
248 case Type::l2:
249 return ValueType::I;
250 case Type::l3:
251 return ValueType::I;
252 case Type::l4:
253 return ValueType::I;
254 case Type::l5:
255 return ValueType::I;
256 case Type::l6:
257 return ValueType::I;
258 case Type::l7:
259 return ValueType::I;
260 case Type::l8:
261 return ValueType::I;
262 case Type::l9:
263 return ValueType::I;
264 case Type::n:
265 return ValueType::S;
266 case Type::parity:
267 return ValueType::S;
268 case Type::r:
269 return ValueType::I;
270 case Type::rotSym:
271 return ValueType::S;
272 case Type::rovibSym:
273 return ValueType::S;
274 case Type::sym:
275 return ValueType::S;
276 case Type::tau:
277 return ValueType::S;
278 case Type::term:
279 return ValueType::S;
280 case Type::v:
281 return ValueType::I;
282 case Type::v1:
283 return ValueType::I;
284 case Type::v10:
285 return ValueType::I;
286 case Type::v11:
287 return ValueType::I;
288 case Type::v12:
289 return ValueType::I;
290 case Type::v2:
291 return ValueType::I;
292 case Type::v3:
293 return ValueType::I;
294 case Type::v4:
295 return ValueType::I;
296 case Type::v5:
297 return ValueType::I;
298 case Type::v6:
299 return ValueType::I;
300 case Type::v7:
301 return ValueType::I;
302 case Type::v8:
303 return ValueType::I;
304 case Type::v9:
305 return ValueType::I;
306 case Type::vibInv:
307 return ValueType::S;
308 case Type::vibRefl:
309 return ValueType::S;
310 case Type::vibSym:
311 return ValueType::S;
312 case Type::FINAL: {
313 }
314 }
315 return ValueType::FINAL;
316}
317
328constexpr ValueType common_value_type(ValueType a, ValueType b) noexcept {
329 // Same is same, H is I, a has both:
330 if (a == b or (a == ValueType::H and b == ValueType::I)) return a;
331
332 // H is I:
333 if (b == ValueType::H and a == ValueType::I) return ValueType::H;
334
335 // Something has gone very wrong:
336 return ValueType::FINAL;
337}
338
344
346 constexpr ValueHolder() noexcept : s("NODEF") {}
347};
348
354 ValueType type;
356
358 friend std::ostream& operator<<(std::ostream& os, ValueDescription x);
359};
360
369
372 : upp(u.val), low(l.val) {
373 auto ct = common_value_type(t);
374 if (u.type not_eq ct) {
375 ARTS_USER_ERROR_IF(u.type not_eq ValueType::I,
376 "Cannot convert from ",
377 u.type,
378 " to ",
379 ct)
380 upp.h.x = 2 * u.val.i.x;
381 }
382
383 if (l.type not_eq ct) {
384 ARTS_USER_ERROR_IF(l.type not_eq ValueType::I,
385 "Cannot convert from ",
386 l.type,
387 " to ",
388 ct)
389 low.h.x = 2 * l.val.i.x;
390 }
391 }
392
393 constexpr TwoLevelValueHolder() = default;
394};
395
403[[nodiscard]] constexpr ValueDescription value_holder(Rational r_) {
405
406 // First reduce it since we technically allow math on rationals to keep non-gcd results
407 const Rational r = reduce_by_gcd(r_);
408
409 // We must now have a half-integer or not
410 if (r.Denom() == 2) {
411 x.type = ValueType::H;
412 x.val.h.x = r.Nom();
413 } else if (r.Denom() == 1) {
414 x.type = ValueType::I;
415 x.val.i.x = r.Nom();
416 } else {
417 x.type = ValueType::I;
418 x.val.i.x = quantum_number_error_value;
419 }
420
421 return x;
422}
423
437[[nodiscard]] constexpr Rational cast_qnrat(std::string_view s) noexcept {
438 // Counts for divides, decimals, and existence
439 int div = 0, dot = 0, any = 0, minus = false;
440 std::size_t n = s.size();
441
442 // Counts relevant items
443 for (std::size_t i = 0; i < n; i++) {
444 auto x = s[i];
445 if (x == '-') {
446 minus = true;
447 if (i) return RATIONAL_UNDEFINED;
448 } else if (x == '+') {
449 if (i) return RATIONAL_UNDEFINED;
450 } else if (x == '/')
451 div++; // Count divs because we can have at most one
452 else if (x == '.')
453 dot++; // Count dots for the same reason
454 else if (not nonstd::isdigit(x))
455 return RATIONAL_UNDEFINED; // Error!
456
457 // There is a value!
458 any++;
459 }
460
461 // Can only have one of div or dot and need some data
462 if ((div + dot) > 1 or any == 0) return RATIONAL_UNDEFINED;
463
464 // We have a rational! Lets see which we have got
465
466 // We have a simple rational
467 if (div) {
468 Index num = 0, den = 0;
469 std::size_t i = 0;
470
471 // Numerator
472 for (; s[i] not_eq '/'; ++i) {
473 if (s[i] == '-' or s[i] == '+') continue;
474 num *= 10;
475 num += s[i] - '0';
476 }
477
478 // Denominator
479 i++;
480 for (; i < s.size(); ++i) {
481 den *= 10;
482 den += s[i] - '0';
483 }
484
485 // Guard for QN style rationals
486 return Rational(minus ? -num : num, den);
487 }
488
489 // We have a decimal number
490 if (dot) {
491 Index f = 0, d = 0;
492 std::size_t i = 0;
493
494 // The integer part
495 for (; s[i] not_eq '.'; ++i) {
496 if (s[i] == '-' or s[i] == '+') continue;
497 f *= 10;
498 f += s[i] - '0';
499 }
500
501 // The decimal part
502 i++;
503 for (; i < s.size(); ++i) {
504 d *= 10;
505 d += s[i] - '0';
506 }
507
508 if (d == 0) return minus ? -f : f;
509 if (d == 5) return Rational((minus ? -1 : 1) * (2 * f + 1), 2);
510 return RATIONAL_UNDEFINED;
511 }
512
513 std::size_t num = 0;
514 for (auto x : s) {
515 if (x == '-' or x == '+') continue;
516 num *= 10;
517 num += x - '0';
518 }
519 return minus ? -num : num;
520}
521
530[[nodiscard]] constexpr ValueDescription value_holder(std::string_view s,
531 Type t) {
533 // If this is possibly a rational, we return this as a rational type
534 switch (common_value_type(t)) {
535 case ValueType::I:
536 case ValueType::H: {
537 const Rational r = cast_qnrat(s);
538 return value_holder(r);
539 }
540 case ValueType::S:
541 x.type = ValueType::S;
542 x.val.s = StringValue(s);
543 return x;
544 case ValueType::FINAL: {
545 }
546 }
547 x.type = ValueType::FINAL;
548 return x;
549}
550
553 bool upp{true};
554 bool low{true};
555
557 constexpr operator bool() const noexcept { return upp and low; }
558};
559
567constexpr Index count_items(std::string_view s) noexcept {
568 // Checks if we are in-between items, we start true as we are inbetween items
569 bool last_space = true;
570
571 Index count = 0;
572 for (auto& x : s) {
573 bool this_space = nonstd::isspace(x);
574
575 // If we had a space and now no longer do, we are in an item
576 if (last_space and not this_space) count++;
577
578 // The current state must be remembere
579 last_space = this_space;
580 }
581 return count;
582}
583
589constexpr std::string_view rstrip(std::string_view x) {
590 while (not x.empty() and nonstd::isspace(x.back())) x.remove_suffix(1);
591 return x;
592}
593
599constexpr std::string_view lstrip(std::string_view x) {
600 while (not x.empty() and nonstd::isspace(x.front())) x.remove_prefix(1);
601 return x;
602}
603
609constexpr std::string_view strip(std::string_view x) {
610 return rstrip(lstrip(x));
611}
612
625template <std::size_t n = 1>
626constexpr std::string_view items(std::string_view s, std::size_t i) noexcept {
627 static_assert(n > 0, "Must want some items");
628 bool last_space = true;
629
630 std::size_t beg = 0, count = 0, end = s.size();
631 if (end == 0) return s;
632
633 for (std::size_t ind = 0; ind < end; ind++) {
634 bool this_space = nonstd::isspace(s[ind]);
635
636 // Return when we find the end of the final item
637 if (this_space and count == i + n) return {&s[beg], ind - beg};
638
639 // If we had a space and now no longer do, we are in an item
640 if (last_space and not this_space) {
641 count++;
642
643 // If that is our first item, we are good!
644 if (count - 1 == i) beg = ind;
645 }
646
647 // Count up the beginning until we have found the first item
648 if (count - 1 < i) beg = ind;
649
650 // The current state must be remembere
651 last_space = this_space;
652 }
653
654 // Remove spaces at the end to be sure
655 while (nonstd::isspace(s[end - 1]) and end > beg) end--;
656 return {&s[beg], end - beg};
657}
658
660struct Value {
661 Type type{Type::FINAL};
663
664 Value() = default;
665
666 constexpr Value(Type t, Rational upp_, Rational low_) : type(t) {
667 Rational upp = reduce_by_gcd(upp_), low = reduce_by_gcd(low_);
668
669 if (common_value_type(type) == ValueType::H) {
670 ARTS_ASSERT(upp.Denom() <= 2 and low.Denom() <= 2)
671 if (upp.Denom() not_eq 2) upp *= 2;
672 if (low.Denom() not_eq 2) low *= 2;
673 qn.upp.h.x = upp.Nom();
674 qn.low.h.x = low.Nom();
675 } else if (common_value_type(type) == ValueType::I) {
676 ARTS_ASSERT(upp.Denom() == 1 and low.Denom() == 1)
677 qn.upp.i.x = upp.Nom();
678 qn.low.i.x = low.Nom();
679 } else {
681 t, " is a string-type, so cannot be constructed from rationals")
682 }
683 }
684
686 constexpr Value(std::string_view s) : type(toTypeOrThrow(items(s, 0))) {
688 "Must have ' TYPE UPPNUM LOWNUM ' but got: '",
689 s,
690 '\'')
691
692 // Get values and ensure they are good types
693 auto upv = value_holder(items(s, 1), type);
694 auto lov = value_holder(items(s, 2), type);
695
696 // Deal with errors while setting the level values
697 qn = TwoLevelValueHolder(upv, lov, type);
698 }
699
701 [[nodiscard]] constexpr Rational upp() const noexcept {
702 switch (common_value_type(type)) {
703 case ValueType::I:
704 return qn.upp.i.val();
705 case ValueType::H:
706 return qn.upp.h.val();
707 default: {
708 }
709 }
710 return RATIONAL_UNDEFINED;
711 }
712
714 [[nodiscard]] constexpr Rational low() const noexcept {
715 switch (common_value_type(type)) {
716 case ValueType::I:
717 return qn.low.i.val();
718 case ValueType::H:
719 return qn.low.h.val();
720 default: {
721 }
722 }
723 return RATIONAL_UNDEFINED;
724 }
725
727 [[nodiscard]] String str_upp() const noexcept;
728
730 [[nodiscard]] String str_low() const noexcept;
731
733 void swap_values(Value& x);
734
736 constexpr void set(std::string_view s, bool upp) {
739 if (upp) {
740 qn.upp = nqn.upp;
741 } else {
742 qn.low = nqn.low;
743 }
744 }
745
754 constexpr LevelMatch operator==(Value other) const noexcept {
755 if (type == other.type) {
756 switch (common_value_type(type)) {
757 case ValueType::I:
758 case ValueType::H:
759 return {upp() == other.upp(), low() == other.low()};
760 case ValueType::S:
761 return {qn.upp.s.x == other.qn.upp.s.x,
762 qn.low.s.x == other.qn.low.s.x};
763 case ValueType::FINAL: {
764 }
765 }
766 }
767 return {false, false};
768 }
769
771 friend std::ostream& operator<<(std::ostream& os, Value x);
772
774 friend std::istream& operator>>(std::istream& is, Value& x);
775
776 bofstream& write(bofstream& bof) const;
777
778 bifstream& read(bifstream& bif);
779
780 [[nodiscard]] constexpr bool good() const {return operator==(*this);}
781};
782
784ENUMCLASS(CheckValue, char, Full, AinB, BinA, Miss)
785
786
788 CheckValue upp{CheckValue::Full};
789 CheckValue low{CheckValue::Full};
790
792 constexpr operator bool() const noexcept {
793 return upp == CheckValue::Full and low == CheckValue::Full;
794 }
795};
796
798constexpr CheckValue update(CheckValue val, CheckValue res) noexcept {
799 if (val == CheckValue::Miss) return val;
800 if (val == CheckValue::Full) return res;
801 if (res == CheckValue::Miss) return res;
802 if (res == CheckValue::Full) return val;
803 if (val == res) return val;
804 return CheckValue::Miss;
805}
806
808constexpr CheckMatch update(CheckMatch val, CheckValue res) noexcept {
809 return {update(val.upp, res), update(val.low, res)};
810}
811
813constexpr CheckMatch update(CheckMatch val, CheckMatch res) noexcept {
814 return {update(val.upp, res.upp), update(val.low, res.low)};
815}
816
824template <size_t N>
825constexpr bool is_sorted(const std::array<Type, N>& types) noexcept {
826 for (size_t i = 1; i < N; i++)
827 if (not(types[i - 1] < types[i])) return false;
828 return true;
829}
830
834
836 void sort_by_type();
837
839 [[nodiscard]] bool has_unique_increasing_types() const;
840
841 public:
843 explicit ValueList(std::string_view s, bool legacy = false);
844
846 ValueList(std::string_view upp, std::string_view low);
847
849 explicit ValueList(Array<Value> values_) : values(std::move(values_)) {
850 finalize();
851 }
852
855
857 Array<Value>::iterator begin() { return values.begin(); }
861 [[nodiscard]] Array<Value>::const_iterator begin() const {
862 return values.begin();
863 }
864 [[nodiscard]] Array<Value>::const_iterator end() const {
865 return values.end();
866 }
867 [[nodiscard]] Array<Value>::const_iterator cbegin() const {
868 return values.cbegin();
869 }
870 [[nodiscard]] Array<Value>::const_iterator cend() const {
871 return values.cend();
872 }
873
875 void finalize();
876
878 [[nodiscard]] Index nelem() const { return values.nelem(); }
879
881 [[nodiscard]] bool perpendicular(const ValueList& that) const ARTS_NOEXCEPT;
882
884 template <typename... Types>
885 [[nodiscard]] bool has(Types... ts) const ARTS_NOEXCEPT {
886 static_assert(sizeof...(Types) > 0);
887
888 ARTS_ASSERT(is_sorted(std::array{Type(ts)...}))
889
890 auto ptr = cbegin();
891 auto end = cend();
892 for (Type t : {Type(ts)...}) {
893 ptr = std::find_if(ptr, end, [t](auto& x) { return x.type == t; });
894 if (ptr == end) return false;
895 }
896 return true;
897 }
898
900 const Value& operator[](Type t) const ARTS_NOEXCEPT;
901
903 Value& operator[](Index i) { return values.at(i); }
904
906 Value& add(Type t);
907
909 Value& add(Value v);
910
912 void set(Value v);
913
915 void set(Index i, std::string_view upp, std::string_view low);
916
918 CheckMatch operator==(const ValueList& other) const noexcept;
919
921 friend std::ostream& operator<<(std::ostream& os, const ValueList& vl);
922
924 friend std::istream& operator>>(std::istream& is, ValueList& vl);
925
927 void add_type_wo_sort(Type);
928
929 [[nodiscard]] bool good() const;
930};
931
932ValueList from_hitran(std::string_view upp, std::string_view low);
933
937
938 LocalState() = default;
939
940 template <typename... Values>
941 LocalState(Values... vals) : val(Array<Value>{Value(vals)...}) {}
942
943 void set_unsorted_qns(const Array<Type>& vals);
944
945 [[nodiscard]] String keys() const;
946
947 [[nodiscard]] String values() const;
948
949 [[nodiscard]] bool same_types_as(const LocalState& that) const;
950
952 friend std::ostream& operator<<(std::ostream& os, const LocalState& vl);
953
955 friend std::istream& operator>>(std::istream& is, LocalState& vl);
956
958 [[nodiscard]] bool good() const;
959};
960
961struct LevelTest {bool upp{true}, low{true};};
962
965 static constexpr Index version = 1; // Second version of quantum identifiers
966
969
970 GlobalState() = default;
971
972 explicit GlobalState(Index i, ValueList v = {})
973 : isotopologue_index(i), val(std::move(v)) {}
974
977
978 explicit GlobalState(std::string_view s, Index v = version);
979
980 [[nodiscard]] Species::IsotopeRecord Isotopologue() const noexcept;
981 [[nodiscard]] Species::Species Species() const noexcept;
982
983 friend std::ostream& operator<<(std::ostream& os, const GlobalState& gs);
984
985 friend std::istream& operator>>(std::istream& is, GlobalState& gs);
986
987 [[nodiscard]] GlobalState LowerLevel() const;
988 [[nodiscard]] GlobalState UpperLevel() const;
989
990 [[nodiscard]] bool operator==(const GlobalState& that) const;
991 [[nodiscard]] bool operator!=(const GlobalState& that) const;
992
994 [[nodiscard]] bool part_of(const GlobalState& other) const;
995
997 [[nodiscard]] LevelTest part_of(const GlobalState& g, const LocalState& l) const;
998
1000 [[nodiscard]] bool good() const;
1001};
1002
1004ENUMCLASS(StateMatchType, char, Full, Level, Isotopologue, Species, None)
1005
1008 StateMatchType type{StateMatchType::None};
1009 bool upp{false}, low{false};
1010
1011 StateMatch() = default;
1012
1013 StateMatch(const GlobalState& target,
1014 const LocalState& local,
1015 const GlobalState& global);
1016
1017 StateMatch(const GlobalState& target, const GlobalState& key);
1018
1020 bool operator==(StateMatchType x) const noexcept {
1021 return x == type;
1022 }
1023
1024 bool operator!=(StateMatchType x) const noexcept { return not((*this) == x); }
1025};
1026
1029 VAMDC,
1030 char,
1031 asymcs, // Schema for specifying the quantum numbers of closed-shell asymmetric top molecules
1032 asymos, // Schema for specifying the quantum numbers of open-shell asymmetric top molecules
1033 dcs, // Schema for specifying the quantum numbers of closed-shell, diatomic molecules
1034 hunda, // Schema for specifying the quantum numbers for Hund's case (a) diatomic molecules
1035 hundb, // Schema for specifying the quantum numbers for Hund's case (b) diatomic molecules
1036 lpcs, // Schema for specifying the quantum numbers of closed-shell linear polyatomic molecules
1037 lpos, // Schema for specifying the quantum numbers of open-shell linear polyatomic molecules
1038 ltcs, // Schema for specifying the quantum numbers of closed-shell linear triatomic molecules
1039 ltos, // Schema for specifying the quantum numbers of open-shell linear triatomic molecules
1040 nltcs, // Schema for specifying the quantum numbers of closed-shell non-linear triatomic molecules
1041 nltos, // Schema for specifying the quantum numbers of open-shell non-linear triatomic molecules
1042 sphcs, // Schema for specifying the quantum numbers of closed-shell spherical top molecules
1043 sphos, // Schema for specifying the quantum numbers of closed-shell spherical top molecules
1044 stcs // Schema for specifying the quantum numbers of closed-shell, symmetric top molecules
1045)
1046
1047
1055bool vamdcCheck(const ValueList& l, VAMDC type) ARTS_NOEXCEPT;
1056
1058[[maybe_unused]] constexpr std::array global_types{Type::alpha,
1059 Type::config,
1060 Type::ElecStateLabel,
1061 Type::L,
1062 Type::Lambda,
1063 Type::Omega,
1064 Type::S,
1065 Type::Sigma,
1066 Type::SpinComponentLabel,
1067 Type::asSym,
1068 Type::elecInv,
1069 Type::elecRefl,
1070 Type::elecSym,
1071 Type::kronigParity,
1072 Type::l,
1073 Type::l1,
1074 Type::l10,
1075 Type::l11,
1076 Type::l12,
1077 Type::l2,
1078 Type::l3,
1079 Type::l4,
1080 Type::l5,
1081 Type::l6,
1082 Type::l7,
1083 Type::l8,
1084 Type::l9,
1085 Type::n,
1086 Type::parity,
1087 Type::r,
1088 Type::rotSym,
1089 Type::rovibSym,
1090 Type::sym,
1091 Type::tau,
1092 Type::term,
1093 Type::v,
1094 Type::v1,
1095 Type::v10,
1096 Type::v11,
1097 Type::v12,
1098 Type::v2,
1099 Type::v3,
1100 Type::v4,
1101 Type::v5,
1102 Type::v6,
1103 Type::v7,
1104 Type::v8,
1105 Type::v9,
1106 Type::vibInv,
1107 Type::vibRefl,
1108 Type::vibSym};
1109
1111[[maybe_unused]] constexpr std::array local_types{Type::F,
1112 Type::F1,
1113 Type::F10,
1114 Type::F11,
1115 Type::F12,
1116 Type::F2,
1117 Type::F3,
1118 Type::F4,
1119 Type::F5,
1120 Type::F6,
1121 Type::F7,
1122 Type::F8,
1123 Type::F9,
1124 Type::I,
1125 Type::J,
1126 Type::K,
1127 Type::Ka,
1128 Type::Kc,
1129 Type::N};
1130} // namespace Quantum::Number
1131
1132using QuantumNumberType = Quantum::Number::Type;
1138
1139#endif // quantun_numbers_h
This can be used to make arrays out of anything.
Definition: array.h:48
A list of many quantum numbers. Should always remain sorted.
Array< Value >::iterator cbegin()
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.
ValueList(Array< Value > values_)
From values (resorted)
Array< Value >::iterator cend()
Index nelem() const
Return number of quantum numbers.
Array< Value >::const_iterator end() const
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 >::const_iterator begin() const
Array< Value >::const_iterator cbegin() const
friend std::ostream & operator<<(std::ostream &os, const ValueList &vl)
ouptut stream if all values
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.
friend std::istream & operator>>(std::istream &is, ValueList &vl)
input stream must have pre-set size
CheckMatch operator==(const ValueList &other) const noexcept
Returns upper and lower matching status.
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)
Value & operator[](Index i)
Legacy manipulation operator access.
Array< Value >::iterator end()
Array< Value >::const_iterator cend() const
Implements rational numbers to work with other ARTS types.
Definition: rational.h:43
constexpr Index Denom() const noexcept
Denominator.
Definition: rational.h:71
constexpr Index Nom() const noexcept
Nominator.
Definition: rational.h:68
Binary output file stream class.
Definition: bifstream.h:43
Binary output file stream class.
Definition: bofstream.h:42
Helper macros for debugging.
#define ARTS_ASSERT(condition,...)
Definition: debug.h:83
#define ARTS_USER_ERROR(...)
Definition: debug.h:150
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:134
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
#define NODEF
Definition: methods.h:35
constexpr Numeric l(const Index p0, const Index n, const Numeric x, const SortedVectorType &xi, const Index j, const std::pair< Numeric, Numeric > cycle={ -180, 180}) noexcept
ENUMCLASS(Type, char, alpha, config, ElecStateLabel, F, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, I, J, K, Ka, Kc, L, Lambda, N, Omega, S, Sigma, SpinComponentLabel, asSym, elecInv, elecRefl, elecSym, kronigParity, l, l1, l10, l11, l12, l2, l3, l4, l5, l6, l7, l8, l9, n, parity, r, rotSym, rovibSym, sym, tau, term, v, v1, v10, v11, v12, v2, v3, v4, v5, v6, v7, v8, v9, vibInv, vibRefl, vibSym) const expr ValueType common_value_type(Type type) noexcept
Three tags, S: str, I: index, H: half-index.
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)
constexpr Rational cast_qnrat(std::string_view s) noexcept
Returns a rational if possible or RATIONAL_UNDEFINED otherwise.
bool vamdcCheck(const ValueList &l, VAMDC type) ARTS_NOEXCEPT
constexpr bool is_sorted(const std::array< Type, N > &types) noexcept
Checks if an array of types is sorted.
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::array global_types
A default state of global quantum numbers.
constexpr std::string_view rstrip(std::string_view x)
Strips spaces at the end of x before returning it.
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.
constexpr std::array local_types
A default state of local quantum numbers.
constexpr std::string_view lstrip(std::string_view x)
Strips spaces at the beginning x before returning it.
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.
VectorView std(VectorView std, const Vector &y, const ArrayOfVector &ys, const Index start, const Index end_tmp)
Compute the standard deviation of the ranged ys.
Definition: raw.cc:205
constexpr Index find_species_index(const Species spec, const std::string_view isot) noexcept
constexpr Rational end(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the largest M for a polarization type of this transition.
Definition: zeemandata.h:113
constexpr int isdigit(int ch) noexcept
Definition: nonstd.h:24
constexpr int isspace(int ch) noexcept
Returns 1 if x is a standard space-character.
Definition: nonstd.h:39
#define F11
#define F12
#define u
#define d
#define v
#define a
#define b
Quantum::Number::Type QuantumNumberType
constexpr Index quantum_number_error_value
Contains the rational class definition.
#define RATIONAL_UNDEFINED
Definition: rational.h:380
constexpr Rational reduce_by_gcd(Rational a) noexcept
Returns the rational reduced by the greates.
Definition: rational.h:336
#define N
Definition: rng.cc:164
Status of comparing two lists that are supposedly of some type.
A logical struct for global quantum numbers with species identifiers.
GlobalState(Index i, ValueList v={})
GlobalState UpperLevel() const
bool part_of(const GlobalState &other) const
Checks wheter all of the LHS is part of RHS.
GlobalState(const Species::IsotopeRecord &ir)
static constexpr Index version
GlobalState LowerLevel() const
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.
Holds half integer values, but only its denominator.
constexpr Rational val() const noexcept
Returns the value as a Rational, keeping that this is a half-integer.
Holds integer values.
constexpr Rational val() const noexcept
Returns the value as a rational.
Struct that converts to bool automatically but allows checking both energy levels matching status.
A logical struct for local quantum numbers.
friend std::ostream & operator<<(std::ostream &os, const LocalState &vl)
ouptut stream if all values
void set_unsorted_qns(const Array< Type > &vals)
friend std::istream & operator>>(std::istream &is, LocalState &vl)
input stream must have pre-set size
bool good() const
Test if there are bad quantum numbers (undefined ones)
bool same_types_as(const LocalState &that) const
StateMatchType operates so that a check less than a level should be 'better', bar None.
bool operator!=(StateMatchType x) const noexcept
bool operator==(StateMatchType x) const noexcept
It is of the desired type if it is less than the value, bar None.
Holds string values but can only hold sizeof(Index) long values.
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.
constexpr StringValue(std::string_view s)
Set to expected value from a view of something at most N-char long.
constexpr StringValue()=default
Default initializer to a zero-first solution.
std::array< char, N > x
constexpr TwoLevelValueHolder(ValueDescription u, ValueDescription l, Type t)
Constructor to ensure two ValueDescription have the same type, for IO purposes.
constexpr TwoLevelValueHolder()=default
A complete description of a value, its type and value.
friend std::ostream & operator<<(std::ostream &os, ValueDescription x)
Debug output only.
A complete quantum number value with type information.
constexpr Value(std::string_view s)
Default constructor from some string of values.
bofstream & write(bofstream &bof) const
friend std::istream & operator>>(std::istream &is, Value &x)
Standard input.
String str_upp() const noexcept
Returns the upper quantum number string copy.
constexpr Value(Type t, Rational upp_, Rational low_)
bifstream & read(bifstream &bif)
constexpr Rational upp() const noexcept
Returns the upper quantum number rational if it exists or an undefined.
constexpr bool good() const
TwoLevelValueHolder qn
constexpr LevelMatch operator==(Value other) const noexcept
Returns a description of whether both levels match.
friend std::ostream & operator<<(std::ostream &os, Value x)
Standard output.
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.
Definition: isotopologues.h:16
A union of the three type of values we need to consider.
constexpr ValueHolder() noexcept
Defaults to an integer type.