ARTS  2.3.1285(git:92a29ea9-dirty)
lineshapemodel.h
Go to the documentation of this file.
1 /* Copyright (C) 2018
2  Richard Larsson <larsson@mps.mpg.de>
3 
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of the GNU General Public License as published by the
7  Free Software Foundation; either version 2, or (at your option) any
8  later version.
9 
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20  USA. */
21 
34 #ifndef lineshapemodel_h
35 #define lineshapemodel_h
36 
37 #include <numeric>
38 #include <algorithm>
39 #include "abs_species_tags.h"
40 #include "constants.h"
41 #include "file.h"
42 #include "jacobian.h"
43 
52  const String& coeff);
53 
56 
59 
67 namespace LineShape {
68 
76 enum class TemperatureModel : Index {
77  None, // 0
78  T0, // Constant, X0
79  T1, // Standard, X0 * (T0/T) ^ X1
80  T2, // X0 * (T0/T) ^ X1 * (1 + X2 * log(T/T0));
81  T3, // X0 + X1 * (T - T0)
82  T4, // (X0 + X1 * (T0/T - 1)) * (T0/T)^X2;
83  T5, // X0 * (T0/T)^(0.25 + 1.5*X1)
84  LM_AER, // X(200) = X0; X(250) = X1; X(298) = X2; X(340) = X3; Linear interpolation in between
85  DPL // X0 * (T0/T) ^ X1 + X2 * (T0/T) ^ X3
86  // ALWAYS ADD NEW AT THE END
87 };
88 
98 inline String temperaturemodel2string(TemperatureModel type) noexcept {
99  switch (type) {
101  return "#";
103  return "T0";
105  return "T1";
107  return "T2";
109  return "T3";
111  return "T4";
113  return "T5";
115  return "LM_AER";
117  return "DPL";
118  }
119  std::terminate(); // Not allowed to reach, fix higher level code
120 }
121 
131 inline TemperatureModel string2temperaturemodel(const String& type) {
132  if (type == "#")
133  return TemperatureModel::None;
134  else if (type == String("T0"))
135  return TemperatureModel::T0;
136  else if (type == String("T1"))
137  return TemperatureModel::T1;
138  else if (type == String("T2"))
139  return TemperatureModel::T2;
140  else if (type == String("T3"))
141  return TemperatureModel::T3;
142  else if (type == String("T4"))
143  return TemperatureModel::T4;
144  else if (type == String("T5"))
145  return TemperatureModel::T5;
146  else if (type == String("LM_AER"))
148  else if (type == String("DPL"))
149  return TemperatureModel::DPL;
150  else {
152  os << "Type: " << type << ", is not accepted. "
153  << "See documentation for accepted types\n";
154  throw std::runtime_error(os.str());
155  }
156 }
157 
162 enum class Variable {
163  G0 = 0, // Pressure broadening speed-independent
164  D0 = 1, // Pressure f-shifting speed-dependent
165  G2 = 2, // Pressure broadening speed-dependent
166  D2 = 3, // Pressure f-shifting speed-independent
167  FVC = 4, // Frequency of velocity-changing collisions
168  ETA = 5, // Correlation
169  Y = 6, // First order line mixing coefficient
170  G = 7, // Second order line mixing coefficient
171  DV = 8 // Second order line mixing f-shifting
172  // ALWAYS ADD NEW AT THE END
173 };
174 
176 inline std::ostream& operator<<(std::ostream& os, Variable v) {
177  switch (v) {
178  case Variable::G0:
179  os << "G0";
180  break;
181  case Variable::D0:
182  os << "D0";
183  break;
184  case Variable::G2:
185  os << "G2";
186  break;
187  case Variable::D2:
188  os << "D2";
189  break;
190  case Variable::FVC:
191  os << "FVC";
192  break;
193  case Variable::ETA:
194  os << "ETA";
195  break;
196  case Variable::Y:
197  os << "Y";
198  break;
199  case Variable::G:
200  os << "G";
201  break;
202  case Variable::DV:
203  os << "DV";
204  break;
205  }
206  return os;
207 }
208 
218 inline String variable2string(Variable type) noexcept {
219 #define VARIABLE2STRINGDEF(X) \
220  case Variable::X: \
221  return #X
222  switch (type) {
232  }
233 #undef VARIABLE2STRINGDEF
234  std::terminate(); // Not allowed to reach, fix higher level code
235 }
236 
246 inline Variable string2variable(const String& type) {
247 #define STRING2VARIABLEDEF(X) \
248  if (type == #X) return Variable::X
250  else STRING2VARIABLEDEF(D0);
251  else STRING2VARIABLEDEF(G2);
252  else STRING2VARIABLEDEF(D2);
253  else STRING2VARIABLEDEF(FVC);
254  else STRING2VARIABLEDEF(ETA);
255  else STRING2VARIABLEDEF(Y);
256  else STRING2VARIABLEDEF(G);
257  else STRING2VARIABLEDEF(DV);
258  else {
260  os << "Type: " << type << ", is not accepted. "
261  << "See documentation for accepted types\n";
262  throw std::runtime_error(os.str());
263  }
264 }
265 
270 struct ModelParameters {
271  TemperatureModel type;
272  Numeric X0;
273  Numeric X1;
274  Numeric X2;
277  Numeric inX0=std::numeric_limits<Numeric>::quiet_NaN(),
278  Numeric inX1=std::numeric_limits<Numeric>::quiet_NaN(),
279  Numeric inX2=std::numeric_limits<Numeric>::quiet_NaN(),
280  Numeric inX3=std::numeric_limits<Numeric>::quiet_NaN())
281  noexcept : type(intype), X0(inX0), X1(inX1), X2(inX2), X3(inX3) {}
282 };
283 
285 
295 inline Numeric& SingleModelParameter(ModelParameters& mp, const String& type) {
296  if (type == "X0")
297  return mp.X0;
298  else if (type == "X1")
299  return mp.X1;
300  else if (type == "X2")
301  return mp.X2;
302  else if (type == "X3")
303  return mp.X3;
304  else {
306  os << "Type: " << type << ", is not accepted. "
307  << "See documentation for accepted types\n";
308  throw std::runtime_error(os.str());
309  }
310  std::terminate();
311 }
312 
313 inline bool modelparameterEmpty(const ModelParameters mp) noexcept {
314  switch(mp.type) {
315  case TemperatureModel::None: // 0
316  return true;
317  case TemperatureModel::T0: // Constant, X0
318  return (mp.X0 == 0);
319  case TemperatureModel::T1: // Standard, X0 * (T0/T) ^ X1
320  return (mp.X0 == 0);
321  case TemperatureModel::T2: // X0 * (T0/T) ^ X1 * (1 + X2 * log(T/T0));
322  return (mp.X0 == 0);
323  case TemperatureModel::T3: // X0 + X1 * (T - T0)
324  return (mp.X0 == 0 and mp.X1 == 0);
325  case TemperatureModel::T4: // (X0 + X1 * (T0/T - 1)) * (T0/T)^X2;
326  return (mp.X0 == 0 and mp.X1 == 0);
327  case TemperatureModel::T5: // X0 * (T0/T)^(0.25 + 1.5*X1)
328  return (mp.X0 == 0);
329  case TemperatureModel::LM_AER: // X(200) = X0; X(250) = X1; X(298) = X2; X(340) = X3; Linear interpolation in between
330  return (mp.X0 == 0 and mp.X1 == 0 and mp.X2 == 0 and mp.X3 == 0);
331  case TemperatureModel::DPL: // X0 * (T0/T) ^ X1 + X2 * (T0/T) ^ X3
332  return (mp.X0 == 0 and mp.X2 == 0);
333  }
334  std::terminate();
335 }
336 
338 inline std::ostream& operator<<(std::ostream& os, const ModelParameters& mp) {
339  os << temperaturemodel2string(mp.type) << ' ' << mp.X0 << ' ' << mp.X1 << ' '
340  << mp.X2 << ' ' << mp.X3 << ' ';
341  return os;
342 }
343 
345 inline std::istream& operator>>(std::istream& is, ModelParameters& mp) {
346  String tmp;
347  is >> tmp >> mp.X0 >> mp.X1 >> mp.X2 >> mp.X3;
348  mp.type = string2temperaturemodel(tmp);
349  return is;
350 }
351 
353 constexpr Index nmaxTempModelParams = 4;
354 
356 constexpr Index nVars = 9;
357 
359 class SingleSpeciesModel {
360  private:
361  std::array<ModelParameters, nVars> X;
362 
374  constexpr Numeric special_linemixing_aer(Numeric T, ModelParameters mp) const noexcept {
375  if (T < 250)
376  return mp.X0 + (T - 200) * (mp.X1 - mp.X0) / (250 - 200);
377  else if (T > 296)
378  return mp.X2 + (T - 296) * (mp.X3 - mp.X2) / (340 - 296);
379  else
380  return mp.X1 + (T - 250) * (mp.X2 - mp.X1) / (296 - 250);
381  }
382 
390  constexpr Numeric special_linemixing_aer_dT(Numeric T, ModelParameters mp) const noexcept {
391  if (T < 250)
392  return (mp.X1 - mp.X0) / (250 - 200);
393  else if (T > 296)
394  return (mp.X3 - mp.X2) / (340 - 296);
395  else
396  return (mp.X2 - mp.X1) / (296 - 250);
397  }
398 
399  public:
411  : X({G0, D0, G2, D2, FVC, ETA, Y, G, DV}) {}
412 
413 #define x0 X[Index(var)].X0
414 #define x1 X[Index(var)].X1
415 #define x2 X[Index(var)].X2
416 #define x3 X[Index(var)].X3
417 
426 Numeric compute(Numeric T, Numeric T0, Variable var) const noexcept {
427  using std::log;
428  using std::pow;
429 
430  Numeric out=std::numeric_limits<Numeric>::quiet_NaN();
431  switch (X[Index(var)].type) {
433  out = 0; break;
435  out = x0; break;
437  out = x0 * pow(T0 / T, x1); break;
439  out = x0 * pow(T0 / T, x1) * (1 + x2 * log(T / T0)); break;
441  out = x0 + x1 * (T - T0); break;
443  out = (x0 + x1 * (T0 / T - 1.)) * pow(T0 / T, x2); break;
445  out = x0 * pow(T0 / T, 0.25 + 1.5 * x1); break;
447  out = special_linemixing_aer(T, X[Index(var)]); break;
449  out = x0 * pow(T0 / T, x1) + x2 * pow(T0 / T, x3); break;
450  }
451  return out;
452 }
453 
462 Numeric compute_dX0(Numeric T, Numeric T0, Variable var) const noexcept {
463  using std::log;
464  using std::pow;
465 
466  Numeric out=std::numeric_limits<Numeric>::quiet_NaN();
467  switch (X[Index(var)].type) {
469  out = 0; break;
471  out = 1; break;
473  out = pow(T0 / T, x1); break;
475  out = pow(T0 / T, x1) * (1 + x2 * log(T / T0)); break;
477  out = 1; break;
479  out = pow(T0 / T, x2); break;
481  out = pow(T0 / T, 1.5 * x1 + 0.25); break;
483  out = 0; break;
485  out = pow(T0 / T, x1); break;
486  }
487  return out;
488 }
489 
498 Numeric compute_dX1(Numeric T, Numeric T0, Variable var) const noexcept {
499  using std::log;
500  using std::pow;
501 
502  Numeric out=std::numeric_limits<Numeric>::quiet_NaN();
503  switch (X[Index(var)].type) {
505  out = 0; break;
507  out = 0; break;
509  out = x0 * pow(T0 / T, x1) * log(T0 / T); break;
511  out = x0 * pow(T0 / T, x1) * (x2 * log(T / T0) + 1.) * log(T0 / T); break;
513  out = (T - T0); break;
515  out = pow(T0 / T, x2) * (T0 / T - 1.); break;
517  out = 1.5 * x0 * pow(T0 / T, 1.5 * x1 + 0.25) * log(T0 / T); break;
519  out = 0; break;
521  out = x0 * pow(T0 / T, x1) * log(T0 / T); break;
522  }
523  return out;
524 }
525 
534 Numeric compute_dX2(Numeric T, Numeric T0, Variable var) const noexcept {
535  using std::log;
536  using std::pow;
537 
538  Numeric out=std::numeric_limits<Numeric>::quiet_NaN();
539  switch (X[Index(var)].type) {
541  out = 0; break;
543  out = 0; break;
545  out = 0; break;
547  out = x0 * pow(T0 / T, x1) * log(T / T0); break;
549  out = 0; break;
551  out = pow(T0 / T, x2) * (x0 + x1 * (T0 / T - 1)) * log(T0 / T); break;
553  out = 0; break;
555  out = 0; break;
557  out = pow(T0 / T, x3); break;
558  }
559  return out;
560 }
561 
570 Numeric compute_dX3(Numeric T, Numeric T0, Variable var) const noexcept {
571  using std::log;
572  using std::pow;
573 
574  Numeric out=std::numeric_limits<Numeric>::quiet_NaN();
575  switch (X[Index(var)].type) {
577  out = 0; break;
579  out = 0; break;
581  out = 0; break;
583  out = 0; break;
585  out = 0; break;
587  out = 0; break;
589  out = 0; break;
591  out = 0; break;
593  out = x2 * pow(T0 / T, x3) * log(T0 / T); break;
594  }
595  return out;
596 }
597 
606 Numeric compute_dT(Numeric T, Numeric T0, Variable var) const noexcept {
607  using std::log;
608  using std::pow;
609 
610  Numeric out=std::numeric_limits<Numeric>::quiet_NaN();
611  switch (X[Index(var)].type) {
613  out = 0; break;
615  out = 0; break;
617  out = -x0 * x1 * pow(T0 / T, x1) / T; break;
619  out = -x0 * x1 * pow(T0 / T, x1) * (x2 * log(T / T0) + 1.) / T +
620  x0 * x2 * pow(T0 / T, x1) / T; break;
622  out = x1; break;
624  out = -x2 * pow(T0 / T, x2) * (x0 + x1 * (T0 / T - 1.)) / T -
625  T0 * x1 * pow(T0 / T, x2) / pow(T, 2); break;
627  out = -x0 * pow(T0 / T, 1.5 * x1 + 0.25) * (1.5 * x1 + 0.25) / T; break;
629  out = special_linemixing_aer_dT(T, X[Index(var)]); break;
631  out = -x0 * x1 * pow(T0 / T, x1) / T + -x2 * x3 * pow(T0 / T, x3) / T; break;
632  }
633  return out;
634 }
635 
644 Numeric compute_dT0(Numeric T, Numeric T0, Variable var) const noexcept {
645  using std::log;
646  using std::pow;
647 
648  Numeric out=std::numeric_limits<Numeric>::quiet_NaN();
649  switch (X[Index(var)].type) {
651  out = 0; break;
653  out = 0; break;
655  out = x0 * x1 * pow(T0 / T, x1) / T0; break;
657  out = x0 * x1 * pow(T0 / T, x1) * (x2 * log(T / T0) + 1.) / T0 -
658  x0 * x2 * pow(T0 / T, x1) / T0; break;
660  out = -x1; break;
662  out = x2 * pow(T0 / T, x2) * (x0 + x1 * (T0 / T - 1.)) / T0 +
663  x1 * pow(T0 / T, x2) / T; break;
665  out = x0 * pow(T0 / T, 1.5 * x1 + 0.25) * (1.5 * x1 + 0.25) / T0; break;
667  out = 0; break;
669  out = x0 * x1 * pow(T0 / T, x1) / T0 + x2 * x3 * pow(T0 / T, x3) / T0; break;
670  }
671  return out;
672 }
673 
674 #undef x0
675 #undef x1
676 #undef x2
677 #undef x3
678 
679 #define ACCESS_INTERNAL(VARPOS) \
680  ModelParameters& VARPOS() noexcept { return X[Index(Variable::VARPOS)]; } \
681  constexpr ModelParameters VARPOS() const noexcept { return X[Index(Variable::VARPOS)]; }
683  ACCESS_INTERNAL(D0);
684  ACCESS_INTERNAL(G2);
685  ACCESS_INTERNAL(D2);
686  ACCESS_INTERNAL(FVC);
687  ACCESS_INTERNAL(ETA);
688  ACCESS_INTERNAL(Y);
689  ACCESS_INTERNAL(G);
690  ACCESS_INTERNAL(DV);
691 #undef ACCESS_INTERNAL
692 
694  std::array<ModelParameters, nVars>& Data() noexcept { return X; }
695 
697  const std::array<ModelParameters, nVars>& Data() const noexcept { return X; }
698 
704  void Set(Variable var, const ModelParameters& x) noexcept {
705 #define MODELPARAMCASESETTER(X) \
706  case Variable::X: \
707  X() = x; \
708  break
709  switch (var) {
719  }
720 #undef MODELPARAMCASESETTER
721  }
722 
729  ModelParameters Get(Variable var) const noexcept {
730  #define MODELPARAMCASEGETTER(X) case Variable::X: out = X(); break;
731  ModelParameters out{};
732  switch (var) {
742  }
743  return out;
744  #undef MODELPARAMCASEGETTER
745  }
746 
749  for (auto& data: X) {
750  Index x;
751  bif >> x >> data.X0 >> data.X1 >> data.X2 >> data.X3;
752  data.type = TemperatureModel(x);
753  }
754  return bif;
755  }
756 
758  bofstream& write(bofstream& bof) const {
759  for (auto& data: X) {
760  bof << Index(data.type) << data.X0 << data.X1 << data.X2 << data.X3;
761  }
762  return bof;
763  }
764 
765  bool MatchTypes(const SingleSpeciesModel& other) const noexcept {
766  return std::equal (X.cbegin(), X.cend(), other.X.cbegin(), other.X.cend(), [](const auto& a, const auto& b){return a.type == b.type;});
767  }
768 };
769 
771 inline std::ostream& operator<<(std::ostream& os,
772  const SingleSpeciesModel& ssm) {
773  for (const auto& mp : ssm.Data())
774  if (mp.type not_eq TemperatureModel::None)
775  os << mp.X0 << ' ' << mp.X1 << ' ' << mp.X2 << ' ' << mp.X3 << ' ';
776  return os;
777 }
778 
780 inline std::istream& operator>>(std::istream& is, SingleSpeciesModel& ssm) {
781  for (auto& mp : ssm.Data())
782  if(mp.type not_eq TemperatureModel::None)
783  is >> double_imanip() >> mp.X0 >> mp.X1 >> mp.X2 >> mp.X3;
784  return is;
785 }
786 
788 enum class Type : Index {
789  DP, // Doppler
790  LP, // Lorentz
791  VP, // Voigt
792  SDVP, // Speed-dependent Voigt
793  HTP, // Hartmann-Tran
794 };
795 
805 inline String shapetype2string(Type type) noexcept {
806  switch (type) {
807  case Type::DP:
808  return "DP";
809  case Type::LP:
810  return "LP";
811  case Type::VP:
812  return "VP";
813  case Type::SDVP:
814  return "SDVP";
815  case Type::HTP:
816  return "HTP";
817  }
818  std::terminate(); // Not allowed to reach, fix higher level code
819 }
820 
830 inline String shapetype2metadatastring(Type type) noexcept {
831  switch (type) {
832  case Type::DP:
833  return "The line shape type is the Doppler profile\n";
834  case Type::LP:
835  return "The line shape type is the Lorentz profile.\n";
836  case Type::VP:
837  return "The line shape type is the Voigt profile.\n";
838  case Type::SDVP:
839  return "The line shape type is the speed-dependent Voigt profile.\n";
840  case Type::HTP:
841  return "The line shape type is the Hartmann-Tran profile.\n";
842  }
843  std::terminate(); // Not allowed to reach, fix higher level code
844 }
845 
855 inline Type string2shapetype(const String& type) {
856  if (type == "DP")
857  return Type::DP;
858  else if (type == String("LP"))
859  return Type::LP;
860  else if (type == String("VP"))
861  return Type::VP;
862  else if (type == String("SDVP"))
863  return Type::SDVP;
864  else if (type == String("HTP"))
865  return Type::HTP;
866  else {
868  os << "Type: " << type << ", is not accepted. "
869  << "See documentation for accepted types\n";
870  throw std::runtime_error(os.str());
871  }
872 }
873 
875 struct Output {
876  Numeric G0, // Pressure broadening speed-independent
877  D0, // Pressure f-shifting speed-independent
878  G2, // Pressure broadening speed-dependent
879  D2, // Pressure f-shifting speed-dependent
880  FVC, // Frequency of velocity-changing collisions
881  ETA, // Correlation
882  Y, // First order line mixing coefficient
883  G, // Second order line mixing coefficient
884  DV; // Second order line mixing f-shifting
885 };
886 
888 inline std::ostream& operator<<(std::ostream& os, Output x) {
889  return os << "G0: " << x.G0 << " D0: " << x.D0 << " G2: " << x.G2
890  << " D2: " << x.D2 << " FVC: " << x.FVC << " ETA: " << x.ETA
891  << " Y: " << x.Y << " G: " << x.G << " DV: " << x.DV;
892 }
893 
895 constexpr Output mirroredOutput(Output x) noexcept {
896  return {x.G0, -x.D0, x.G2, -x.D2, x.FVC, x.ETA, x.Y, x.G, -x.DV};
897 }
898 
900 constexpr Output negativeOutput(Output x) noexcept {
901  return {-x.G0, -x.D0, -x.G2, -x.D2, -x.FVC, -x.ETA, -x.Y, -x.G, -x.DV};
902 }
903 
905 constexpr Output si2cgs(Output x) noexcept {
907  return {freq2kaycm(x.G0),
908  freq2kaycm(x.D0),
909  freq2kaycm(x.D2),
910  freq2kaycm(x.G2),
911  freq2kaycm(x.FVC),
912  x.ETA,
913  x.Y,
914  x.G,
915  freq2kaycm(x.DV)};
916 }
917 
919 constexpr Output differenceOutput(Output y, Output x) noexcept {
920  return {y.G0 - x.G0,
921  y.D0 - x.D0,
922  y.G2 - x.G2,
923  y.D2 - x.D2,
924  y.FVC - x.FVC,
925  y.ETA - x.ETA,
926  y.Y - x.Y,
927  y.G - x.G,
928  y.DV - x.DV};
929 }
930 
931 
932 
953 Vector vmrs(const ConstVectorView& atmospheric_vmrs,
954  const ArrayOfArrayOfSpeciesTag& atmospheric_species,
955  const QuantumIdentifier& self,
956  const ArrayOfSpeciesTag& lineshape_species,
957  bool self_in_list,
958  bool bath_in_list,
959  Type type);
960 
962 static constexpr const char* const bath_broadening = "AIR";
963 
965 static constexpr const char* const self_broadening = "SELF";
966 
967 
972 class Model {
973  private:
974  std::vector<SingleSpeciesModel> mdata;
975 
976  public:
978  Model(Index n=0) noexcept : mdata(n) {}
979 
981  explicit Model(const std::vector<SingleSpeciesModel>& assm) noexcept : mdata(assm) {}
982 
984  Model(const Model& m) noexcept : Model(m.mdata) {}
985 
987  explicit Model(std::vector<SingleSpeciesModel>&& assm) noexcept : mdata(std::move(assm)) {}
988 
990  Model(Model&& m) noexcept : Model(std::move(m.mdata)) {}
991 
993  Model& operator=(const Model& m) {mdata=m.mdata; return *this;}
994 
996  Model& operator=(Model&& m) {mdata=std::move(m.mdata); return *this;}
997 
1008  Numeric nself,
1009  Numeric agam,
1010  Numeric nair,
1011  Numeric psf,
1012  std::array<Numeric, 12> aer_interp =
1013  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) noexcept : mdata(2) {
1014  mdata.front().G0() = {TemperatureModel::T1, sgam, nself, 0, 0};
1015  mdata.front().D0() = {TemperatureModel::T5, psf, nair, 0, 0};
1016 
1017  mdata.back().G0() = {TemperatureModel::T1, agam, nair, 0, 0};
1018  mdata.back().D0() = {TemperatureModel::T5, psf, nair, 0, 0};
1019 
1020  if (std::any_of(aer_interp.cbegin(), aer_interp.cend(), [](auto x){return x not_eq 0;})) {
1021  mdata.front().Y().type = TemperatureModel::LM_AER;
1022  mdata.front().Y().X0 = aer_interp[4];
1023  mdata.front().Y().X1 = aer_interp[5];
1024  mdata.front().Y().X2 = aer_interp[6];
1025  mdata.front().Y().X3 = aer_interp[7];
1026  mdata.front().G().type = TemperatureModel::LM_AER;
1027  mdata.front().G().X0 = aer_interp[8];
1028  mdata.front().G().X1 = aer_interp[9];
1029  mdata.front().G().X2 = aer_interp[10];
1030  mdata.front().G().X3 = aer_interp[11];
1031 
1032  mdata.back().Y().type = TemperatureModel::LM_AER;
1033  mdata.back().Y().X0 = aer_interp[4];
1034  mdata.back().Y().X1 = aer_interp[5];
1035  mdata.back().Y().X2 = aer_interp[6];
1036  mdata.back().Y().X3 = aer_interp[7];
1037  mdata.back().G().type = TemperatureModel::LM_AER;
1038  mdata.back().G().X0 = aer_interp[8];
1039  mdata.back().G().X1 = aer_interp[9];
1040  mdata.back().G().X2 = aer_interp[10];
1041  mdata.back().G().X3 = aer_interp[11];
1042  }
1043  }
1044 
1049  bool OK(Type type, bool self, bool bath, const std::vector<SpeciesTag>& species) const noexcept {
1050  Index n = mdata.size();
1051  Index k = species.size();
1052  Index m = Index(self) + Index(bath);
1053  bool needs_any = type not_eq Type::DP;
1054  if (n not_eq k or m > n or (needs_any and not n))
1055  return false;
1056  else
1057  return true;
1058  }
1059 
1060 #define LSPC(XVAR, PVAR) \
1061  Numeric XVAR( \
1062  Numeric T, Numeric T0, Numeric P [[maybe_unused]], ConstVectorView vmrs) \
1063  const noexcept { \
1064  return PVAR * \
1065  std::inner_product( \
1066  mdata.cbegin(), \
1067  mdata.cend(), \
1068  vmrs.begin(), \
1069  0.0, \
1070  std::plus<Numeric>(), \
1071  [=](auto& x, auto vmr) -> Numeric { \
1072  return vmr * x.compute(T, T0, Variable::XVAR); \
1073  }); \
1074  }
1075  LSPC(G0, P)
1076  LSPC(D0, P)
1077  LSPC(G2, P)
1078  LSPC(D2, P)
1079  LSPC(FVC, P)
1080  LSPC(ETA, 1)
1081  LSPC(Y, P)
1082  LSPC(G, P* P)
1083  LSPC(DV, P* P)
1084 #undef LSPC
1085 
1086 #define LSPCV(XVAR, PVAR) \
1087  Numeric d##XVAR##_dVMR(Numeric T, \
1088  Numeric T0, \
1089  Numeric P [[maybe_unused]], \
1090  const Index deriv_pos) const noexcept { \
1091  if (deriv_pos not_eq -1) \
1092  return PVAR * mdata[deriv_pos].compute(T, T0, Variable::XVAR); \
1093  else \
1094  return 0; \
1095  }
1096  LSPCV(G0, P)
1097  LSPCV(D0, P)
1098  LSPCV(G2, P)
1099  LSPCV(D2, P)
1100  LSPCV(FVC, P)
1101  LSPCV(ETA, 1)
1102  LSPCV(Y, P)
1103  LSPCV(G, P* P)
1104  LSPCV(DV, P* P)
1105 #undef LSPCV
1106 
1107 #define LSPCT(XVAR, PVAR) \
1108  Numeric d##XVAR##_dT( \
1109  Numeric T, Numeric T0, Numeric P [[maybe_unused]], ConstVectorView vmrs) \
1110  const noexcept { \
1111  return PVAR * \
1112  std::inner_product( \
1113  mdata.cbegin(), \
1114  mdata.cend(), \
1115  vmrs.begin(), \
1116  0.0, \
1117  std::plus<Numeric>(), \
1118  [=](auto& x, auto vmr) -> Numeric { \
1119  return vmr * x.compute_dT(T, T0, Variable::XVAR); \
1120  }); \
1121  }
1122  LSPCT(G0, P)
1123  LSPCT(D0, P)
1124  LSPCT(G2, P)
1125  LSPCT(D2, P)
1126  LSPCT(FVC, P)
1127  LSPCT(ETA, 1)
1128  LSPCT(Y, P)
1129  LSPCT(G, P* P)
1130  LSPCT(DV, P* P)
1131 #undef LSPCT
1132 
1133 // All shape model derivatives
1134 #define LSPDC(XVAR, DERIV, PVAR) \
1135  Numeric d##XVAR##DERIV(Numeric T, \
1136  Numeric T0, \
1137  Numeric P [[maybe_unused]], \
1138  Index deriv_pos, \
1139  ConstVectorView vmrs) const noexcept { \
1140  if (deriv_pos not_eq -1) \
1141  return vmrs[deriv_pos] * PVAR * \
1142  mdata[deriv_pos].compute##DERIV(T, T0, Variable::XVAR); \
1143  else \
1144  return 0; \
1145  }
1146  LSPDC(G0, _dT0, P)
1147  LSPDC(G0, _dX0, P)
1148  LSPDC(G0, _dX1, P)
1149  LSPDC(G0, _dX2, P)
1150  LSPDC(G0, _dX3, P)
1151  LSPDC(D0, _dT0, P)
1152  LSPDC(D0, _dX0, P)
1153  LSPDC(D0, _dX1, P)
1154  LSPDC(D0, _dX2, P)
1155  LSPDC(D0, _dX3, P)
1156  LSPDC(G2, _dT0, P)
1157  LSPDC(G2, _dX0, P)
1158  LSPDC(G2, _dX1, P)
1159  LSPDC(G2, _dX2, P)
1160  LSPDC(G2, _dX3, P)
1161  LSPDC(D2, _dT0, P)
1162  LSPDC(D2, _dX0, P)
1163  LSPDC(D2, _dX1, P)
1164  LSPDC(D2, _dX2, P)
1165  LSPDC(D2, _dX3, P)
1166  LSPDC(FVC, _dT0, P)
1167  LSPDC(FVC, _dX0, P)
1168  LSPDC(FVC, _dX1, P)
1169  LSPDC(FVC, _dX2, P)
1170  LSPDC(FVC, _dX3, P)
1171  LSPDC(ETA, _dT0, 1)
1172  LSPDC(ETA, _dX0, 1)
1173  LSPDC(ETA, _dX1, 1)
1174  LSPDC(ETA, _dX2, 1)
1175  LSPDC(ETA, _dX3, 1)
1176  LSPDC(Y, _dT0, P)
1177  LSPDC(Y, _dX0, P)
1178  LSPDC(Y, _dX1, P)
1179  LSPDC(Y, _dX2, P)
1180  LSPDC(Y, _dX3, P)
1181  LSPDC(G, _dT0, P* P)
1182  LSPDC(G, _dX0, P* P)
1183  LSPDC(G, _dX1, P* P)
1184  LSPDC(G, _dX2, P* P)
1185  LSPDC(G, _dX3, P* P)
1186  LSPDC(DV, _dT0, P* P)
1187  LSPDC(DV, _dX0, P* P)
1188  LSPDC(DV, _dX1, P* P)
1189  LSPDC(DV, _dX2, P* P)
1190  LSPDC(DV, _dX3, P* P)
1191 #undef LSPDC
1192 
1203  Numeric T0,
1204  Numeric P,
1205  ConstVectorView vmrs) const noexcept {
1206  return {G0(T, T0, P, vmrs),
1207  D0(T, T0, P, vmrs),
1208  G2(T, T0, P, vmrs),
1209  D2(T, T0, P, vmrs),
1210  FVC(T, T0, P, vmrs),
1211  ETA(T, T0, P, vmrs),
1212  Y(T, T0, P, vmrs),
1213  G(T, T0, P, vmrs),
1214  DV(T, T0, P, vmrs)};
1215  }
1216 
1227  Numeric T0,
1228  Numeric P,
1229  ConstVectorView vmrs) const noexcept {
1230  return {dG0_dT(T, T0, P, vmrs),
1231  dD0_dT(T, T0, P, vmrs),
1232  dG2_dT(T, T0, P, vmrs),
1233  dD2_dT(T, T0, P, vmrs),
1234  dFVC_dT(T, T0, P, vmrs),
1235  dETA_dT(T, T0, P, vmrs),
1236  dY_dT(T, T0, P, vmrs),
1237  dG_dT(T, T0, P, vmrs),
1238  dDV_dT(T, T0, P, vmrs)};
1239  }
1240 
1250  Output GetVMRDerivs(Numeric T, Numeric T0, Numeric P, const Index pos) const
1251  noexcept {
1252  return {dG0_dVMR(T, T0, P, pos),
1253  dD0_dVMR(T, T0, P, pos),
1254  dG2_dVMR(T, T0, P, pos),
1255  dD2_dVMR(T, T0, P, pos),
1256  dFVC_dVMR(T, T0, P, pos),
1257  dETA_dVMR(T, T0, P, pos),
1258  dY_dVMR(T, T0, P, pos),
1259  dG_dVMR(T, T0, P, pos),
1260  dDV_dVMR(T, T0, P, pos)};
1261  }
1262 
1275  Numeric T0,
1276  Numeric P,
1277  Index pos,
1278  ConstVectorView vmrs,
1279  JacPropMatType deriv) const noexcept {
1280  if (pos < 0) return 0;
1281 
1282 #define RETURNINTERNALDERIVATIVE(TYPE) \
1283  case JacPropMatType::LineShape##TYPE##X0: \
1284  return d##TYPE##_dX0(T, T0, P, pos, vmrs); \
1285  case JacPropMatType::LineShape##TYPE##X1: \
1286  return d##TYPE##_dX1(T, T0, P, pos, vmrs); \
1287  case JacPropMatType::LineShape##TYPE##X2: \
1288  return d##TYPE##_dX2(T, T0, P, pos, vmrs); \
1289  case JacPropMatType::LineShape##TYPE##X3: \
1290  return d##TYPE##_dX3(T, T0, P, pos, vmrs)
1291  switch (deriv) {
1301  default:
1302  return 0;
1303  }
1304 #undef RETURNINTERNALDERIVATIVE
1305  }
1306 
1308  Index nelem() const { return Index(mdata.size()); }
1309 
1311  Index size() const { return Index(mdata.size()); }
1312 
1319  void resize(Index n) {mdata.resize(n);}
1320 
1327  void reserve(Index n) {mdata.reserve(n);}
1328 
1334  SingleSpeciesModel& operator[](Index i) {return mdata[i];}
1335 
1341  const SingleSpeciesModel& operator[](Index i) const {return mdata[i];}
1342 
1343 
1345  const std::vector<SingleSpeciesModel>& Data() const noexcept { return mdata; }
1346 
1348  std::vector<SingleSpeciesModel>& Data() noexcept { return mdata; }
1349 
1357  void Remove(Index i, ArrayOfSpeciesTag& specs) {
1358  mdata.erase(mdata.begin() + i);
1359  specs.erase(specs.begin() + i);
1360  }
1361 
1373  for (auto& ssm : mdata) {
1374  ssm.Y() = x.Y();
1375  ssm.G() = x.G();
1376  ssm.DV() = x.DV();
1377  }
1378  }
1379 
1380  bool Match(const Model& other) const noexcept {
1381  return std::equal (mdata.cbegin(), mdata.cend(), other.mdata.cbegin(), other.mdata.cend(), [](auto& a, auto& b) {return a.MatchTypes(b);});
1382  }
1383 
1384  friend
1385  std::istream& from_linefunctiondata(std::istream& data,
1386  Type& type,
1387  bool& self,
1388  bool& bath,
1389  Model& m,
1390  ArrayOfSpeciesTag& species);
1391 
1392  friend
1393  std::istream& from_artscat4(std::istream& is,
1394  Type& type,
1395  bool& self,
1396  bool& bath,
1397  Model& m,
1398  ArrayOfSpeciesTag& species,
1399  const QuantumIdentifier& qid);
1400 
1401 
1404  for (auto& data: mdata)
1405  data.read(bif);
1406  return bif;
1407  }
1408 
1410  bofstream& write(bofstream& bof) const {
1411  for (auto& data: mdata)
1412  data.write(bof);
1413  return bof;
1414  }
1415 }; // Model;
1416 
1417 std::ostream& operator<<(std::ostream&, const Model&);
1418 std::istream& operator>>(std::istream&, Model&);
1419 
1420 String ModelShape2MetaData(const Model& m);
1421 Model MetaData2ModelShape(const String& s);
1422 
1423 ArrayOfString ModelMetaDataArray(const Model& m, const bool self, const bool bath, const ArrayOfSpeciesTag& sts, const Numeric T0);
1424 
1425 std::istream& from_artscat4(std::istream& is,
1426  Type& type,
1427  bool& self,
1428  bool& bath,
1429  Model& m,
1430  ArrayOfSpeciesTag& species,
1431  const QuantumIdentifier& qid);
1432 
1433 std::istream& from_linefunctiondata(std::istream& data,
1434  Type& type,
1435  bool& self,
1436  bool& bath,
1437  Model& m,
1438  ArrayOfSpeciesTag& species);
1439 
1441 std::istream& from_linemixingdata(std::istream& data, Model& lsc);
1442 
1444 std::istream& from_pressurebroadeningdata(std::istream& data,
1445  LineShape::Type& type,
1446  bool& self,
1447  bool& bath,
1448  Model& m,
1449  ArrayOfSpeciesTag& species,
1450  const QuantumIdentifier& qid);
1451 
1453 namespace LegacyLineFunctionData {
1455 inline Index temperaturemodel2legacynelem(TemperatureModel type) noexcept {
1456  switch (type) {
1458  return 0;
1459  case TemperatureModel::T0:
1460  return 1;
1461  case TemperatureModel::T1:
1462  return 2;
1463  case TemperatureModel::T2:
1464  return 3;
1465  case TemperatureModel::T3:
1466  return 2;
1467  case TemperatureModel::T4:
1468  return 3;
1469  case TemperatureModel::T5:
1470  return 2;
1472  return 12;
1473  case TemperatureModel::DPL:
1474  return 4;
1475  }
1476  std::terminate(); // Not allowed to reach, fix higher level code
1477 }
1478 
1480 inline std::vector<Variable> lineshapetag2variablesvector(String type) {
1481  if (type == String("DP"))
1482  return {};
1483  else if (type == String("LP"))
1484  return {Variable::G0, Variable::D0};
1485  else if (type == String("VP"))
1486  return {Variable::G0, Variable::D0};
1487  else if (type == String("SDVP"))
1489  else if (type == String("HTP"))
1490  return {Variable::G0,
1491  Variable::D0,
1492  Variable::G2,
1493  Variable::D2,
1494  Variable::FVC,
1495  Variable::ETA};
1496  else {
1497  std::ostringstream os;
1498  os << "Type: " << type << ", is not accepted. "
1499  << "See documentation for accepted types\n";
1500  throw std::runtime_error(os.str());
1501  }
1502 }
1503 
1505 inline std::vector<Variable> linemixingtag2variablesvector(String type) {
1506  if (type == "#")
1507  return {};
1508  else if (type == "LM1")
1509  return {Variable::Y};
1510  else if (type == "LM2")
1512  else if (type == "INT")
1513  return {};
1514  else if (type == "ConstG")
1515  return {Variable::G};
1516  else {
1517  std::ostringstream os;
1518  os << "Type: " << type << ", is not accepted. "
1519  << "See documentation for accepted types\n";
1520  throw std::runtime_error(os.str());
1521  }
1522 }
1523 }; // namespace LegacyLineFunctionData
1524 
1526 namespace LegacyLineMixingData {
1528 enum class TypeLM {
1529  LM_NONE, // Reserved for no line mixing
1530  LM_LBLRTM, // Reserved for LBLRTM line mixing
1531  LM_LBLRTM_O2NonResonant, // Reserved for the non-resonant O2 line in LBLRTM
1532  LM_1STORDER, // Reserved for Tretyakov et al. 2005 1st order of line mixing
1533  LM_2NDORDER, // Reserved for Makarov et al. 2011 second order of line mixing
1534  LM_BYBAND // Reserved for Paris data of relaxation matrix line mixing for band
1535 };
1536 
1539  if (type == "NA") // The standard case
1540  return TypeLM::LM_NONE;
1541  else if (type == "LL") // The LBLRTM case
1542  return TypeLM::LM_LBLRTM;
1543  else if (type == "NR") // The LBLRTM O2 non-resonant case
1544  return TypeLM::LM_LBLRTM_O2NonResonant;
1545  else if (type == "L2") // The 2nd order case
1546  return TypeLM::LM_2NDORDER;
1547  else if (type == "L1") // The 2nd order case
1548  return TypeLM::LM_1STORDER;
1549  else if (type == "BB") // The band class
1550  return TypeLM::LM_BYBAND;
1551  else {
1552  std::ostringstream os;
1553  os << "Type: " << type << ", is not accepted. "
1554  << "See documentation for accepted types\n";
1555  throw std::runtime_error(os.str());
1556  }
1557 }
1558 
1561  switch (type) {
1562  case TypeLM::LM_NONE: // The standard case
1563  return 0;
1564  case TypeLM::LM_LBLRTM: // The LBLRTM case
1565  return 12;
1566  case TypeLM::LM_LBLRTM_O2NonResonant: // Nonresonant is just a tag
1567  return 1;
1568  case TypeLM::LM_2NDORDER: // The 2nd order case
1569  return 10;
1570  case TypeLM::LM_1STORDER: // The 2nd order case
1571  return 3;
1572  case TypeLM::LM_BYBAND: // The band class
1573  return 1;
1574  }
1575  std::terminate();
1576 }
1577 
1580 }; // namespace LegacyLineMixingData
1581 
1583 namespace LegacyPressureBroadeningData {
1585 enum class TypePB {
1586  PB_NONE, // No pressure broadening
1587  PB_AIR_BROADENING, // Air broadening and self broadening only
1588  PB_AIR_AND_WATER_BROADENING, // Air, water, and self broadening
1589  PB_PLANETARY_BROADENING, // Gas broadening as done for solar system planets
1590  // PB_SD_AIR_VOLUME, // HTP in air for SD limit NOT SUPPORTED
1591  // PB_HTP_AIR_VOLUME, // HTP in air NOT SUPPORTED
1592  // PB_VOIGT_TEST_WATER, // Voigt parameters for testing NOT SUPPORTED
1593  // PB_SD_TEST_WATER, // SD parameters for testing NOT SUPPORTED
1594  // PB_PURELY_FOR_TESTING // Testing tag for new input structures --- can be changed by anyone... NOT SUPPORTED
1595 };
1596 
1599  if (type == "NA") // The none case
1600  return TypePB::PB_NONE;
1601  else if (type == "N2") // Air Broadening is N2 broadening mostly...
1602  return TypePB::PB_AIR_BROADENING;
1603  else if (type == "WA") // Water and Air Broadening
1604  return TypePB::PB_AIR_AND_WATER_BROADENING;
1605  else if (type == "AP") // Planetary broadening
1606  return TypePB::PB_PLANETARY_BROADENING;
1607  else {
1608  std::ostringstream os;
1609  os << "Type: " << type << ", is not accepted. "
1610  << "See documentation for accepted types\n";
1611  throw std::runtime_error(os.str());
1612  }
1613 }
1614 
1616 inline Index self_listed(const QuantumIdentifier& qid,
1618  if (t == TypePB::PB_PLANETARY_BROADENING and
1619  (qid.Species() == SpeciesTag(String("N2")).Species() or
1620  qid.Species() == SpeciesTag(String("O2")).Species() or
1621  qid.Species() == SpeciesTag(String("H2O")).Species() or
1622  qid.Species() == SpeciesTag(String("CO2")).Species() or
1623  qid.Species() == SpeciesTag(String("H2")).Species() or
1624  qid.Species() == SpeciesTag(String("He")).Species()))
1625  return true;
1626  else if (t == TypePB::PB_AIR_AND_WATER_BROADENING and
1627  qid.Species() == SpeciesTag(String("H2O")).Species())
1628  return true;
1629  else
1630  return false;
1631 }
1632 
1635  switch (type) {
1636  case TypePB::PB_NONE:
1637  return 0;
1638  case TypePB::PB_AIR_BROADENING:
1639  return 10;
1640  case TypePB::PB_AIR_AND_WATER_BROADENING:
1641  return 9;
1642  case TypePB::PB_PLANETARY_BROADENING:
1643  return 20;
1644  }
1645  std::terminate();
1646 }
1647 
1649 void vector2modelpb(LineShape::Type& mtype,
1650  bool& self,
1651  bool& bath,
1652  Model& m,
1653  ArrayOfSpeciesTag& species,
1654  Vector x,
1656  bool self_in_list);
1657 }; // namespace LegacyPressureBroadeningData
1658 }; // namespace LineShape
1659 
1662 
1663 #endif // lineshapemodel_h
1664 
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
Model(Numeric sgam, Numeric nself, Numeric agam, Numeric nair, Numeric psf, std::array< Numeric, 12 > aer_interp={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) noexcept
Standard HITRAN init.
SingleSpeciesModel & operator[](Index i)
Get a SingleSpeciesModel.
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.
Definition: raw.cc:49
TemperatureModel string2temperaturemodel(const String &type)
Turns predefined strings into a TemperatureModel type.
LegacyLineMixingData::TypeLM string2typelm(String type)
Line mixing types from string.
void vector2modelpb(LineShape::Type &mtype, bool &self, bool &bath, Model &m, ArrayOfSpeciesTag &species, Vector x, LegacyPressureBroadeningData::TypePB type, bool self_in_list)
LineShape::Model from legacy input vector.
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&#39;s main calculations.
std::istream & from_linefunctiondata(std::istream &data, Model &lsc)
Index typepb2nelem(LegacyPressureBroadeningData::TypePB type)
Pressure broadening types to number of elements.
#define MODELPARAMCASESETTER(X)
const std::array< ModelParameters, nVars > & Data() const noexcept
Get const internal Data reference.
Model(Model &&m) noexcept
Init from moving a itself.
void resize(Index n)
Resize function for Model.
constexpr ModelParameters(TemperatureModel intype=TemperatureModel::None, Numeric inX0=std::numeric_limits< Numeric >::quiet_NaN(), Numeric inX1=std::numeric_limits< Numeric >::quiet_NaN(), Numeric inX2=std::numeric_limits< Numeric >::quiet_NaN(), Numeric inX3=std::numeric_limits< Numeric >::quiet_NaN()) noexcept
Main output of Model.
#define RETURNINTERNALDERIVATIVE(TYPE)
#define x0
std::vector< SingleSpeciesModel > & Data() noexcept
The line shape model data reference.
Output GetVMRDerivs(Numeric T, Numeric T0, Numeric P, const Index pos) const noexcept
Derivative of GetParams(...) wrt VMR.
std::vector< Variable > linemixingtag2variablesvector(String type)
Line mixing models.
Index temperaturemodel2legacynelem(TemperatureModel type) noexcept
Length per variable.
std::vector< SingleSpeciesModel > mdata
Routines for setting up the jacobian.
The Vector class.
Definition: matpackI.h:860
#define x2
Model vector2modellm(Vector x, LegacyLineMixingData::TypeLM type)
LineShape::Model from legacy input vector.
Index Species() const
Molecular species index.
bool OK(Type type, bool self, bool bath, const std::vector< SpeciesTag > &species) const noexcept
The Model is good to use.
Numeric GetInternalDeriv(Numeric T, Numeric T0, Numeric P, Index pos, ConstVectorView vmrs, JacPropMatType deriv) const noexcept
Derivative of GetParams(...) wrt Coefficient.
Index size() const
Number of species in Model.
#define LSPDC(XVAR, DERIV, PVAR)
Constants of physical expressions as constexpr.
bofstream & write(bofstream &bof) const
Binary write for Model.
bool modelparameterEmpty(const ModelParameters mp) noexcept
bool MatchTypes(const SingleSpeciesModel &other) const noexcept
Main line shape model class.
constexpr Numeric special_linemixing_aer(Numeric T, ModelParameters mp) const noexcept
Line mixing as done by AER data in ARTS.
void reserve(Index n)
Reserve function for Model.
bifstream & read(bifstream &bif)
Binary read for Model.
Numeric & SingleModelParameter(ModelParameters &mp, const String &type)
Get a coefficient from ModelParameters by name.
Index typelm2nelem(LegacyLineMixingData::TypeLM type)
Line mixing types to number.
void Remove(Index i, ArrayOfSpeciesTag &specs)
Remove species and data at position.
LineShape::SingleSpeciesModel LineShapeSingleSpeciesModel
Numeric compute_dT(Numeric T, Numeric T0, Variable var) const noexcept
Derivative of compute(...) wrt T.
LineShape::Model LineShapeModel
bofstream & write(bofstream &bof) const
Binary write for SingleSpeciesModel.
#define MODELPARAMCASEGETTER(X)
bool Match(const Model &other) const noexcept
This file contains basic functions to handle ASCII files.
Numeric compute(Numeric T, Numeric T0, Variable var) const noexcept
Compute the broadening parameter at the input.
const SingleSpeciesModel & operator[](Index i) const
Get a SingleSpeciesModel.
String shapetype2metadatastring(Type type) noexcept
Turns selected Type into a human readable string.
constexpr Output negativeOutput(Output x) noexcept
Output turned negative.
#define LSPC(XVAR, PVAR)
G0 G2 FVC Y DV Numeric Numeric Numeric Zeeman LowerQuantumNumbers void * data
constexpr SingleSpeciesModel(ModelParameters G0=ModelParameters{}, ModelParameters D0=ModelParameters{}, ModelParameters G2=ModelParameters{}, ModelParameters D2=ModelParameters{}, ModelParameters FVC=ModelParameters{}, ModelParameters ETA=ModelParameters{}, ModelParameters Y=ModelParameters{}, ModelParameters G=ModelParameters{}, ModelParameters DV=ModelParameters{})
Default initialization.
Numeric compute_dX0(Numeric T, Numeric T0, Variable var) const noexcept
Derivative of compute(...) wrt x0.
#define LSPCT(XVAR, PVAR)
const std::vector< SingleSpeciesModel > & Data() const noexcept
The line shape model data.
JacPropMatType
List of Jacobian properties for analytical line shape related derivatives.
Definition: jacobian.h:46
Computations of line shape derived parameters.
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)
Model(std::vector< SingleSpeciesModel > &&assm) noexcept
Init from moving a vector.
#define LSPCV(XVAR, PVAR)
Output GetTemperatureDerivs(Numeric T, Numeric T0, Numeric P, ConstVectorView vmrs) const noexcept
Derivative of GetParams(...) wrt T.
constexpr Index nmaxTempModelParams
Current max number of coefficients.
void Species(Index sp)
Set the Species.
Definition: quantum.h:481
Binary output file stream class.
Definition: bifstream.h:42
JacPropMatType select_derivativeLineShape(const String &var, const String &coeff)
Return the derivative type based on string input.
#define STRING2VARIABLEDEF(X)
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.
void Set(Variable var, const ModelParameters &x) noexcept
Set variable to a different ModelParameters.
LegacyPressureBroadeningData::TypePB string2typepb(String type)
Pressure broadening types from string.
Class to identify and match lines by their quantum numbers.
Definition: quantum.h:390
void SetLineMixingModel(SingleSpeciesModel x)
Sets the same line mixing model to all species.
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Model(const Model &m) noexcept
Init from copying itself.
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)
String shapetype2string(Type type) noexcept
Turns selected Type into a string.
Numeric pow(const Rational base, Numeric exp)
Power of.
Definition: rational.h:628
std::istream & from_linemixingdata(std::istream &data, Model &lsc)
Legacy reading of old deprecated LineMixingData class.
ArrayOfString AllLineShapeCoeffs()
All available line shape coefficients.
basic_ostringstream< char, string_char_traits< char >, alloc > ostringstream
Definition: sstream.h:204
#define x1
This can be used to make arrays out of anything.
Definition: array.h:40
String temperaturemodel2string(TemperatureModel type) noexcept
Turns selected TemperatureModel type into a string.
Numeric compute_dX2(Numeric T, Numeric T0, Variable var) const noexcept
Derivative of compute(...) wrt x2.
constexpr Output differenceOutput(Output y, Output x) noexcept
Diff of two output.
Numeric compute_dT0(Numeric T, Numeric T0, Variable var) const noexcept
Derivative of compute(...) wrt T0.
std::array< ModelParameters, nVars > & Data() noexcept
Get internal Data reference.
#define VARIABLE2STRINGDEF(X)
constexpr Output si2cgs(Output x) noexcept
Output turned from SI to CGS units.
#define ACCESS_INTERNAL(VARPOS)
A constant view of a Vector.
Definition: matpackI.h:476
Model & operator=(const Model &m)
Copy and equals.
constexpr Output mirroredOutput(Output x) noexcept
Output to be used by mirroring calls.
Header file for stuff related to absorption species tags.
Model(Index n=0) noexcept
Default init just sets the size.
Index nelem() const
Number of species in Model.
constexpr Numeric freq2kaycm(T x)
Definition: constants.h:387
std::istream & from_pressurebroadeningdata(std::istream &data, Model &lsc, const QuantumIdentifier &qid)
Binary output file stream class.
Definition: bofstream.h:42
#define x3
Output GetParams(Numeric T, Numeric T0, Numeric P, ConstVectorView vmrs) const noexcept
Compute all shape parameters.
ArrayOfString AllLineShapeVars()
All available line shape variables.
Numeric compute_dX1(Numeric T, Numeric T0, Variable var) const noexcept
Derivative of compute(...) wrt x1.
Numeric compute_dX3(Numeric T, Numeric T0, Variable var) const noexcept
Derivative of compute(...) wrt x3.
constexpr Numeric special_linemixing_aer_dT(Numeric T, ModelParameters mp) const noexcept
The temperature derivative of special_linemixing_aer.
Model & operator=(Model &&m)
Move and equals.
TemperatureModel
Temperature models.
ModelParameters Get(Variable var) const noexcept
Get variable by type.
Compute the line shape parameters for a single broadening species.
Model(const std::vector< SingleSpeciesModel > &assm) noexcept
Init from copying a vector.
Type string2shapetype(const String &type)
Turns predefined strings into a Type.
bifstream & read(bifstream &bif)
Binary read for SingleSpeciesModel.
constexpr Index nVars
Current max number of line shape variables.
String variable2string(Variable type) noexcept
Turns selected Variable type into a string.
Input manipulator class for doubles to enable nan and inf parsing.
Definition: file.h:117
String ModelShape2MetaData(const Model &m)
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:280
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)