ARTS  2.4.0(git:4fb77825)
agenda_record.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-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 
26 #include "agenda_record.h"
27 #include <iostream>
28 #include <map>
29 #include "messages.h"
30 #include "workspace_ng.h"
31 #include "wsv_aux.h"
32 
33 namespace global_data {
35 map<String, Index> AgendaMap;
36 
37 extern const Array<AgRecord> agenda_data;
38 extern const ArrayOfString wsv_group_names;
39 } // namespace global_data
40 
42 
52 AgRecord::AgRecord(const char name[],
53  const char description[],
54  const ArrayOfString& output,
55  const ArrayOfString& input)
56  : mname(name), mdescription(description), moutput(0), minput(0) {
57  // We must check that this agenda exists in the workspace
58 
59  // Find returns end() if the name is not found in the map. If
60  // this assertion fails, it means that we are trying to set the
61  // lookup data for an agenda that has not been defined in
62  // wsv_data (i.e., in workspace.cc). First make a record entry
63  // in workspace.cc for your agenda. If you have done so and
64  // still get an assertion failure, then check that you spelled
65  // the name in exactly the same way in both places.
67  std::ostringstream os;
68  os << "Agenda *" << mname << "* not found in WSV data.";
69  throw std::runtime_error(os.str());
70  }
71 
72  moutput.resize(output.nelem());
73  for (Index j = 0; j < output.nelem(); ++j) {
74  moutput[j] = get_wsv_id(output[j]);
75  if (moutput[j] == -1) {
76  ostringstream os;
77 
78  os << "Unknown output WSV " << output[j] << " in WSM " << mname;
79  throw runtime_error(os.str());
80  }
81  }
82 
83  minput.resize(input.nelem());
84  for (Index j = 0; j < input.nelem(); ++j) {
85  minput[j] = get_wsv_id(input[j]);
86  if (minput[j] == -1) {
87  ostringstream os;
88 
89  os << "Unknown input WSV " << input[j] << " in WSM " << mname;
90  throw runtime_error(os.str());
91  }
92  }
93 }
94 
98 
99  for (Index i = 0; i < agenda_data.nelem(); ++i) {
100  AgendaMap[agenda_data[i].Name()] = i;
101  }
102 }
103 
105 
116  // Make external data visible
119 
120  Index i, j, k;
121 
122  k = 0;
123 
124  // Check, that each agenda from agenda_data occurs in wsv_data:
125  for (i = 0; i < agenda_data.nelem(); ++i) {
126  // cout << "Checking wsv_data for " << agenda_data[i].Name() << ".\n";
127 
128  // Find returns end() if the name is not found in the map. If
129  // this assertion fails, it means that wsv_data does not contain
130  // this agenda.
131  // You have to add a record for your agenda in both files:
132  // workspace.cc and agendas.cc. The name has to be spelled
133  // exactly the same in both places.
134  // Uncomment the cout statement above and recompile to see which
135  // agenda causes the trouble.
136  assert(Workspace::WsvMap.end() !=
137  Workspace::WsvMap.find(agenda_data[i].Name()));
138  }
139 
140  // Check, that each agenda from wsv_data occurs in agenda_data:
141  for (j = 0; j < Workspace::wsv_data.nelem(); ++j) {
142  // Is this an agenda WSV?
143  if (get_wsv_group_id("Agenda") == Workspace::wsv_data[j].Group() ||
144  get_wsv_group_id("ArrayOfAgenda") == Workspace::wsv_data[j].Group()) {
145  // cout << "Checking agenda_data for " << Workspace::wsv_data[j].Name() << ".\n";
146 
147  // Find returns end() if the name is not found in the map. If
148  // this assertion fails, it means that agenda_data does not contain
149  // this agenda.
150  // You have to add a record for your agenda in both files:
151  // workspace.cc and agendas.cc. The name has to be spelled
152  // exactly the same in both places.
153  // Uncomment the cout statement above and recompile to see which
154  // agenda causes the trouble.
155  assert(AgendaMap.end() != AgendaMap.find(Workspace::wsv_data[j].Name()));
156 
157  // Counts the number of agenda WSVs in Workspace::wsv_data:
158  ++k;
159  }
160  }
161 
162  // As a last check we make sure that both lists contain the same
163  // number of agendas:
164  assert(i == k);
165 
166  return true;
167 }
168 
170 
177 ostream& operator<<(ostream& os, const AgRecord& agr) {
178  bool first;
179 
180  os << "\n*-------------------------------------------------------------------*\n"
181  << "Workspace variable = " << agr.Name()
182  << "\n---------------------------------------------------------------------\n"
183  << "\n"
184  << agr.Description() << "\n"
185  << "\n---------------------------------------------------------------------\n";
186 
187  os << "Group = Agenda\n";
188 
189  // Output:
190  first = true;
191  os << "Output = ";
192  for (Index i = 0; i < agr.Out().nelem(); ++i) {
193  if (first)
194  first = false;
195  else
196  os << ", ";
197 
198  os << Workspace::wsv_data[agr.Out()[i]].Name();
199  }
200  os << "\n";
201 
202  // Input:
203  first = true;
204  os << "Input = ";
205  for (Index i = 0; i < agr.In().nelem(); ++i) {
206  if (first)
207  first = false;
208  else
209  os << ", ";
210 
211  os << Workspace::wsv_data[agr.In()[i]].Name();
212  }
213 
214  os << "\n*-------------------------------------------------------------------*\n";
215 
216  return os;
217 }
218 
220 
229 ostream& operator<<(ostream& os, const WsvRecord& wr) {
231 
232  // We need a special treatment for the case that the WSV is an agenda.
233 
234  if (get_wsv_group_id("Agenda") != wr.Group() &&
235  get_wsv_group_id("ArrayOfAgenda") != wr.Group()) {
236  // No agenda.
237 
238  os << "\n*-------------------------------------------------------------------*\n"
239  << "Workspace variable = " << wr.Name()
240  << "\n---------------------------------------------------------------------\n"
241  << "\n"
242  << wr.Description() << "\n"
243  << "\n---------------------------------------------------------------------\n"
244  << "Group = " << wsv_group_names[wr.Group()]
245  << "\n*-------------------------------------------------------------------*\n";
246  } else {
247  // Agenda.
248 
250 
251  // AgendaMap is constant here and should never be changed
253 
254  map<String, Index>::const_iterator j = AgendaMap.find(wr.Name());
255 
256  // Just for added safety, check that we really found something:
257  assert(j != AgendaMap.end());
258 
259  cout << agenda_data[j->second] << "\n";
260  }
261 
262  return os;
263 }
264 
266 
270 void write_agenda_wrapper_header(ofstream& ofs,
271  const AgRecord& agr,
272  bool is_agenda_array) {
274 
275  // Wrapper function
276  ofs << "void " << agr.Name() << "Execute(\n";
277 
278  // Wrapper function Workspace parameters
279  ofs << " // Workspace\n";
280  ofs << " Workspace& ws,\n";
281  // Wrapper function output parameters
282  const ArrayOfIndex& ago = agr.Out();
283  ofs << " // Output\n";
284  for (ArrayOfIndex::const_iterator j = ago.begin(); j != ago.end(); j++) {
285  ofs << " ";
286  ofs << wsv_group_names[Workspace::wsv_data[*j].Group()] << "& ";
287  ofs << Workspace::wsv_data[*j].Name() << ",\n";
288  }
289 
290  // Wrapper function input parameters
291  const ArrayOfIndex& agi = agr.In();
292  ofs << " // Input\n";
293  for (ArrayOfIndex::const_iterator j = agi.begin(); j != agi.end(); j++) {
294  // Ignore Input parameters that are also output
295  ArrayOfIndex::const_iterator it = ago.begin();
296  while (it != ago.end() && *it != *j) it++;
297 
298  if (it == ago.end()) {
299  String group_name = wsv_group_names[Workspace::wsv_data[*j].Group()];
300 
301  ofs << " const ";
302  ofs << group_name;
303 
304  // Don't pass by reference for elementary types
305  if (group_name != "Index" && group_name != "Numeric") {
306  ofs << "&";
307  }
308  ofs << " " << Workspace::wsv_data[*j].Name() << ",\n";
309  }
310  }
311 
312  // Wrapper function agenda and silent parameters
313  ofs << " // Wrapper Input\n";
314  if (is_agenda_array) {
315  ofs << " const ArrayOfAgenda& input_agenda_array)";
316  } else {
317  ofs << " const Agenda& input_agenda)";
318  }
319 }
agenda_record.h
Declarations for AgRecord, storing lookup information for one agenda.
write_agenda_wrapper_header
void write_agenda_wrapper_header(ofstream &ofs, const AgRecord &agr, bool is_agenda_array)
Write a agenda wrapper header.
Definition: agenda_record.cc:270
Workspace::wsv_data
static Array< WsvRecord > wsv_data
Global WSV data.
Definition: workspace_ng.h:58
AgRecord::minput
ArrayOfIndex minput
Workspace Input.
Definition: agenda_record.h:83
AgRecord::AgRecord
AgRecord()
Default constructor.
Definition: agenda_record.h:46
get_wsv_id
Index get_wsv_id(const String &name)
Get index of WSV.
Definition: workspace.cc:5751
global_data::AgendaMap
map< String, Index > AgendaMap
The map associated with agenda_data.
Definition: agenda_record.cc:35
DEBUG_ONLY
#define DEBUG_ONLY(...)
Definition: debug.h:36
Group
Definition: make_autoarts_h.cc:10
Array
This can be used to make arrays out of anything.
Definition: array.h:108
WsvRecord::Group
Index Group() const
The wsv group to which this variable belongs.
Definition: wsv_aux.h:106
Absorption::nelem
Index nelem(const Lines &l)
Number of lines.
Definition: absorptionlines.h:1820
messages.h
Declarations having to do with the four output streams.
AgRecord
Lookup information for one agenda.
Definition: agenda_record.h:43
my_basic_string< char >
AgRecord::moutput
ArrayOfIndex moutput
Workspace Output.
Definition: agenda_record.h:80
WsvRecord::Name
const String & Name() const
Name of this workspace variable.
Definition: wsv_aux.h:102
AgRecord::Name
const String & Name() const
Definition: agenda_record.h:58
AgRecord::mname
String mname
The name of this agenda.
Definition: agenda_record.h:74
check_agenda_data
bool check_agenda_data()
Check that agendas.cc and workspace.cc are consistent.
Definition: agenda_record.cc:115
Zeeman::end
constexpr Rational end(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the largest M for a polarization type of this transition.
Definition: zeemandata.h:108
AgRecord::In
const ArrayOfIndex & In() const
Definition: agenda_record.h:61
define_agenda_map
void define_agenda_map()
Definition: agenda_record.cc:95
WsvRecord
This class contains all static information for one workspace variable.
Definition: wsv_aux.h:56
workspace_ng.h
This file contains the Workspace class.
WsvRecord::Description
const String & Description() const
A text describing this workspace variable.
Definition: wsv_aux.h:104
global_data
Definition: agenda_record.cc:33
Workspace::WsvMap
static map< String, Index > WsvMap
Global map associated with wsv_data.
Definition: workspace_ng.h:61
global_data::agenda_data
const Array< AgRecord > agenda_data
The lookup information for the agendas.
Definition: agendas.cc:41
operator<<
ostream & operator<<(ostream &os, const AgRecord &agr)
Output operator for AgRecord.
Definition: agenda_record.cc:177
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
AgRecord::Description
const String & Description() const
Definition: agenda_record.h:59
global_data::wsv_group_names
const ArrayOfString wsv_group_names
The names associated with Wsv groups as Strings.
Definition: global_data.h:93
get_wsv_group_id
Index get_wsv_group_id(const String &name)
Returns the id of the given group.
Definition: groups.cc:223
AgRecord::Out
const ArrayOfIndex & Out() const
Definition: agenda_record.h:60
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:195
wsv_aux.h
Auxiliary header stuff related to workspace variable groups.