ARTS  2.4.0(git:4fb77825)
make_autoarts_h.cc
Go to the documentation of this file.
1 #include <auto_md.h>
2 #include <global_data.h>
3 
4 #include <algorithm>
5 #include <iostream>
6 #include <map>
7 #include <string>
8 #include <vector>
9 
10 struct Group {
11  std::string varname_group;
12  std::string varname_desc;
13  std::size_t artspos;
14 };
15 
16 struct Method {
17  struct Gin {
18  std::vector<std::string> desc;
19  std::vector<std::string> group;
20  std::vector<std::string> name;
21  std::vector<std::string> defs;
22  std::vector<bool> hasdefs;
23  };
24 
25  struct Gout {
26  std::vector<std::string> desc;
27  std::vector<std::string> group;
28  std::vector<std::string> name;
29  };
30 
31  struct In {
32  std::vector<std::string> varname;
33  std::vector<std::size_t> varpos;
34  };
35 
36  struct Out {
37  std::vector<std::string> varname;
38  std::vector<std::size_t> varpos;
39  };
40 
41  std::string name;
42  std::size_t pos;
43  std::string desc;
44  std::vector<std::string> authors;
45  bool set_method;
51  In in;
55  std::vector<std::size_t> inoutvarpos;
56 };
57 
58 struct AgendaData {
59  std::size_t pos;
60  std::string desc;
61  std::vector<std::string> ins;
62  std::vector<std::string> outs;
63 };
64 
65 std::map<std::string, Group> groups() {
66  std::map<std::string, std::size_t> group;
67  for (auto& x : global_data::WsvGroupMap) group[x.first] = x.second;
68  std::map<std::string, std::size_t> name;
69  for (auto& x : Workspace::wsv_data) name[x.Name()] = x.Group();
70  std::map<std::string, std::string> desc;
71  for (auto& x : Workspace::wsv_data) desc[x.Name()] = x.Description();
72  std::map<std::string, std::size_t> pos;
73  for (auto& x : Workspace::WsvMap) pos[x.first] = x.second;
74 
75  std::map<std::string, Group> out;
76  for (auto& x : name) {
77  for (auto& y : group) {
78  if (y.second == x.second) {
79  out[x.first] = {y.first, desc[x.first], pos[x.first]};
80  break;
81  }
82  }
83  }
84  return out;
85 }
86 
87 std::pair<std::vector<std::string>, std::vector<bool>> fixed_defaults(
88  const std::vector<std::string>& vargroups,
89  const std::vector<std::string>& vardefaults) {
90  std::vector<std::string> defaults(vargroups.size());
91  std::vector<bool> hasdefaults(vargroups.size());
92  for (size_t i = 0; i < vargroups.size(); i++) {
93  if (vardefaults[i] == NODEF)
94  hasdefaults[i] = false;
95  else
96  hasdefaults[i] = true;
97 
98  if (vargroups[i] == "String") {
99  defaults[i] = std::string("\"") + vardefaults[i] + std::string("\"");
100  } else if (vargroups[i] == "Numeric") {
101  if ("NaN" == vardefaults[i] or "nan" == vardefaults[i]) {
102  defaults[i] = "std::numeric_limits<Numeric>::quiet_NaN()";
103  } else if ("Inf" == vardefaults[i] or "inf" == vardefaults[i]) {
104  defaults[i] = "std::numeric_limits<Numeric>::infinity()";
105  } else if ("-Inf" == vardefaults[i] or "-inf" == vardefaults[i]) {
106  defaults[i] = "-std::numeric_limits<Numeric>::infinity()";
107  } else {
108  defaults[i] = vardefaults[i];
109  }
110  } else if (vardefaults[i] == "[]") {
111  defaults[i] = "{}";
112  } else {
113  defaults[i] = vardefaults[i];
114  }
115 
116  if (defaults[i] == "") defaults[i] = "{}";
117 
118  for (auto& x : defaults[i]) {
119  if (x == '[')
120  x = '{';
121  else if (x == ']')
122  x = '}';
123  }
124  }
125 
126  return {defaults, hasdefaults};
127 }
128 
129 std::vector<Method> methods() {
130  std::map<std::string, std::size_t> vargroup;
131  for (auto& x : global_data::WsvGroupMap) vargroup[x.first] = x.second;
132  std::map<std::string, std::size_t> varpos;
133  for (auto& x : Workspace::WsvMap) varpos[x.first] = x.second;
134  std::map<std::string, std::size_t> methodpos;
135  for (auto& x : global_data::MdMap) methodpos[x.first] = x.second;
136 
137  std::vector<std::string> metname;
138  for (auto& x : global_data::md_data) metname.push_back(x.Name());
139  std::vector<std::string> actual_groups;
140  for (auto& x : global_data::md_data)
141  actual_groups.push_back(x.ActualGroups());
142  std::vector<std::vector<std::size_t>> gin_group;
143  for (auto& x : global_data::md_data)
144  gin_group.push_back({x.GInType().cbegin(), x.GInType().cend()});
145  std::vector<std::vector<std::string>> gin_names;
146  for (auto& x : global_data::md_data)
147  gin_names.push_back({x.GIn().cbegin(), x.GIn().cend()});
148  std::vector<std::vector<std::string>> gin_defaults;
149  for (auto& x : global_data::md_data)
150  gin_defaults.push_back({x.GInDefault().cbegin(), x.GInDefault().cend()});
151  std::vector<std::vector<std::string>> gin_desc;
152  for (auto& x : global_data::md_data)
153  gin_desc.push_back(
154  {x.GInDescription().cbegin(), x.GInDescription().cend()});
155  std::vector<std::vector<std::size_t>> gout_group;
156  for (auto& x : global_data::md_data)
157  gout_group.push_back({x.GOutType().cbegin(), x.GOutType().cend()});
158  std::vector<std::vector<std::string>> gout_names;
159  for (auto& x : global_data::md_data)
160  gout_names.push_back({x.GOut().cbegin(), x.GOut().cend()});
161  std::vector<std::vector<std::string>> gout_desc;
162  for (auto& x : global_data::md_data)
163  gout_desc.push_back(
164  {x.GOutDescription().cbegin(), x.GOutDescription().cend()});
165  std::vector<std::vector<std::size_t>> in_wspace;
166  for (auto& x : global_data::md_data)
167  in_wspace.push_back({x.In().cbegin(), x.In().cend()});
168  std::vector<std::vector<std::size_t>> out_wspace;
169  for (auto& x : global_data::md_data)
170  out_wspace.push_back({x.Out().cbegin(), x.Out().cend()});
171  std::vector<std::string> desc;
172  for (auto& x : global_data::md_data) desc.push_back(x.Description());
173  std::vector<std::vector<std::string>> authors;
174  for (auto& x : global_data::md_data)
175  authors.push_back({x.Authors().cbegin(), x.Authors().cend()});
176 
177  std::vector<bool> set_method;
178  for (auto& x : global_data::md_data) set_method.push_back(x.SetMethod());
179  std::vector<bool> agenda_method;
180  for (auto& x : global_data::md_data)
181  agenda_method.push_back(x.AgendaMethod());
182  std::vector<bool> supergeneric;
183  for (auto& x : global_data::md_data) supergeneric.push_back(x.Supergeneric());
184  std::vector<bool> uses_templates;
185  for (auto& x : global_data::md_data)
186  uses_templates.push_back(x.UsesTemplates());
187  std::vector<bool> pass_workspace;
188  for (auto& x : global_data::md_data)
189  pass_workspace.push_back(x.PassWorkspace());
190  std::vector<bool> pass_wsv_names;
191  for (auto& x : global_data::md_data)
192  pass_wsv_names.push_back(x.PassWsvNames());
193 
194  std::vector<std::vector<std::size_t>> inoutvarpos;
195  for (auto& x : global_data::md_data)
196  inoutvarpos.push_back({x.InOut().cbegin(), x.InOut().cend()});
197  std::vector<std::vector<std::size_t>> invarpos;
198  for (auto& x : global_data::md_data)
199  invarpos.push_back({x.InOnly().cbegin(), x.InOnly().cend()});
200  std::vector<std::vector<std::size_t>> outvarpos;
201  for (auto& x : global_data::md_data)
202  outvarpos.push_back({x.Out().cbegin(), x.Out().cend()});
203 
204  std::vector<Method> retval;
205  for (std::size_t i = 0; i < desc.size(); i++) {
206  Method m;
207  m.name = metname[i];
208  if (supergeneric[i])
209  m.pos = methodpos[metname[i] + String("_sg_") + actual_groups[i]];
210  else
211  m.pos = methodpos[metname[i]];
212  m.desc = desc[i];
213  m.authors = authors[i];
214 
215  Method::Gin gin;
216  gin.desc = gin_desc[i];
217  for (auto g : gin_group[i]) {
218  bool found = false;
219  for (auto& y : vargroup) {
220  if (y.second == g) {
221  gin.group.push_back(y.first);
222  found = true;
223  break;
224  }
225  }
226  if (not found) {
227  std::cerr << "Cannot find group\n";
228  std::terminate();
229  }
230  }
231  gin.name = gin_names[i];
232  auto fixgin = fixed_defaults(gin.group, gin_defaults[i]);
233  gin.defs = fixgin.first;
234  gin.hasdefs = fixgin.second;
235  m.gin = gin;
236 
237  Method::Gout gout;
238  gout.desc = gout_desc[i];
239  for (auto g : gout_group[i]) {
240  bool found = false;
241  for (auto& y : vargroup) {
242  if (y.second == g) {
243  gout.group.push_back(y.first);
244  found = true;
245  break;
246  }
247  }
248  if (not found) {
249  std::cerr << "Cannot find group\n";
250  std::terminate();
251  }
252  }
253  gout.name = gout_names[i];
254  m.gout = gout;
255 
256  Method::In in;
257  for (auto v : in_wspace[i]) {
258  bool found = false;
259  for (auto& y : varpos) {
260  if (v == y.second) {
261  in.varname.push_back(y.first);
262  found = true;
263  break;
264  }
265  }
266  if (not found) {
267  std::cerr << "Cannot find variable\n";
268  std::terminate();
269  }
270  }
271  in.varpos = invarpos[i];
272  m.in = in;
273 
274  Method::Out out;
275  for (auto v : out_wspace[i]) {
276  bool found = false;
277  for (auto& y : varpos) {
278  if (v == y.second) {
279  out.varname.push_back(y.first);
280  found = true;
281  break;
282  }
283  }
284  if (not found) {
285  std::cerr << "Cannot find variable\n";
286  std::terminate();
287  }
288  }
289  out.varpos = outvarpos[i];
290  m.out = out;
291 
292  m.set_method = set_method[i];
293  m.agenda_method = agenda_method[i];
294  m.supergeneric = supergeneric[i];
295  m.uses_templates = uses_templates[i];
296  m.pass_workspace = pass_workspace[i];
297  m.pass_wsv_names = pass_wsv_names[i];
298  m.inoutvarpos = inoutvarpos[i];
299  retval.push_back(m);
300  }
301 
302  return retval;
303 }
304 
305 std::map<std::string, AgendaData> agendas() {
306  auto g = groups();
307 
308  std::map<std::string, AgendaData> out;
309  for (auto& x : global_data::agenda_data) {
310  out[x.Name()].pos = global_data::AgendaMap.at(x.Name());
311  out[x.Name()].desc = x.Description();
312 
313  for (std::size_t i : x.In()) {
314  bool found = false;
315  for (auto& y : g) {
316  if (y.second.artspos == i) {
317  out[x.Name()].ins.push_back(y.first);
318  found = true;
319  break;
320  }
321  }
322  if (not found) {
323  std::cerr << "Cannot find the variable\n";
324  std::terminate();
325  }
326  }
327 
328  for (std::size_t i : x.Out()) {
329  bool found = false;
330  for (auto& y : g) {
331  if (y.second.artspos == i) {
332  out[x.Name()].outs.push_back(y.first);
333  found = true;
334  break;
335  }
336  }
337  if (not found) {
338  std::cerr << "Cannot find the variable\n";
339  std::terminate();
340  }
341  }
342  }
343  return out;
344 }
345 
346 struct NameMaps {
347  std::map<std::string, AgendaData> agendaname_agenda;
348  std::vector<Method> methodname_method;
349  std::map<std::string, Group> varname_group;
350  std::map<std::string, std::size_t> group;
351 
353  for (auto& x : global_data::WsvGroupMap) group[x.first] = x.second;
354  varname_group = groups();
357  }
358 };
359 
360 int main() {
366  define_md_map();
371 
372  const auto artsname = NameMaps();
373 
374  std::cout << "#ifndef autoarts_h\n"
375  << "#define autoarts_h\n"
376  << '\n'
377  << "#include <auto_md.h>" << '\n'
378  << "#include <arts.h>" << '\n'
379  << "#include <global_data.h>" << '\n'
380  << "#include <m_basic_types.h>" << '\n'
381  << "#include <m_general.h>" << '\n'
382  << "#include <m_append.h>" << '\n'
383  << "#include <m_conversion.h>" << '\n'
384  << "#include <m_copy.h>" << '\n'
385  << "#include <m_gridded_fields.h>" << '\n'
386  << "#include <m_xml.h>" << '\n'
387  << "#include <m_select.h>" << '\n'
388  << "#include <m_reduce.h>" << '\n'
389  << "#include <m_nc.h>" << '\n'
390  << "#include <m_delete.h>" << '\n'
391  << "#include <m_extract.h>" << '\n'
392  << "#include <m_ignore.h>" << '\n'
393  << '\n'
394  << '\n';
395 
396  std::cout << "extern String out_basename;\n\n";
397 
398  std::cout << "namespace ARTS { using Workspace=Workspace; }\n\n";
399  std::cout << "namespace ARTS::Group {\n";
400  for (auto& x : artsname.group) {
401  if (x.first == "Any") continue;
402  std::cout << "using " << x.first << '=' << x.first << ';' << '\n';
403  }
404  std::cout << "} // ARTS::Group \n\n";
405 
406  std::cout << "namespace ARTS::Var {\n";
407  for (auto& x : artsname.group) {
408  if (x.first == "Any") continue;
409 
410  std::cout << "class " << x.first << ' ' << '{' << '\n';
411  std::cout << " using type = Group::" << x.first << ";\n";
412  std::cout << " std::size_t p;\n";
413  std::cout << " type* v;\n";
414  std::cout << "public:\n";
415  std::cout << " " << x.first
416  << "() noexcept : p(std::numeric_limits<std::size_t>::max()), "
417  "v(nullptr) {}\n";
418  std::cout << " " << x.first
419  << "(std::size_t i, void * x) noexcept : p(i), "
420  "v(static_cast<type *>(x)) {}\n";
421  std::cout << " ~" << x.first
422  << "() noexcept {if (islast() and not isnull()) delete v;}\n";
423  std::cout
424  << " " << x.first
425  << "(const type& val) noexcept : p(std::numeric_limits<std::size_t>::max()), v(new type(val)) {}\n";
426  std::cout << " type& value() noexcept {return *v;}\n";
427  std::cout << " const type& value() const noexcept {return *v;}\n";
428  std::cout
429  << " " << x.first
430  << "& operator=(const type& t) noexcept {value() = t; return *this;}\n";
431  std::cout << " std::size_t pos() const noexcept {return p;}\n";
432  std::cout << " bool isnull() const noexcept {return v == nullptr;}\n";
433  std::cout
434  << " bool islast() const noexcept {return p == std::numeric_limits<std::size_t>::max();}\n";
435  std::cout
436  << " const Group::String& name() const noexcept {return Workspace::wsv_data[p].Name();}\n";
437  std::cout << '}' << ';' << '\n' << '\n';
438  }
439  for (auto& x : artsname.varname_group) {
440  std::cout << "/*! " << x.second.varname_desc << '\n';
441  std::cout << "@param[in,out] Workspace ws - An ARTS workspace\n";
442  std::cout << "@return A class with a pointer to this variable and its "
443  "position in the workspace\n*/\n";
444  std::cout << "[[nodiscard]] inline ";
445  std::cout << x.second.varname_group << ' ' << x.first
446  << "(Workspace& ws) "
447  "noexcept { "
448  "return {"
449  << x.second.artspos << ", ws[" << x.second.artspos
450  << "]}; "
451  "}\n\n";
452  }
453  for (auto& x : artsname.group) {
454  if (x.first == "Any") continue;
455 
456  std::cout << "/*! Creates in, and returns from, Workspace a/an " << x.first
457  << '\n'
458  << '\n';
459  std::cout << "@param[in,out] Workspace ws - An ARTS workspace\n";
460  std::cout << "@param[in] " << x.first
461  << " inval - The default value the variable will have in "
462  "the workspace\n";
463  std::cout << "@param[in] String name - The name the variable will have in "
464  "the workspace\n";
465  std::cout << "@param[in] String desc - The description the variable will "
466  "have in the workspace (default: \"nodescription\")\n";
467  std::cout << "@return A class with a pointer to this variable and its new "
468  "position in the workspace\n";
469  std::cout << "*/\n";
470  std::cout << "[[nodiscard]] inline\n";
471  std::cout
472  << x.first << ' ' << x.first
473  << "Create(\n Workspace& ws,\n const Group::"
474  << x.first
475  << "& inval,\n const Group::String& name,\n const Group::"
476  "String& "
477  "desc=\"nodescription\") {\n";
478  std::cout << " const std::size_t ind = "
479  "std::size_t(ws.add_wsv_inplace({name.c_str(), desc.c_str(), "
480  << x.second << "}));\n";
481  std::cout << " " << x.first << ' ' << "val{ind, ws[ind]};\n";
482  std::cout << " return val = inval;\n"
483  << "}\n\n";
484  }
485  std::cout << "} // ARTS::Var \n\n";
486 
487  std::cout << "namespace ARTS::Method {\n";
488 
489  for (auto& x : artsname.methodname_method) {
490  // Skip methods using verbosity and Agenda methods (for now)
491  if (x.agenda_method) continue;
492 
493  // Also skip create methods since these must be called via Var
494  if (std::any_of(artsname.group.cbegin(),
495  artsname.group.cend(),
496  [metname = x.name](auto& y) {
497  return (y.first + String("Create")) == metname;
498  }))
499  continue;
500 
501  // Describe the method
502  std::cout << "/*! " << x.desc << '\n';
503  for (auto a : x.authors) std::cout << "@author " << a << '\n';
504  std::cout << "\n"
505  "@param[in,out] Workspace ws - An ARTS workspace\n";
506  for (std::size_t i = 0; i < x.gout.name.size(); i++)
507  std::cout << "@param[out] " << x.gout.name[i] << " - " << x.gout.desc[i]
508  << "\n";
509  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
510  std::cout << "@param[in] " << x.gin.name[i] << " - " << x.gin.desc[i];
511  if (x.gin.hasdefs[i]) std::cout << " (default: " << x.gin.defs[i] << ")";
512  std::cout << '\n';
513  }
514  std::cout << "\nUse the ARTS documentation to read more on how the "
515  "workspace is manipulated\n";
516  std::cout << "This interface function has been automatically generated\n";
517  std::cout << "*/" << '\n';
518 
519  // Make the function
520  std::cout << "inline void " << x.name << "(\n Workspace& ws";
521 
522  // First put all GOUT variables
523  for (std::size_t i = 0; i < x.gout.group.size(); i++) {
524  std::cout << ',' << "\n Var::" << x.gout.group[i] << ' '
525  << x.gout.name[i];
526  }
527 
528  // Second put all GIN variables that have no default argument
529  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
530  if (not x.gin.hasdefs[i]) {
531  std::cout << ',' << "\n "
532  << "const Var::" << x.gin.group[i] << ' ' << x.gin.name[i];
533  }
534  }
535 
536  // Lastly put all GIN variables that have a default argument
537  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
538  if (x.gin.hasdefs[i]) {
539  if (x.gin.defs[i] == "{}") {
540  std::cout << ',' << "\n "
541  << "const Var::" << x.gin.group[i] << ' ' << x.gin.name[i]
542  << '=' << "Group::" << x.gin.group[i] << x.gin.defs[i];
543  } else {
544  std::cout << ',' << "\n "
545  << "const Var::" << x.gin.group[i] << ' ' << x.gin.name[i]
546  << '=' << "Group::" << x.gin.group[i] << '{'
547  << x.gin.defs[i] << '}';
548  }
549  }
550  }
551 
552  // End of function definition and open function block
553  std::cout << ')' << ' ' << '{' << '\n';
554 
555  // Output variables have to be on the Workspace
556  if (x.gout.group.size()) std::cout << ' ';
557  for (std::size_t i = 0; i < x.gout.group.size(); i++) {
558  std::cout << " if (" << x.gout.name[i]
559  << ".islast()) {\n throw std::runtime_error(\""
560  << x.gout.name[i] << " needs to be a defined Workspace"
561  << x.gout.group[i] << " since it is output of " << x.name
562  << "\");\n }";
563  }
564  if (x.gout.group.size()) std::cout << '\n' << '\n';
565 
566  // Call the ARTS auto_md.h function
567  std::cout << ' ' << ' ' << x.name << '(';
568 
569  // We need the workspace if we input an Agenda or simply pass the workspace
570  bool has_any = false;
571  if (x.pass_workspace or x.agenda_method or
572  std::any_of(
573  x.gin.group.cbegin(),
574  x.gin.group.cend(),
575  [](auto& g) { return g == "Agenda" or g == "ArrayOfAgenda"; }) or
576  std::any_of(x.in.varname.cbegin(), x.in.varname.cend(), [&](auto& g) {
577  return artsname.varname_group.at(g).varname_group == "Agenda" or
578  artsname.varname_group.at(g).varname_group == "ArrayOfAgenda";
579  })) {
580  std::cout << "ws";
581  has_any = true;
582  }
583 
584  // First are all the outputs
585  for (std::size_t i = 0; i < x.out.varname.size(); i++) {
586  if (has_any) std::cout << ',' << ' ';
587  has_any = true;
588  std::cout << "Var::" << x.out.varname[i] << "(ws).value()";
589  }
590 
591  // Second comes all the generic outputs
592  for (std::size_t i = 0; i < x.gout.name.size(); i++) {
593  if (has_any) std::cout << ',' << ' ';
594  has_any = true;
595  std::cout << x.gout.name[i];
596  std::cout << ".value()";
597  }
598 
599  // And their filenames if relevant
600  if (x.pass_wsv_names) {
601  for (std::size_t i = 0; i < x.gout.name.size(); i++) {
602  if (has_any) std::cout << ',' << ' ';
603  has_any = true;
604  std::cout << x.gout.name[i] << ".name()";
605  }
606  }
607 
608  // Then come all the inputs that are not also outputs
609  for (std::size_t i = 0; i < x.in.varname.size(); i++) {
610  if (std::any_of(
611  x.out.varname.cbegin(),
612  x.out.varname.cend(),
613  [in = x.in.varname[i]](const auto& out) { return in == out; }))
614  continue;
615  if (has_any) std::cout << ',' << ' ';
616  has_any = true;
617  std::cout << "Var::" << x.in.varname[i] << "(ws).value()";
618  }
619 
620  // Lastly are all the generic inputs, which cannot also be outputs
621  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
622  if (has_any) std::cout << ',' << ' ';
623  has_any = true;
624  std::cout << x.gin.name[i];
625  std::cout << ".value()";
626  }
627 
628  // And their filenames if relevant
629  if (x.pass_wsv_names) {
630  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
631  if (has_any) std::cout << ',' << ' ';
632  has_any = true;
633  std::cout << x.gin.name[i] << ".islast() ? Group::String{\""
634  << x.gin.name[i] << "\"} : " << x.gin.name[i] << ".name()";
635  }
636  }
637 
638  // Check verbosity
639  const bool has_verbosity =
640  std::any_of(x.in.varname.cbegin(), x.in.varname.cend(), [](auto& name) {
641  return name == "verbosity";
642  });
643 
644  // Add verbosity of it does not exist
645  if (not has_verbosity) {
646  if (has_any) std::cout << ',' << ' ';
647  has_any = true;
648  std::cout << "Var::verbosity(ws).value()";
649  }
650 
651  // Close the function call and the function itself
652  std::cout << ')' << ';' << '\n' << '}' << '\n' << '\n' << '\n';
653  }
654  std::cout << "} // ARTS::Method \n\n";
655 
656  std::cout << "namespace ARTS::AgendaMethod {\n";
657 
658  for (auto& x : artsname.methodname_method) {
659  // Skip methods using verbosity and Agenda methods (for now)
660  if (x.agenda_method) continue;
661 
662  // Also skip create methods since these must be called via Var
663  if (std::any_of(artsname.group.cbegin(),
664  artsname.group.cend(),
665  [metname = x.name](auto& y) {
666  return (y.first + String("Create")) == metname;
667  }))
668  continue;
669 
670  // Describe the method
671  std::cout << "/*! " << x.desc << '\n';
672  for (auto a : x.authors) std::cout << "@author " << a << '\n';
673  std::cout << "\n"
674  "@param[in,out] Workspace ws - An ARTS workspace\n";
675  for (std::size_t i = 0; i < x.gout.name.size(); i++)
676  std::cout << "@param[out] " << x.gout.name[i] << " - " << x.gout.desc[i]
677  << "\n";
678  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
679  std::cout << "@param[in] " << x.gin.name[i] << " - " << x.gin.desc[i];
680  if (x.gin.hasdefs[i]) std::cout << " (default: " << x.gin.defs[i] << ")";
681  std::cout << '\n';
682  }
683  std::cout << "\nUse the ARTS documentation to read more on how the "
684  "workspace is manipulated\n";
685  std::cout << "This interface function has been automatically generated\n";
686  std::cout << "\n"
687  << "@return MRecord to call this method\n";
688  std::cout << "*/" << '\n';
689 
690  // Make the function
691  std::cout << "[[nodiscard]] inline\nMRecord " << x.name
692  << "(\n [[maybe_unused]] Workspace& ws";
693 
694  // Check if we have the first input
695  for (std::size_t i = 0; i < x.gout.group.size(); i++) {
696  std::cout << ',' << '\n';
697  std::cout << " Var::" << x.gout.group[i] << ' '
698  << x.gout.name[i];
699  }
700 
701  // Second put all GIN variables that have no default argument
702  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
703  if (not x.gin.hasdefs[i]) {
704  std::cout << ',' << "\n";
705  std::cout << " const Var::" << x.gin.group[i] << ' '
706  << x.gin.name[i];
707  }
708  }
709 
710  // Lastly put all GIN variables that have a default argument
711  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
712  if (x.gin.hasdefs[i]) {
713  std::cout << ',' << "\n";
714  std::cout << " const Var::" << x.gin.group[i] << '&'
715  << ' ' << x.gin.name[i] << '=' << "{}";
716  }
717  }
718 
719  // End of function definition and open function block
720  std::cout << ')' << ' ' << '{' << '\n';
721 
722  // Output variables have to be on the Workspace
723  if (x.gout.group.size() or x.gin.group.size()) std::cout << ' ';
724  for (std::size_t i = 0; i < x.gout.group.size(); i++) {
725  std::cout << " if (" << x.gout.name[i]
726  << ".islast()) {\n throw std::runtime_error(\""
727  << x.gout.name[i] << " needs to be a defined Workspace"
728  << x.gout.group[i] << " since it is output of " << x.name
729  << "\");\n }";
730  }
731  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
732  if (x.gin.hasdefs[i])
733  std::cout << " if (not " << x.gin.name[i] << ".isnull() and "
734  << x.gin.name[i]
735  << ".islast()) {\n throw std::runtime_error(\""
736  << x.gin.name[i] << " needs to be a defined Workspace"
737  << x.gin.group[i]
738  << " (or left default) since it is agenda input to " << x.name
739  << "\");\n }";
740  else
741  std::cout << " if (" << x.gin.name[i]
742  << ".islast()) {\n throw std::runtime_error(\""
743  << x.gin.name[i] << " needs to be a defined Workspace"
744  << x.gin.group[i] << " since it is agenda input to " << x.name
745  << "\");\n }";
746  }
747  if (x.gout.group.size() or x.gin.group.size()) std::cout << '\n' << '\n';
748 
749  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
750  if (x.gin.hasdefs[i]) {
751  std::cout
752  << " static const auto " << x.gin.name[i]
753  << "_default = Var::" << x.gin.group[i] << "Create(ws, "
754  << x.gin.defs[i] << ",\n \"" << x.name << '_' << x.gin.name[i]
755  << "_autodefault"
756  << "\",\n \"auto generated variable with default from method "
757  "definition\");\n";
758  }
759  }
760 
761  // Call the ARTS auto_md.h function
762  std::cout << " return MRecord(" << x.pos << ',' << ' '
763  << "\n Group::ArrayOfIndex(" << '{';
764 
765  // First are all the outputs
766  for (std::size_t i = 0; i < x.out.varpos.size(); i++) {
767  std::cout << x.out.varpos[i] << ',' << ' ';
768  }
769 
770  // Second comes all the generic outputs
771  for (std::size_t i = 0; i < x.gout.name.size(); i++) {
772  std::cout << "Group::Index(" << x.gout.name[i] << ".pos())" << ',' << ' ';
773  }
774  std::cout << '}' << ')' << ',' << ' ' << "\n Group::ArrayOfIndex("
775  << '{';
776 
777  // Then come all the inputs that are not also outputs
778  for (std::size_t i = 0; i < x.in.varpos.size(); i++) {
779  std::cout << x.in.varpos[i] << ',' << ' ';
780  }
781 
782  // Lastly are all the generic inputs, which cannot also be outputs
783  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
784  if (x.gin.hasdefs[i])
785  std::cout << x.gin.name[i] << ".isnull() ? Index(" << x.gin.name[i]
786  << "_default.pos()) : ";
787  std::cout << "Group::Index(" << x.gin.name[i] << ".pos())" << ',' << ' ';
788  }
789 
790  std::cout << '}' << ')' << ',' << ' ';
791 
792  if (x.set_method)
793  std::cout << "\n TokVal{" << x.gin.name[0] << ".value()}";
794  else
795  std::cout << "\n TokVal{}";
796 
797  std::cout << ", Agenda{}";
798 
799  // Close the function call and the function itself
800  std::cout << ')' << ';' << '\n' << '}' << '\n' << '\n' << '\n';
801  }
802  std::cout << "} // ARTS::AgendaMethod \n\n";
803 
804  std::cout << "namespace ARTS::AgendaExecute { \n\n";
805  for (auto& x : artsname.agendaname_agenda) {
806  std::cout << "/*! " << x.second.desc << '\n'
807  << "@param[in,out] Workspace ws - An ARTS workspace\n"
808  << "*/\n"
809  << "inline void " << x.first << "(Workspace& ws) {\n " << x.first
810  << "Execute(ws";
811  for (auto& name : x.second.outs) {
812  std::cout << ',' << "\n " << ' ' << "Var::" << name
813  << "(ws).value()";
814  }
815  for (auto& name : x.second.ins) {
816  if (not std::any_of(x.second.outs.cbegin(),
817  x.second.outs.cend(),
818  [name](auto& outname) { return name == outname; }))
819  std::cout << ',' << "\n " << ' ' << "Var::" << name
820  << "(ws).value()";
821  }
822  std::cout << ",\n Var::" << x.first << "(ws).value());\n}\n\n";
823  }
824  std::cout << "} // ARTS::AgendaExecute \n\n";
825 
826  std::cout << "namespace ARTS::AgendaDefine { \n";
827  std::cout << "/*! Append Records to an agenda */\n";
828  std::cout << "template <typename ... Records>\nvoid Append(Agenda& ag, "
829  "Records ... records) {\n"
830  << " for (auto& x: { MRecord(records)... })\n "
831  "ag.push_back(x);\n}\n\n";
832  for (auto& x : artsname.agendaname_agenda) {
833  if (artsname.varname_group.at(x.first).varname_group == "ArrayOfAgenda")
834  continue;
835  std::cout << "/*! " << x.second.desc << '\n'
836  << "@param[in,out] Workspace ws - An ARTS workspace\n"
837  << "@param[in] MRecords records - Any number of ARTS methods "
838  "from ARTS::AgendaMethod\n"
839  << "*/\n"
840  << "template <typename ... Records> "
841  << "inline\nvoid " << x.first
842  << "(Workspace& ws, Records ... records) {\n"
843  << " ARTS::Var::" << x.first << "(ws).value().resize(0);\n"
844  << " ARTS::Var::" << x.first << "(ws).value().set_name(\""
845  << x.first << "\");\n"
846  << " Append(ARTS::Var::" << x.first
847  << "(ws).value(), records...);"
848  << "\n"
849  << " Var::" << x.first
850  << "(ws).value().check(ws, Var::verbosity(ws).value());\n}\n\n";
851  }
852  std::cout << "} // ARTS::AgendaDefine \n\n";
853 
854  // Make the main "startup"
855  std::cout << "namespace ARTS {\n";
856  std::cout << "/*! Create a Workspace and set its main verbosity\n\n"
857  << " @param[in] screen Screen verbosity\n"
858  << " @param[in] file File verbosity\n"
859  << " @param[in] agenda Agenda verbosity\n"
860  << " @param[in] basename Default basename for output variables\n"
861  << " @param[in] numthreads OpenMP thread count (defaults to max if invalid count)\n"
862  << " @return Workspace a full ARTS Workspace\n"
863  << "*/\n";
864  std::cout
865  << "inline Workspace init(std::size_t screen=0, std::size_t file=0, std::size_t agenda=0, const Group::String& basename=\"arts\", int numthreads=0) {\n"
866 #ifdef _OPENMP
867  " omp_set_num_threads(numthreads < 1 ? arts_omp_get_max_threads() : numthreads > arts_omp_get_max_threads() ? arts_omp_get_max_threads() : numthreads);\n"
868  "\n"
869 #endif
870  " define_wsv_group_names();\n"
871  " Workspace::define_wsv_data();\n"
872  " Workspace::define_wsv_map();\n"
873  " define_md_data_raw();\n"
874  " expand_md_data_raw_to_md_data();\n"
875  " define_md_map();\n"
876  " define_agenda_data();\n"
877  " define_agenda_map();\n"
878  " define_species_data();\n"
879  " define_species_map();\n"
880  " global_data::workspace_memory_handler.initialize();\n"
881  "\n"
882  " Workspace ws;\n"
883  " ws.initialize();\n"
884  " Var::verbosity(ws).value().set_screen_verbosity(screen);\n"
885  " Var::verbosity(ws).value().set_agenda_verbosity(agenda);\n"
886  " Var::verbosity(ws).value().set_file_verbosity(file);\n"
887  " Var::verbosity(ws).value().set_main_agenda(1);\n"
888  "\n"
889  " out_basename = basename;\n"
890  "\n"
891  " #ifndef NDEBUG\n"
892  " ws.context = \"\";\n"
893  " #endif\n"
894  "\n"
895  " return ws;\n"
896  "}\n";
897  std::cout << "} // namespace::ARTS\n\n";
898 
899  std::cout << "#endif // autoarts_h\n\n";
900 }
define_species_map
void define_species_map()
Definition: species_data.cc:1069
Workspace::wsv_data
static Array< WsvRecord > wsv_data
Global WSV data.
Definition: workspace_ng.h:58
Method::Out
Definition: make_autoarts_h.cc:36
auto_md.h
Method::inoutvarpos
std::vector< std::size_t > inoutvarpos
Definition: make_autoarts_h.cc:55
define_agenda_data
void define_agenda_data()
Definition: agendas.cc:44
Group::varname_group
std::string varname_group
Definition: make_autoarts_h.cc:11
NameMaps::NameMaps
NameMaps()
Definition: make_autoarts_h.cc:352
agendas
std::map< std::string, AgendaData > agendas()
Definition: make_autoarts_h.cc:305
Method
Definition: make_autoarts_h.cc:16
Method::Gin::hasdefs
std::vector< bool > hasdefs
Definition: make_autoarts_h.cc:22
NameMaps::methodname_method
std::vector< Method > methodname_method
Definition: make_autoarts_h.cc:348
NameMaps::varname_group
std::map< std::string, Group > varname_group
Definition: make_autoarts_h.cc:349
Method::Gout::name
std::vector< std::string > name
Definition: make_autoarts_h.cc:28
Method::pass_wsv_names
bool pass_wsv_names
Definition: make_autoarts_h.cc:50
Method::Gin::group
std::vector< std::string > group
Definition: make_autoarts_h.cc:19
global_data::AgendaMap
map< String, Index > AgendaMap
The map associated with agenda_data.
Definition: agenda_record.cc:35
ARTS::Var::y
Vector y(Workspace &ws) noexcept
Definition: autoarts.h:7401
Method::pass_workspace
bool pass_workspace
Definition: make_autoarts_h.cc:49
Method::supergeneric
bool supergeneric
Definition: make_autoarts_h.cc:47
ARTS::Var::Vector::pos
std::size_t pos() const noexcept
Definition: autoarts.h:1678
Group
Definition: make_autoarts_h.cc:10
Method::Gout::group
std::vector< std::string > group
Definition: make_autoarts_h.cc:27
Method::Out::varname
std::vector< std::string > varname
Definition: make_autoarts_h.cc:37
groups
std::map< std::string, Group > groups()
Definition: make_autoarts_h.cc:65
AgendaData::outs
std::vector< std::string > outs
Definition: make_autoarts_h.cc:62
Method::Gout::desc
std::vector< std::string > desc
Definition: make_autoarts_h.cc:26
methods
std::vector< Method > methods()
Definition: make_autoarts_h.cc:129
Method::gout
Gout gout
Definition: make_autoarts_h.cc:54
Method::in
In in
Definition: make_autoarts_h.cc:51
Group::artspos
std::size_t artspos
Definition: make_autoarts_h.cc:13
Method::out
Out out
Definition: make_autoarts_h.cc:53
NODEF
#define NODEF
Definition: methods.h:35
Method::Gin::name
std::vector< std::string > name
Definition: make_autoarts_h.cc:20
Method::desc
std::string desc
Definition: make_autoarts_h.cc:43
global_data::MdMap
const map< String, Index > MdMap
The map associated with md_data.
Definition: methods_aux.cc:39
Workspace::define_wsv_data
static void define_wsv_data()
Define workspace variables.
Definition: workspace.cc:39
NameMaps::agendaname_agenda
std::map< std::string, AgendaData > agendaname_agenda
Definition: make_autoarts_h.cc:347
Method::authors
std::vector< std::string > authors
Definition: make_autoarts_h.cc:44
AgendaData::ins
std::vector< std::string > ins
Definition: make_autoarts_h.cc:61
AgendaData::desc
std::string desc
Definition: make_autoarts_h.cc:60
expand_md_data_raw_to_md_data
void expand_md_data_raw_to_md_data()
Expand supergeneric methods.
Definition: methods_aux.cc:410
Method::In::varname
std::vector< std::string > varname
Definition: make_autoarts_h.cc:32
define_wsv_group_names
void define_wsv_group_names()
Define the array of workspace variable group names.
Definition: groups.cc:77
Method::agenda_method
bool agenda_method
Definition: make_autoarts_h.cc:46
global_data.h
global_data::WsvGroupMap
const map< String, Index > WsvGroupMap
The map associated with wsv_group_names.
Definition: groups.cc:41
Method::Gin::defs
std::vector< std::string > defs
Definition: make_autoarts_h.cc:21
global_data::md_data
const Array< MdRecord > md_data
Lookup information for workspace methods.
Definition: interactive_workspace.cc:19
Method::Gin::desc
std::vector< std::string > desc
Definition: make_autoarts_h.cc:18
Method::gin
Gin gin
Definition: make_autoarts_h.cc:52
Method::pos
std::size_t pos
Definition: make_autoarts_h.cc:42
fixed_defaults
std::pair< std::vector< std::string >, std::vector< bool > > fixed_defaults(const std::vector< std::string > &vargroups, const std::vector< std::string > &vardefaults)
Definition: make_autoarts_h.cc:87
define_agenda_map
void define_agenda_map()
Definition: agenda_record.cc:95
Group::varname_desc
std::string varname_desc
Definition: make_autoarts_h.cc:12
Method::name
std::string name
Definition: make_autoarts_h.cc:41
Method::uses_templates
bool uses_templates
Definition: make_autoarts_h.cc:48
Method::Gin
Definition: make_autoarts_h.cc:17
Method::set_method
bool set_method
Definition: make_autoarts_h.cc:45
NameMaps::group
std::map< std::string, std::size_t > group
Definition: make_autoarts_h.cc:350
String
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:280
Method::In
Definition: make_autoarts_h.cc:31
Workspace::WsvMap
static map< String, Index > WsvMap
Global map associated with wsv_data.
Definition: workspace_ng.h:61
Method::Gout
Definition: make_autoarts_h.cc:25
ARTS::Var::Vector::name
const Group::String & name() const noexcept
Definition: autoarts.h:1681
global_data::agenda_data
const Array< AgRecord > agenda_data
The lookup information for the agendas.
Definition: agendas.cc:41
Method::Out::varpos
std::vector< std::size_t > varpos
Definition: make_autoarts_h.cc:38
ARTS::Var::x
Vector x(Workspace &ws) noexcept
Definition: autoarts.h:7346
define_species_data
void define_species_data()
Definition: species_data.cc:158
define_md_map
void define_md_map()
Define MdMap.
Definition: methods_aux.cc:473
Workspace::define_wsv_map
static void define_wsv_map()
Map WSV names to indices.
Definition: workspace_ng.cc:48
AgendaData
Definition: make_autoarts_h.cc:58
Method::In::varpos
std::vector< std::size_t > varpos
Definition: make_autoarts_h.cc:33
NameMaps
Definition: make_autoarts_h.cc:346
main
int main()
Definition: make_autoarts_h.cc:360
define_md_data_raw
void define_md_data_raw()
Definition: methods.cc:191
AgendaData::pos
std::size_t pos
Definition: make_autoarts_h.cc:59