ARTS  2.3.1285(git:92a29ea9-dirty)
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();
355  methodname_method = methods();
356  agendaname_agenda = agendas();
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 << "namespace ARTS { using Workspace=Workspace; }\n\n";
397  std::cout << "namespace ARTS::Group {\n";
398  for (auto& x : artsname.group) {
399  if (x.first == "Any") continue;
400  std::cout << "using " << x.first << '=' << x.first << ';' << '\n';
401  }
402  std::cout << "} // ARTS::Group \n\n";
403 
404  std::cout << "namespace ARTS::Var {\n";
405  for (auto& x : artsname.group) {
406  if (x.first == "Any") continue;
407 
408  std::cout << "class Workspace" << x.first << ' ' << '{' << '\n';
409  std::cout << " using type = Group::" << x.first << ";\n";
410  std::cout << " std::size_t p;\n";
411  std::cout << " type* v;\n";
412  std::cout << "public:\n";
413  std::cout << " Workspace" << x.first
414  << "() noexcept : p(std::numeric_limits<std::size_t>::max()), "
415  "v(nullptr) {}\n";
416  std::cout << " Workspace" << x.first << "(std::size_t i, void * x) noexcept : p(i), " "v(static_cast<type *>(x)) {}\n";
417  std::cout << " ~Workspace" << x.first << "() noexcept {if (islast() and not isnull()) delete v;}\n";
418  std::cout << " Workspace" << x.first << "(const type& val) noexcept : p(std::numeric_limits<std::size_t>::max()), v(new type(val)) {}\n";
419  std::cout << " type& value() noexcept {return *v;}\n";
420  std::cout << " const type& value() const noexcept {return *v;}\n";
421  std::cout
422  << " Workspace" << x.first
423  << "& operator=(const type& t) noexcept {value() = t; return *this;}\n";
424  std::cout << " std::size_t pos() const noexcept {return p;}\n";
425  std::cout << " bool isnull() const noexcept {return v == nullptr;}\n";
426  std::cout << " bool islast() const noexcept {return p == std::numeric_limits<std::size_t>::max();}\n";
427  std::cout << " const Group::String& name() const noexcept {return Workspace::wsv_data[p].Name();}\n";
428  std::cout << '}' << ';' << '\n' << '\n';
429  }
430  for (auto& x : artsname.varname_group) {
431  std::cout << "/*! " << x.second.varname_desc << '\n';
432  std::cout << "@param[in,out] Workspace ws - An ARTS workspace\n";
433  std::cout << "@return A class with a pointer to this variable and its "
434  "position in the workspace\n*/\n";
435  std::cout << "[[nodiscard]] inline ";
436  std::cout << "Workspace" << x.second.varname_group << ' ' << x.first
437  << "(Workspace& ws) "
438  "noexcept { "
439  "return {"
440  << x.second.artspos << ", ws[" << x.second.artspos
441  << "]}; "
442  "}\n\n";
443  }
444  for (auto& x : artsname.group) {
445  if (x.first == "Any") continue;
446 
447  std::cout << "/*! Creates in, and returns from, Workspace a/an " << x.first
448  << '\n'
449  << '\n';
450  std::cout << "@param[in,out] Workspace ws - An ARTS workspace\n";
451  std::cout << "@param[in] " << x.first
452  << " inval - The default value the variable will have in "
453  "the workspace\n";
454  std::cout << "@param[in] String name - The name the variable will have in "
455  "the workspace\n";
456  std::cout << "@param[in] String desc - The description the variable will "
457  "have in the workspace (default: \"nodescription\")\n";
458  std::cout << "@return A class with a pointer to this variable and its new "
459  "position in the workspace\n";
460  std::cout << "*/\n";
461  std::cout << "[[nodiscard]] inline\n";
462  std::cout << "Workspace" << x.first << ' ' << x.first
463  << "Create(\n Workspace& ws,\n const Group::"
464  << x.first
465  << "& inval,\n const Group::String& name,\n const Group::"
466  "String& "
467  "desc=\"nodescription\") {\n";
468  std::cout << " const std::size_t ind = "
469  "std::size_t(ws.add_wsv_inplace({name.c_str(), desc.c_str(), "
470  << x.second << "}));\n";
471  std::cout << " Workspace" << x.first << ' ' << "val{ind, ws[ind]};\n";
472  std::cout << " return val = inval;\n"
473  << "}\n\n";
474  }
475  std::cout << "} // ARTS::Var \n\n";
476 
477  std::cout << "namespace ARTS::Method {\n";
478 
479  for (auto& x : artsname.methodname_method) {
480  // Skip methods using verbosity and Agenda methods (for now)
481  if (x.agenda_method) continue;
482 
483  // Also skip create methods since these must be called via Var
484  if (std::any_of(artsname.group.cbegin(), artsname.group.cend(),
485  [metname = x.name](auto& y) {
486  return (y.first + String("Create")) == metname;
487  }))
488  continue;
489 
490  // Describe the method
491  std::cout << "/*! " << x.desc << '\n';
492  for (auto a : x.authors) std::cout << "@author " << a << '\n';
493  std::cout << "\n"
494  "@param[in,out] Workspace ws - An ARTS workspace\n";
495  for (std::size_t i = 0; i < x.gout.name.size(); i++)
496  std::cout << "@param[out] " << x.gout.name[i] << " - " << x.gout.desc[i]
497  << "\n";
498  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
499  std::cout << "@param[in] " << x.gin.name[i] << " - " << x.gin.desc[i];
500  if (x.gin.hasdefs[i]) std::cout << " (default: " << x.gin.defs[i] << ")";
501  std::cout << '\n';
502  }
503  std::cout << "\nUse the ARTS documentation to read more on how the "
504  "workspace is manipulated\n";
505  std::cout << "This interface function has been automatically generated\n";
506  std::cout << "*/" << '\n';
507 
508  // Make the function
509  std::cout << "inline void " << x.name << "(\n Workspace& ws";
510 
511  // First put all GOUT variables
512  for (std::size_t i = 0; i < x.gout.group.size(); i++) {
513  std::cout << ',' << "\n Var::Workspace" << x.gout.group[i] << ' '
514  << x.gout.name[i];
515  }
516 
517  // Second put all GIN variables that have no default argument
518  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
519  if (not x.gin.hasdefs[i]) {
520  std::cout << ',' << "\n "
521  << "const Var::Workspace" << x.gin.group[i] << ' '
522  << x.gin.name[i];
523  }
524  }
525 
526  // Lastly put all GIN variables that have a default argument
527  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
528  if (x.gin.hasdefs[i]) {
529  if (x.gin.defs[i] == "{}") {
530  std::cout << ',' << "\n "
531  << "const Var::Workspace" << x.gin.group[i] << ' ' << x.gin.name[i]
532  << '=' << "Group::" << x.gin.group[i] << x.gin.defs[i];
533  } else {
534  std::cout << ',' << "\n "
535  << "const Var::Workspace" << x.gin.group[i] << ' ' << x.gin.name[i]
536  << '=' << "Group::" << x.gin.group[i] << '{' << x.gin.defs[i] << '}';
537  }
538  }
539  }
540 
541  // End of function definition and open function block
542  std::cout << ')' << ' ' << '{' << '\n';
543 
544  // Output variables have to be on the Workspace
545  if (x.gout.group.size()) std::cout << ' ';
546  for (std::size_t i = 0; i < x.gout.group.size(); i++) {
547  std::cout << " if (" << x.gout.name[i] << ".islast()) {\n throw std::runtime_error(\""
548  << x.gout.name[i] << " needs to be a defined Workspace"
549  << x.gout.group[i] << " since it is output of "<<x.name<<"\");\n }";
550  }
551  if (x.gout.group.size()) std::cout << '\n' << '\n';
552 
553  // Call the ARTS auto_md.h function
554  std::cout << ' ' << ' ' << x.name << '(';
555 
556  // We need the workspace if we input an Agenda or simply pass the workspace
557  bool has_any = false;
558  if (x.pass_workspace or x.agenda_method or
559  std::any_of(
560  x.gin.group.cbegin(), x.gin.group.cend(),
561  [](auto& g) { return g == "Agenda" or g == "ArrayOfAgenda"; }) or
562  std::any_of(x.in.varname.cbegin(), x.in.varname.cend(), [&](auto& g) {
563  return artsname.varname_group.at(g).varname_group == "Agenda" or
564  artsname.varname_group.at(g).varname_group == "ArrayOfAgenda";
565  })) {
566  std::cout << "ws";
567  has_any = true;
568  }
569 
570  // First are all the outputs
571  for (std::size_t i = 0; i < x.out.varname.size(); i++) {
572  if (has_any) std::cout << ',' << ' ';
573  has_any = true;
574  std::cout << "Var::" << x.out.varname[i] << "(ws).value()";
575  }
576 
577  // Second comes all the generic outputs
578  for (std::size_t i = 0; i < x.gout.name.size(); i++) {
579  if (has_any) std::cout << ',' << ' ';
580  has_any = true;
581  std::cout << x.gout.name[i];
582  std::cout << ".value()";
583  }
584 
585  // And their filenames if relevant
586  if (x.pass_wsv_names) {
587  for (std::size_t i = 0; i < x.gout.name.size(); i++) {
588  if (has_any) std::cout << ',' << ' ';
589  has_any = true;
590  std::cout << x.gout.name[i] << ".name()";
591  }
592  }
593 
594  // Then come all the inputs that are not also outputs
595  for (std::size_t i = 0; i < x.in.varname.size(); i++) {
596  if (std::any_of(
597  x.out.varname.cbegin(), x.out.varname.cend(),
598  [in = x.in.varname[i]](const auto& out) { return in == out; }))
599  continue;
600  if (has_any) std::cout << ',' << ' ';
601  has_any = true;
602  std::cout << "Var::" << x.in.varname[i] << "(ws).value()";
603  }
604 
605  // Lastly are all the generic inputs, which cannot also be outputs
606  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
607  if (has_any) std::cout << ',' << ' ';
608  has_any = true;
609  std::cout << x.gin.name[i];
610  std::cout << ".value()";
611  }
612 
613  // And their filenames if relevant
614  if (x.pass_wsv_names) {
615  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
616  if (has_any) std::cout << ',' << ' ';
617  has_any = true;
618  std::cout << x.gin.name[i] << ".islast() ? Group::String{\"" << x.gin.name[i] << "\"} : " << x.gin.name[i] << ".name()";
619  }
620  }
621 
622  // Check verbosity
623  const bool has_verbosity =
624  std::any_of(x.in.varname.cbegin(), x.in.varname.cend(),
625  [](auto& name) { return name == "verbosity"; });
626 
627  // Add verbosity of it does not exist
628  if (not has_verbosity) {
629  if (has_any) std::cout << ',' << ' ';
630  has_any = true;
631  std::cout << "Var::verbosity(ws).value()";
632  }
633 
634  // Close the function call and the function itself
635  std::cout << ')' << ';' << '\n' << '}' << '\n' << '\n' << '\n';
636  }
637  std::cout << "} // ARTS::Method \n\n";
638 
639  std::cout << "namespace ARTS::AgendaMethod {\n";
640 
641  for (auto& x : artsname.methodname_method) {
642  // Skip methods using verbosity and Agenda methods (for now)
643  if (x.agenda_method) continue;
644 
645  // Also skip create methods since these must be called via Var
646  if (std::any_of(artsname.group.cbegin(), artsname.group.cend(),
647  [metname = x.name](auto& y) {
648  return (y.first + String("Create")) == metname;
649  }))
650  continue;
651 
652  // Describe the method
653  std::cout << "/*! " << x.desc << '\n';
654  for (auto a : x.authors) std::cout << "@author " << a << '\n';
655  std::cout << "\n"
656  "@param[in,out] Workspace ws - An ARTS workspace\n";
657  for (std::size_t i = 0; i < x.gout.name.size(); i++)
658  std::cout << "@param[out] " << x.gout.name[i] << " - " << x.gout.desc[i]
659  << "\n";
660  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
661  std::cout << "@param[in] " << x.gin.name[i] << " - " << x.gin.desc[i];
662  if (x.gin.hasdefs[i]) std::cout << " (default: " << x.gin.defs[i] << ")";
663  std::cout << '\n';
664  }
665  std::cout << "\nUse the ARTS documentation to read more on how the "
666  "workspace is manipulated\n";
667  std::cout << "This interface function has been automatically generated\n";
668  std::cout << "\n"
669  << "@return MRecord to call this method\n";
670  std::cout << "*/" << '\n';
671 
672  // Make the function
673  std::cout << "[[nodiscard]] inline\nMRecord " << x.name
674  << "(\n [[maybe_unused]] Workspace& ws";
675 
676  // Check if we have the first input
677  for (std::size_t i = 0; i < x.gout.group.size(); i++) {
678  std::cout << ',' << '\n';
679  std::cout << " Var::Workspace"
680  << x.gout.group[i] << ' ' << x.gout.name[i];
681  }
682 
683  // Second put all GIN variables that have no default argument
684  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
685  if (not x.gin.hasdefs[i]) {
686  std::cout << ',' << "\n";
687  std::cout << " const Var::Workspace"
688  << x.gin.group[i] << ' ' << x.gin.name[i];
689  }
690  }
691 
692  // Lastly put all GIN variables that have a default argument
693  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
694  if (x.gin.hasdefs[i]) {
695  std::cout << ',' << "\n";
696  std::cout << " const Var::Workspace"
697  << x.gin.group[i] << '&' << ' ' << x.gin.name[i] << '='
698  << "{}";
699  }
700  }
701 
702  // End of function definition and open function block
703  std::cout << ')' << ' ' << '{' << '\n';
704 
705  // Output variables have to be on the Workspace
706  if (x.gout.group.size() or x.gin.group.size()) std::cout << ' ';
707  for (std::size_t i = 0; i < x.gout.group.size(); i++) {
708  std::cout << " if (" << x.gout.name[i] << ".islast()) {\n throw std::runtime_error(\""
709  << x.gout.name[i] << " needs to be a defined Workspace"
710  << x.gout.group[i] << " since it is output of "<<x.name<<"\");\n }";
711  }
712  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
713  if (x.gin.hasdefs[i])
714  std::cout << " if (not " << x.gin.name[i] << ".isnull() and " << x.gin.name[i] << ".islast()) {\n throw std::runtime_error(\""
715  << x.gin.name[i] << " needs to be a defined Workspace"
716  << x.gin.group[i] << " (or left default) since it is agenda input to "<<x.name<<"\");\n }";
717  else
718  std::cout << " if (" << x.gin.name[i] << ".islast()) {\n throw std::runtime_error(\""
719  << x.gin.name[i] << " needs to be a defined Workspace"
720  << x.gin.group[i] << " since it is agenda input to "<<x.name<<"\");\n }";
721  }
722  if (x.gout.group.size() or x.gin.group.size()) std::cout << '\n' << '\n';
723 
724  for (std::size_t i = 0; i < x.gin.group.size(); i++) {
725  if (x.gin.hasdefs[i]) {
726  std::cout
727  << " static const auto " << x.gin.name[i]
728  << "_default = Var::" << x.gin.group[i] << "Create(ws, "
729  << x.gin.defs[i] << ",\n \"" << x.name << '_' << x.gin.name[i]
730  << "_autodefault"
731  << "\",\n \"auto generated variable with default from method "
732  "definition\");\n";
733  }
734  }
735 
736  // Call the ARTS auto_md.h function
737  std::cout << " return MRecord(" << x.pos << ',' << ' '
738  << "\n Group::ArrayOfIndex(" << '{';
739 
740  // First are all the outputs
741  for (std::size_t i = 0; i < x.out.varpos.size(); i++) {
742  std::cout << x.out.varpos[i] << ',' << ' ';
743  }
744 
745  // Second comes all the generic outputs
746  for (std::size_t i = 0; i < x.gout.name.size(); i++) {
747  std::cout << "Group::Index(" << x.gout.name[i] << ".pos())" << ',' << ' ';
748  }
749  std::cout << '}' << ')' << ',' << ' ' << "\n Group::ArrayOfIndex(" << '{';
750 
751  // Then come all the inputs that are not also outputs
752  for (std::size_t i = 0; i < x.in.varpos.size(); i++) {
753  std::cout << x.in.varpos[i] << ',' << ' ';
754  }
755 
756  // Lastly are all the generic inputs, which cannot also be outputs
757  for (std::size_t i = 0; i < x.gin.name.size(); i++) {
758  if (x.gin.hasdefs[i])
759  std::cout << x.gin.name[i] << ".isnull() ? Index(" << x.gin.name[i]
760  << "_default.pos()) : ";
761  std::cout << "Group::Index(" << x.gin.name[i] << ".pos())" << ',' << ' ';
762  }
763 
764  std::cout << '}' << ')' << ',' << ' ';
765 
766  if (x.set_method)
767  std::cout << "\n TokVal{" << x.gin.name[0] << ".value()}";
768  else
769  std::cout << "\n TokVal{}";
770 
771  std::cout << ", Agenda{}";
772 
773  // Close the function call and the function itself
774  std::cout << ')' << ';' << '\n' << '}' << '\n' << '\n' << '\n';
775  }
776  std::cout << "} // ARTS::AgendaMethod \n\n";
777 
778  std::cout << "namespace ARTS::AgendaExecute { \n\n";
779  for (auto& x : artsname.agendaname_agenda) {
780  std::cout << "/*! " << x.second.desc << '\n'
781  << "@param[in,out] Workspace ws - An ARTS workspace\n"
782  << "*/\n"
783  << "inline void " << x.first << "(Workspace& ws) {\n " << x.first
784  << "Execute(ws";
785  for (auto& name : x.second.outs) {
786  std::cout << ',' << "\n " << ' ' << "Var::" << name << "(ws).value()";
787  }
788  for (auto& name : x.second.ins) {
789  if (not std::any_of(x.second.outs.cbegin(), x.second.outs.cend(),
790  [name](auto& outname) { return name == outname; }))
791  std::cout << ',' << "\n " << ' ' << "Var::" << name
792  << "(ws).value()";
793  }
794  std::cout << ",\n Var::" << x.first << "(ws).value());\n}\n\n";
795  }
796  std::cout << "} // ARTS::AgendaExecute \n\n";
797 
798  std::cout << "namespace ARTS::AgendaDefine { \n";
799  std::cout << "/*! Append Records to an agenda */\n";
800  std::cout << "template <typename ... Records>\nvoid Append(Agenda& ag, "
801  "Records ... records) {\n"
802  << " for (auto& x: { MRecord(records)... })\n "
803  "ag.push_back(x);\n}\n\n";
804  for (auto& x : artsname.agendaname_agenda) {
805  if (artsname.varname_group.at(x.first).varname_group == "ArrayOfAgenda")
806  continue;
807  std::cout << "/*! " << x.second.desc << '\n'
808  << "@param[in,out] Workspace ws - An ARTS workspace\n"
809  << "@param[in] MRecords records - Any number of ARTS methods "
810  "from ARTS::AgendaMethod\n"
811  << "*/\n"
812  << "template <typename ... Records> "
813  << "inline\nvoid " << x.first
814  << "(Workspace& ws, Records ... records) {\n"
815  << " ARTS::Var::" << x.first << "(ws).value().resize(0);\n"
816  << " ARTS::Var::" << x.first << "(ws).value().set_name(\"" << x.first
817  << "\");\n"
818  << " Append(ARTS::Var::" << x.first << "(ws).value(), records...);"
819  << "\n"
820  << " Var::" << x.first
821  << "(ws).value().check(ws, Var::verbosity(ws).value());\n}\n\n";
822  }
823  std::cout << "} // ARTS::AgendaDefine \n\n";
824 
825  // Make the main "startup"
826  std::cout << "namespace ARTS {\n";
827  std::cout <<
828  "inline Workspace init(std::size_t screen=0, std::size_t file=0, std::size_t agenda=0) {\n"
829  " define_wsv_group_names();\n"
830  " Workspace::define_wsv_data();\n"
831  " Workspace::define_wsv_map();\n"
832  " define_md_data_raw();\n"
833  " expand_md_data_raw_to_md_data();\n"
834  " define_md_map();\n"
835  " define_agenda_data();\n"
836  " define_agenda_map();\n"
837  " define_species_data();\n"
838  " define_species_map();\n"
839  " global_data::workspace_memory_handler.initialize();\n"
840  "\n"
841  " Workspace ws;\n"
842  " ws.initialize();\n"
843  " Var::verbosity(ws).value().set_screen_verbosity(screen);\n"
844  " Var::verbosity(ws).value().set_agenda_verbosity(agenda);\n"
845  " Var::verbosity(ws).value().set_file_verbosity(file);\n"
846  " Var::verbosity(ws).value().set_main_agenda(1);\n"
847  "\n"
848  " #ifndef NDEBUG\n"
849  " ws.context = \"\";\n"
850  " #endif\n"
851  "\n"
852  " return ws;"
853  "}\n";
854  std::cout << "} // namespace::ARTS\n\n";
855 
856  std::cout << "#endif // autoarts_h\n\n";
857 }
static Array< WsvRecord > wsv_data
Global WSV data.
Definition: workspace_ng.h:58
void define_md_map()
Define MdMap.
Definition: methods_aux.cc:473
std::string varname_desc
std::vector< std::string > authors
map< String, Index > AgendaMap
The map associated with agenda_data.
std::vector< std::size_t > varpos
std::vector< std::size_t > varpos
std::map< std::string, AgendaData > agendaname_agenda
std::map< std::string, Group > groups()
std::vector< Method > methodname_method
std::vector< std::string > desc
std::vector< std::string > varname
void define_species_map()
bool uses_templates
std::map< std::string, std::size_t > group
void define_agenda_map()
void define_agenda_data()
Definition: agendas.cc:44
const map< String, Index > MdMap
The map associated with md_data.
Definition: methods_aux.cc:39
bool pass_workspace
std::vector< std::string > outs
std::vector< std::size_t > inoutvarpos
void expand_md_data_raw_to_md_data()
Expand supergeneric methods.
Definition: methods_aux.cc:410
std::string name
#define NODEF
Definition: methods.h:35
std::string varname_group
std::string desc
static void define_wsv_data()
Define workspace variables.
Definition: workspace.cc:39
std::size_t pos
bool agenda_method
std::vector< Method > methods()
std::vector< std::string > name
std::map< std::string, Group > varname_group
const Array< AgRecord > agenda_data
The lookup information for the agendas.
Definition: agendas.cc:41
std::vector< std::string > desc
std::vector< std::string > ins
std::vector< std::string > name
void define_species_data()
std::vector< std::string > group
std::vector< std::string > group
void define_wsv_group_names()
Define the array of workspace variable group names.
Definition: groups.cc:77
static map< String, Index > WsvMap
Global map associated with wsv_data.
Definition: workspace_ng.h:61
const map< String, Index > WsvGroupMap
The map associated with wsv_group_names.
Definition: groups.cc:41
std::size_t artspos
void define_md_data_raw()
Definition: methods.cc:191
std::string desc
std::size_t pos
bool set_method
const Array< MdRecord > md_data
Lookup information for workspace methods.
static void define_wsv_map()
Map WSV names to indices.
Definition: workspace_ng.cc:48
bool supergeneric
std::pair< std::vector< std::string >, std::vector< bool > > fixed_defaults(const std::vector< std::string > &vargroups, const std::vector< std::string > &vardefaults)
std::vector< std::string > varname
int main()
std::map< std::string, AgendaData > agendas()
std::vector< std::string > defs
std::vector< bool > hasdefs
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:280
bool pass_wsv_names