ARTS  2.3.1285(git:92a29ea9-dirty)
methods_aux.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 
30 #include <algorithm>
31 #include <map>
32 #include "arts.h"
33 #include "methods.h"
34 #include "workspace_ng.h"
35 #include "wsv_aux.h"
36 
37 namespace global_data {
39 map<String, Index> MdMap;
41 map<String, Index> MdRawMap;
43 
49 
50 extern const Array<MdRecord> md_data_raw;
51 extern const ArrayOfString wsv_group_names;
52 } // namespace global_data
53 
54 void limit_line_length(ostream& os,
55  ostringstream& curline,
56  ostringstream& token,
57  const String& indent,
58  size_t linelen);
59 
61 
67 MdRecord::MdRecord(const char name[],
68  const char description[],
69  const ArrayOfString& authors,
70  const ArrayOfString& output,
71  const ArrayOfString& gout,
72  const ArrayOfString& gouttype,
73  const ArrayOfString& goutdesc,
74  const ArrayOfString& input,
75  const ArrayOfString& gin,
76  const ArrayOfString& gintype,
77  const ArrayOfString& gindefault,
78  const ArrayOfString& gindesc,
79  bool set_method,
80  bool agenda_method,
81  bool uses_templates,
82  bool pass_workspace,
83  bool pass_wsv_names)
84  : mname(name),
85  mdescription(description),
86  mauthors(authors),
87  moutput(0),
88  mgout(gout),
89  mgouttype(0),
90  mgoutdesc(goutdesc),
91  minput(0),
92  mgin(gin),
93  mgintype(0),
94  mgindefault(gindefault),
95  mgindesc(gindesc),
96  mset_method(set_method),
97  magenda_method(agenda_method),
98  msupergeneric(false),
99  muses_templates(uses_templates),
100  mpass_workspace(pass_workspace),
101  mpass_wsv_names(pass_wsv_names),
102  mactual_groups("") {
103  // Initializing the various arrays with input data should now
104  // work correctly.
105 
106  // Generic variable names, types and defaults must have the same number of
107  // elements. (Defaults specifies the default values associated with each
108  // generic input.)
109  assert(mgout.nelem() == gouttype.nelem());
110  assert(mgout.nelem() == goutdesc.nelem());
111  assert(mgin.nelem() == mgindefault.nelem());
112  assert(mgin.nelem() == gintype.nelem());
113  assert(mgin.nelem() == gindesc.nelem());
114 
115  // Check that GIN and GOUT don't contain duplicates
116  ArrayOfString gin_sorted = mgin;
117  std::sort(gin_sorted.begin(), gin_sorted.end());
118  ArrayOfString gout_sorted = mgout;
119  std::sort(gout_sorted.begin(), gout_sorted.end());
120 
121  for (auto par = mgin.begin(); mgin.nelem() > 1 && par + 1 != mgin.end();
122  par++) {
123  if (*par == *(par + 1)) {
125  os << "Two input parameters by the same name are not allowed: \n";
126  os << "Method: " << mname << ", Parameter: " << *par;
127  throw std::runtime_error(os.str());
128  }
129  }
130 
131  for (auto par = mgout.begin(); mgout.nelem() > 1 && par + 1 != mgout.end();
132  par++) {
133  if (*par == *(par + 1)) {
135  os << "Two output parameters by the same name are not allowed: \n";
136  os << "Method: " << mname << ", Parameter: " << *par;
137  throw std::runtime_error(os.str());
138  }
139  }
140 
141  // Check that GIN and GOUT don't share parameter names
142  ArrayOfString gisect(gin_sorted.nelem());
143  auto it = std::set_intersection(gin_sorted.begin(),
144  gin_sorted.end(),
145  gout_sorted.begin(),
146  gout_sorted.end(),
147  gisect.begin());
148  gisect.resize(it - gisect.begin());
149 
150  if (gisect.nelem() > 0) {
152  os << "Using the same name for a generic input and generic output variable is not allowed: \n";
153  os << "Method: " << mname << ", Parameter: ";
154  for (auto& gname : gisect) {
155  os << gname << " ";
156  }
157  throw std::runtime_error(os.str());
158  }
159 
160  // Map the WSV names to indexes
161  moutput.resize(output.nelem());
162  for (Index j = 0; j < output.nelem(); ++j) {
163  moutput[j] = get_wsv_id(output[j]);
164  if (moutput[j] == -1) {
165  ostringstream os;
166  os << "Unknown WSV " << output[j] << " for output (parameter #" << j
167  << ") "
168  << "in WSM " << mname;
169  throw runtime_error(os.str());
170  }
171  }
172 
173  minput.resize(input.nelem());
174  for (Index j = 0; j < input.nelem(); ++j) {
175  minput[j] = get_wsv_id(input[j]);
176  if (minput[j] == -1) {
177  ostringstream os;
178  os << "Unknown WSV " << input[j] << " for input (parameter #" << j << ") "
179  << "in WSM " << mname;
180  throw runtime_error(os.str());
181  }
182  }
183 
184  // Map the group names to groups' indexes
185  mgoutspectype.resize(gouttype.nelem());
186  mgouttype.resize(gouttype.nelem());
187  for (Index j = 0; j < gouttype.nelem(); ++j) {
188  ArrayOfIndex types;
189  get_wsv_group_ids(types, gouttype[j]);
190 
191  if (types.nelem() == 1) {
192  mgouttype[j] = types[0];
193  mgoutspectype[j].resize(0);
194  if (types[0] == get_wsv_group_id("Any") && !muses_templates) {
195  ostringstream os;
196  os << "WSM " << mname << " takes \"Any\" as input and\n"
197  << "therefore must be implemented as a template function.\n"
198  << "Pass USES_TEMPLATES(true) in methods.cc!";
199  throw runtime_error(os.str());
200  }
201  } else if (types.nelem() > 1) {
202  mgouttype[j] = get_wsv_group_id("Any");
203  mgoutspectype[j] = types;
204  } else {
205  ostringstream os;
206  os << "Unknown WSV Group " << gouttype[j] << " for generic output "
207  << "in WSM " << mname;
208  throw runtime_error(os.str());
209  }
210  }
211 
212  mginspectype.resize(gintype.nelem());
213  mgintype.resize(gintype.nelem());
214  for (Index j = 0; j < gintype.nelem(); ++j) {
215  ArrayOfIndex types;
216  get_wsv_group_ids(types, gintype[j]);
217 
218  if (types.nelem() == 1) {
219  mgintype[j] = get_wsv_group_id(gintype[j]);
220  mginspectype[j].resize(0);
221  if (types[0] == get_wsv_group_id("Any") && !muses_templates) {
222  ostringstream os;
223  os << "WSM " << mname << " defines \"Any\" as output and\n"
224  << "therefore must be implemented as a template function.\n"
225  << "Pass USES_TEMPLATES(true) in methods.cc!";
226  throw runtime_error(os.str());
227  }
228  } else if (types.nelem() > 1) {
229  mgintype[j] = get_wsv_group_id("Any");
230  mginspectype[j] = types;
231  } else {
232  ostringstream os;
233  os << "Unknown WSV Group " << gintype[j] << " for generic input "
234  << "in WSM " << mname;
235  throw runtime_error(os.str());
236  }
237  }
238 
239  // Check that the number of types for all supergeneric variables are
240  // consistent
241  if (mginspectype.nelem() && mgoutspectype.nelem()) {
242  bool consistent = true;
243  Index nspecs = 0;
244  for (Index i = 0; consistent && i < mginspectype.nelem(); i++) {
245  if (mginspectype[0].nelem()) {
246  if (!nspecs)
247  nspecs = mginspectype[0].nelem();
248  else if (nspecs != mginspectype[0].nelem())
249  consistent = false;
250  }
251  }
252 
253  for (Index i = 0; consistent && i < mgoutspectype.nelem(); i++) {
254  if (mgoutspectype[0].nelem()) {
255  if (!nspecs)
256  nspecs = mgoutspectype[0].nelem();
257  else if (nspecs != mgoutspectype[0].nelem())
258  consistent = false;
259  }
260  }
261  if (!consistent) {
262  ostringstream os;
263  os << "Inconsistent number of types given for supergeneric variables"
264  << endl
265  << "in WSM " << mname << "." << endl;
266  throw runtime_error(os.str());
267  }
268  }
269 
270  // Find out if this method is supergeneric, and set the flag if
271  // yes:
272  const Index anyid = get_wsv_group_id("Any");
273  for (Index j = 0; j < mgouttype.nelem(); ++j)
274  if (anyid == mgouttype[j]) msupergeneric = true;
275  for (Index j = 0; j < mgintype.nelem(); ++j)
276  if (anyid == mgintype[j]) msupergeneric = true;
277 
278  // Determine variables that are only input
279  minonly = minput; // Input
280  for (ArrayOfIndex::const_iterator j = moutput.begin(); j < moutput.end(); ++j)
281  for (ArrayOfIndex::iterator k = minonly.begin(); k < minonly.end(); ++k)
282  if (*j == *k) {
283  k = minonly.erase(k) - 1;
284  // We need the -1 here, otherwise due to the
285  // following increment we would miss the element
286  // behind the erased one, which is now at the
287  // position of the erased one.
288  }
289 
290  // Determine variables that are input and output
291  minout.resize(0);
292  Index i = 0;
293  for (ArrayOfIndex::const_iterator j = moutput.begin(); j < moutput.end();
294  ++j, ++i)
295  for (ArrayOfIndex::const_iterator k = minput.begin(); k < minput.end(); ++k)
296  if (*j == *k) minout.push_back(i);
297 
298  // Determine variables that are only output
299  moutonly = moutput; // Output
300  for (ArrayOfIndex::const_iterator j = minput.begin(); j < minput.end(); ++j)
301  for (ArrayOfIndex::iterator k = moutonly.begin(); k < moutonly.end(); ++k)
302  if (*j == *k) {
303  k = moutonly.erase(k) - 1;
304  // We need the -1 here, otherwise due to the
305  // following increment we would miss the element
306  // behind the erased one, which is now at the
307  // position of the erased one.
308  }
309 }
310 
312 
322  const Index wsv_group_id_Any = get_wsv_group_id("Any");
323  // The group names, we need them for the expansion:
325 
326  // Make sure they are initialized:
327  assert(0 != wsv_group_names.nelem());
328 
329  // Make sure that g is in the allowed range, which means
330  // 0<=g<wsv_group_names.nelem() and g != Any_
331  assert(0 <= g);
332  assert(wsv_group_id_Any != g);
333  assert(g < wsv_group_names.nelem());
334 
335  // Make sure that this really is a supergeneric method:
336  assert(Supergeneric());
337 
338  // Modify the name:
339  // {
340  // ostringstream os;
341  // os << mname << "_sg_" << wsv_group_names[g];
342  // mname = os.str();
343  // }
344 
345  for (Index j = 0; j < mgouttype.nelem(); ++j)
346  if (wsv_group_id_Any == mgouttype[j]) mgouttype[j] = g;
347  for (Index j = 0; j < mgintype.nelem(); ++j)
348  if (wsv_group_id_Any == mgintype[j]) mgintype[j] = g;
349 
350  // Set the field for the actual group:
352 }
353 
355 
365  // The group names, we need them for the expansion:
367 
368  const Index wsv_group_id_Any = get_wsv_group_id("Any");
369 
370  // Make sure that g is in the allowed range, which means
371  // 0<=g<wsv_group_names.nelem() and g != Any_
372  assert(0 <= g);
373 
374  // Make sure that this really is a supergeneric method:
375  assert(Supergeneric());
376 
377  // Modify the name:
378  // {
379  // ostringstream os;
380  // os << mname << "_sg_" << wsv_group_names[g];
381  // mname = os.str();
382  // }
383 
384  mactual_groups = "";
385  for (Index j = 0; j < mgouttype.nelem(); ++j)
386  if (wsv_group_id_Any == mgouttype[j]) {
387  mgouttype[j] = mgoutspectype[j][g];
388  // Set the field for the actual group:
390  }
391 
392  for (Index j = 0; j < mgintype.nelem(); ++j)
393  if (wsv_group_id_Any == mgintype[j]) {
394  mgintype[j] = mginspectype[j][g];
395  // Set the field for the actual group:
397  }
398 }
399 
401 
411  using global_data::md_data;
413 
414  // The group names, we need them for the expansion:
416 
417  const Index wsv_group_id_Any = get_wsv_group_id("Any");
418 
419  // Make sure that they have been initialized:
420  assert(0 != wsv_group_names.nelem());
421 
422  // Reset md_data, just in case:
423  md_data.resize(0);
424 
425  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
426  const MdRecord& mdd = md_data_raw[i];
427 
428  if (!mdd.Supergeneric()) {
429  md_data.push_back(mdd);
430  } else {
431  // Special treatment for supergeneric methods:
432 
433  // Check if the method is really supergeneric or just valid
434  // for certain types.
435 
436  if ((mdd.GInSpecType().nelem() && mdd.GInSpecType()[0].nelem()) ||
437  (mdd.GOutSpecType().nelem() && mdd.GOutSpecType()[0].nelem())) {
438  Index max = 0;
439  if (mdd.GInSpecType().nelem()) max = mdd.GInSpecType()[0].nelem();
440  if (mdd.GOutSpecType().nelem() && mdd.GOutSpecType()[0].nelem() > max)
441  max = mdd.GOutSpecType()[0].nelem();
442 
443  for (Index k = 0; k < max; k++) {
444  MdRecord mdlocal = mdd;
445 
447 
448  md_data.push_back(mdlocal);
449  }
450  } else {
451  for (Index j = 0; j < wsv_group_names.nelem(); ++j) {
452  // Any_ itself is also a group, but we don't want to
453  // create a record for Any_!
454  if (wsv_group_id_Any != j) {
455  // Not a reference but a copy this time, since we
456  // have to manipulate this.
457  MdRecord mdlocal = mdd;
458 
459  mdlocal.subst_any_with_group(j);
460 
461  md_data.push_back(mdlocal);
462  }
463  }
464  }
465  }
466  }
467 }
468 
470 
474  // md_data is constant here and should never be changed
475  using global_data::md_data;
476  using global_data::MdMap;
478 
479  // Check that md_data and wsv_group_names have already be defined:
480  assert(0 != md_data.nelem());
481  assert(0 != wsv_group_names.nelem());
482 
483  for (Index i = 0; i < md_data.nelem(); ++i) {
484  const MdRecord& mdd = md_data[i];
485 
486  // For supergeneric methods, add group to method name
487  String methodname;
488  ostringstream os;
489  if (mdd.Supergeneric()) {
490  os << mdd.Name() << "_sg_" << mdd.ActualGroups();
491  } else {
492  os << mdd.Name();
493  }
494  methodname = os.str();
495 
496  MdMap[methodname] = i;
497  }
498 }
499 
501 
511  using global_data::MdRawMap;
512 
513  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
514  MdRawMap[md_data_raw[i].Name()] = i;
515  }
516 }
517 
519  const String& indent,
520  const size_t linelen,
521  const size_t offset) {
522  bool fit = true;
523  String out;
524  String token;
525  size_t currentlinelength = offset;
526  for (size_t i = 0; i < s.length(); i++) {
527  if (s[i] == '\n') s[i] = ' ';
528  token += s[i];
529  if (s[i] == ' ') {
530  if (currentlinelength + token.length() > linelen) {
531  out += '\n' + indent;
532  currentlinelength = indent.length();
533  fit = false;
534  }
535  out += token;
536  currentlinelength += token.length();
537  token = "";
538  }
539  }
540 
541  if (token.length()) {
542  if (currentlinelength + token.length() > linelen) {
543  out += '\n' + indent;
544  fit = false;
545  }
546  out += token;
547  }
548  s = out;
549  return fit;
550 }
551 
552 void get_short_wsv_description(String& s, const String& desc) {
553  Index pos;
554  Index pos2;
555 
556  // Find the end of the short WSV description
557  pos = desc.find(".\n");
558  pos2 = desc.find(". ");
559  if (pos == String::npos || (pos2 != String::npos && pos2 < pos)) pos = pos2;
560  if (pos == String::npos) pos = desc.find("\n");
561  if (pos != String::npos)
562  s = desc.substr(0, pos + 1);
563  else
564  s = desc;
565 
566  // Replace any newlines inside the description with spaces
567  while ((pos = s.find("\n")) != String::npos) {
568  s.replace(pos, 1, " ");
569  }
570 }
571 
572 ostream& MdRecord::PrintTemplate(ostream& os, bool show_description) const {
574 
575  if (show_description) {
576  // FIXME: Print description String!
577  }
578 
579  os << Name();
580 
581  // Is this a generic method? -- Then we need round braces.
582  if (0 != GOutType().nelem() + GInType().nelem()) {
583  // First entry needs to comma before:
584  bool first = true;
585 
586  os << '(';
587 
588  for (Index i = 0; i < GOutType().nelem(); ++i) {
589  if (first)
590  first = false;
591  else
592  os << ",\n";
593 
594  os << wsv_group_names[GOutType()[i]];
595  }
596 
597  for (Index i = 0; i < GInType().nelem(); ++i) {
598  if (first)
599  first = false;
600  else
601  os << ",\n";
602 
603  os << wsv_group_names[GInType()[i]];
604  }
605 
606  os << ')';
607  }
608 
609  // Now the keywords:
610 
611  os << '{';
612 
613  // Determine the length of the longest keyword:
614  Index maxsize = 0;
615  for (Index i = 0; i < GIn().nelem(); ++i)
616  if (GIn()[i].nelem() > maxsize) maxsize = GIn()[i].nelem();
617 
618  for (Index i = 0; i < GIn().nelem(); ++i) {
619  os << "\t" << setw((int)maxsize) << GIn()[i] << " = \n";
620  }
621 
622  os << '}';
623 
624  return os;
625 }
626 
628 
633 void limit_line_length(ostream& os,
634  ostringstream& curline,
635  ostringstream& token,
636  const String& indent,
637  size_t linelen) {
638  if (indent.length() + curline.str().length() + token.str().length() >
639  linelen) {
640  os << curline.str() << endl << indent;
641  curline.str("");
642  }
643  curline << token.str();
644  token.str("");
645 }
646 
648 ostream& operator<<(ostream& os, const MdRecord& mdr) {
650  bool first;
651  ostringstream buf;
652  ostringstream param;
653  String indent = "";
654  const size_t linelen = 68;
655  bool fit;
656  size_t lastlen;
657 
658  os << "\n*-------------------------------------------------------------------*\n"
659  << "Workspace method = " << mdr.Name()
660  << "\n---------------------------------------------------------------------\n"
661  << "\n"
662  << mdr.Description() << "\n";
663 
664  if (mdr.Description()[mdr.Description().nelem() - 1] != '\n') {
665  os << "\n";
666  }
667 
668  // Print the method's synopsis
669  while (indent.length() < mdr.Name().length() + 2) indent += ' ';
670 
671  os << "\nSynopsis:\n\n";
672  buf << mdr.Name() << "( ";
673  first = true;
674  for (Index i = 0; i < mdr.Out().nelem(); ++i) {
675  if (first)
676  first = false;
677  else
678  buf << ", ";
679  param << Workspace::wsv_data[mdr.Out()[i]].Name();
680 
681  limit_line_length(os, buf, param, indent, linelen);
682  }
683 
684  for (Index i = 0; i < mdr.GOutType().nelem(); ++i) {
685  if (first)
686  first = false;
687  else
688  buf << ", ";
689  if (mdr.GOut()[i].length())
690  param << mdr.GOut()[i];
691  else
692  param << "gout" << i;
693 
694  limit_line_length(os, buf, param, indent, linelen);
695  }
696 
697  const ArrayOfIndex& inonly = mdr.InOnly();
698  for (Index i = 0; i < inonly.nelem(); ++i) {
699  if (first)
700  first = false;
701  else
702  buf << ", ";
703  param << Workspace::wsv_data[inonly[i]].Name();
704 
705  limit_line_length(os, buf, param, indent, linelen);
706  }
707 
708  for (Index i = 0; i < mdr.GInType().nelem(); ++i) {
709  if (first)
710  first = false;
711  else
712  buf << ", ";
713  if (mdr.GIn()[i].length()) {
714  param << mdr.GIn()[i];
715  } else {
716  param << "gin" << i;
717  }
718 
719  limit_line_length(os, buf, param, indent, linelen);
720  }
721  if (buf.str().length()) os << buf.str();
722 
723  os << " )\n\n\n";
724 
725  {
726  bool is_first_author = true;
727  for (Index i = 0; i < mdr.Authors().nelem(); i++) {
728  if (is_first_author) {
729  os << "Authors: ";
730  is_first_author = false;
731  } else
732  os << ", ";
733 
734  os << mdr.Authors()[i];
735  }
736  os << "\n";
737  }
738 
739  os << "\n\nVariables:\n\n";
740 
741  // os << "\n-----\nName = " << mdr.Name() << '\n\n'
742  // << "Description =\n" << mdr.Description() << "\n\n";
743 
744  // Out:
745  indent = String(6);
746  String desc;
747  for (Index i = 0; i < mdr.Out().nelem(); ++i) {
748  buf.str("");
749  buf << "OUT ";
750 
751  buf << Workspace::wsv_data[mdr.Out()[i]].Name();
752  buf << " (";
753  buf << wsv_group_names[Workspace::wsv_data[mdr.Out()[i]].Group()];
754  buf << "): ";
755 
757  Workspace::wsv_data[mdr.Out()[i]].Description());
758 
759  if (buf.str().length() + desc.length() > linelen) {
760  format_paragraph(desc, indent, linelen);
761  buf << endl << indent << desc;
762  } else {
763  buf << desc;
764  }
765 
766  os << buf.str() << endl;
767  }
768 
769  for (Index i = 0; i < mdr.GOut().nelem(); ++i) {
770  buf.str("");
771  buf << "GOUT " << mdr.GOut()[i] << " (";
772  if (mdr.GOutType()[i] == get_wsv_group_id("Any") &&
773  mdr.GOutSpecType()[i].nelem()) {
774  bool firstarg = true;
775  for (Index j = 0; j < mdr.GOutSpecType()[i].nelem(); j++) {
776  if (!firstarg)
777  buf << ", ";
778  else
779  firstarg = false;
780  buf << wsv_group_names[mdr.GOutSpecType()[i][j]];
781  }
782  } else {
783  buf << wsv_group_names[mdr.GOutType()[i]];
784  }
785 
786  buf << "): ";
787  desc = buf.str();
788  lastlen = desc.length();
789  fit = format_paragraph(desc, indent, linelen);
790  buf.str("");
791  os << desc;
792 
793  desc = mdr.GOutDescription()[i];
794  if (!fit) {
795  format_paragraph(desc, indent, linelen);
796  buf << endl << indent << desc;
797  } else if (lastlen + desc.length() > linelen) {
798  format_paragraph(desc, indent, linelen, lastlen);
799  buf << endl << desc;
800  } else {
801  buf << desc;
802  }
803 
804  os << buf.str() << endl;
805  }
806 
807  for (Index i = 0; i < mdr.In().nelem(); ++i) {
808  buf.str("");
809  buf << "IN ";
810 
811  buf << Workspace::wsv_data[mdr.In()[i]].Name();
812  buf << " (";
813  buf << wsv_group_names[Workspace::wsv_data[mdr.In()[i]].Group()];
814  buf << "): ";
815 
817  Workspace::wsv_data[mdr.In()[i]].Description());
818 
819  if (buf.str().length() + desc.length() > linelen) {
820  format_paragraph(desc, indent, linelen, indent.length());
821  buf << endl << indent << desc;
822  } else {
823  buf << desc;
824  }
825 
826  os << buf.str() << endl;
827  }
828 
829  for (Index i = 0; i < mdr.GIn().nelem(); ++i) {
830  buf.str("");
831  buf << "GIN " << mdr.GIn()[i] << " (";
832  if (mdr.GInType()[i] == get_wsv_group_id("Any") &&
833  mdr.GInSpecType()[i].nelem()) {
834  bool firstarg = true;
835  for (Index j = 0; j < mdr.GInSpecType()[i].nelem(); j++) {
836  if (!firstarg)
837  buf << ", ";
838  else
839  firstarg = false;
840  buf << wsv_group_names[mdr.GInSpecType()[i][j]];
841  }
842  } else {
843  buf << wsv_group_names[mdr.GInType()[i]];
844  }
845 
846  if (mdr.GInDefault()[i] != NODEF) {
847  buf << ", Default: ";
848  if (mdr.GInType()[i] == get_wsv_group_id("String")) {
849  buf << "\"" << mdr.GInDefault()[i] << "\"";
850  } else {
851  buf << mdr.GInDefault()[i];
852  }
853  }
854 
855  buf << "): ";
856  desc = buf.str();
857  lastlen = desc.length();
858  fit = format_paragraph(desc, indent, linelen);
859  buf.str("");
860  os << desc;
861 
862  desc = mdr.GInDescription()[i];
863  if (!fit) {
864  format_paragraph(desc, indent, linelen);
865  buf << endl << indent << desc;
866  } else if (lastlen + desc.length() > linelen) {
867  format_paragraph(desc, indent, linelen, indent.length());
868  buf << endl << indent << desc;
869  } else {
870  buf << desc;
871  }
872 
873  os << buf.str() << endl;
874  }
875 
876  os << "\n*-------------------------------------------------------------------*\n";
877 
878  return os;
879 }
Index get_wsv_group_id(const String &name)
Returns the id of the given group.
Definition: groups.cc:223
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
static Array< WsvRecord > wsv_data
Global WSV data.
Definition: workspace_ng.h:58
ostream & PrintTemplate(ostream &os, bool show_description=true) const
Print method template for the control file.
Definition: methods_aux.cc:572
String mname
The name of this method.
Definition: methods.h:147
Index nelem() const
Number of elements.
Definition: array.h:195
ArrayOfIndex mgouttype
Generic Workspace Output Type.
Definition: methods.h:162
void get_short_wsv_description(String &s, const String &desc)
Definition: methods_aux.cc:552
MdRecord()
Default constructor.
Definition: methods.h:44
ArrayOfIndex minput
Workspace Input.
Definition: methods.h:172
bool muses_templates
Flag, whether method implementation relies on templates.
Definition: methods.h:225
const ArrayOfIndex & Out() const
Definition: methods.h:91
const Array< String > & GInDescription() const
Definition: methods.h:101
const map< String, Index > MdRawMap
The map associated with md_data_raw.
Definition: methods_aux.cc:41
All information for one workspace method.
Definition: methods.h:41
bool Supergeneric() const
Definition: methods.h:107
void define_md_raw_map()
Define MdRawMap.
Definition: methods_aux.cc:509
const String & Name() const
Definition: methods.h:88
ArrayOfArrayOfIndex mgoutspectype
Generic Workspace Output Types (Contains the valid types if the method.
Definition: methods.h:166
const map< String, Index > MdMap
The map associated with md_data.
Definition: methods_aux.cc:39
const ArrayOfString & GOut() const
Definition: methods.h:92
This file contains the Workspace class.
Index get_wsv_id(const String &name)
Get index of WSV.
Definition: workspace.cc:5751
const Array< String > & GInDefault() const
Definition: methods.h:100
The global header file for ARTS.
#define NODEF
Definition: methods.h:35
#define DEBUG_ONLY(...)
Definition: debug.h:36
void get_wsv_group_ids(ArrayOfIndex &ids, String name)
Returns list of ids of the given group names.
Definition: groups.cc:186
_CS_string_type str() const
Definition: sstream.h:491
const String & ActualGroups() const
Definition: methods.h:111
void subst_any_with_specific_group(Index g)
Expand supergeneric record for given Index in GOutSpecType and GInSpecType.
Definition: methods_aux.cc:364
ArrayOfIndex minout
Indexes of Input-Output variables.
Definition: methods.h:197
const ArrayOfIndex & In() const
Definition: methods.h:96
const ArrayOfArrayOfIndex & GInSpecType() const
Definition: methods.h:99
String mactual_groups
The actual groups of a supergeneric method.
Definition: methods.h:246
const ArrayOfString & Authors() const
Definition: methods.h:90
ArrayOfString mgin
Generic Workspace Input Names.
Definition: methods.h:175
Index nelem() const
Number of elements.
Definition: mystring.h:246
ArrayOfString mgout
Generic Workspace Output Names.
Definition: methods.h:159
basic_ostringstream< char, string_char_traits< char >, alloc > ostringstream
Definition: sstream.h:204
This can be used to make arrays out of anything.
Definition: array.h:40
const ArrayOfIndex & InOnly() const
Definition: methods.h:102
const ArrayOfIndex & GOutType() const
Definition: methods.h:93
ArrayOfIndex moutput
Workspace Output.
Definition: methods.h:156
const ArrayOfString wsv_group_names
The names associated with Wsv groups as Strings.
Definition: global_data.h:93
#define max(a, b)
ArrayOfIndex moutonly
Indexes of Output-only variables.
Definition: methods.h:194
bool format_paragraph(String &s, const String &indent, const size_t linelen, const size_t offset)
Definition: methods_aux.cc:518
ArrayOfString mgindefault
Generic Workspace Input Defaults.
Definition: methods.h:185
Index nelem(const Lines &l)
Number of lines.
const Array< String > & GOutDescription() const
Definition: methods.h:95
const ArrayOfArrayOfIndex & GOutSpecType() const
Definition: methods.h:94
const Array< MdRecord > md_data
Lookup information for workspace methods.
void expand_md_data_raw_to_md_data()
Expand supergeneric methods.
Definition: methods_aux.cc:410
const String & Description() const
Definition: methods.h:89
const ArrayOfIndex & GInType() const
Definition: methods.h:98
static const Index npos
Define npos:
Definition: mystring.h:106
void subst_any_with_group(Index g)
Expand supergeneric record for given group.
Definition: methods_aux.cc:321
void limit_line_length(ostream &os, ostringstream &curline, ostringstream &token, const String &indent, size_t linelen)
Limit length of output.
Definition: methods_aux.cc:633
ostream & operator<<(ostream &os, const MdRecord &mdr)
Output operator for MdRecord.
Definition: methods_aux.cc:648
void define_md_map()
Define MdMap.
Definition: methods_aux.cc:473
ArrayOfIndex mgintype
Generic Workspace Input.
Definition: methods.h:178
bool msupergeneric
Flag, whether this method is supergeneric.
Definition: methods.h:218
Declaration of the class MdRecord.
const ArrayOfString & GIn() const
Definition: methods.h:97
ArrayOfArrayOfIndex mginspectype
Generic Workspace Input Types (Contains the valid types if the method.
Definition: methods.h:182
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:280
ArrayOfIndex minonly
Indexes of Input-only variables.
Definition: methods.h:191
const Array< MdRecord > md_data_raw
Lookup information for workspace methods.
Definition: methods.cc:39
Auxiliary header stuff related to workspace variable groups.