ARTS  2.2.66
make_auto_md_cc.cc
Go to the documentation of this file.
1 /* Copyright (C) 2000-2012 Stefan Buehler <sbuehler@ltu.se>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
18 #include "arts.h"
19 #include "array.h"
20 #include "file.h"
21 #include "methods.h"
22 #include "workspace_ng.h"
23 #include "agenda_record.h"
24 #include "global_data.h"
25 
26 /* Adds commas and indentation to parameter lists. */
27 void align(ofstream& ofs, bool& is_first_parameter, const String& indent)
28 {
29  // Add comma and line break, if not first element:
30  if (is_first_parameter)
31  is_first_parameter = false;
32  else
33  {
34  ofs << ",\n";
35  // Make proper indentation:
36  ofs << indent;
37  }
38 }
39 
40 int main()
41 {
42  try
43  {
44  // Make the global data visible:
47  const Array<WsvRecord>& wsv_data = Workspace::wsv_data;
48 
49  // Initialize the wsv group name array:
51 
52  // Initialize wsv data.
54 
55  // Initialize WsvMap.
57 
58  // Initialize method data.
60 
61  // Expand supergeneric methods:
63 
64 
65  const Index n_md = md_data.nelem();
66 
67  // Write auto_md.cc:
68  // -----------
69  ofstream ofs;
70  open_output_file(ofs,"auto_md.cc");
71 
72  ofs << "// This file was generated automatically by make_auto_md_cc.cc.\n";
73  ofs << "// DO NOT EDIT !\n";
74  ofs << "// Generated: "
75  << __DATE__ << ", "
76  << __TIME__ << "\n\n";
77 
78  ofs << "#include \"arts.h\"\n"
79  << "#include \"make_array.h\"\n"
80  << "#include \"auto_md.h\"\n"
81  << "#include \"wsv_aux.h\"\n"
82  << "#include \"mc_interp.h\"\n"
83  << "#include \"m_append.h\"\n"
84  << "#include \"m_delete.h\"\n"
85  << "#include \"m_copy.h\"\n"
86  << "#include \"m_conversion.h\"\n"
87  << "#include \"m_extract.h\"\n"
88  << "#include \"m_general.h\"\n"
89  << "#include \"m_ignore.h\"\n"
90  << "#include \"m_nc.h\"\n"
91  << "#include \"m_reduce.h\"\n"
92  << "#include \"m_select.h\"\n"
93  << "#include \"m_xml.h\"\n"
94  << "#include \"m_basic_types.h\"\n"
95  << "#include \"agenda_record.h\"\n"
96  << "#include \"workspace_ng.h\"\n"
97  << "#include \"global_data.h\"\n"
98  << "\n";
99 
100  //ofs << "static Index agendacallcount = 0;\n";
101 
102  // Write all get-away functions:
103  // -----------------------------
104  for (Index i=0; i<n_md; ++i)
105  {
106  const MdRecord& mdd = md_data[i];
107 
108  // This is needed to flag the first function parameter, which
109  // needs no line break before being written:
110  bool is_first_parameter = true;
111  // The String indent is needed to achieve the correct
112  // indentation of the functin parameters:
113  String indent = String(mdd.Name().nelem()+3,' ');;
114  // Flag to pass the workspace to the WSM. Only true if the WSM has
115  // an Agenda as input.
116  bool pass_workspace = false;
117 
118  // There are four lists of parameters that we have to
119  // write.
120  ArrayOfIndex vo=mdd.Out(); // Output
121  const ArrayOfIndex& vi = mdd.InOnly(); // Input
122  ArrayOfIndex vgo=mdd.GOutType(); // Generic Output
123  ArrayOfIndex vgi=mdd.GInType(); // Generic Input
124  // vo and vi contain handles of workspace variables,
125  // vgo and vgi handles of workspace variable groups.
126 
127  // There used to be a similar block here for the generic
128  // input/output variables. However, this was a mistake. For
129  // example, if a method has a vector as generic input and a
130  // vector as generic output, this does not mean that it is
131  // the same vector!
132 
133  {
134 
135  String ws, mr;
136 
137  // Use parameter name only if it is used inside the function
138  // to avoid warnings
139  ws = " ws";
140 // if (!mdd.AgendaMethod() && !mdd.PassWorkspace() && !vo.nelem () && !vi.nelem () && !vgo.nelem () && !vgi.nelem ())
141 // {
142 // ws = "";
143 // }
144 
145  // Find out if the WSM gets an agenda as input. If so, pass
146  // the current workspace to this method
147  for (Index j = 0; !pass_workspace && j < mdd.In().nelem(); j++)
148  {
149  if (wsv_data[mdd.In()[j]].Group() == get_wsv_group_id ("Agenda"))
150  {
151  pass_workspace = true;
152  }
153  }
154 
155  // Find out if the WSM gets an agenda as input. If so, pass
156  // the current workspace to this method
157  for (Index j = 0; !pass_workspace && j < mdd.GInType().nelem(); j++)
158  {
159  if (mdd.GInType()[j] == get_wsv_group_id ("Agenda"))
160  {
161  pass_workspace = true;
162  }
163  }
164 
165  // Use parameter name only if it is used inside the function
166  // to avoid warnings
167  if ( vo.nelem () || vi.nelem () || vgo.nelem () || vgi.nelem ()
168  || mdd.AgendaMethod())
169  {
170  mr = " mr";
171  }
172 
173  if ( mdd.Supergeneric() )
174  {
175  ofs << "void " << mdd.Name()
176  << "_sg_" << mdd.ActualGroups()
177  << "_g(Workspace&" << ws
178  << ", const MRecord&" << mr << ")\n"
179  << "{\n";
180  }
181  else
182  {
183  ofs << "void " << mdd.Name()
184  << "_g(Workspace&" << ws
185  << ", const MRecord&" << mr << ")\n"
186  << "{\n";
187  }
188  }
189 
190  // Erase all Output only variables to uncover if they are
191  // misused as Input variables
192 #ifndef NDEBUG
193 #define DUMMY_ELEMS 0
194 #define DUMMY_COLS DUMMY_ELEMS
195 #define DUMMY_ROWS DUMMY_ELEMS
196 #define DUMMY_PAGES DUMMY_ELEMS
197 #define DUMMY_BOOKS DUMMY_ELEMS
198 #define DUMMY_SHELVES DUMMY_ELEMS
199 #define DUMMY_VITRINES DUMMY_ELEMS
200 #define DUMMY_LIBRARIES DUMMY_ELEMS
201 
202 
203  // Determine indexes of variables in vo that are only use as output
204  ArrayOfIndex voutonly; // Output only
205  for (Index k=0; k<vo.nelem(); ++k)
206  {
207  bool output_only = true;
208  for (ArrayOfIndex::const_iterator j=mdd.In().begin(); j != mdd.In().end(); ++j)
209  if (vo[k] == *j)
210  {
211  output_only = false;
212  break;
213  }
214 
215  if (output_only) voutonly.push_back(k);
216  }
217 
218  for (Index j=0; j < voutonly.nelem(); j++)
219  {
220  ostringstream docstr;
221  docstr << " " << "// " << wsv_data[vo[voutonly[j]]].Name() << " is Output only.\n";
222 
223  String gname = wsv_group_names[wsv_data[vo[voutonly[j]]].Group()];
224  ostringstream initstr;
225  if (gname == "Numeric")
226  initstr << " = NAN;";
227  else if (gname == "Index")
228  initstr << " = -1;";
229  else if (gname == "Vector")
230  initstr << ".resize(" << DUMMY_ELEMS << ");";
231  else if (gname == "Matrix")
232  initstr << ".resize(" << DUMMY_ROWS << ","
233  << DUMMY_COLS << ");";
234  else if (gname == "Tensor3")
235  initstr << ".resize("
236  << DUMMY_PAGES << ","
237  << DUMMY_ROWS << ","
238  << DUMMY_COLS << ");";
239  else if (gname == "Tensor4")
240  initstr << ".resize("
241  << DUMMY_BOOKS << ","
242  << DUMMY_PAGES << ","
243  << DUMMY_ROWS << ","
244  << DUMMY_COLS << ");";
245  else if (gname == "Tensor5")
246  initstr << ".resize("
247  << DUMMY_SHELVES << ","
248  << DUMMY_BOOKS << ","
249  << DUMMY_PAGES << ","
250  << DUMMY_ROWS << ","
251  << DUMMY_COLS << ");";
252  else if (gname == "Tensor6")
253  initstr << ".resize("
254  << DUMMY_VITRINES << ","
255  << DUMMY_SHELVES << ","
256  << DUMMY_BOOKS << ","
257  << DUMMY_PAGES << ","
258  << DUMMY_ROWS << ","
259  << DUMMY_COLS << ");";
260  else if (gname == "Tensor7")
261  initstr << ".resize("
262  << DUMMY_LIBRARIES << ","
263  << DUMMY_VITRINES << ","
264  << DUMMY_SHELVES << ","
265  << DUMMY_BOOKS << ","
266  << DUMMY_PAGES << ","
267  << DUMMY_ROWS << ","
268  << DUMMY_COLS << ");";
269 
270  if (initstr.str().length())
271  {
272  ofs << " (*(("
273  << wsv_group_names[wsv_data[vo[voutonly[j]]].Group()]
274  << " *)ws[mr.Out()[" << voutonly[j]
275  << "]]))" << initstr.str();
276  }
277  ofs << docstr.str();
278 
279  }
280 #endif /* NDEBUG */
281 
282  ofs << " " << mdd.Name() << "(";
283 
284  if (pass_workspace || mdd.PassWorkspace() || mdd.AgendaMethod())
285  {
286  ofs << "ws";
287  is_first_parameter = false;
288  }
289 
290  // Write the Output workspace variables:
291  for (Index j=0; j<vo.nelem(); ++j)
292  {
293  // Check by assert whether the group identifier is too
294  // large to correspond to a group. This can easily
295  // happen if somebody puts a variable identifier instead
296  // of a group identifier in the argument of GOUTPUT:
297  assert( wsv_data[vo[j]].Group() < wsv_group_names.nelem() );
298 
299  // Add comma and line break, if not first element:
300  align(ofs,is_first_parameter,indent);
301 
302  ofs << "*(("
303  << wsv_group_names[wsv_data[vo[j]].Group()]
304  << " *)ws[mr.Out()[" << j
305  << "]])";
306  }
307 
308  // Write the Generic output workspace variables:
309  for (Index j=0; j<vgo.nelem(); ++j)
310  {
311  // Check by assert whether the group identifier is too
312  // large to correspond to a group. This can easily
313  // happen if somebody puts a variable identifier instead
314  // of a group identifier in the argument of GOUTPUT:
315  assert( vgo[j] < wsv_group_names.nelem() );
316 
317  // Add comma and line break, if not first element:
318  align(ofs,is_first_parameter,indent);
319 
320  ofs << "*((" << wsv_group_names[vgo[j]]
321  << " *)ws[mr.Out()[" << j+vo.nelem()
322  << "]])";
323  }
324 
325  // Write the Generic output workspace variable names:
326  if (mdd.PassWsvNames())
327  {
328  for (Index j=0; j<vgo.nelem(); ++j)
329  {
330  // Add comma and line break, if not first element:
331  align(ofs,is_first_parameter,indent);
332 
333  ofs << "Workspace::wsv_data[mr.Out()["
334  << j+vo.nelem()
335  << "]].Name()";
336  }
337  }
338 
339  // Write the Input workspace variables:
340  for (Index j=0; j<vi.nelem(); ++j)
341  {
342  // Add comma and line break, if not first element:
343  align(ofs,is_first_parameter,indent);
344 
345  if (wsv_data[vi[j]].Group() == get_wsv_group_id("Agenda"))
346  {
347  ofs << "*(("
348  << wsv_group_names[wsv_data[vi[j]].Group()]
349  << " *)ws[mr.In()[" << j
350  << "]])";
351  }
352  else
353  {
354  ofs << "*(("
355  << wsv_group_names[wsv_data[vi[j]].Group()]
356  << " *)ws[mr.In()[" << j
357  << "]])";
358  }
359  }
360 
361  // Write the control parameters:
362  {
363  if (mdd.SetMethod())
364  {
365  // Add comma and line break, if not first element:
366  align(ofs,is_first_parameter,indent);
367 
368  ofs << "mr.SetValue()";
369  }
370  else
371  {
372  // Write the Generic input workspace variables:
373  for (Index j=0; j<vgi.nelem(); ++j)
374  {
375  // Check by assert whether the group identifier is too
376  // large to correspond to a group. This can easily
377  // happen if somebody puts a variable identifier instead
378  // of a group identifier in the argument of GINPUT:
379  assert( vgi[j] < wsv_group_names.nelem() );
380 
381  // Add comma and line break, if not first element:
382  align(ofs,is_first_parameter,indent);
383 
384  ofs << "*((" << wsv_group_names[vgi[j]]
385  << " *)ws[mr.In()[" << j+vi.nelem()
386  << "]])";
387  }
388 
389  // Write the Generic input workspace variable names:
390  if (mdd.PassWsvNames())
391  {
392  for (Index j=0; j<vgi.nelem(); ++j)
393  {
394  // Add comma and line break, if not first element:
395  align(ofs,is_first_parameter,indent);
396 
397  ofs << "Workspace::wsv_data[mr.In()["
398  << j+vi.nelem()
399  << "]].Name()";
400  }
401  }
402  }
403  }
404 
405  // Write the agenda, if there is one.
406  if ( mdd.AgendaMethod() )
407  {
408  align(ofs,is_first_parameter,indent);
409  ofs << "mr.Tasks()";
410  }
411 
412  // Flag that is set to false if the WSM has verbosity as an input or
413  // output already. Otherwise it's passed as the last parameter.
414  bool pass_verbosity = true;
415 
416  // Find out if the WSM has the verbosity as input.
417  for (Index j = 0; pass_verbosity && j < mdd.In().nelem(); j++)
418  {
419  if (wsv_data[mdd.In()[j]].Name() == "verbosity")
420  {
421  pass_verbosity = false;
422  }
423  }
424 
425  // Find out if the WSM has the verbosity as output.
426  for (Index j = 0; pass_verbosity && j < mdd.Out().nelem(); j++)
427  {
428  if (wsv_data[mdd.Out()[j]].Name() == "verbosity")
429  {
430  pass_verbosity = false;
431  }
432  }
433 
434  if (pass_verbosity)
435  {
436  static Index verbosity_wsv_id = get_wsv_id("verbosity");
437  static Index verbosity_group_id = get_wsv_group_id("Verbosity");
438  align(ofs,is_first_parameter,indent);
439  ofs << "*((" << wsv_group_names[verbosity_group_id]
440  << " *)ws[" << verbosity_wsv_id
441  << "])";
442  }
443 
444  ofs << ");\n";
445  ofs << "}\n\n";
446  }
447 
448  // Add getaways, the array that hold pointers to the getaway functions:
449  {
450  String indent = " ";
451  bool is_first_parameter = true;
452 
453  ofs << "// The array holding the pointers to the getaway functions.\n"
454  << "void (*getaways[])(Workspace&, const MRecord&)\n"
455  << " = {";
456  for (Index i=0; i<n_md; ++i)
457  {
458  const MdRecord& mdd = md_data[i];
459 
460  // Add comma and line break, if not first element:
461  align(ofs,is_first_parameter,indent);
462 
463  if ( mdd.Supergeneric() )
464  {
465  ofs << mdd.Name()
466  << "_sg_" << mdd.ActualGroups()
467  << "_g";
468  }
469  else
470  {
471  ofs << mdd.Name() << "_g";
472  }
473  }
474  ofs << "};\n\n";
475  }
476 
477 
478  // Create implementation of the agenda wrappers
479 
480  // Initialize agenda data.
483 
485  for (Index i = 0; i < agenda_data.nelem (); i++)
486  {
487  const AgRecord& agr = agenda_data[i];
488  const ArrayOfIndex& ago = agr.Out();
489  const ArrayOfIndex& agi = agr.In();
490  ostringstream ain_push_os, ain_pop_os;
491  ostringstream aout_push_os, aout_pop_os;
492 
493  write_agenda_wrapper_header (ofs, agr);
494 
495  ofs << "\n";
496  ofs << "{\n";
497 
498  if (ago.nelem () || agi.nelem ())
499  {
500  ofs << " using global_data::AgendaMap;\n"
501  << " using global_data::agenda_data;\n"
502  << "\n"
503  << " assert(input_agenda.checked());\n"
504  << "\n"
505  << " const AgRecord& agr =\n"
506  << " agenda_data[AgendaMap.find (input_agenda.name ())->second];\n"
507  << "\n";
508  }
509  if (ago.nelem ())
510  {
511  for (Index j = 0; j < ago.nelem (); j++)
512  {
513  // Mark agenda output-only variables as uninitialized
514  ArrayOfIndex::const_iterator it = agi.begin ();
515  while (it != agi.end () && *it != ago[j]) it++;
516  if (it == agi.end ())
517  {
518  aout_push_os << " ws.push_uninitialized (aout[" << j << "], "
519  << "(void *)&" << wsv_data[ago[j]].Name () << ");\n";
520  }
521  else
522  {
523  aout_push_os << " ws.push (aout[" << j << "], "
524  << "(void *)&" << wsv_data[ago[j]].Name () << ");\n";
525  }
526  aout_pop_os << " ws.pop (aout[" << j << "]);\n";
527  }
528  }
529  if (agi.nelem ())
530  {
531  for (Index j = 0; j < agi.nelem (); j++)
532  {
533  // Ignore Input parameters that are also output
534  ArrayOfIndex::const_iterator it = ago.begin ();
535  while (it != ago.end () && *it != agi[j]) it++;
536  if (it == ago.end ())
537  {
538  ain_push_os << " ws.push (ain[" << j << "], "
539  << "(void *)&" << wsv_data[agi[j]].Name () << ");\n";
540  ain_pop_os << " ws.pop (ain[" << j << "]);\n";
541  }
542  }
543  }
544 
545  if (aout_push_os.str().length())
546  {
547  ofs << " const ArrayOfIndex& aout = agr.Out();\n";
548  ofs << aout_push_os.str () << "\n";
549  }
550  if (ain_push_os.str().length())
551  {
552  ofs << " const ArrayOfIndex& ain = agr.In();\n";
553  ofs << ain_push_os.str () << "\n";
554  }
555 
556  ofs << " const ArrayOfIndex& outputs_to_push = input_agenda.get_output2push();\n"
557  << " const ArrayOfIndex& outputs_to_dup = input_agenda.get_output2dup();\n"
558  << "\n"
559  << " for (ArrayOfIndex::const_iterator it = outputs_to_push.begin ();\n"
560  << " it != outputs_to_push.end (); it++)\n"
561  << " {\n"
562  // Even if a variable is only used as WSM output inside this agenda,
563  // It is possible that it is used as input further down by another agenda,
564  // which we can't see here. Therefore initialized variables have to be
565  // duplicated.
566  << " if (ws.is_initialized(*it))\n"
567  << " ws.duplicate (*it);\n"
568  << " else\n"
569  << " ws.push_uninitialized (*it, NULL);\n"
570  << " }\n"
571  << "\n"
572  << " for (ArrayOfIndex::const_iterator it = outputs_to_dup.begin ();\n"
573  << " it != outputs_to_dup.end (); it++)\n"
574  << " { ws.duplicate (*it); }\n"
575  << "\n";
576 
577  ofs << " String agenda_error_msg;\n"
578  << " bool agenda_failed = false;\n\n"
579  << " try {\n"
580  << " input_agenda.execute (ws);\n"
581  << " } catch (runtime_error e) {\n"
582  << " ostringstream os;\n"
583  << " os << \"Run-time error in agenda: \"\n"
584  << " << input_agenda.name() << \'\\n\' << e.what();\n"
585  << " agenda_failed = true;\n"
586  << " agenda_error_msg = os.str();\n"
587  << " }\n";
588 
589  ofs << " for (ArrayOfIndex::const_iterator it = outputs_to_push.begin ();\n"
590  << " it != outputs_to_push.end (); it++)\n"
591  << " { ws.pop_free (*it); }\n"
592  << "\n"
593  << " for (ArrayOfIndex::const_iterator it = outputs_to_dup.begin ();\n"
594  << " it != outputs_to_dup.end (); it++)\n"
595  << " { ws.pop_free (*it); }\n\n";
596 
597  if (aout_pop_os.str().length())
598  {
599  ofs << aout_pop_os.str () << "\n";
600  }
601  if (ain_pop_os.str().length())
602  {
603  ofs << ain_pop_os.str () << "\n";
604  }
605 
606  ofs << " if (agenda_failed) throw runtime_error (agenda_error_msg);\n\n";
607 
608  ofs << "}\n\n";
609  }
610 
611 
612  // Create implementation of the GroupCreate WSMs
613  //
614  for (ArrayOfString::const_iterator it = wsv_group_names.begin();
615  it != wsv_group_names.end(); it++)
616  {
617  if (*it != "Any")
618  {
619  ofs
620  << "/* Workspace method: Doxygen documentation will be auto-generated */\n"
621  << "void " << *it << "Create(" << *it << "& var, const Verbosity&)\n"
622  << "{ ";
623 
624  // Treat atomic types separately.
625  // For objects the default constructor is used.
626  if (*it == "Index")
627  ofs << "var = 0;";
628  else if (*it == "Numeric")
629  ofs << "var = 0.;";
630  else
631  ofs << "var = " << *it << "();";
632 
633  ofs << " }\n\n";
634  }
635  }
636  }
637  catch (runtime_error x)
638  {
639  cout << "Something went wrong. Message text:\n";
640  cout << x.what() << '\n';
641  return 1;
642  }
643 
644  return 0;
645 }
Index get_wsv_group_id(const String &name)
Returns the id of the given group.
Definition: groups.cc:205
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:35
static Array< WsvRecord > wsv_data
Definition: workspace_ng.h:64
Lookup information for one agenda.
Definition: agenda_record.h:44
Index nelem() const
Number of elements.
Definition: array.h:176
bool AgendaMethod() const
Definition: methods.h:107
bool SetMethod() const
Definition: methods.h:106
const ArrayOfIndex & Out() const
Definition: methods.h:92
bool PassWsvNames() const
Definition: methods.h:111
const ArrayOfIndex & Out() const
Definition: agenda_record.h:64
This file contains basic functions to handle ASCII files.
All information for one workspace method.
Definition: methods.h:42
bool Supergeneric() const
Definition: methods.h:108
#define DUMMY_ELEMS
const String & Name() const
Definition: methods.h:89
#define DUMMY_COLS
#define DUMMY_BOOKS
void define_agenda_data()
Definition: agendas.cc:44
This file contains the definition of Array.
This file contains the declaration and partly the implementation of the workspace class...
Index get_wsv_id(const String &name)
Get index of WSV.
Definition: workspace.cc:4998
The implementation for String, the ARTS string class.
Definition: mystring.h:63
void expand_md_data_raw_to_md_data()
Expand supergeneric methods.
Definition: methods_aux.cc:396
The global header file for ARTS.
#define DUMMY_LIBRARIES
void align(ofstream &ofs, bool &is_first_parameter, const String &indent)
const String & ActualGroups() const
Definition: methods.h:112
static void define_wsv_data()
Definition: workspace.cc:50
#define DUMMY_ROWS
const ArrayOfIndex & In() const
Definition: methods.h:97
#define DUMMY_PAGES
Index nelem() const
Number of elements.
Definition: mystring.h:278
const Array< AgRecord > agenda_data
The lookup information for the agendas.
Definition: agendas.cc:41
const ArrayOfIndex & In() const
Definition: agenda_record.h:65
const ArrayOfIndex & InOnly() const
Definition: methods.h:103
void open_output_file(ofstream &file, const String &name)
Open a file for writing.
Definition: file.cc:103
const ArrayOfIndex & GOutType() const
Definition: methods.h:94
void define_wsv_group_names()
Define the array of workspace variable group names.
Definition: groups.cc:84
const ArrayOfString wsv_group_names
The names associated with Wsv groups as Strings.
Definition: global_data.h:94
int main()
void define_md_data_raw()
Definition: methods.cc:126
void write_agenda_wrapper_header(ofstream &ofs, const AgRecord &agr)
Write a agenda wrapper header.
const Array< MdRecord > md_data
Lookup information for workspace methods.
Definition: methods_aux.cc:48
static void define_wsv_map()
Definition: workspace_ng.cc:53
const ArrayOfIndex & GInType() const
Definition: methods.h:99
#define DUMMY_VITRINES
#define DUMMY_SHELVES
Declaration of the class MdRecord.
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:318
Declarations for AgRecord, storing lookup information for one agenda.
bool PassWorkspace() const
Definition: methods.h:110