27 void align(ofstream& ofs,
bool& is_first_parameter,
const String& indent) {
29 if (is_first_parameter)
30 is_first_parameter =
false;
67 ofs <<
"// This file was generated automatically by make_auto_md_cc.cc.\n";
68 ofs <<
"// DO NOT EDIT !\n";
69 ofs <<
"// Generated: " << __DATE__ <<
", " << __TIME__ <<
"\n\n";
71 ofs <<
"#include \"arts.h\"\n"
72 <<
"#include \"auto_md.h\"\n"
73 <<
"#include \"wsv_aux.h\"\n"
74 <<
"#include \"mc_interp.h\"\n"
75 <<
"#include \"m_append.h\"\n"
76 <<
"#include \"m_delete.h\"\n"
77 <<
"#include \"m_copy.h\"\n"
78 <<
"#include \"m_conversion.h\"\n"
79 <<
"#include \"m_extract.h\"\n"
80 <<
"#include \"m_general.h\"\n"
81 <<
"#include \"m_gridded_fields.h\"\n"
82 <<
"#include \"m_ignore.h\"\n"
83 <<
"#include \"m_nc.h\"\n"
84 <<
"#include \"m_reduce.h\"\n"
85 <<
"#include \"m_select.h\"\n"
86 <<
"#include \"m_xml.h\"\n"
87 <<
"#include \"m_basic_types.h\"\n"
88 <<
"#include \"propagationmatrix.h\"\n"
89 <<
"#include \"transmissionmatrix.h\"\n"
90 <<
"#include \"agenda_record.h\"\n"
91 <<
"#include \"workspace_ng.h\"\n"
92 <<
"#include \"global_data.h\"\n"
93 <<
"#include \"absorptionlines.h\"\n"
100 for (
Index i = 0; i < n_md; ++i) {
105 bool is_first_parameter =
true;
112 bool pass_workspace =
false;
142 for (
Index j = 0; !pass_workspace && j < mdd.
In().
nelem(); j++) {
144 pass_workspace =
true;
152 pass_workspace =
true;
165 <<
"_g(Workspace&" << ws <<
", const MRecord&" << mr <<
")\n"
168 ofs <<
"void " << mdd.
Name() <<
"_g(Workspace&" << ws
169 <<
", const MRecord&" << mr <<
")\n"
180 bool output_only =
true;
181 for (ArrayOfIndex::const_iterator j = mdd.
In().begin();
189 if (output_only) voutonly.push_back(k);
194 for (
Index j = 0; j < voutonly.
nelem(); j++) {
195 ostringstream docstr;
196 docstr <<
" // " << wsv_data[vo[voutonly[j]]].Name() <<
"\n";
199 ostringstream initstr;
200 if (gname ==
"Numeric")
201 initstr <<
" = NAN;";
202 else if (gname ==
"Index")
205 initstr <<
" = " << gname <<
"();";
209 ofs <<
" if (mr.In().end() == find(mr.In().begin(), mr.In().end(),"
210 <<
" mr.Out()[" << voutonly[j] <<
"]))\n";
212 <<
" *)ws[mr.Out()[" << voutonly[j] <<
"]]))" << initstr.str();
217 ofs <<
" " << mdd.
Name() <<
"(";
221 is_first_parameter =
false;
233 align(ofs, is_first_parameter, indent);
236 <<
" *)ws[mr.Out()[" << j <<
"]])";
248 align(ofs, is_first_parameter, indent);
251 << j + vo.
nelem() <<
"]])";
258 align(ofs, is_first_parameter, indent);
260 ofs <<
"Workspace::wsv_data[mr.Out()[" << j + vo.
nelem()
268 align(ofs, is_first_parameter, indent);
272 <<
" *)ws[mr.In()[" << j <<
"]])";
275 <<
" *)ws[mr.In()[" << j <<
"]])";
283 align(ofs, is_first_parameter, indent);
285 ofs <<
"mr.SetValue()";
296 align(ofs, is_first_parameter, indent);
299 << j + vi.
nelem() <<
"]])";
306 align(ofs, is_first_parameter, indent);
308 ofs <<
"Workspace::wsv_data[mr.In()[" << j + vi.
nelem()
317 align(ofs, is_first_parameter, indent);
323 bool pass_verbosity =
true;
326 for (
Index j = 0; pass_verbosity && j < mdd.
In().
nelem(); j++) {
327 if (wsv_data[mdd.
In()[j]].Name() ==
"verbosity") {
328 pass_verbosity =
false;
333 for (
Index j = 0; pass_verbosity && j < mdd.
Out().
nelem(); j++) {
334 if (wsv_data[mdd.
Out()[j]].Name() ==
"verbosity") {
335 pass_verbosity =
false;
339 if (pass_verbosity) {
342 align(ofs, is_first_parameter, indent);
344 << verbosity_wsv_id <<
"])";
354 bool is_first_parameter =
true;
356 ofs <<
"// The array holding the pointers to the getaway functions.\n"
357 <<
"void (*getaways[])(Workspace&, const MRecord&)\n"
359 for (
Index i = 0; i < n_md; ++i) {
363 align(ofs, is_first_parameter, indent);
368 ofs << mdd.
Name() <<
"_g";
372 ofs <<
", nullptr};\n\n";
377 ofs <<
"void auto_md_agenda_execute_helper(bool& agenda_failed, String& agenda_error_msg, Workspace& ws, const Agenda& input_agenda)\n";
379 ofs <<
" const ArrayOfIndex& outputs_to_push = input_agenda.get_output2push();\n";
380 ofs <<
" const ArrayOfIndex& outputs_to_dup = input_agenda.get_output2dup();\n";
382 ofs <<
" for (auto&& i : outputs_to_push)\n";
384 ofs <<
" // Even if a variable is only used as WSM output inside this agenda,\n";
385 ofs <<
" // It is possible that it is used as input further down by another agenda,\n";
386 ofs <<
" // which we can't see here. Therefore initialized variables have to be\n";
387 ofs <<
" // duplicated.\n";
388 ofs <<
" if (ws.is_initialized(i))\n";
389 ofs <<
" ws.duplicate(i);\n";
391 ofs <<
" ws.push_uninitialized(i, NULL);\n";
394 ofs <<
" for (auto&& i : outputs_to_dup)\n";
395 ofs <<
" ws.duplicate(i);\n";
397 ofs <<
" agenda_failed = false;\n";
400 ofs <<
" input_agenda.execute(ws);\n";
402 ofs <<
" catch (const std::exception &e)\n";
404 ofs <<
" ostringstream os;\n";
405 ofs <<
" os << \"Run-time error in agenda: \"\n";
406 ofs <<
" << input_agenda.name() << \'\\n\' << e.what();\n";
407 ofs <<
" agenda_failed = true;\n";
408 ofs <<
" agenda_error_msg = os.str();\n";
411 ofs <<
" for (auto&& i : outputs_to_push)\n";
412 ofs <<
" ws.pop_free(i);\n";
414 ofs <<
" for (auto&& i : outputs_to_dup)\n";
415 ofs <<
" ws.pop_free(i);\n";
429 ostringstream ain_push_os, ain_pop_os;
430 ostringstream aout_push_os, aout_pop_os;
432 bool is_agenda_array = wsv_data[
get_wsv_id(agr.
Name())].Group() ==
440 if (is_agenda_array) {
441 ofs <<
" if (agenda_array_index < 0 || agenda_array_index >= input_agenda_array.nelem())\n"
443 <<
" std::ostringstream os;\n"
444 <<
" os << \"Agenda index \" << agenda_array_index\n"
445 <<
" << \" out of bounds. 0 <= index < \" << input_agenda_array.nelem();\n"
446 <<
" throw std::runtime_error(os.str());\n"
448 <<
" const Agenda& input_agenda = input_agenda_array[agenda_array_index];\n\n";
450 ofs <<
" using global_data::AgendaMap;\n"
451 <<
" using global_data::agenda_data;\n"
453 <<
" if (!input_agenda.checked())\n"
454 <<
" throw std::runtime_error(\"" << agr.
Name()
455 <<
" is uninitialized. Use *AgendaSet* to add methods to it.\\n"
456 <<
"Agenda variables defined in the controlfile cannot be executed.\\nThe agenda must "
457 <<
"be copied to a workspace variable for execution.\");\n"
459 <<
" const AgRecord& agr =\n"
460 <<
" agenda_data[AgendaMap.find (input_agenda.name ())->second];\n"
466 ArrayOfIndex::const_iterator it = agi.begin();
467 while (it != agi.end() && *it != ago[j]) it++;
468 if (it == agi.end()) {
469 aout_push_os <<
" ws.push_uninitialized (aout[" << j <<
"], "
470 <<
"(void *)&" << wsv_data[ago[j]].Name() <<
");\n";
472 aout_push_os <<
" ws.push (aout[" << j <<
"], "
473 <<
"(void *)&" << wsv_data[ago[j]].Name() <<
");\n";
475 aout_pop_os <<
" ws.pop (aout[" << j <<
"]);\n";
481 ArrayOfIndex::const_iterator it = ago.begin();
482 while (it != ago.end() && *it != agi[j]) it++;
483 if (it == ago.end()) {
484 ain_push_os <<
" ws.push (ain[" << j <<
"], "
485 <<
"(void *)&" << wsv_data[agi[j]].Name() <<
");\n";
486 ain_pop_os <<
" ws.pop (ain[" << j <<
"]);\n";
491 if (aout_push_os.str().length()) {
492 ofs <<
" const ArrayOfIndex& aout = agr.Out();\n";
493 ofs << aout_push_os.str() <<
"\n";
495 if (ain_push_os.str().length()) {
496 ofs <<
" const ArrayOfIndex& ain = agr.In();\n";
497 ofs << ain_push_os.str() <<
"\n";
500 ofs <<
" bool agenda_failed;\n";
501 ofs <<
" String agenda_error_msg;\n";
502 ofs <<
" auto_md_agenda_execute_helper(agenda_failed, agenda_error_msg, ws, input_agenda);\n\n";
504 if (aout_pop_os.str().length()) {
505 ofs << aout_pop_os.str() <<
"\n";
507 if (ain_pop_os.str().length()) {
508 ofs << ain_pop_os.str() <<
"\n";
511 ofs <<
" if (agenda_failed) throw runtime_error (agenda_error_msg);\n";
519 ofs <<
"/* Workspace method: Doxygen documentation will be auto-generated */\n"
520 <<
"void " << it <<
"Create(" << it <<
"& var, const Verbosity&)\n"
527 else if (it ==
"Numeric")
530 ofs <<
"var = " << it <<
"();";
535 }
catch (
const std::runtime_error&
x) {
536 cout <<
"Something went wrong. Message text:\n";
537 cout <<
x.what() <<
'\n';