ARTS 2.5.11 (git: 6827797f)
agenda_class.cc
Go to the documentation of this file.
1
9#include <algorithm>
10#include <iterator>
11#include <memory>
12#include <ostream>
13
14#include "agenda_class.h"
15#include "agenda_record.h" // only for test functions
16#include "arts.h"
17#include "arts_omp.h"
18#include "auto_md.h"
19#include "debug.h"
20#include "global_data.h"
21#include "messages.h"
22#include "methods.h"
23#include "tokval.h"
24#include "workspace_ng.h"
25
26MRecord::MRecord() : moutput(), minput(), msetvalue(), mtasks() {}
27
29 : moutput(), minput(), msetvalue(), mtasks(ws) {}
30
31MRecord::MRecord(const Index id,
32 ArrayOfIndex output,
33 ArrayOfIndex input,
34 const TokVal& setvalue,
35 const Agenda& tasks,
36 bool internal)
37 : mid(id),
38 moutput(std::move(output)),
39 minput(std::move(input)),
40 msetvalue(setvalue),
41 mtasks(tasks),
42 minternal(internal) {
43}
44
45
47 : ws(workspace.weak_from_this()),
48 mname(),
49 mml(),
50 moutput_push(),
51 moutput_dup() {}
52
54
68void Agenda::append(const String& methodname, const TokVal& keywordvalue) {
70
71 const auto i2 = MdMap.find(methodname);
72 ARTS_ASSERT(i2 != MdMap.end());
73 Index id = i2->second;
74
76 ArrayOfIndex output = md_data[id].Out();
77
78 // Find explicit method id in MdMap.
79 ArrayOfIndex input = md_data[id].InOnly();
80
81 mml.push_back(MRecord(id, output, input, keywordvalue, Agenda(*workspace())));
82 mchecked = false;
83}
84
86
90void Agenda::check(Workspace& ws_in, const Verbosity& verbosity) {
91 // Check that this agenda has a default workspace
92 if (not workspace().get()) {
93 mchecked = false;
94 return;
95 }
96
97 // Check that this workspace lives on ws_in
99 "Agendas must share workspace"
100 )
101
102 // Make external data visible
105
106 // First we have to find the lookup information for this agenda. We
107 // use AgendaMap for this.
108
109 auto mi = AgendaMap.find(mname);
110
111 // Find return end() if the string is not found. This means we deal with
112 // agenda defined in the control file and therefore we don't check its
113 // consistency. Custom agendas can't be executed and we delay the check
114 // until it is copied to a predefined agenda.
115 if (mi == AgendaMap.end()) {
116 mchecked = false;
117 return;
118 }
119
120 const AgRecord& this_data = agenda_data[mi->second];
121
122 // Ok, we have the lookup data now.
123
124 // Check that the output produced by the actual methods in the
125 // agenda corresponds to what is desired in the lookup data:
126 for (Index i = 0; i < this_data.Out().nelem(); ++i) {
127 // The WSV for which to check:
128 Index this_wsv = this_data.Out()[i];
129
130 if (!is_output(this_wsv)) {
131 ostringstream os;
132 os << "The agenda " << mname << " must generate the output WSV "
133 << (*ws_in.wsv_data_ptr)[this_wsv].Name() << ",\n"
134 << "but it does not. It only generates:\n";
135 for (Index j = 0; j < (*ws_in.wsv_data_ptr).nelem(); ++j)
136 if (is_output(j)) os << (*ws_in.wsv_data_ptr)[j].Name() << "\n";
137 throw runtime_error(os.str());
138 }
139 }
140
141 // Check that the input used by the actual methods in the
142 // agenda corresponds to what is desired in the lookup data:
143 for (Index i = 0; i < this_data.In().nelem(); ++i) {
144 // The WSV for which to check:
145 Index this_wsv = this_data.In()[i];
146
147 if (!is_input(ws_in, this_wsv)) {
148 ostringstream os;
149 os << "The agenda " << mname << " must use the input WSV "
150 << (*ws_in.wsv_data_ptr)[this_wsv].Name() << ",\n"
151 << "but it does not. It only uses:\n";
152 for (Index j = 0; j < (*ws_in.wsv_data_ptr).nelem(); ++j)
153 if (is_input(ws_in, j)) os << (*ws_in.wsv_data_ptr)[j].Name() << "\n";
154 throw runtime_error(os.str());
155 }
156 }
157
159
160 mchecked = true;
161}
162
164
169void Agenda::execute(Workspace& ws_in) const {
170 ARTS_USER_ERROR_IF (not mchecked, "Agenda *", mname, R"--(* hasn't been checked for consistency yet.
171
172This check is usually done by AgendaSet or AgendaAppend.
173
174There are three possible causes for this:
175 1) Custom agenda: You're trying to execute an agenda that has been
176 created manually. This is not allowed. You have to use one of
177 the predefined agendas and execute that one.
178 2) Developer error: If you have written code that modifies an Agenda
179 directly (changing its name or altering its method list), it's up
180 to you to call Agenda::check in your code after your modifications.
181 3) Workspace mismatch: All Agendas live on the workspace and can only
182 be executed by the workspace, or a child of the workspace, that
183 was originally connected to the workspace.
184)--")
185
187 not has_same_origin(ws_in), mname, " is on another original workspace.")
188
189 // An empty Agenda name indicates that something going wrong here
190 ARTS_ASSERT(mname != "");
191
192 // The method description lookup table:
194
195 // The array holding the pointers to the getaway functions:
196 extern void (*getaways[])(Workspace&, const MRecord&);
197
198 const Index wsv_id_verbosity = ws_in.WsvMap_ptr->at("verbosity");
199 ws_in.duplicate(wsv_id_verbosity);
200
201 Verbosity& averbosity =
202 *(static_cast<Verbosity*>(ws_in[wsv_id_verbosity].get()));
203
204 averbosity.set_main_agenda(is_main_agenda());
205
206 ArtsOut1 aout1(averbosity);
207 {
208 // ostringstream os; // disabled for performance reasons
209 // os << "Executing " << name() << "\n"
210 // << "{\n";
211 // aout1 << os.str();
212 aout1 << "Executing " << name() << "\n"
213 << "{\n";
214 }
215
216 for (Index i = 0; i < mml.nelem(); ++i) {
217 const Verbosity& verbosity =
218 *static_cast<Verbosity*>(ws_in[wsv_id_verbosity].get());
221
222 // Runtime method data for this method:
223 const MRecord& mrr = mml[i];
224 // Method data for this method:
225 const MdRecord& mdd = md_data[mrr.Id()];
226
227 try {
228 {
229 if (mrr.isInternal()) {
230 out3 << "- " + mdd.Name() + "\n";
231 } else {
232 out1 << "- " + mdd.Name() + "\n";
233 }
234 }
235
236 { // Check if all input variables are initialized:
237 const ArrayOfIndex& v(mrr.In());
238 for (Index s = 0; s < v.nelem(); ++s) {
239 if ((s != v.nelem() - 1 || !mdd.SetMethod()) &&
240 !ws_in.is_initialized(v[s]))
241 throw runtime_error(
242 "Method " + mdd.Name() +
243 " needs input variable: " + (*ws_in.wsv_data_ptr)[v[s]].Name());
244 }
245 }
246
247 { // Check if all output variables which are also used as input
248 // are initialized
249 const ArrayOfIndex& v = mdd.InOut();
250 for (Index s = 0; s < v.nelem(); ++s)
251 if (!ws_in.is_initialized(mrr.Out()[v[s]]))
252 throw runtime_error("Method " + mdd.Name() +
253 " needs input variable: " +
254 (*ws_in.wsv_data_ptr)[mrr.Out()[v[s]]].Name());
255 }
256
257 // Call the getaway function:
258 getaways[mrr.Id()](ws_in, mrr);
259
260 } catch (const std::bad_alloc& x) {
261 aout1 << "}\n";
262
263 ostringstream os;
264 os << "Memory allocation error in method: " << mdd.Name() << '\n'
265 << "For memory intensive jobs it could help to limit the\n"
266 << "number of threads with the -n option.\n"
267 << x.what();
268
269 throw runtime_error(os.str());
270 } catch (const std::exception& x) {
271 aout1 << "}\n";
272
273 ostringstream os;
274 os << "Run-time error in method: " << mdd.Name() << '\n' << x.what();
275
276 throw runtime_error(os.str());
277 }
278 }
279
280 aout1 << "}\n";
281
282 ws_in.pop(wsv_id_verbosity);
283}
284
286
295 using global_data::MdMap;
297
298 set<Index> inputs;
299 set<Index> outputs;
300 set<Index> outs2push;
301 set<Index> outs2dup;
302
303 const Index WsmAgendaExecuteIndex = MdMap.find("AgendaExecute")->second;
304 const Index WsmAgendaExecuteExclIndex =
305 MdMap.find("AgendaExecuteExclusive")->second;
306 const Index WsmDeleteIndex = MdMap.find("Delete")->second;
307 const Index WsvAgendaGroupIndex = WsvGroupMap.find("Agenda")->second;
308
309 for (auto & method : mml) {
310 // Collect output WSVs
311 const ArrayOfIndex& gouts = method.Out();
312
313 // Put the outputs into a new set to sort them. Otherwise
314 // set_intersection and set_difference screw up.
315 set<Index> souts;
316 souts.insert(gouts.begin(), gouts.end());
317
318 // Collect generic input WSVs
319 const ArrayOfIndex& gins = method.In();
320 inputs.insert(gins.begin(), gins.end());
321
322 /* Special case: For the Delete WSM add its input to the list
323 * of output variables to force a duplication of those variables.
324 * It avoids deleting variables outside the agenda's scope.
325 */
326 if (method.Id() == WsmDeleteIndex) {
327 souts.insert(gins.begin(), gins.end());
328 }
329
330 /* Special case: For WSMs that execute generic input Agendas
331 it is necessary for proper scoping to also add the output and input variables of the
332 agenda to our output and input variable lists.
333 */
334 if (method.Id() == WsmAgendaExecuteIndex ||
335 method.Id() == WsmAgendaExecuteExclIndex) {
336 for (Index j = 0; j < md_data[method.Id()].GInType().nelem(); j++) {
337 if (md_data[method.Id()].GInType()[j] == WsvAgendaGroupIndex) {
338 const String& agenda_name = (*workspace()->wsv_data_ptr)[gins[j]].Name();
339 const auto agenda_it =
340 AgendaMap.find(agenda_name);
341 // The executed agenda must not be a user created agenda
342 if (agenda_it == AgendaMap.end()) {
343 ostringstream os;
344 os << "Manual execution of the agenda \"" << agenda_name
345 << "\" is not supported.";
346 throw std::runtime_error(os.str());
347 }
348 const ArrayOfIndex& agouts = agenda_data[agenda_it->second].Out();
349 souts.insert(agouts.begin(), agouts.end());
350 const ArrayOfIndex& agins = agenda_data[agenda_it->second].In();
351 inputs.insert(agins.begin(), agins.end());
352 }
353 }
354 }
355
356 // Add all outputs of this WSM to global list of outputs
357 outputs.insert(souts.begin(), souts.end());
358
359 // Find out all output WSVs of current WSM which were
360 // already used as input. We have to place a copy of them on
361 // the WSV stack.
362 set_intersection(souts.begin(),
363 souts.end(),
364 inputs.begin(),
365 inputs.end(),
366 insert_iterator<set<Index> >(outs2dup, outs2dup.begin()));
367
368 // Get a handle on the InOut list for the current method:
369 const ArrayOfIndex& mdinout = md_data[method.Id()].InOut();
370 const ArrayOfIndex& output = method.Out();
371
372 for (Index j = 0; j < mdinout.nelem(); j++) {
373 inputs.insert(output[mdinout[j]]);
374 }
375 }
376
377 // Find all outputs which are not in the list of WSVs to duplicate
378 set_difference(outputs.begin(),
379 outputs.end(),
380 outs2dup.begin(),
381 outs2dup.end(),
382 insert_iterator<set<Index> >(outs2push, outs2push.begin()));
383
384 const auto [ain, aout] = get_global_inout();
385
386 // We have to build a new set of agenda input and output because the
387 // set_difference function only works properly on sorted input.
388 set<Index> saout;
389 set<Index> sain;
390
391 saout.insert(aout.begin(), aout.end());
392 sain.insert(ain.begin(), ain.end());
393
394 moutput_push.clear();
395 moutput_dup.clear();
396
397 // Remove the WSVs which are agenda input from the list of
398 // output variables for which we have to create an new
399 // entry on the stack. This is already done for agenda inputs.
400 set<Index> outs2push_without_agenda_input;
401 set_difference(
402 outs2push.begin(),
403 outs2push.end(),
404 sain.begin(),
405 sain.end(),
406 insert_iterator<set<Index> >(outs2push_without_agenda_input,
407 outs2push_without_agenda_input.begin()));
408
409 // Same for agenda output variables.
410 set_difference(
411 outs2push_without_agenda_input.begin(),
412 outs2push_without_agenda_input.end(),
413 saout.begin(),
414 saout.end(),
415 insert_iterator<ArrayOfIndex>(moutput_push, moutput_push.begin()));
416
417 // Remove the WSVs which are agenda input from the list of
418 // output variables for which we have to create a duplicate
419 // on the stack. This is already done for agenda inputs.
420 set<Index> outs2dup_without_agenda_input;
421 set_difference(
422 outs2dup.begin(),
423 outs2dup.end(),
424 sain.begin(),
425 sain.end(),
426 insert_iterator<set<Index> >(outs2dup_without_agenda_input,
427 outs2dup_without_agenda_input.begin()));
428
429 // Same for agenda output variables.
430 set_difference(
431 outs2dup_without_agenda_input.begin(),
432 outs2dup_without_agenda_input.end(),
433 saout.begin(),
434 saout.end(),
435 insert_iterator<ArrayOfIndex>(moutput_dup, moutput_dup.begin()));
436
437 // Special case: Variables which are defined in the agenda only
438 // as output but are used first as input in one of the WSMs
439 // For those the current WSV value must be copied to the agenda
440 // input variable
441 set<Index> saout_only;
442
443 set_difference(saout.begin(),
444 saout.end(),
445 sain.begin(),
446 sain.end(),
447 insert_iterator<set<Index> >(saout_only, saout_only.begin()));
448
449 ArrayOfIndex agenda_only_out_wsm_in;
450 set_intersection(outs2dup.begin(),
451 outs2dup.end(),
452 saout_only.begin(),
453 saout_only.end(),
454 insert_iterator<ArrayOfIndex>(
455 agenda_only_out_wsm_in, agenda_only_out_wsm_in.begin()));
456
457 // Special case: Variables which are defined in the agenda only
458 // as input but are used as output in one of the WSMs
459 // For those the current WSV value must be copied to the agenda
460 // input variable
461 set<Index> sain_only;
462
463 set_difference(sain.begin(),
464 sain.end(),
465 saout.begin(),
466 saout.end(),
467 insert_iterator<set<Index> >(sain_only, sain_only.begin()));
468
469 ArrayOfIndex agenda_only_in_wsm_out;
470 set_intersection(outs2push.begin(),
471 outs2push.end(),
472 sain_only.begin(),
473 sain_only.end(),
474 insert_iterator<ArrayOfIndex>(
475 agenda_only_in_wsm_out, agenda_only_in_wsm_out.begin()));
476
478
479 out3 << " [Agenda::pushpop] : " << name() << "\n";
480 out3 << " [Agenda::pushpop] - # Funcs in Ag : " << mml.nelem() << "\n";
481 out3 << " [Agenda::pushpop] - AgOut : ";
482 PrintWsvNames(out3, *workspace(), aout);
483 out3 << "\n";
484 out3 << " [Agenda::pushpop] - AgIn : ";
485 PrintWsvNames(out3, *workspace(), ain);
486 out3 << "\n";
487 out3 << " [Agenda::pushpop] - All WSM output: ";
488 PrintWsvNames(out3, *workspace(), outputs);
489 out3 << "\n";
490 out3 << " [Agenda::pushpop] - All WSM input : ";
491 PrintWsvNames(out3, *workspace(), inputs);
492 out3 << "\n";
493 out3 << " [Agenda::pushpop] - Output WSVs push : ";
495 out3 << "\n";
496 out3 << " [Agenda::pushpop] - Output WSVs dup : ";
498 out3 << "\n";
499 out3 << " [Agenda::pushpop] - Ag inp dup : ";
500 PrintWsvNames(out3, *workspace(), agenda_only_in_wsm_out);
501 out3 << "\n";
502 out3 << " [Agenda::pushpop] - Ag out dup : ";
503 PrintWsvNames(out3, *workspace(), agenda_only_out_wsm_in);
504 out3 << "\n";
505}
506
508
516bool Agenda::is_input(Workspace& ws_in, Index var) const {
517 // Make global method data visible:
521 using global_data::MdMap;
523
524 const Index WsmAgendaExecuteIndex = MdMap.find("AgendaExecute")->second;
525 const Index WsmAgendaExecuteExclIndex =
526 MdMap.find("AgendaExecuteExclusive")->second;
527
528 // Make sure that var is the index of a valid WSV:
529 ARTS_ASSERT(0 <= var);
530 ARTS_ASSERT(var < (*ws_in.wsv_data_ptr).nelem());
531
532 // Determine the index of WsvGroup Agenda
533 const Index WsvAgendaGroupIndex = WsvGroupMap.find("Agenda")->second;
534
535 // Loop all methods in this agenda:
536 for (Index i = 0; i < nelem(); ++i) {
537 // Get a handle on this methods runtime data record:
538 const MRecord& this_method = mml[i];
539
540 // Is var a generic input?
541 {
542 // Get a handle on the Input list:
543 const ArrayOfIndex& input = this_method.In();
544
545 for (Index j = 0; j < input.nelem(); ++j) {
546 if (var == input[j]) return true;
547 }
548
549 // Get a handle on the InOut list for the current method:
550 const ArrayOfIndex& mdinout = md_data[this_method.Id()].InOut();
551 const ArrayOfIndex& output = this_method.Out();
552
553 for (Index j = 0; j < mdinout.nelem(); j++) {
554 if (var == output[mdinout[j]]) return true;
555 }
556
557 /* Special case: For WSMs that execute generic input Agendas
558 it is necessary to check their inputs.
559 */
560 if (this_method.Id() == WsmAgendaExecuteIndex ||
561 this_method.Id() == WsmAgendaExecuteExclIndex) {
562 for (Index j = 0; j < md_data[this_method.Id()].GInType().nelem();
563 j++) {
564 if (md_data[this_method.Id()].GInType()[j] == WsvAgendaGroupIndex) {
565 const String& agenda_name = (*ws_in.wsv_data_ptr)[input[j]].Name();
566 const auto agenda_it =
567 AgendaMap.find(agenda_name);
568 // The executed agenda must not be a user created agenda
569 if (agenda_it == AgendaMap.end()) {
570 ostringstream os;
571 os << "Manual execution of the agenda \"" << agenda_name
572 << "\" is not supported.";
573 throw std::runtime_error(os.str());
574 }
575 const ArrayOfIndex& agins = agenda_data[agenda_it->second].In();
576 for (Index k = 0; k < agins.nelem(); ++k) {
577 if (var == agins[k]) return true;
578 }
579 }
580 }
581 }
582 }
583 }
584
585 // Ok, that means var is no input at all.
586 return false;
587}
588
590
598bool Agenda::is_output(Index var) const {
599 // Make global method data visible:
603 using global_data::MdMap;
605
606 const Index WsmAgendaExecuteIndex = MdMap.find("AgendaExecute")->second;
607 const Index WsmAgendaExecuteExclIndex =
608 MdMap.find("AgendaExecuteExclusive")->second;
609
610 // Determine the index of WsvGroup Agenda
611 const Index WsvAgendaGroupIndex = WsvGroupMap.find("Agenda")->second;
612
613 // Loop all methods in this agenda:
614 for (Index i = 0; i < nelem(); ++i) {
615 // Get a handle on this methods runtime data record:
616 const MRecord& this_method = mml[i];
617
618 // Is var a generic output?
619 {
620 // Get a handle on the Output list:
621 const ArrayOfIndex& output = this_method.Out();
622
623 for (Index j = 0; j < output.nelem(); ++j) {
624 if (var == output[j]) return true;
625 }
626
627 /* Special case: For WSMs that execute generic input Agendas
628 it is necessary to check their outputs.
629 */
630 if (this_method.Id() == WsmAgendaExecuteIndex ||
631 this_method.Id() == WsmAgendaExecuteExclIndex) {
632 for (Index j = 0; j < md_data[this_method.Id()].GInType().nelem();
633 j++) {
634 if (md_data[this_method.Id()].GInType()[j] == WsvAgendaGroupIndex) {
635 const String& agenda_name =
636 (*workspace()->wsv_data_ptr)[this_method.In()[j]].Name();
637 const auto agenda_it =
638 AgendaMap.find(agenda_name);
639 // The executed agenda must not be a user created agenda
640 if (agenda_it == AgendaMap.end()) {
641 ostringstream os;
642 os << "Manual execution of the agenda \"" << agenda_name
643 << "\" is not supported.";
644 throw std::runtime_error(os.str());
645 }
646 const ArrayOfIndex& agouts = agenda_data[agenda_it->second].Out();
647 for (Index k = 0; k < agouts.nelem(); k++)
648 if (agouts[k] == var) return true;
649 }
650 }
651 }
652 }
653 }
654
655 // Ok, that means var is no output at all.
656 return false;
657}
658
660
665void Agenda::set_name(const String& nname) {
666 mname = nname;
667 mchecked = false;
668}
669
671
676String Agenda::name() const { return mname; }
677
679
690bool Agenda::has_method(const String& methodname) const {
692
693 bool found = false;
694 for (auto it = mml.begin();
695 !found && it != mml.end();
696 it++) {
697 if (md_data[it->Id()].Name() == methodname) found = true;
698 }
699
700 return found;
701}
702
704 mml = ml;
705 mchecked = false;
706}
707
709
719void Agenda::print(ostream& os, const String& indent) const {
720 for (Index i = 0; i < mml.nelem(); ++i) {
721 // Print member methods with 3 characters more indentation:
722 mml[i].print(os, indent);
723 }
724}
725
727
730void Agenda::resize(Index n) { mml.resize(n); }
731
733
739Index Agenda::nelem() const { return mml.nelem(); }
740
742
748 mml.push_back(n);
749 mchecked = false;
750}
751
753 ws = x.ws;
754 mml = x.mml;
755 mname = x.mname;
758 mchecked = x.mchecked;
759 return *this;
760}
761
762bool Agenda::has_same_origin(const Workspace& ws2) const {return workspace()->original_workspace == ws2.original_workspace;}
763
764std::shared_ptr<Workspace> Agenda::workspace() const {
765 auto workspace = ws.lock();
766 ARTS_USER_ERROR_IF(workspace == nullptr,
767 "This agenda does not contain a valid Workspace.\n"
768 "The workspace might have gotten deleted, or\n"
769 "you're accessing a default-constructed agenda.");
770 return workspace;
771}
772
774
785ostream& operator<<(ostream& os, const Agenda& a) {
786 // Print agenda as it would apear in a controlfile.
787 a.print(os, " ");
788 return os;
789}
790
791//--------------------------------
792// Functions for MRecord:
793//--------------------------------
794
796
816void MRecord::print(ostream& os, const String& indent) const {
818
819 // Get a handle on the right record:
820 const MdRecord& tmd = md_data[Id()];
821
822 os << indent << tmd.Name();
823
824 // Is this a generic method? -- Then we need round braces.
825 if (0 != tmd.GOutType().nelem() + tmd.GInType().nelem()) {
826 // First entry needs no leading comma:
827 bool first = true;
828
829 os << "(";
830
831 for (Index i = 0; i < Out().nelem(); ++i) {
832 if (first)
833 first = false;
834 else
835 os << ",";
836
837 os << mtasks.workspace()->wsv_data_ptr->operator[](Out()[i]).Name();
838 }
839
840 for (Index i = 0; i < In().nelem(); ++i) {
841 if (first)
842 first = false;
843 else
844 os << ",";
845
846 os << mtasks.workspace()->wsv_data_ptr->operator[](In()[i]).Name();
847 }
848
849 os << ")";
850 }
851
852 if (0 != Tasks().nelem()) {
853 os << " {\n";
854 Tasks().print(os, indent + " ");
855 os << indent << "}\n";
856 } else
857 os << "\n";
858}
859
861 mid = x.mid;
862
864
865 moutput = x.moutput;
866
867 minput = x.minput;
868
869 mtasks = x.mtasks;
870
871 return *this;
872}
873
874void MRecord::ginput_only(ArrayOfIndex& ginonly) const {
875 ginonly = minput; // Input
876 for (auto j = moutput.begin(); j < moutput.end(); ++j)
877 for (auto k = ginonly.begin(); k < ginonly.end(); ++k)
878 if (*j == *k) {
879 // erase_vector_element(vi,k);
880 k = ginonly.erase(k) - 1;
881 // We need the -1 here, otherwise due to the
882 // following increment we would miss the element
883 // behind the erased one, which is now at the
884 // position of the erased one.
885 }
886}
887
889
900ostream& operator<<(ostream& os, const MRecord& a) {
901 a.print(os, "");
902 return os;
903}
904
906 ArrayOfAgenda out;
907 for (auto& ag : agendas) out.push_back(ag.deepcopy_if(ws));
908 return out;
909}
910
911// Method to share indices of variables from one workspace to another
913 const Workspace& ws_in,
914 const ArrayOfIndex& vars) {
915 return ws_out.wsvs(ws_in.wsvs(vars));
916}
917
919 if (mtasks.has_same_origin(workspace)) return *this;
920
921 MRecord out(workspace);
922
923 out.mid = mid;
924 out.moutput = make_same_wsvs(workspace, *mtasks.workspace(), moutput);
925 out.minput = make_same_wsvs(workspace, *mtasks.workspace(), minput);
926 out.msetvalue = msetvalue;
927 out.mtasks = mtasks.deepcopy_if(workspace);
928 out.minternal = minternal;
929
930 return out;
931}
932
934 if (has_same_origin(workspace)) return *this;
935
936 Agenda out(workspace);
937 out.mname = mname;
938 for (auto& method : mml) out.mml.push_back(method.deepcopy_if(workspace));
942 out.mchecked = mchecked;
943
944 return out;
945}
946
947std::pair<ArrayOfIndex, ArrayOfIndex> Agenda::get_global_inout() const {
950 ArrayOfIndex aout;
951 ArrayOfIndex ain;
952 if (auto agenda_it = AgendaMap.find(name());
953 agenda_it != AgendaMap.end()) {
954 const AgRecord& agr = agenda_data[agenda_it->second];
955 aout = agr.Out();
956 ain = agr.In();
957 }
958 return {ain, aout};
959}
960
962 ws = x.shared_from_this();
963 for (auto& mr: mml) {
964 mr.set_workspace(x);
965 }
966}
967
970 if (msetvalue.holdsAgenda()) {
972 a.set_workspace(x);
973 msetvalue = a;
974 } else if (msetvalue.holdsArrayOfAgenda()) {
976 for (auto& b: a) b.set_workspace(x);
977 msetvalue = a;
978 }
979}
ArrayOfIndex make_same_wsvs(Workspace &ws_out, const Workspace &ws_in, const ArrayOfIndex &vars)
ArrayOfAgenda deepcopy_if(Workspace &ws, const ArrayOfAgenda &agendas)
Same as Agenda member method but for an entire array.
ostream & operator<<(ostream &os, const Agenda &a)
Output operator for Agenda.
Declarations for agendas.
void PrintWsvNames(OutputStream &outstream, const Workspace &ws, const Container &container)
Print list of WSV names to output stream.
Definition: agenda_class.h:35
Declarations for AgRecord, storing lookup information for one agenda.
The global header file for ARTS.
Header file for helper functions for OpenMP.
void(* getaways[])(Workspace &, const MRecord &)
Definition: auto_md.cc:22522
Lookup information for one agenda.
Definition: agenda_record.h:26
const ArrayOfIndex & Out() const
Definition: agenda_record.h:44
const ArrayOfIndex & In() const
Definition: agenda_record.h:45
The Agenda class.
Definition: agenda_class.h:52
bool mchecked
Flag indicating that the agenda was checked for consistency.
Definition: agenda_class.h:114
bool has_same_origin(const Workspace &ws2) const
void print(ostream &os, const String &indent) const
Print an agenda.
std::weak_ptr< Workspace > ws
Definition: agenda_class.h:102
void append(const String &methodname, const TokVal &keywordvalue)
Appends methods to an agenda.
Definition: agenda_class.cc:68
String name() const
Agenda name.
Array< MRecord > mml
Definition: agenda_class.h:104
void execute(Workspace &ws_in) const
Execute an agenda.
bool has_method(const String &methodname) const
Check if method is in Agenda.
void set_workspace(Workspace &x)
bool is_output(Index var) const
Check if given variable is agenda output.
bool main_agenda
Is set to true if this is the main agenda.
Definition: agenda_class.h:111
void set_methods(const Array< MRecord > &ml)
void check(Workspace &ws_in, const Verbosity &verbosity)
Checks consistency of an agenda.
Definition: agenda_class.cc:90
bool is_input(Workspace &ws_in, Index var) const
Check if given variable is agenda input.
Agenda & operator=(const Agenda &x)
std::pair< ArrayOfIndex, ArrayOfIndex > get_global_inout() const
Get index lists of global input and output variables from agenda_data of this agenda.
void set_outputs_to_push_and_dup(const Verbosity &verbosity)
Retrieve indexes of all input and output WSVs.
void push_back(const MRecord &n)
Append a new method to end of list.
Agenda deepcopy_if(Workspace &) const
Creates a deep copy of the agenda if necessary (i.e., different workspace)!
Agenda()=default
String mname
Definition: agenda_class.h:103
void resize(Index n)
Resize the method list.
ArrayOfIndex moutput_push
Definition: agenda_class.h:106
std::shared_ptr< Workspace > workspace() const
void set_name(const String &nname)
Set agenda name.
ArrayOfIndex moutput_dup
Definition: agenda_class.h:108
bool is_main_agenda() const
Definition: agenda_class.h:84
Index nelem() const
Return the number of agenda elements.
Index nelem() const ARTS_NOEXCEPT
Definition: array.h:75
Method runtime data.
Definition: agenda_class.h:125
Agenda mtasks
An agenda, which can be given in the controlfile instead of keywords.
Definition: agenda_class.h:211
const ArrayOfIndex & In() const
Definition: agenda_class.h:142
ArrayOfIndex minput
Input workspace variables.
Definition: agenda_class.h:206
void set_workspace(Workspace &x)
MRecord & operator=(const MRecord &x)
Assignment operator for MRecord.
const Agenda & Tasks() const
Definition: agenda_class.h:144
void print(ostream &os, const String &indent) const
Print an MRecord.
bool minternal
Flag if this method is called internally by the engine.
Definition: agenda_class.h:213
MRecord deepcopy_if(Workspace &) const
Creates a deep copy of the method if necessary (i.e., different workspace)!
ArrayOfIndex moutput
Output workspace variables.
Definition: agenda_class.h:204
Index Id() const
Definition: agenda_class.h:140
Index mid
Method id.
Definition: agenda_class.h:202
void ginput_only(ArrayOfIndex &ginonly) const
Get list of generic input only WSVs.
bool isInternal() const
Indicates the origin of this method.
Definition: agenda_class.h:157
const ArrayOfIndex & Out() const
Definition: agenda_class.h:141
TokVal msetvalue
Keyword value for Set methods.
Definition: agenda_class.h:208
All information for one workspace method.
Definition: methods.h:21
const String & Name() const
Definition: methods.h:68
const ArrayOfIndex & GOutType() const
Definition: methods.h:73
const ArrayOfIndex & InOut() const
Definition: methods.h:83
bool SetMethod() const
Definition: methods.h:85
const ArrayOfIndex & GInType() const
Definition: methods.h:78
Definition: tokval.h:244
bool holdsAgenda() const
Definition: tokval.cc:202
bool holdsArrayOfAgenda() const
Definition: tokval.cc:205
void set_main_agenda(bool main_agenda)
Definition: messages.h:55
Workspace class.
Definition: workspace_ng.h:36
std::shared_ptr< wsv_data_type > wsv_data_ptr
Definition: workspace_ng.h:59
void pop(Index i)
Remove the topmost WSV from its stack.
Definition: workspace_ng.cc:92
T * get(const char *name)
Retrieve a value ptr if it exist (FIXME: C++20 allows const char* as template argument)
Definition: workspace_ng.h:174
bool is_initialized(Index i) const
Checks existence of the given WSV.
wsv_data_type wsvs(const ArrayOfIndex &) const
Workspace * original_workspace
Definition: workspace_ng.h:64
void duplicate(Index i)
Duplicate WSV.
Definition: workspace_ng.cc:39
std::shared_ptr< WsvMap_type > WsvMap_ptr
Definition: workspace_ng.h:62
Helper macros for debugging.
#define ARTS_ASSERT(condition,...)
Definition: debug.h:84
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:135
Declarations having to do with the four output streams.
#define CREATE_OUT1
Definition: messages.h:187
#define CREATE_OUT3
Definition: messages.h:189
Declaration of the class MdRecord.
const Array< MdRecord > md_data
Lookup information for workspace methods.
Definition: methods_aux.cc:33
const map< String, Index > MdMap
The map associated with md_data.
Definition: methods_aux.cc:24
const Array< AgRecord > agenda_data
The lookup information for the agendas.
Definition: agendas.cc:24
const map< String, Index > WsvGroupMap
The map associated with wsv_groups.
Definition: groups.cc:24
map< String, Index > AgendaMap
The map associated with agenda_data.
Definition: mystring.h:246
#define v
#define a
#define b
This file contains the Workspace class.