40 return {
"G0",
"D0",
"G2",
"D2",
"FVC",
"ETA",
"Y",
"G",
"DV"};
49 if (var == v) var_OK =
true;
53 bool coeff_OK =
false;
54 for (
auto& c : coeffs)
55 if (coeff == c) coeff_OK =
true;
58 if (not var_OK or not coeff_OK) {
60 os <<
"At least one of your variable and/or your coefficient is not OK\n";
61 os <<
"Your variable: \"" << var <<
"\". OK variables include: " << vars
63 os <<
"Your coefficient: \"" << coeff
64 <<
"\". OK coefficients include: " << coeffs <<
"\n";
65 throw std::runtime_error(os.str());
69 #define ReturnJacPropMatType(ID) \ 72 return JacPropMatType::LineShape##ID##X0; \ 73 else if (coeff == "X1") \ 74 return JacPropMatType::LineShape##ID##X1; \ 75 else if (coeff == "X2") \ 76 return JacPropMatType::LineShape##ID##X2; \ 77 else if (coeff == "X3") \ 78 return JacPropMatType::LineShape##ID##X3; \ 90 #undef ReturnJacPropMatType 106 m.
mdata = std::vector<SingleSpeciesModel>(7);
118 for (
auto& v : m.
mdata) {
119 v.G0().type = TemperatureModel::T1;
120 v.D0().type = TemperatureModel::T5;
124 for (
auto& v : m.
mdata) is >> v.G0().X0;
127 for (
auto& v : m.
mdata) {
129 v.D0().X1 = v.G0().X1;
133 m.
mdata.front().D0().X0 = 0;
134 for (
int k = 1; k < 7; k++)
135 is >> m.
mdata[k].D0().X0;
138 for (
int k = 1; k < 7; k++) {
139 if (qid.
Species() == species[k].Species()) {
140 if(m.
mdata.front().G0().X0 not_eq m.
mdata[k].G0().X0 or
141 m.
mdata.front().G0().X1 not_eq m.
mdata[k].G0().X1 or
142 m.
mdata.front().D0().X1 not_eq m.
mdata[k].D0().X1) {
144 os <<
"Species is " << qid.
SpeciesName() <<
" and this is a broadening species in ARTSCAT-4.\n" 145 <<
"Despite this, values representing self and " << qid.
SpeciesName() <<
" does not match " 146 <<
"in input string\n";
147 throw std::runtime_error(os.str());
173 const auto shapeparams =
180 const auto mixingparams =
185 species.resize(specs);
186 m.
mdata.resize(specs);
188 if (not specs and mtype not_eq Type::DP)
189 throw std::runtime_error(
190 "Need at least one species for non-Doppler line shapes");
196 if (s == self_broadening) {
200 throw std::runtime_error(
"Self broadening must be first, it is not\n");
203 else if (s == bath_broadening) {
208 throw std::runtime_error(
209 "Air/bath broadening must be last, it is not\n");
214 }
catch (
const std::runtime_error& e) {
216 os <<
"Encountered " << s
217 <<
" in a position where a species should have been ";
218 os <<
"defined.\nPlease check your pressure broadening data structure and ensure ";
219 os <<
"that it follows the correct conventions.\n";
220 os <<
"SpeciesTag error reads: " << e.what();
221 throw std::runtime_error(os.
str());
226 for (
auto& params : {shapeparams, mixingparams}) {
227 for (
auto& param : params) {
252 throw std::runtime_error(
253 "Unknown number of input parameters in Legacy mode.");
257 throw std::runtime_error(
258 "Too many input parameters in interpolation results Legacy mode.");
288 const auto self_in_list =
292 for (
auto& num : x) data >> num;
315 for (
auto& num : x)
data >> num;
332 case TypePB::PB_NONE:
338 case TypePB::PB_AIR_BROADENING:
341 m =
Model(x[0], x[1], x[2], x[3], x[4]);
344 case TypePB::PB_AIR_AND_WATER_BROADENING:
350 m.
Data()[0].G0() = {TemperatureModel::T1, x[0], x[1], 0, 0};
351 m.
Data()[0].D0() = {TemperatureModel::T5, x[2], x[1], 0, 0};
352 m.
Data()[1].G0() = {TemperatureModel::T1, x[3], x[4], 0, 0};
353 m.
Data()[1].D0() = {TemperatureModel::T5, x[5], x[4], 0, 0};
361 m.
Data()[0].G0() = {TemperatureModel::T1, x[0], x[1], 0, 0};
362 m.
Data()[0].D0() = {TemperatureModel::T5, x[2], x[1], 0, 0};
363 m.
Data()[2].G0() = {TemperatureModel::T1, x[3], x[4], 0, 0};
364 m.
Data()[2].D0() = {TemperatureModel::T5, x[5], x[4], 0, 0};
365 m.
Data()[1].G0() = {TemperatureModel::T1, x[6], x[7], 0, 0};
366 m.
Data()[1].D0() = {TemperatureModel::T5, x[8], x[7], 0, 0};
371 case TypePB::PB_PLANETARY_BROADENING:
376 m.
Data()[0].G0() = {TemperatureModel::T1, x[1], x[8], 0, 0};
377 m.
Data()[0].D0() = {TemperatureModel::T5, x[14], x[8], 0, 0};
378 m.
Data()[1].G0() = {TemperatureModel::T1, x[2], x[9], 0, 0};
379 m.
Data()[1].D0() = {TemperatureModel::T5, x[15], x[9], 0, 0};
380 m.
Data()[2].G0() = {TemperatureModel::T1, x[3], x[10], 0, 0};
381 m.
Data()[2].D0() = {TemperatureModel::T5, x[16], x[10], 0, 0};
382 m.
Data()[3].G0() = {TemperatureModel::T1, x[4], x[11], 0, 0};
383 m.
Data()[3].D0() = {TemperatureModel::T5, x[17], x[11], 0, 0};
384 m.
Data()[4].G0() = {TemperatureModel::T1, x[5], x[12], 0, 0};
385 m.
Data()[4].D0() = {TemperatureModel::T5, x[18], x[12], 0, 0};
386 m.
Data()[5].G0() = {TemperatureModel::T1, x[6], x[13], 0, 0};
387 m.
Data()[5].D0() = {TemperatureModel::T5, x[19], x[13], 0, 0};
400 m.
Data()[0].G0() = {TemperatureModel::T1, x[0], x[7], 0, 0};
402 m.
Data()[1].G0() = {TemperatureModel::T1, x[1], x[8], 0, 0};
403 m.
Data()[1].D0() = {TemperatureModel::T5, x[14], x[8], 0, 0};
404 m.
Data()[2].G0() = {TemperatureModel::T1, x[2], x[9], 0, 0};
405 m.
Data()[2].D0() = {TemperatureModel::T5, x[15], x[9], 0, 0};
406 m.
Data()[3].G0() = {TemperatureModel::T1, x[3], x[10], 0, 0};
407 m.
Data()[3].D0() = {TemperatureModel::T5, x[16], x[10], 0, 0};
408 m.
Data()[4].G0() = {TemperatureModel::T1, x[4], x[11], 0, 0};
409 m.
Data()[4].D0() = {TemperatureModel::T5, x[17], x[11], 0, 0};
410 m.
Data()[5].G0() = {TemperatureModel::T1, x[5], x[12], 0, 0};
411 m.
Data()[5].D0() = {TemperatureModel::T5, x[18], x[12], 0, 0};
412 m.
Data()[6].G0() = {TemperatureModel::T1, x[6], x[13], 0, 0};
413 m.
Data()[6].D0() = {TemperatureModel::T5, x[19], x[13], 0, 0};
431 case TypeLM::LM_NONE:
433 case TypeLM::LM_LBLRTM:
436 y.
Data().front().Y().X0 = x[4];
437 y.
Data().front().Y().X1 = x[5];
438 y.
Data().front().Y().X2 = x[6];
439 y.
Data().front().Y().X3 = x[7];
440 y.
Data().front().G().X0 = x[8];
441 y.
Data().front().G().X1 = x[9];
442 y.
Data().front().G().X2 = x[10];
443 y.
Data().front().G().X3 = x[11];
445 case TypeLM::LM_LBLRTM_O2NonResonant:
447 y.
Data().front().G().X0 = x[0];
449 case TypeLM::LM_2NDORDER:
451 y.
Data().front().Y().X0 = x[0];
452 y.
Data().front().Y().X1 = x[1];
453 y.
Data().front().Y().X2 = x[7];
455 y.
Data().front().G().X0 = x[2];
456 y.
Data().front().G().X1 = x[3];
457 y.
Data().front().G().X2 = x[8];
459 y.
Data().front().DV().X0 = x[4];
460 y.
Data().front().DV().X1 = x[5];
461 y.
Data().front().DV().X2 = x[9];
463 case TypeLM::LM_1STORDER:
465 y.
Data().front().Y().X0 = x[1];
466 y.
Data().front().Y().X1 = x[2];
468 case TypeLM::LM_BYBAND:
481 if (atmospheric_species.
nelem() != atmospheric_vmrs.
nelem())
482 throw std::runtime_error(
"Bad atmospheric inputs");
486 const Index back = lineshape_species.
nelem() - 1;
488 if (type == Type::DP)
return line_vmrs;
491 for (
Index i = 0;
i < lineshape_species.
nelem()-bath_in_list;
i++) {
494 (self_in_list and &lineshape_species[
i] == &lineshape_species.front()) ?
self.
Species() : lineshape_species[
i].Species();
497 Index this_species_index = -1;
498 for (
Index j = 0; j < atmospheric_species.
nelem(); j++)
499 if (atmospheric_species[j][0].
Species() == target)
500 this_species_index = j;
503 if (this_species_index not_eq -1)
504 line_vmrs[
i] = atmospheric_vmrs[this_species_index];
509 line_vmrs[back] = 1.0 - line_vmrs.
sum();
510 else if(line_vmrs.sum() == 0)
513 line_vmrs /= line_vmrs.sum();
516 if (not std::isnormal(line_vmrs.sum()))
517 throw std::runtime_error(
518 "Bad VMRs, your atmosphere does not support the line of interest");
543 std::vector<Variable> vars(0);
547 for (
auto&
var: vars) {
548 if (std::any_of(m.
Data().cbegin(), m.
Data().cend(),
549 [
var](
auto& x){
return x.Get(
var).type not_eq TemperatureModel::None;})) {
551 for (
auto& ssm: m.
Data())
576 std::vector<SingleSpeciesModel> ssms(0);
577 while (not str.eof()) {
579 if(std::any_of(names.cbegin(), names.cend(),
580 [part](
auto x){
return part == x;})) {
591 else if (i <
Index(ssms.size()))
596 auto mp = ssms[i].Get(var);
598 ssms[i].Set(var, mp);
602 return Model(std::move(ssms));
609 case TemperatureModel::None:
612 case TemperatureModel::T0:
615 case TemperatureModel::T1:
616 os << mp.
X0 <<
" * (" << T0 <<
"/T)^" << mp.
X1;
618 case TemperatureModel::T2:
619 os << mp.
X0 <<
" * (" << T0 <<
"/T)^" << mp.
X1 <<
" / (1 + " << mp.
X2 <<
" * log(T/" << T0 <<
"))";
621 case TemperatureModel::T3:
622 os << mp.
X0 <<
" + " << mp.
X1 <<
" * (" << T0 <<
" - T)";
624 case TemperatureModel::T4:
625 os <<
"(" << mp.
X0 <<
" + " << mp.
X1 <<
" * (" << T0 <<
"/T - 1)) * (" << T0 <<
"/T)^" << mp.
X2;
627 case TemperatureModel::T5:
628 os << mp.
X0 <<
" * (" << T0 <<
"/T)^(0.25 + 1.5 * " << mp.
X1 <<
")";
630 case TemperatureModel::LM_AER:
631 os <<
'(' <<
"Linear interpolation to y(x) from x-ref = [200, 250, 296, 340] and y-ref = [" << mp.
X0 <<
", " << mp.
X1 <<
", " << mp.
X2 <<
", " << mp.
X3 <<
']' <<
')';
633 case TemperatureModel::DPL:
634 os <<
'(' << mp.
X0 <<
" * (" << T0 <<
"/T)^" << mp.
X1 <<
" + " << mp.
X2 <<
" * (" << T0 <<
"/T)^" << mp.
X3 <<
')';
648 std::vector<Variable> vars(0);
654 for (
Index i=0;
i<names.nelem();
i++) {
657 if (std::any_of(m.
Data().cbegin(), m.
Data().cend(),
658 [
var](
auto& x){
return x.Get(var).type not_eq TemperatureModel::None;})) {
661 os << names[
i] <<
" ~ ";
663 if (&sts[j] == &sts.front() and
self)
664 os <<
"VMR(" << self_broadening <<
") * " 666 else if (&sts[j] == &sts.back() and bath)
667 os <<
"VMR(" << bath_broadening <<
") * " 670 os <<
"VMR(" << sts[j].SpeciesNameMain() <<
") * " 673 if (&sts[j] not_eq &sts.back())
676 as.push_back(os.str());
INDEX Index
The type to use for all integer numbers and indices.
std::istream & operator>>(std::istream &is, ModelParameters &mp)
Input operator for ModelParameters.
void var(VectorView var, const Vector &y, const ArrayOfVector &ys, const Index start=0, const Index end=-1)
Compute the variance of the ranged ys.
TemperatureModel string2temperaturemodel(const String &type)
Turns predefined strings into a TemperatureModel type.
LegacyLineMixingData::TypeLM string2typelm(String type)
Line mixing types from string.
Vector vmrs(const ConstVectorView &atmospheric_vmrs, const ArrayOfArrayOfSpeciesTag &atmospheric_species, const QuantumIdentifier &self, const ArrayOfSpeciesTag &lineshape_species, bool self_in_list, bool bath_in_list, Type type)
Returns a VMR vector for this model's main calculations.
std::istream & from_linefunctiondata(std::istream &data, Model &lsc)
Index typepb2nelem(LegacyPressureBroadeningData::TypePB type)
Pressure broadening types to number of elements.
Index nelem() const
Number of elements.
QuantumIdentifier::QType Index LowerQuantumNumbers Species
std::vector< Variable > linemixingtag2variablesvector(String type)
Line mixing models.
Index temperaturemodel2legacynelem(TemperatureModel type) noexcept
Length per variable.
std::vector< SingleSpeciesModel > mdata
#define ReturnJacPropMatType(ID)
Model vector2modellm(Vector x, LegacyLineMixingData::TypeLM type)
LineShape::Model from legacy input vector.
Main line shape model class.
Index typelm2nelem(LegacyLineMixingData::TypeLM type)
Line mixing types to number.
ArrayOfString AllLineShapeCoeffs()
All available line shape coefficients.
Model vector2modelpb(Vector x, LegacyPressureBroadeningData::TypePB type, bool self_in_list)
G0 G2 FVC Y DV Numeric Numeric Numeric Zeeman LowerQuantumNumbers void * data
const std::vector< SingleSpeciesModel > & Data() const noexcept
basic_istringstream< char, string_char_traits< char >, alloc > istringstream
Index nelem() const
Returns the number of elements.
String SpeciesName() const
Return the Species by name.
JacPropMatType
List of Jacobian properties for analytical line shape related derivatives.
bool self_listed(const QuantumIdentifier &qid, LegacyPressureBroadeningData::TypePB t)
Pressure broadening if self exist.
std::istream & from_artscat4(std::istream &is, Model &lsc, const QuantumIdentifier &qid)
_CS_string_type str() const
constexpr Index nmaxTempModelParams
Current max number of coefficients.
Numeric sum() const
The sum of all elements of a Vector.
void Species(Index sp)
Set the Species.
A tag group can consist of the sum of several of these.
Variable
List of possible shape variables.
Coefficients and temperature model for SingleSpeciesModel.
std::ostream & operator<<(std::ostream &os, Variable v)
Output operator for Variable to be human-readable.
LegacyPressureBroadeningData::TypePB string2typepb(String type)
Pressure broadening types from string.
Class to identify and match lines by their quantum numbers.
NUMERIC Numeric
The type to use for all floating point numbers.
Contains the line shape namespace.
Index nelem() const
Number of elements.
ArrayOfString ModelMetaDataArray(const Model &m, const bool self, const bool bath, const ArrayOfSpeciesTag &sts, const Numeric T0)
String modelparameters2metadata(const ModelParameters mp, const Numeric T0)
ArrayOfString AllLineShapeVars()
All available line shape variables.
std::istream & from_linemixingdata(std::istream &data, Model &lsc)
Legacy reading of old deprecated LineMixingData class.
basic_ostringstream< char, string_char_traits< char >, alloc > ostringstream
This can be used to make arrays out of anything.
String temperaturemodel2string(TemperatureModel type) noexcept
Turns selected TemperatureModel type into a string.
A constant view of a Vector.
std::istream & from_pressurebroadeningdata(std::istream &data, Model &lsc, const QuantumIdentifier &qid)
JacPropMatType select_derivativeLineShape(const String &var, const String &coeff)
Select the derivative that will be used in Jacobian calculations — also checks validity of var and c...
TemperatureModel
Temperature models.
Compute the line shape parameters for a single broadening species.
Type string2shapetype(const String &type)
Turns predefined strings into a Type.
String variable2string(Variable type) noexcept
Turns selected Variable type into a string.
String ModelShape2MetaData(const Model &m)
my_basic_string< char > String
The String type for ARTS.
Variable string2variable(const String &type)
Turns predefined strings into a Variable type.
std::vector< Variable > lineshapetag2variablesvector(String type)
Line shape models.
Model MetaData2ModelShape(const String &s)