41 for(
size_t i=0; i<mlocalquanta.size(); i++)
42 if(mlocalquanta[i] == qnt)
43 return mlines[k].LowerQuantumNumber(i);
44 return mquantumidentity.LowerQuantumNumber(qnt);
48 for(
size_t i=0; i<mlocalquanta.size(); i++)
49 if(mlocalquanta[i] == qnt)
50 return mlines[k].UpperQuantumNumber(i);
51 return mquantumidentity.UpperQuantumNumber(qnt);
55 for(
size_t i=0; i<mlocalquanta.size(); i++)
56 if(mlocalquanta[i] == qnt)
57 return mlines[k].LowerQuantumNumber(i);
58 return mquantumidentity.LowerQuantumNumber(qnt);
62 for(
size_t i=0; i<mlocalquanta.size(); i++)
63 if(mlocalquanta[i] == qnt)
64 return mlines[k].UpperQuantumNumber(i);
65 return mquantumidentity.UpperQuantumNumber(qnt);
69 auto x = mlines[k].LineShape().GetParams(T, mT0, P,
vmrs);
71 if (not DoLineMixing(P))
x.Y =
x.G =
x.DV = 0;
77 auto x = mlines[k].LineShape().GetTemperatureDerivs(T, mT0, P,
vmrs);
79 if (not DoLineMixing(P))
x.Y =
x.G =
x.DV = 0;
86 if(mselfbroadening and spec == mquantumidentity.Species())
90 for(
Index i=
Index(mselfbroadening); i<
Index(mbroadeningspecies.size())-
Index(mbathbroadening); i++) {
91 if(spec == mbroadeningspecies[i].
Species())
97 return Index(mbroadeningspecies.size())-
Index(mbathbroadening);
103 const auto self = vmr_qid.Species() == mquantumidentity.Species();
104 const auto& ls = mlines[k].LineShape();
106 if (mselfbroadening and
self) {
107 auto x = ls.GetVMRDerivs(T, mT0, P, 0);
111 T, mT0, P, ls.nelem() - 1));
113 if (not DoLineMixing(P))
x.Y =
x.G =
x.DV = 0;
116 }
else if (mbathbroadening and
self)
117 return {0, 0, 0, 0, 0, 0, 0, 0, 0};
119 auto x = ls.GetVMRDerivs(T, mT0, P, LineShapePos(vmr_qid));
123 T, mT0, P, ls.nelem() - 1));
125 if (not DoLineMixing(P))
x.Y =
x.G =
x.DV = 0;
132 const auto self = derivative.Mode() == LineShape::self_broadening;
133 const auto bath = derivative.Mode() == LineShape::bath_broadening;
134 const auto& ls = mlines[k].LineShape();
136 if(derivative.QuantumIdentity().Species() not_eq
Species() or
137 derivative.QuantumIdentity().Isotopologue() not_eq
Isotopologue())
139 else if(
self and mselfbroadening)
140 return ls.GetInternalDeriv(
141 T, mT0, P, 0,
vmrs, derivative.PropMatType());
143 return ls.GetInternalDeriv(
145 else if(bath and mbathbroadening)
146 return ls.GetInternalDeriv(
147 T, mT0, P, ls.nelem() - 1,
vmrs, derivative.PropMatType());
151 return ls.GetInternalDeriv(
158 data.selfbroadening =
true;
159 data.bathbroadening =
true;
160 data.lineshapetype = LineShape::Type::VP;
161 data.species.resize(2);
169 static map<String, SpecIsoMap> ArtsMap;
172 static bool hinit =
false;
181 ArtsMap[buf] = indicies;
197 if (is.eof())
return data;
200 if (!is)
throw runtime_error(
"Stream bad.");
209 if (line.
nelem() == 0 && is.eof())
return data;
222 istringstream icecream(line);
227 if (artsid.length() != 0) {
230 const map<String, SpecIsoMap>::const_iterator i = ArtsMap.find(artsid);
231 if (i == ArtsMap.end()) {
233 os <<
"ARTS Tag: " << artsid <<
" is unknown.";
234 throw runtime_error(os.str());
240 data.quantumidentity.Species(
id.Speciesindex());
243 data.quantumidentity.Isotopologue(
id.Isotopologueindex());
259 icecream >>
data.line.E0();
283 for (
Index j = 0; j < naux; j++) {
298 }
catch (
const std::runtime_error&) {
302 if (tgam !=
data.T0) {
303 agam = agam *
pow(tgam /
data.T0, nair);
304 sgam = sgam *
pow(tgam /
data.T0, nself);
320 data.selfbroadening =
true;
321 data.bathbroadening =
false;
322 data.lineshapetype = LineShape::Type::VP;
330 static map<String, SpecIsoMap> ArtsMap;
333 static bool hinit =
false;
343 ArtsMap[buf] = indicies;
359 if (is.eof())
return data;
362 if (!is)
throw runtime_error(
"Stream bad.");
371 if (line.
nelem() == 0 && is.eof())
return data;
384 istringstream icecream(line);
389 if (artsid.length() != 0) {
392 const map<String, SpecIsoMap>::const_iterator i = ArtsMap.find(artsid);
393 if (i == ArtsMap.end()) {
395 os <<
"ARTS Tag: " << artsid <<
" is unknown.";
396 throw runtime_error(os.str());
402 data.quantumidentity.Species(
id.Speciesindex());
403 data.quantumidentity.Isotopologue(
id.Isotopologueindex());
430 data.line.LineShape(),
432 data.quantumidentity);
435 String mquantum_numbers_str;
436 getline(icecream, mquantum_numbers_str);
438 mquantum_numbers_str.
trim();
446 data.quantumidentity.UpperQuantumNumbers().Set(
448 Rational(atoi(mquantum_numbers_str.substr(0, 3).c_str())));
449 data.quantumidentity.LowerQuantumNumbers().Set(
451 Rational(atoi(mquantum_numbers_str.substr(6, 3).c_str())));
452 data.quantumidentity.UpperQuantumNumbers().Set(
454 Rational(atoi(mquantum_numbers_str.substr(3, 3).c_str())));
455 data.quantumidentity.LowerQuantumNumbers().Set(
457 Rational(atoi(mquantum_numbers_str.substr(9, 3).c_str())));
460 if (mquantum_numbers_str.
nelem() >= 25) {
462 String vstr = mquantum_numbers_str.substr(0, 3);
464 for (
Index vi = 0; vi < 3; vi++) {
476 String qstr1 = mquantum_numbers_str.substr(4, 12);
477 String qstr2 = mquantum_numbers_str.substr(4 + 12 + 1, 12);
479 for (
Index qi = 0; qi < 3; qi++) {
480 if (qstr1.substr(0, 4) !=
" ")
485 for (
Index qi = 3; qi < 6; qi++) {
486 if (qstr2.substr(0, 4) !=
" ")
523 static map<String, SpecIsoMap> ArtsMap;
526 static bool hinit =
false;
529 bool lmd_found =
false;
539 ArtsMap[buf] = indicies;
555 if (is.eof())
return data;
558 if (!is)
throw runtime_error(
"Stream bad.");
567 if (line.
nelem() == 0 && is.eof())
return data;
580 istringstream icecream(line);
586 if (artsid.length() != 0) {
589 const map<String, SpecIsoMap>::const_iterator i = ArtsMap.find(artsid);
590 if (i == ArtsMap.end()) {
592 os <<
"ARTS Tag: " << artsid <<
" is unknown.";
593 throw runtime_error(os.str());
599 data.quantumidentity.Species(
id.Speciesindex());
600 data.quantumidentity.Isotopologue(
id.Isotopologueindex());
635 data.line.LineShape(),
637 data.quantumidentity);
639 }
else if (token ==
"QN") {
645 os <<
"Unknown quantum number tag: " << token;
646 throw std::runtime_error(os.str());
654 data.quantumidentity.UpperQuantumNumbers().Set(token, r);
656 if (token ==
"LO")
break;
659 if (!is || token !=
"LO") {
660 std::ostringstream os;
661 os <<
"Error in catalog. Lower quantum number tag 'LO' not found.";
662 throw std::runtime_error(os.str());
668 data.quantumidentity.LowerQuantumNumbers().Set(token, r);
671 }
else if (token ==
"LM") {
675 }
else if (token ==
"LF") {
680 data.line.LineShape(),
683 }
else if (token ==
"ZM") {
685 icecream >>
data.line.Zeeman();
687 }
else if (token ==
"LSM") {
696 if (token ==
"CUT") {
697 icecream >>
data.cutofffreq;
698 data.cutoff = CutoffType::LineByLineOffset;
702 if (token ==
"LML") {
703 icecream >>
data.linemixinglimit;
707 else if (token ==
"MTM") {
715 else if (token ==
"LNT") {
724 os <<
"Unknown line modifications given: " << token;
725 throw std::runtime_error(os.str());
731 os <<
"Unknown line data tag: " << token;
732 throw std::runtime_error(os.str());
736 }
catch (
const std::runtime_error& e) {
738 os <<
"Parse error in catalog line: " << endl;
741 throw std::runtime_error(os.str());
745 data.line.LineShape().SetLineMixingModel(line_mixing_model.
Data()[0]);
755 data.selfbroadening =
true;
756 data.bathbroadening =
true;
757 data.lineshapetype = LineShape::Type::VP;
758 data.species.resize(2);
780 static bool hinit =
false;
812 iso_tags.resize(n_iso);
813 for (
Index j = 0; j < n_iso; ++j) {
824 hiso[mo].resize(
max(iso_tags) % 10 + 1);
828 for (
Index j = 0; j < n_iso; ++j) {
833 hiso[mo][iso_tags[j] % 10] = j;
855 if (is.eof())
return data;
858 if (!is)
throw runtime_error(
"Stream bad.");
867 if (line.
nelem() == 0 && is.eof())
return data;
871 if (line[line.
nelem() - 1] == 13) {
872 line.erase(line.
nelem() - 1, 1);
888 if (missing != hspec[mo]) {
894 if ((nChar == 161 && line[158] !=
' ') || nChar > 161) {
896 os <<
"Invalid HITRAN 2004 line data record with " << nChar
897 <<
" characters (expected: 160).";
898 throw std::runtime_error(os.str());
908 data.quantumidentity.Species(hspec[mo]);
919 data.quantumidentity.Isotopologue(missing);
921 if (missing != hiso[mo][
iso])
data.quantumidentity.Isotopologue(hiso[mo][
iso]);
924 if (missing ==
data.quantumidentity.Isotopologue()) {
927 <<
", isotopologue iso = " <<
iso <<
" is unknown.";
928 throw std::runtime_error(os.str());
938 const Numeric w2Hz = Constant::c * 100.;
944 data.line.F0() = v * w2Hz;
959 const Numeric hi2arts = 1e-2 * Constant::c;
966 data.line.I0() = s * hi2arts;
969 .Isotopologue()[
data.quantumidentity.Isotopologue()]
988 const Numeric w2Hz = Constant::c * 1e2;
990 const Numeric hi2arts = w2Hz / Conversion::ATM2PA;
996 agam = gam * hi2arts;
1002 sgam = gam * hi2arts;
1005 if (0 == sgam) sgam = agam;
1041 const Numeric w2Hz = Constant::c * 1e2;
1043 const Numeric hi2arts = w2Hz / Conversion::ATM2PA;
1055 const String qstr = line.substr(0, 15 * 4);
1082 quantum_parser.
Parse(
data.quantumidentity, qstr);
1151 std::vector<std::array<String, 2>> out(0);
1154 auto pos_semicolon = qns.find(
";");
1155 while (pos_semicolon < qns.length() and (pos_semicolon > 0)) {
1156 String var = qns.substr(0, pos_semicolon);
1157 qns.erase(0, pos_semicolon + 1);
1159 const auto pos_equality =
var.find(
"=");
1160 out.push_back({
var.substr(0, pos_equality),
var.substr(pos_equality+1,
var.length())});
1161 pos_semicolon = qns.find(
";");
1164 const auto pos_equality = qns.find(
"=");
1165 out.push_back({qns.substr(0, pos_equality), qns.substr(pos_equality+1, qns.length())});
1174 data.selfbroadening =
true;
1175 data.bathbroadening =
true;
1176 data.lineshapetype = LineShape::Type::VP;
1177 data.species.resize(2);
1199 static bool hinit =
false;
1231 iso_tags.resize(n_iso);
1232 for (
Index j = 0; j < n_iso; ++j) {
1243 hiso[mo].resize(
max(iso_tags) % 10 + 1);
1247 for (
Index j = 0; j < n_iso; ++j) {
1248 if (0 < iso_tags[j])
1252 hiso[mo][iso_tags[j] % 10] = j;
1270 bool comment =
true;
1274 if (is.eof())
return data;
1277 if (!is)
throw runtime_error(
"Stream bad.");
1286 if (line.
nelem() == 0 && is.eof())
return data;
1290 if (line[line.
nelem() - 1] == 13) {
1291 line.erase(line.
nelem() - 1, 1);
1307 if (missing != hspec[mo]) {
1316 data.quantumidentity.Species(hspec[mo]);
1327 data.quantumidentity.Isotopologue(missing);
1329 if (missing != hiso[mo][
iso])
data.quantumidentity.Isotopologue(hiso[mo][
iso]);
1332 if (missing ==
data.quantumidentity.Isotopologue()) {
1335 <<
", isotopologue iso = " <<
iso <<
" is unknown.";
1336 throw std::runtime_error(os.str());
1346 const Numeric w2Hz = Constant::c * 100.;
1352 data.line.F0() = v * w2Hz;
1367 const Numeric hi2arts = 1e-2 * Constant::c;
1374 data.line.I0() = s * hi2arts;
1377 .Isotopologue()[
data.quantumidentity.Isotopologue()]
1396 const Numeric w2Hz = Constant::c * 1e2;
1398 const Numeric hi2arts = w2Hz / Conversion::ATM2PA;
1404 agam = gam * hi2arts;
1410 sgam = gam * hi2arts;
1413 if (0 == sgam) sgam = agam;
1449 const Numeric w2Hz = Constant::c * 1e2;
1451 const Numeric hi2arts = w2Hz / Conversion::ATM2PA;
1548 std::stringstream ss;
1550 ss >> upper >> lower;
1563 data.selfbroadening =
true;
1564 data.bathbroadening =
true;
1565 data.lineshapetype = LineShape::Type::VP;
1566 data.species.resize(2);
1588 static bool hinit =
false;
1620 iso_tags.resize(n_iso);
1621 for (
Index j = 0; j < n_iso; ++j) {
1632 hiso[mo].resize(
max(iso_tags) % 10 + 1);
1636 for (
Index j = 0; j < n_iso; ++j) {
1637 if (0 < iso_tags[j])
1641 hiso[mo][iso_tags[j] % 10] = j;
1659 bool comment =
true;
1663 if (is.eof())
return data;
1666 if (!is)
throw runtime_error(
"Stream bad.");
1675 if (line.
nelem() == 0 && is.eof())
return data;
1679 if (line[line.
nelem() - 1] == 13) {
1680 line.erase(line.
nelem() - 1, 1);
1696 if (missing != hspec[mo]) {
1704 os <<
"Invalid HITRAN 1986-2001 line data record with " << nChar
1705 <<
" characters (expected: 100)." << endl
1706 << line <<
" n: " << line.
nelem();
1707 throw runtime_error(os.str());
1716 data.quantumidentity.Species(hspec[mo]);
1727 data.quantumidentity.Isotopologue(missing);
1729 if (missing != hiso[mo][
iso])
data.quantumidentity.Isotopologue(hiso[mo][
iso]);
1732 if (missing ==
data.quantumidentity.Isotopologue()) {
1735 <<
", isotopologue iso = " <<
iso <<
" is unknown.";
1736 throw runtime_error(os.str());
1746 const Numeric w2Hz = Constant::c * 100.;
1752 data.line.F0() = v * w2Hz;
1768 const Numeric hi2arts = 1e-2 * Constant::c;
1775 data.line.I0() = s * hi2arts;
1778 .Isotopologue()[
data.quantumidentity.Isotopologue()]
1796 const Numeric w2Hz = Constant::c * 1e2;
1798 const Numeric hi2arts = w2Hz / Conversion::ATM2PA;
1804 agam = gam * hi2arts;
1810 sgam = gam * hi2arts;
1813 if (0 == sgam) sgam = agam;
1849 const Numeric w2Hz = Constant::c * 1e2;
1851 const Numeric hi2arts = w2Hz / Conversion::ATM2PA;
1925 data.selfbroadening =
true;
1926 data.bathbroadening =
true;
1927 data.lineshapetype = LineShape::Type::VP;
1928 data.species.resize(2);
1950 static bool hinit =
false;
1979 iso_tags.resize(n_iso);
1980 for (
Index j = 0; j < n_iso; ++j) {
1991 hiso[mo].resize(
max(iso_tags) % 10 + 1);
1995 for (
Index j = 0; j < n_iso; ++j) {
1996 if (0 < iso_tags[j])
2000 hiso[mo][iso_tags[j] % 10] = j;
2018 bool comment =
true;
2022 if (is.eof())
return data;
2025 if (!is)
throw std::runtime_error(
"Stream bad.");
2034 if (line.
nelem() == 0 && is.eof())
return data;
2038 if (line[line.
nelem() - 1] == 13) {
2039 line.erase(line.
nelem() - 1, 1);
2055 if (missing != hspec[mo]) {
2063 os <<
"Invalid HITRAN 1986-2001 line data record with " << nChar
2064 <<
" characters (expected: 100)." << endl
2065 << line <<
" n: " << line.
nelem();
2066 throw std::runtime_error(os.str());
2076 data.quantumidentity.Species(hspec[mo]);
2087 data.quantumidentity.Isotopologue(missing);
2089 if (missing != hiso[mo][
iso])
data.quantumidentity.Isotopologue(hiso[mo][
iso]);
2092 if (missing ==
data.quantumidentity.Isotopologue()) {
2095 <<
", isotopologue iso = " <<
iso <<
" is unknown.";
2096 throw std::runtime_error(os.str());
2106 const Numeric w2Hz = Constant::c * 100.;
2112 data.line.F0() = v * w2Hz;
2128 const Numeric hi2arts = 1e-2 * Constant::c;
2131 if (line[6] ==
'D') line[6] =
'E';
2137 data.line.I0() = s * hi2arts;
2140 .Isotopologue()[
data.quantumidentity.Isotopologue()]
2158 const Numeric w2Hz = Constant::c * 1e2;
2160 const Numeric hi2arts = w2Hz / Conversion::ATM2PA;
2166 agam = gam * hi2arts;
2172 sgam = gam * hi2arts;
2175 if (0 == sgam) sgam = agam;
2211 const Numeric w2Hz = Constant::c * 1e2;
2213 const Numeric hi2arts = w2Hz / Conversion::ATM2PA;
2246 String helper = line.substr(0, 9);
2247 Index DJ = -helper.compare(3, 1,
"Q");
2248 Index DN = -helper.compare(0, 1,
"Q");
2249 Index N = atoi(helper.substr(1, 2).c_str());
2250 Index J = atoi(helper.substr(4, 2).c_str());
2306 if (test == -1 || test == -3)
2326 throw std::runtime_error(
"There is an error in the line mixing\n");
2379 Y /= Conversion::ATM2PA;
2380 G /= Conversion::ATM2PA / Conversion::ATM2PA;
2409 }
else if (test == -3) {
2436 const std::vector<QuantumNumberType>& localquantas,
2437 const std::vector<QuantumNumberType>& globalquantas)
2439 std::vector<Lines> lines(0);
2440 std::vector<Rational> lowerquanta_local(localquantas.size());
2441 std::vector<Rational> upperquanta_local(localquantas.size());
2442 std::vector<Rational> lowerquanta_global(globalquantas.size());
2443 std::vector<Rational> upperquanta_global(globalquantas.size());
2446 while(external_lines.size()) {
2447 auto& sle = external_lines.back();
2450 std::transform(localquantas.cbegin(), localquantas.cend(), lowerquanta_local.begin(),
2451 [&](
auto qn){return sle.quantumidentity.LowerQuantumNumber(qn);});
2452 std::transform(localquantas.cbegin(), localquantas.cend(), upperquanta_local.begin(),
2453 [&](
auto qn){return sle.quantumidentity.UpperQuantumNumber(qn);});
2454 std::transform(globalquantas.cbegin(), globalquantas.cend(), lowerquanta_global.begin(),
2455 [&](
auto qn){return sle.quantumidentity.LowerQuantumNumber(qn);});
2456 std::transform(globalquantas.cbegin(), globalquantas.cend(), upperquanta_global.begin(),
2457 [&](
auto qn){return sle.quantumidentity.UpperQuantumNumber(qn);});
2460 auto line = sle.line;
2461 line.LowerQuantumNumbers() = lowerquanta_local;
2462 line.UpperQuantumNumbers() = upperquanta_local;
2465 const QuantumIdentifier qid(sle.quantumidentity.Species(), sle.quantumidentity.Isotopologue(),
2466 globalquantas, upperquanta_global, lowerquanta_global);
2469 auto band = std::find_if(lines.begin(), lines.end(), [&](
const Lines& li){return li.MatchWithExternal(sle, qid);});
2470 if (band not_eq lines.end()) {
2471 band -> AppendSingleLine(line);
2473 lines.push_back(
Lines(sle.selfbroadening, sle.bathbroadening, sle.cutoff,
2474 sle.mirroring, sle.population, sle.normalization,
2475 sle.lineshapetype, sle.T0, sle.cutofffreq,
2476 sle.linemixinglimit, qid, localquantas, sle.species, {line}));
2478 external_lines.pop_back();
2499 os << line.
F0() <<
' '
2502 << line.
g_low() <<
' '
2503 << line.
g_upp() <<
' '
2556 return spr.
Name() +
"-" +
2562 std::ostringstream out;
2563 out << mquantumidentity.UpperQuantumNumbers() <<
' ';
2572 std::ostringstream out;
2573 out << mquantumidentity.LowerQuantumNumbers() <<
' ';
2582 std::ostringstream os;
2584 os <<
"\nLines meta-data:\n";
2585 os <<
'\t' <<
"Species identity:\n";
2586 os <<
"\t\tSpecies: "<< SpeciesName() <<
'\n';
2587 os <<
"\t\tLower Quantum Numbers: "<< LowerQuantumNumbers() <<
'\n';
2588 os <<
"\t\tUpper Quantum Numbers: "<< UpperQuantumNumbers() <<
'\n';
2594 os <<
'\t' <<
"The reference temperature for all line parameters is "
2596 if(mlinemixinglimit < 0)
2597 os <<
'\t' <<
"If applicable, there is no line mixing limit.\n";
2599 os <<
'\t' <<
"If applicable, there is a line mixing limit at "
2600 << mlinemixinglimit <<
" Pa.\n";
2602 if (not NumLines()) {
2603 os <<
"\tNo line data is available.\n";
2606 os <<
"\tThere are " << NumLines() <<
" lines available.\n";
2608 auto& line = mlines.front();
2609 os <<
"\tThe front line has:\n";
2610 os <<
"\t\t" <<
"f0: " << line.F0() <<
" Hz\n";
2611 os <<
"\t\t" <<
"i0: " << line.I0() <<
" m^2/Hz\n";
2612 os <<
"\t\t" <<
"e0: " << line.E0() <<
" J\n";
2613 os <<
"\t\t" <<
"Lower stat. weight: " << line.g_low() <<
" [-]\n";
2614 os <<
"\t\t" <<
"Upper stat. weight: " << line.g_upp() <<
" [-]\n";
2615 os <<
"\t\t" <<
"A: " << line.A() <<
" 1/s\n";
2616 os <<
"\t\t" <<
"Zeeman splitting of lower state: " << line.Zeeman().gl() <<
" [-]\n";
2617 os <<
"\t\t" <<
"Zeeman splitting of upper state: " << line.Zeeman().gu() <<
" [-]\n";
2618 os <<
"\t\t" <<
"Lower state local quantum numbers:";
2619 for(
size_t i=0; i<mlocalquanta.size(); i++)
2621 <<
"=" << line.LowerQuantumNumber(i) <<
";";
2623 os <<
"\t\t" <<
"Upper state local quantum numbers:";
2624 for(
size_t i=0; i<mlocalquanta.size(); i++)
2626 <<
"=" << line.UpperQuantumNumber(i) <<
";";
2633 os <<
"\t\t" <<
"Line shape parameters (are normalized by sum(VMR)):\n";
2634 for(
auto& ls_form: ls_meta)
2635 os <<
"\t\t\t" << ls_form <<
"\n";
2646 std::vector<size_t> hits(0);
2649 for (
size_t i=0; i<mlocalquanta.size(); i++) {
2651 for (
auto& line: mlines) {
2652 if (line.LowerQuantumNumber(i).isDefined() or line.UpperQuantumNumber(i).isDefined()) {
2663 while (not hits.empty()) {
2664 RemoveLocalQuantum(hits.back());
2671 mlocalquanta.erase(mlocalquanta.begin() +
x);
2672 for (
auto& line: mlines) {
2673 line.LowerQuantumNumbers().erase(line.LowerQuantumNumbers().begin() +
x);
2674 line.UpperQuantumNumbers().erase(line.UpperQuantumNumbers().begin() +
x);
2682 std::equal(mlowerquanta.cbegin(), mlowerquanta.cend(), sl.mlowerquanta.cbegin(), sl.mlowerquanta.cend()) and
2683 std::equal(mupperquanta.cbegin(), mupperquanta.cend(), sl.mupperquanta.cbegin(), sl.mupperquanta.cend()) ;
2689 mlines.erase(mlines.begin() + i);
2695 auto line = mlines[i];
2703 al.Population(), al.Normalization(), al.LineShapeType(),
2704 al.T0(), al.CutoffFreqValue(), al.LinemixingLimit(),
2705 al.QuantumIdentity(), al.LocalQuanta(), al.BroadeningSpecies());
2722 std::reverse(mlines.begin(), mlines.end());
2734 BroadeningSpecies(),
Self(), Bath(), LineShapeType());
2740 if (atm_vmrs.
nelem() not_eq atm_spec.
nelem())
2741 throw std::runtime_error(
"Bad species and vmr lists");
2751 if (band.
Species() !=
id.Species())
2760 throw std::runtime_error(
"Cannot match energy level to line");
2766 if ((qn_id.isUndefined() and qn_line.isDefined()) or
2767 (qn_line.isDefined() and qn_line not_eq qn_id)) {
2776 if ((qn_id.isUndefined() and qn_line.isDefined()) or
2777 (qn_line.isDefined() and qn_line not_eq qn_id)) {
2788 if (band.
Species() !=
id.Species())
2797 throw std::runtime_error(
"Cannot match transition level to energy level");
2803 if ((qn_id.isUndefined() and qn_line.isDefined()) or
2804 (qn_line.isDefined() and qn_line not_eq qn_id)) {
2815 if (band.
Species() !=
id.Species())
2824 throw std::runtime_error(
"Cannot match transition level to energy level");
2830 if ((qn_id.isUndefined() and qn_line.isDefined()) or
2831 (qn_line.isDefined() and qn_line not_eq qn_id)) {
2842 if (band.
Species() !=
id.Species())
2851 throw std::runtime_error(
"Cannot match energy level to line");
2857 if ((qn_line.isUndefined() and qn_id.isDefined()) or
2858 (qn_id.isDefined() and qn_id not_eq qn_line)) {
2867 if ((qn_line.isUndefined() and qn_id.isDefined()) or
2868 (qn_id.isDefined() and qn_id not_eq qn_line)) {
2879 if (band.
Species() !=
id.Species())
2888 throw std::runtime_error(
"Cannot match transition level to energy level");
2894 if ((qn_line.isUndefined() and qn_id.isDefined()) or
2895 (qn_id.isDefined() and qn_id not_eq qn_line)) {
2906 if (band.
Species() !=
id.Species())
2915 throw std::runtime_error(
"Cannot match transition level to energy level");
2921 if ((qn_line.isUndefined() and qn_id.isDefined()) or
2922 (qn_id.isDefined() and qn_id not_eq qn_line)) {
2940 if (not
even(Jf + lf + 1))
2941 return -
sqrt(2 * Jf + 1) *
wigner3j(Jf, k, Ji, li, lf - li, -lf);
2943 return +
sqrt(2 * Jf + 1) *
wigner3j(Jf, k, Ji, li, lf - li, -lf);
2947 if (not
even(Jf +
N))
2948 return -
sqrt(6 * (2 * Jf + 1) * (2 * Ji + 1)) *
wigner6j(1_rat, 1_rat, 1_rat, Ji, Jf,
N);
2950 return +
sqrt(6 * (2 * Jf + 1) * (2 * Ji + 1)) *
wigner6j(1_rat, 1_rat, 1_rat, Ji, Jf,
N);
2957 data.selfbroadening =
true;
2958 data.bathbroadening =
true;
2959 data.lineshapetype = LineShape::Type::VP;
2960 data.species.resize(2);
2983 static bool hinit =
false;
3011 iso_tags.resize(n_iso);
3012 for (
Index j = 0; j < n_iso; ++j) {
3023 hiso[mo].resize(
max(iso_tags) % 10 + 1);
3027 for (
Index j = 0; j < n_iso; ++j) {
3028 if (0 < iso_tags[j])
3033 hiso[mo][iso_tags[j] % 10] = j;
3051 bool comment =
true;
3055 if (is.eof())
return data;
3058 if (!is)
throw runtime_error(
"Stream bad.");
3067 if (line.
nelem() == 0 && is.eof())
return data;
3083 if (missing != hspec[mo])
3088 if (0 == std::count(warned_missing.begin(), warned_missing.end(), mo)) {
3089 warned_missing.push_back(mo);
3098 data.quantumidentity.Species(hspec[mo]);
3109 data.quantumidentity.Isotopologue(missing);
3111 if (missing != hiso[mo][
iso])
data.quantumidentity.Isotopologue(hiso[mo][
iso]);
3114 if (missing ==
data.quantumidentity.Isotopologue()) {
3117 <<
", isotopologue iso = " <<
iso <<
" is unknown.";
3118 throw runtime_error(os.str());
3130 data.line.F0() = v * 1E6;
3162 data.line.I0() = s * hi2arts;
3296 if (tgam !=
data.T0) {
3297 agam *=
pow(tgam /
data.T0, nair);
3298 sgam *=
pow(tgam /
data.T0, nself);
3314 data.selfbroadening =
true;
3315 data.bathbroadening =
true;
3316 data.lineshapetype = LineShape::Type::VP;
3317 data.species.resize(2);
3326 static map<Index, SpecIsoMap> JplMap;
3329 static bool hinit =
false;
3352 bool comment =
true;
3356 if (is.eof())
return data;
3359 if (!is)
throw runtime_error(
"Stream bad.");
3368 if (line.
nelem() == 0 && is.eof())
return data;
3385 data.line.F0() = v * 1E6;
3416 data.line.I0() = s / 1E12;
3454 tag = tag > 0 ? tag : -tag;
3460 const map<Index, SpecIsoMap>::const_iterator i = JplMap.find(tag);
3461 if (i == JplMap.end()) {
3463 os <<
"JPL Tag: " << tag <<
" is unknown.";
3464 throw runtime_error(os.str());
3470 data.quantumidentity.Species(
id.Speciesindex());
3471 data.quantumidentity.Isotopologue(
id.Isotopologueindex());
3529 const Index nq = mlocalquanta.size();
3530 const Index nb = mbroadeningspecies.nelem();
3533 if (nb < (
Index(mselfbroadening) +
Index(mbathbroadening)))
3541 if (std::any_of(mlines.cbegin(), mlines.cend(), [nb](
auto& line){return line.LineShapeElems() != nb;}))
3545 if (std::any_of(mlines.cbegin(), mlines.cend(), [nq](
auto& line){return line.LowerQuantumElems() != nq or line.UpperQuantumElems() != nq;}))