ARTS  2.4.0(git:4fb77825)
main.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 
31 #include "arts.h"
32 
33 #ifdef TIME_SUPPORT
34 #include <sys/stat.h>
35 #include <sys/times.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38 #include <ctime>
39 #endif
40 #include <algorithm>
41 #include <map>
42 
43 #include "absorption.h"
44 #include "agenda_record.h"
45 #include "arts_omp.h"
46 #include "auto_md.h"
47 #include "auto_version.h"
48 #include "docserver.h"
49 #include "exceptions.h"
50 #include "file.h"
51 #include "global_data.h"
52 #include "messages.h"
53 #include "methods.h"
54 #include "mystring.h"
55 #include "parameters.h"
56 #include "parser.h"
57 #include "workspace_ng.h"
58 #include "wsv_aux.h"
59 
61 void polite_goodby() {
62  cerr << "Try `arts --help' for help.\n";
63  arts_exit();
64 }
65 
81 
82  if (-1 == r) {
83  // Reporting was not specified, set default. (No output from
84  // agendas (except main of course), only the important stuff to
85  // the screen, nothing to the file.)
89  } else {
90  // Reporting was specified. Check consistency and set report
91  // level accordingly.
92 
93  // Separate the three digits:
97 
98  if (!verbosity_at_launch.valid()) {
99  cerr << "Illegal value specified for --reporting (-r).\n"
100  << "The specified value is " << r << ", which would be\n"
101  << "interpreted as:\n"
102  << "Verbosity for agendas: "
104  << "Verbosity for screen: "
106  << "Verbosity for report file: "
108  << "Only values of 0-3 are allowed for each verbosity.\n";
109  arts_exit();
110  }
111  }
112 }
113 
122  Workspace workspace;
123  workspace.initialize();
124  // Make global data visible:
126  extern const Parameters parameters;
128 
129  // This is used to count the number of matches to a query, so
130  // that `none' can be output if necessary
131  Index hitcount;
132 
133  // First check if the user gave the special name `all':
134 
135  if ("all" == methods) {
136  if (!parameters.plain) {
137  cout
138  << "\n*-------------------------------------------------------------------*\n"
139  << "Complete list of ARTS workspace methods:\n"
140  << "---------------------------------------------------------------------\n";
141  }
142  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
143  if (!parameters.plain) cout << "- ";
144  cout << md_data_raw[i].Name() << "\n";
145  }
146 
147  if (!parameters.plain)
148  cout
149  << "*-------------------------------------------------------------------*\n\n";
150 
151  return;
152  }
153 
154  // Ok, so the user has probably specified a workspace variable or
155  // workspace variable group.
156 
157  // Check if the user gave the name of a specific variable.
158  map<String, Index>::const_iterator mi = Workspace::WsvMap.find(methods);
159  if (mi != Workspace::WsvMap.end()) {
160  // If we are here, then the given name matches a variable.
161  Index wsv_key = mi->second;
162 
163  // List generic methods:
164  hitcount = 0;
165  cout
166  << "\n*-------------------------------------------------------------------*\n"
167  << "Generic and supergeneric methods that can generate "
168  << Workspace::wsv_data[wsv_key].Name() << ":\n"
169  << "---------------------------------------------------------------------\n";
170  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
171  // Get handle on method record:
172  const MdRecord& mdd = md_data_raw[i];
173 
174  // This if statement checks whether GOutType, the list
175  // of output variable types contains the group of the
176  // requested variable.
177  // The else clause picks up methods with supergeneric input.
178  if (count(mdd.GOutType().begin(),
179  mdd.GOutType().end(),
180  Workspace::wsv_data[wsv_key].Group())) {
181  cout << "- " << mdd.Name() << "\n";
182  ++hitcount;
183  } else if (count(mdd.GOutType().begin(),
184  mdd.GOutType().end(),
185  get_wsv_group_id("Any"))) {
186  for (Index j = 0; j < mdd.GOutType().nelem(); j++) {
187  if (mdd.GOutType()[j] == get_wsv_group_id("Any")) {
188  if (mdd.GOutSpecType()[j].nelem()) {
189  if (count(mdd.GOutSpecType()[j].begin(),
190  mdd.GOutSpecType()[j].end(),
191  Workspace::wsv_data[wsv_key].Group())) {
192  cout << "- " << mdd.Name() << "\n";
193  ++hitcount;
194  }
195  } else {
196  cout << "- " << mdd.Name() << "\n";
197  ++hitcount;
198  }
199  }
200  }
201  }
202  }
203  if (0 == hitcount) cout << "none\n";
204 
205  // List specific methods:
206  hitcount = 0;
207  cout
208  << "\n---------------------------------------------------------------------\n"
209  << "Specific methods that can generate "
210  << Workspace::wsv_data[wsv_key].Name() << ":\n"
211  << "---------------------------------------------------------------------\n";
212  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
213  // Get handle on method record:
214  const MdRecord& mdd = md_data_raw[i];
215 
216  // This if statement checks whether Output, the list
217  // of output variables contains the workspace
218  // variable key.
219  if (count(mdd.Out().begin(), mdd.Out().end(), wsv_key)) {
220  cout << "- " << mdd.Name() << "\n";
221  ++hitcount;
222  }
223  }
224  if (0 == hitcount) cout << "none\n";
225 
226  cout
227  << "*-------------------------------------------------------------------*\n\n";
228 
229  return;
230  }
231 
232  // Check if the user gave the name of a variable group.
233 
234  // We use the find algorithm from the STL to do this. It
235  // returns an iterator, so to get the index we take the
236  // difference to the begin() iterator.
237  Index group_key =
238  find(wsv_group_names.begin(), wsv_group_names.end(), methods) -
239  wsv_group_names.begin();
240 
241  // group_key == wsv_goup_names.nelem() indicates that a
242  // group with this name was not found.
243  if (group_key != wsv_group_names.nelem()) {
244  // List generic methods:
245  hitcount = 0;
246  cout
247  << "\n*-------------------------------------------------------------------*\n"
248  << "Generic and supergeneric methods that can generate variables of group "
249  << wsv_group_names[group_key] << ":\n"
250  << "---------------------------------------------------------------------\n";
251  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
252  // Get handle on method record:
253  const MdRecord& mdd = md_data_raw[i];
254 
255  // This if statement checks whether GOutType, the list
256  // of output variable types contains the
257  // requested group.
258  // The else clause picks up methods with supergeneric input.
259  if (count(mdd.GOutType().begin(), mdd.GOutType().end(), group_key)) {
260  cout << "- " << mdd.Name() << "\n";
261  ++hitcount;
262  } else if (count(mdd.GOutType().begin(),
263  mdd.GOutType().end(),
264  get_wsv_group_id("Any"))) {
265  for (Index j = 0; j < mdd.GOutType().nelem(); j++) {
266  if (mdd.GOutType()[j] == get_wsv_group_id("Any")) {
267  if (mdd.GOutSpecType()[j].nelem()) {
268  if (count(mdd.GOutSpecType()[j].begin(),
269  mdd.GOutSpecType()[j].end(),
270  group_key)) {
271  cout << "- " << mdd.Name() << "\n";
272  ++hitcount;
273  }
274  } else {
275  cout << "- " << mdd.Name() << "\n";
276  ++hitcount;
277  }
278  }
279  }
280  }
281  }
282  if (0 == hitcount) cout << "none\n";
283 
284  cout
285  << "*-------------------------------------------------------------------*\n\n";
286 
287  return;
288  }
289 
290  // If we are here it means that what the user specified is neither
291  // `all', nor a variable, nor a variable group.
292  cerr << "The name " << methods << " matches neither `all',\n"
293  << "nor the name of a workspace variable, nor the name\n"
294  << "of a workspace variable group.\n";
295  arts_exit();
296 }
297 
305 void option_input(const String& input) {
306  // Make global data visible:
309 
310  // Ok, so the user has probably specified a workspace variable or
311  // workspace variable group.
312 
313  // Check if the user gave the name of a specific variable.
314  map<String, Index>::const_iterator mi = Workspace::WsvMap.find(input);
315  if (mi != Workspace::WsvMap.end()) {
316  // This is used to count the number of matches to a query, so
317  // that `none' can be output if necessary
318  Index hitcount = 0;
319 
320  // If we are here, then the given name matches a variable.
321  Index wsv_key = mi->second;
322 
323  // List generic methods:
324  cout
325  << "\n*-------------------------------------------------------------------*\n"
326  << "Generic and supergeneric methods that can use "
327  << Workspace::wsv_data[wsv_key].Name() << ":\n"
328  << "---------------------------------------------------------------------\n";
329  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
330  // Get handle on method record:
331  const MdRecord& mdd = md_data_raw[i];
332 
333  // This if statement checks whether GInType, the list
334  // of input variable types contains the group of the
335  // requested variable.
336  // The else clause picks up methods with supergeneric input.
337  if (count(mdd.GInType().begin(),
338  mdd.GInType().end(),
339  Workspace::wsv_data[wsv_key].Group())) {
340  cout << "- " << mdd.Name() << "\n";
341  ++hitcount;
342  } else if (count(mdd.GInType().begin(),
343  mdd.GInType().end(),
344  get_wsv_group_id("Any"))) {
345  for (Index j = 0; j < mdd.GInType().nelem(); j++) {
346  if (mdd.GInType()[j] == get_wsv_group_id("Any")) {
347  if (mdd.GInSpecType()[j].nelem()) {
348  if (count(mdd.GInSpecType()[j].begin(),
349  mdd.GInSpecType()[j].end(),
350  Workspace::wsv_data[wsv_key].Group())) {
351  cout << "- " << mdd.Name() << "\n";
352  ++hitcount;
353  }
354  } else {
355  cout << "- " << mdd.Name() << "\n";
356  ++hitcount;
357  }
358  }
359  }
360  }
361  }
362  if (0 == hitcount) cout << "none\n";
363 
364  // List specific methods:
365  hitcount = 0;
366  cout
367  << "\n---------------------------------------------------------------------\n"
368  << "Specific methods that require "
369  << Workspace::wsv_data[wsv_key].Name() << ":\n"
370  << "---------------------------------------------------------------------\n";
371  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
372  // Get handle on method record:
373  const MdRecord& mdd = md_data_raw[i];
374 
375  // This if statement checks whether Output, the list
376  // of output variables contains the workspace
377  // variable key.
378  if (count(mdd.In().begin(), mdd.In().end(), wsv_key)) {
379  cout << "- " << mdd.Name() << "\n";
380  ++hitcount;
381  }
382  }
383  if (0 == hitcount) cout << "none\n";
384 
385  cout
386  << "*-------------------------------------------------------------------*\n\n";
387 
388  return;
389  }
390 
391  // Check if the user gave the name of a variable group.
392 
393  // We use the find algorithm from the STL to do this. It
394  // returns an iterator, so to get the index we take the
395  // difference to the begin() iterator.
396  Index group_key =
397  find(wsv_group_names.begin(), wsv_group_names.end(), input) -
398  wsv_group_names.begin();
399 
400  // group_key == wsv_goup_names.nelem() indicates that a
401  // group with this name was not found.
402  if (group_key != wsv_group_names.nelem()) {
403  // This is used to count the number of matches to a query, so
404  // that `none' can be output if necessary
405  Index hitcount = 0;
406 
407  // List generic methods:
408  cout
409  << "\n*-------------------------------------------------------------------*\n"
410  << "Generic and supergeneric methods that require a variable of group "
411  << wsv_group_names[group_key] << ":\n"
412  << "---------------------------------------------------------------------\n";
413  for (Index i = 0; i < md_data_raw.nelem(); ++i) {
414  // Get handle on method record:
415  const MdRecord& mdd = md_data_raw[i];
416 
417  // This if statement checks whether GOutType, the list
418  // of output variable types contains the
419  // requested group.
420  // The else clause picks up methods with supergeneric input.
421  if (count(mdd.GInType().begin(), mdd.GInType().end(), group_key)) {
422  cout << "- " << mdd.Name() << "\n";
423  ++hitcount;
424  } else if (count(mdd.GInType().begin(),
425  mdd.GInType().end(),
426  get_wsv_group_id("Any"))) {
427  for (Index j = 0; j < mdd.GInType().nelem(); j++) {
428  if (mdd.GInType()[j] == get_wsv_group_id("Any")) {
429  if (mdd.GInSpecType()[j].nelem()) {
430  if (count(mdd.GInSpecType()[j].begin(),
431  mdd.GInSpecType()[j].end(),
432  group_key)) {
433  cout << "- " << mdd.Name() << "\n";
434  ++hitcount;
435  }
436  } else {
437  cout << "- " << mdd.Name() << "\n";
438  ++hitcount;
439  }
440  }
441  }
442  }
443  }
444  if (0 == hitcount) cout << "none\n";
445 
446  cout
447  << "*-------------------------------------------------------------------*\n\n";
448 
449  return;
450  }
451 
452  // If we are here it means that what the user specified is neither
453  // a variable nor a variable group.
454  cerr << "The name " << input << " matches neither the name of a\n"
455  << "workspace variable, nor the name of a workspace variable group.\n";
456  arts_exit();
457 }
458 
466 void option_workspacevariables(const String& workspacevariables) {
467  // Make global data visible:
468  using global_data::md_data;
469  using global_data::MdMap;
470  extern const Parameters parameters;
472 
473  // This is used to count the number of matches to a query, so
474  // that `none' can be output if necessary
475  Index hitcount;
476 
477  // First check for `all':
478 
479  if ("all" == workspacevariables) {
480  if (!parameters.plain) {
481  cout
482  << "\n*-------------------------------------------------------------------*\n"
483  << "Complete list of ARTS workspace variables:\n"
484  << "---------------------------------------------------------------------\n";
485  }
486 
487  for (Index i = 0; i < Workspace::wsv_data.nelem(); ++i) {
488  if (!parameters.plain) cout << "- ";
489  cout << Workspace::wsv_data[i].Name() << "\n";
490  }
491 
492  if (!parameters.plain)
493  cout
494  << "*-------------------------------------------------------------------*\n\n";
495  return;
496  }
497 
498  // Now check if the user gave the name of a method.
499  map<String, Index>::const_iterator mi = MdMap.find(workspacevariables);
500  if (mi != MdMap.end()) {
501  // If we are here, then the given name matches a method.
502  // Assign the data record for this method to a local
503  // variable for easier access:
504  const MdRecord& mdr = md_data[mi->second];
505 
506  // List generic variables required by this method.
507  hitcount = 0;
508  cout
509  << "\n*-------------------------------------------------------------------*\n"
510  << "Generic workspace variables required by " << mdr.Name()
511  << " are of type:\n"
512  << "---------------------------------------------------------------------\n";
513  for (Index i = 0; i < mdr.GInType().nelem(); ++i) {
514  cout << "- " << wsv_group_names[mdr.GInType()[i]] << "\n";
515  ++hitcount;
516  }
517  if (0 == hitcount) cout << "none\n";
518 
519  // List specific variables required by this method.
520  hitcount = 0;
521  cout
522  << "\n---------------------------------------------------------------------\n"
523  << "Specific workspace variables required by " << mdr.Name() << ":\n"
524  << "---------------------------------------------------------------------\n";
525  for (Index i = 0; i < mdr.In().nelem(); ++i) {
526  cout << "- " << Workspace::wsv_data[mdr.In()[i]].Name() << "\n";
527  ++hitcount;
528  }
529  if (0 == hitcount) cout << "none\n";
530 
531  cout
532  << "*-------------------------------------------------------------------*\n\n";
533 
534  return;
535  }
536 
537  // If we are here, then the user specified nothing that makes sense.
538  cerr << "The name " << workspacevariables << " matches neither `all',\n"
539  << "nor the name of a workspace method.\n";
540  arts_exit();
541 }
542 
549  // Make global data visible:
551  using global_data::MdRawMap;
552 
553  // Let's first assume it is a method that the user wants to have
554  // described.
555 
556  // Find method id:
557  map<String, Index>::const_iterator i = MdRawMap.find(describe);
558  if (i != MdRawMap.end()) {
559  // If we are here, then the given name matches a method.
560  cout << md_data_raw[i->second] << "\n";
561  return;
562  }
563 
564  // Ok, let's now assume it is a variable that the user wants to have
565  // described.
566 
567  // Find wsv id:
568  i = Workspace::WsvMap.find(describe);
569  if (i != Workspace::WsvMap.end()) {
570  // If we are here, then the given name matches a workspace
571  // variable.
572  cout << Workspace::wsv_data[i->second] << "\n";
573  return;
574  }
575 
576  // If we are here, then the given name does not match anything.
577  cerr << "The name " << describe << " matches neither method nor variable.\n";
578  arts_exit();
579 }
580 
585 #ifdef TIME_SUPPORT
586 String arts_mod_time(String filename) {
587  struct stat buf;
588  if (stat(filename.c_str(), &buf) != -1) {
589  String ts = ctime(&buf.st_mtime);
590  return String(" (compiled ") + ts.substr(0, ts.length() - 1) + ")";
591  } else
592  return String("");
593 }
594 #else
596 #endif
597 
612 int main(int argc, char** argv) {
613  extern const Parameters parameters; // Global variable that holds
614  // all command line parameters.
615 
616  //---------------< -1. Time the arts run if possible >---------------
617 #ifdef TIME_SUPPORT
618  struct tms arts_cputime_start;
619  clock_t arts_realtime_start;
620  arts_realtime_start = times(&arts_cputime_start);
621 #endif
622 
623  //---------------< 1. Get command line parameters >---------------
624  if (get_parameters(argc, argv)) {
625  // Print an error message and exit:
626  polite_goodby();
627  }
628 
629  //----------< 2. Evaluate the command line parameters >----------
630  if (parameters.help) {
631  // Just print a help message and then exit.
632  cout << "\n" << parameters.usage << "\n\n";
633  cout << parameters.helptext << "\n\n";
634  arts_exit(EXIT_SUCCESS);
635  }
636 
637  ostringstream osfeatures;
638  {
639  osfeatures << "Compiler: " << String(COMPILER) << endl;
640 
641  if (String(COMPILER) != "Xcode")
642  osfeatures << "Compile flags: " << COMPILE_FLAGS << endl;
643 
644  osfeatures << "Features in this build: " << endl
645  << " Numeric precision: "
646  << ((sizeof(Numeric) == sizeof(double)) ? "double" : "float")
647  << endl
648  << " OpenMP support: "
649 #ifdef _OPENMP
650  << "enabled" << endl
651 #else
652  << "disabled" << endl
653 #endif
654  << " Documentation server: "
655 #ifdef ENABLE_DOCSERVER
656  << "enabled" << endl
657 #else
658  << "disabled" << endl
659 #endif
660  << " Zipped XML support: "
661 #ifdef ENABLE_ZLIB
662  << "enabled" << endl
663 #else
664  << "disabled" << endl
665 #endif
666  << " NetCDF support: "
667 #ifdef ENABLE_NETCDF
668  << "enabled" << endl
669 #else
670  << "disabled" << endl
671 #endif
672  << " Fortran support: "
673 #ifdef FORTRAN_COMPILER
674  << "enabled (" << FORTRAN_COMPILER << ")" << endl
675 #else
676  << "disabled" << endl
677 #endif
678  << " Legacy Fortran Disort:"
679 #ifdef ENABLE_DISORT
680  << "enabled" << endl
681 #else
682  << "disabled" << endl
683 #endif
684  << " RT4 support: "
685 #ifdef ENABLE_RT4
686  << "enabled" << endl
687 #else
688  << "disabled" << endl
689 #endif
690  << " FASTEM support: "
691 #ifdef ENABLE_FASTEM
692  << "enabled" << endl
693 #else
694  << "disabled" << endl
695 #endif
696  << " OEM support: "
697 #ifdef OEM_SUPPORT
698  << "enabled" << endl
699  << " MPI support for OEM: "
700 #ifdef ENABLE_MPI
701  << "enabled" << endl
702 #else
703  << "disabled" << endl
704 #endif
705 #else
706  << "disabled" << endl
707 #endif
708  << " Refice support: "
709 #ifdef ENABLE_REFICE
710  << "enabled" << endl
711 #else
712  << "disabled" << endl
713 #endif
714  << " Tmatrix support: "
715 #ifdef ENABLE_TMATRIX
716 #ifdef ENABLE_TMATRIX_QUAD
717  << "enabled (quad-precision)" << endl
718 #else
719  << "enabled (double-precision)" << endl
720 #endif
721 #else
722  << "disabled" << endl
723 #endif
724  << " Hitran Xsec support: "
725 #ifdef ENABLE_FFTW
726  << "enabled (experimental)" << endl
727 #else
728  << "enabled (experimental, no FFTW support, using slow convolution method)"
729  << endl
730 #endif
731  << "";
732 
733  osfeatures << "Include search paths: " << endl;
734  for (auto& path : parameters.includepath) {
735  osfeatures << " " << path << endl;
736  }
737 
738  osfeatures << "Data searchpaths: " << endl;
739  for (auto& path : parameters.datapath) {
740  osfeatures << " " << path << endl;
741  }
742  }
743 
744  if (parameters.version) {
745  cout << ARTS_FULL_VERSION << arts_mod_time(argv[0]) << endl;
746  cout << osfeatures.str();
747  arts_exit(EXIT_SUCCESS);
748  }
749 
750  if (parameters.numthreads) {
751 #ifdef _OPENMP
752  omp_set_num_threads((int)parameters.numthreads);
753 #else
754  cerr << "Ignoring commandline option --numthreads/-n.\n"
755  << "This option only works with an OpenMP enabled ARTS build.\n";
756 #endif
757  }
758 
759  // For the next couple of options we need to have the workspce and
760  // method lookup data.
761 
762  // Initialize the wsv group name array:
764 
765  // Initialize the wsv data:
767 
768  // Initialize WsvMap:
770 
771  // Initialize the md data:
773 
774  // Expand supergeneric methods:
776 
777  // Initialize MdMap:
778  define_md_map();
779 
780  // Initialize MdRawMap (needed by parser and online docu).
782 
783  // Initialize the agenda lookup data:
785 
786  // Initialize AgendaMap:
788 
789  // Check that agenda information in wsv_data and agenda_data is consistent:
790  assert(check_agenda_data());
791 
792  // Initialize memory handler.
794 
795  // While we are at it, we can also initialize the molecular data and
796  // the coefficients of the partition function that we need for the
797  // absorption part, and check that the inputs are sorted the same way:
799 
800  // And also the species map:
802 
803  // Make all global data visible:
805 
806  // Now we are set to deal with the more interesting command line
807  // switches.
808 #ifdef ENABLE_DOCSERVER
809  if (parameters.check_docs) {
810  // Check built-in docs and then exit
811  const auto broken_links = Docserver::list_broken_description_links();
812  const size_t nbroken = std::get<0>(broken_links);
813  for (auto&& s : std::get<1>(broken_links)) {
814  std::cout << s << std::endl;
815  }
816  std::cout << std::endl
817  << nbroken << " broken link" << (nbroken == 1 ? "" :"s")
818  << " found." << std::endl;
819  arts_exit(nbroken ? EXIT_FAILURE : EXIT_SUCCESS);
820  }
821 #endif
822 
823  // React to option `methods'. If given the argument `all', it
824  // should simply prints a list of all methods. If given the name of
825  // a variable, it should print all methods that produce this
826  // variable as output.
827  if ("" != parameters.methods) {
829  arts_exit(EXIT_SUCCESS);
830  }
831 
832  // React to option `input'. Given the name of a variable (or group)
833  // it should print all methods that need this variable (or group) as
834  // input.
835  if ("" != parameters.input) {
837  arts_exit(EXIT_SUCCESS);
838  }
839 
840  // React to option `workspacevariables'. If given the argument `all',
841  // it should simply prints a list of all variables. If given the
842  // name of a method, it should print all variables that are needed
843  // by that method.
844  if ("" != parameters.workspacevariables) {
846  arts_exit(EXIT_SUCCESS);
847  }
848 
849  // React to option `describe'. This should print the description
850  // String of the given workspace variable or method.
851  if ("" != parameters.describe) {
853  arts_exit(EXIT_SUCCESS);
854  }
855 
856  // React to option `groups'. This should simply print a list of all
857  // workspace variable groups.
858  if (parameters.groups) {
859  if (!parameters.plain) {
860  cout
861  << "\n*-------------------------------------------------------------------*\n"
862  << "Complete list of ARTS workspace variable groups:\n"
863  << "---------------------------------------------------------------------\n";
864  }
865 
866  for (Index i = 0; i < wsv_group_names.nelem(); ++i) {
867  if (!parameters.plain) cout << "- ";
868  cout << wsv_group_names[i] << "\n";
869  }
870 
871  if (!parameters.plain)
872  cout
873  << "*-------------------------------------------------------------------*\n\n";
874  arts_exit(EXIT_SUCCESS);
875  }
876 
877 #ifdef ENABLE_DOCSERVER
878  if (0 != parameters.docserver) {
879  if (parameters.daemon) {
880  int pid = fork();
881  if (!pid) {
882  Docserver docserver(parameters.docserver, parameters.baseurl);
883  docserver.launch(parameters.daemon);
884  arts_exit(0);
885  } else {
886  cout << "Docserver daemon started with PID: " << pid << endl;
887  arts_exit(0);
888  }
889  } else {
890  Docserver docserver(parameters.docserver, parameters.baseurl);
891  cout << "Starting the arts documentation server." << endl;
892  docserver.launch(parameters.daemon);
893  arts_exit(0);
894  }
895  }
896 #endif
897 
898  // Ok, we are past all the special options. This means the user
899  // wants to get serious and really do a calculation. Check if we
900  // have at least one control file:
901  if (0 == parameters.controlfiles.nelem()) {
902  cerr << "You must specify at least one control file name.\n";
903  polite_goodby();
904  }
905 
906  // Set the basename according to the first control file, if not
907  // explicitly specified.
908  if ("" == parameters.basename) {
909  extern String out_basename;
910  ArrayOfString fileparts;
911  parameters.controlfiles[0].split(fileparts, "/");
912  out_basename = fileparts[fileparts.nelem() - 1];
913  // Find the last . in the name
914  String::size_type p = out_basename.rfind(".arts");
915 
916  if (String::npos == p) {
917  // This is an error handler for the case that somebody gives
918  // a supposed file name that does not contain the extension
919  // ".arts"
920 
921  cerr << "The controlfile must have the extension .arts.\n";
922  polite_goodby();
923  }
924 
925  // Kill everything starting from the `.'
926  out_basename.erase(p);
927  } else {
928  extern String out_basename;
930  }
931 
932  // Set the global reporting level, either from reporting command line
933  // option or default.
935 
936  // Keep around a global copy of the verbosity levels at launch, so that
937  // verbosityInit() can be used to reset them in the control file
941  verbosity.set_main_agenda(true);
942 
943  CREATE_OUTS;
944 
945  //--------------------< Open report file >--------------------
946  // This one needs its own little try block, because we have to
947  // write error messages to cerr directly since the report file
948  // will not exist.
949  try {
950  extern String out_basename; // Basis for file name
951  extern ofstream report_file; // Report file pointer
952  ostringstream report_file_ext;
953 
954  report_file_ext << ".rep";
955  open_output_file(report_file, out_basename + report_file_ext.str());
956  } catch (const std::runtime_error& x) {
957  cerr << x.what() << "\n"
958  << "I have to be able to write to my report file.\n";
959  arts_exit();
960  }
961 
962  // Now comes the global try block. Exceptions caught after this
963  // one are general stuff like file opening errors.
964  try {
965  out1 << "Executing ARTS.\n";
966 
967  // Output command line:
968  out1 << "Command line:\n";
969  for (Index i = 0; i < argc; ++i) {
970  out1 << argv[i] << " ";
971  }
972  out1 << "\n";
973 
974  // Output full program name (with version number):
975  out1 << "Version: " << ARTS_FULL_VERSION << arts_mod_time(argv[0]) << "\n";
976 
977  // Output more details about the compilation:
978  out2 << osfeatures.str() << "\n";
979 
980  // Output some OpenMP specific information on output level 2:
981 #ifdef _OPENMP
982  out2 << "Running with OpenMP, "
983  << "maximum number of threads = " << arts_omp_get_max_threads()
984  << ".\n";
985 #else
986  out2 << "Running without OpenMP.\n";
987 #endif
988 
989  // Output a short hello from each thread to out3:
990 #ifdef _OPENMP
991 #pragma omp parallel default(none) shared(out3)
992  {
993  ostringstream os;
994  int tn = arts_omp_get_thread_num();
995  os << " Thread " << tn << ": ready.\n";
996  out3 << os.str();
997  }
998 #endif
999  out2 << "\n";
1000 
1001  time_t rawtime;
1002  struct tm* timeinfo;
1003 
1004  time(&rawtime);
1005  timeinfo = localtime(&rawtime);
1006  out2 << "Run started: " << asctime(timeinfo) << "\n";
1007 
1008  // Output verbosity settings. This is not too interesting, it
1009  // goes only to out3.
1010  out3 << "Verbosity settings: Agendas: "
1011  << verbosity.get_agenda_verbosity() << "\n"
1012  << " Screen: "
1013  << verbosity.get_screen_verbosity() << "\n"
1014  << " Report file: "
1015  << verbosity.get_file_verbosity() << "\n";
1016 
1017  out3 << "\nReading control files:\n";
1018  for (Index i = 0; i < parameters.controlfiles.nelem(); ++i) {
1019  try {
1020  out3 << "- " << parameters.controlfiles[i] << "\n";
1021 
1022  // The list of methods to execute and their keyword data from
1023  // the control file.
1024  Agenda tasklist;
1025 
1026  Workspace workspace;
1027 
1028  // Call the parser to parse the control text:
1029  ArtsParser arts_parser(tasklist, parameters.controlfiles[i], verbosity);
1030 
1031  arts_parser.parse_tasklist();
1032 
1033  tasklist.set_name("Arts");
1034 
1035  tasklist.set_main_agenda();
1036 
1037  //tasklist.find_unused_variables();
1038 
1039  workspace.initialize();
1040 
1041  // Execute main agenda:
1042  Arts2(workspace, tasklist, verbosity);
1043  } catch (const std::exception& x) {
1044  ostringstream os;
1045  os << "Run-time error in controlfile: " << parameters.controlfiles[i]
1046  << '\n'
1047  << x.what();
1048  throw runtime_error(os.str());
1049  }
1050  }
1051  } catch (const std::runtime_error& x) {
1052 #ifdef TIME_SUPPORT
1053  struct tms arts_cputime_end;
1054  clock_t arts_realtime_end;
1055  long clktck = 0;
1056 
1057  clktck = sysconf(_SC_CLK_TCK);
1058  arts_realtime_end = times(&arts_cputime_end);
1059  if (clktck > 0 && arts_realtime_start != (clock_t)-1 &&
1060  arts_realtime_end != (clock_t)-1) {
1061  out1 << "This run took " << fixed << setprecision(2)
1062  << (Numeric)(arts_realtime_end - arts_realtime_start) /
1063  (Numeric)clktck
1064  << "s (" << fixed << setprecision(2)
1065  << (Numeric)(
1066  (arts_cputime_end.tms_stime - arts_cputime_start.tms_stime) +
1067  (arts_cputime_end.tms_utime - arts_cputime_start.tms_utime)) /
1068  (Numeric)clktck
1069  << "s CPU time)\n";
1070  }
1071 #endif
1072 
1073  arts_exit_with_error_message(x.what(), out0);
1074  }
1075 
1076 #ifdef TIME_SUPPORT
1077  struct tms arts_cputime_end;
1078  clock_t arts_realtime_end;
1079  long clktck = 0;
1080 
1081  clktck = sysconf(_SC_CLK_TCK);
1082  arts_realtime_end = times(&arts_cputime_end);
1083  if (clktck > 0 && arts_realtime_start != (clock_t)-1 &&
1084  arts_realtime_end != (clock_t)-1) {
1085  out1 << "This run took " << fixed << setprecision(2)
1086  << (Numeric)(arts_realtime_end - arts_realtime_start) / (Numeric)clktck
1087  << "s (" << fixed << setprecision(2)
1088  << (Numeric)(
1089  (arts_cputime_end.tms_stime - arts_cputime_start.tms_stime) +
1090  (arts_cputime_end.tms_utime - arts_cputime_start.tms_utime)) /
1091  (Numeric)clktck
1092  << "s CPU time)\n";
1093  }
1094 #endif
1095 
1096  out1 << "Everything seems fine. Goodbye.\n";
1097  arts_exit(EXIT_SUCCESS);
1098 }
agenda_record.h
Declarations for AgRecord, storing lookup information for one agenda.
Parameters::reporting
Index reporting
This should be a two digit integer.
Definition: parameters.h:98
Parameters::help
bool help
Only display the help text.
Definition: parameters.h:76
arts_omp_get_thread_num
int arts_omp_get_thread_num()
Wrapper for omp_get_thread_num.
Definition: arts_omp.cc:76
docserver.h
Declarations for the arts documentation server.
define_species_map
void define_species_map()
Definition: species_data.cc:1069
Workspace::wsv_data
static Array< WsvRecord > wsv_data
Global WSV data.
Definition: workspace_ng.h:58
MdRecord::GOutSpecType
const ArrayOfArrayOfIndex & GOutSpecType() const
Definition: methods.h:94
MdRecord::GOutType
const ArrayOfIndex & GOutType() const
Definition: methods.h:93
exceptions.h
The declarations of all the exception classes.
auto_md.h
out_basename
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:42
Parameters::docserver
Index docserver
Port to use for the docserver.
Definition: parameters.h:125
absorption.h
Declarations required for the calculation of absorption coefficients.
define_agenda_data
void define_agenda_data()
Definition: agendas.cc:44
MdRecord::GInType
const ArrayOfIndex & GInType() const
Definition: methods.h:98
Parameters
Structure to hold all command line Parameters.
Definition: parameters.h:42
global_data::md_data_raw
const Array< MdRecord > md_data_raw
Lookup information for workspace methods.
Definition: methods.cc:39
ARTS::Var::verbosity
Verbosity verbosity(Workspace &ws) noexcept
Definition: autoarts.h:7112
WorkspaceMemoryHandler::initialize
void initialize()
Initialization dispatch functions.
Definition: workspace_memory_handler.cc:838
Parameters::usage
String usage
Short message how to call the program.
Definition: parameters.h:72
Parameters::version
bool version
Display version information.
Definition: parameters.h:78
option_input
void option_input(const String &input)
React to option ‘input’.
Definition: main.cc:305
global_data::MdRawMap
const map< String, Index > MdRawMap
The map associated with md_data_raw.
Definition: methods_aux.cc:41
arts_omp_get_max_threads
int arts_omp_get_max_threads()
Wrapper for omp_get_max_threads.
Definition: arts_omp.cc:46
ARTS_FULL_VERSION
#define ARTS_FULL_VERSION
Definition: auto_version.h:1
parameters
Parameters parameters
Holds the command line parameters.
Definition: parameters.cc:41
Agenda
The Agenda class.
Definition: agenda_class.h:44
Parameters::workspacevariables
String workspacevariables
If this is given the argument ‘all’, it simply prints a list of all workspace variables.
Definition: parameters.h:116
my_basic_string< char >::size_type
Index size_type
Definition: mystring.h:108
Agenda::set_main_agenda
void set_main_agenda()
Definition: agenda_class.h:88
Array< String >
Parameters::plain
bool plain
Generate plain help out suitable for script processing.
Definition: parameters.h:123
methods
std::vector< Method > methods()
Definition: make_autoarts_h.cc:129
Absorption::nelem
Index nelem(const Lines &l)
Number of lines.
Definition: absorptionlines.h:1820
Parameters::describe
String describe
Print the description String of the given workspace variable or method.
Definition: parameters.h:119
Parameters::helptext
String helptext
Longer message explaining the options.
Definition: parameters.h:74
messages.h
Declarations having to do with the four output streams.
describe
String describe(ConstTensor7View x)
Describe Tensor7.
Definition: describe.cc:38
global_data::workspace_memory_handler
WorkspaceMemoryHandler workspace_memory_handler
The workspace memory handler Defined in workspace_ng.cc.
Definition: interactive_workspace.cc:21
my_basic_string< char >
Parameters::basename
String basename
If this is specified (with the -b –basename option), it is used as the base name for the report file ...
Definition: parameters.h:82
global_data::MdMap
const map< String, Index > MdMap
The map associated with md_data.
Definition: methods_aux.cc:39
get_parameters
bool get_parameters(int argc, char **argv)
Get the command line parameters.
Definition: parameters.cc:71
Workspace::define_wsv_data
static void define_wsv_data()
Define workspace variables.
Definition: workspace.cc:39
report_file
ofstream report_file
The report file.
Definition: messages.cc:45
ArtsParser::parse_tasklist
void parse_tasklist()
Public interface to the main function of the parser.
Definition: parser.cc:50
expand_md_data_raw_to_md_data
void expand_md_data_raw_to_md_data()
Expand supergeneric methods.
Definition: methods_aux.cc:410
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Verbosity
Definition: messages.h:49
Verbosity::set_agenda_verbosity
void set_agenda_verbosity(Index v)
Definition: messages.h:70
Parameters::controlfiles
ArrayOfString controlfiles
The filenames of the controlfiles.
Definition: parameters.h:90
verbosity_at_launch
Verbosity verbosity_at_launch
The global message verbosity settings:
Definition: messages.cc:34
Verbosity::get_agenda_verbosity
Index get_agenda_verbosity() const
Definition: messages.h:65
define_wsv_group_names
void define_wsv_group_names()
Define the array of workspace variable group names.
Definition: groups.cc:77
main
int main(int argc, char **argv)
This is the main function of ARTS.
Definition: main.cc:612
global_data.h
ARTS::Var::time
Time time(Workspace &ws) noexcept
Definition: autoarts.h:7043
set_reporting_level
void set_reporting_level(Index r)
Set the reporting level.
Definition: main.cc:79
MdRecord::Name
const String & Name() const
Definition: methods.h:88
MdRecord::In
const ArrayOfIndex & In() const
Definition: methods.h:96
check_agenda_data
bool check_agenda_data()
Check that agendas.cc and workspace.cc are consistent.
Definition: agenda_record.cc:115
parameters.h
This file contains header information for the dealing with command line parameters.
Parameters::groups
bool groups
Print a list of all workspace variable groups.
Definition: parameters.h:121
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
open_output_file
void open_output_file(ofstream &file, const String &name)
Open a file for writing.
Definition: file.cc:93
Parameters::daemon
bool daemon
Flag to run the docserver in the background.
Definition: parameters.h:129
Workspace::initialize
void initialize()
Reset the size of the workspace.
Definition: workspace_ng.h:111
Parameters::methods
String methods
If this is given the argument ‘all’, it simply prints a list of all methods.
Definition: parameters.h:102
global_data::md_data
const Array< MdRecord > md_data
Lookup information for workspace methods.
Definition: interactive_workspace.cc:19
polite_goodby
void polite_goodby()
Remind the user of –help and exit return value 1.
Definition: main.cc:61
define_agenda_map
void define_agenda_map()
Definition: agenda_record.cc:95
auto_version.h
parser.h
Verbosity::valid
bool valid() const
Check if artsmessages contains valid message levels.
Definition: messages.h:61
define_md_raw_map
void define_md_raw_map()
Define MdRawMap.
Definition: methods_aux.cc:509
workspace_ng.h
This file contains the Workspace class.
MdRecord
All information for one workspace method.
Definition: methods.h:41
Arts2
void Arts2(Workspace &ws, const Agenda &input_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: Arts2.
Definition: m_agenda.cc:231
Parameters::baseurl
String baseurl
Baseurl for the docserver.
Definition: parameters.h:127
ArtsParser
Definition: parser.h:26
option_methods
void option_methods(const String &methods)
React to option ‘methods’.
Definition: main.cc:121
String
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:280
Parameters::check_docs
bool check_docs
Flag to check built-in documentation.
Definition: parameters.h:133
Workspace::WsvMap
static map< String, Index > WsvMap
Global map associated with wsv_data.
Definition: workspace_ng.h:61
Verbosity::set_file_verbosity
void set_file_verbosity(Index v)
Definition: messages.h:72
Workspace
Workspace class.
Definition: workspace_ng.h:40
MdRecord::GInSpecType
const ArrayOfArrayOfIndex & GInSpecType() const
Definition: methods.h:99
Agenda::set_name
void set_name(const String &nname)
Set agenda name.
Definition: agenda_class.cc:647
option_workspacevariables
void option_workspacevariables(const String &workspacevariables)
React to option ‘workspacevariables’.
Definition: main.cc:466
COMPILE_FLAGS
#define COMPILE_FLAGS
Definition: config.h:4
Verbosity::get_screen_verbosity
Index get_screen_verbosity() const
Definition: messages.h:66
file.h
This file contains basic functions to handle ASCII files.
Verbosity::get_file_verbosity
Index get_file_verbosity() const
Definition: messages.h:67
Parameters::input
String input
This is complementary to the methods switch.
Definition: parameters.h:112
ARTS::Var::x
Vector x(Workspace &ws) noexcept
Definition: autoarts.h:7346
option_describe
void option_describe(const String &describe)
React to option ‘describe’.
Definition: main.cc:548
Parameters::numthreads
Index numthreads
The maximum number of threads to use.
Definition: parameters.h:104
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
MdRecord::Out
const ArrayOfIndex & Out() const
Definition: methods.h:91
global_data::wsv_group_names
const ArrayOfString wsv_group_names
The names associated with Wsv groups as Strings.
Definition: global_data.h:93
define_species_data
void define_species_data()
Definition: species_data.cc:158
arts_exit
void arts_exit(int status)
This is the exit function of ARTS.
Definition: arts.cc:42
FORTRAN_COMPILER
#define FORTRAN_COMPILER
Definition: config.h:10
define_md_map
void define_md_map()
Define MdMap.
Definition: methods_aux.cc:473
Workspace::define_wsv_map
static void define_wsv_map()
Map WSV names to indices.
Definition: workspace_ng.cc:48
my_basic_string< char >::npos
static const Index npos
Define npos:
Definition: mystring.h:106
Parameters::includepath
ArrayOfString includepath
List of paths to search for include files.
Definition: parameters.h:106
arts_mod_time
String arts_mod_time(String)
This function returns the modification time of the arts executable as a string.
Definition: main.cc:595
arts_omp.h
Header file for helper functions for OpenMP.
get_wsv_group_id
Index get_wsv_group_id(const String &name)
Returns the id of the given group.
Definition: groups.cc:223
arts_exit_with_error_message
void arts_exit_with_error_message(const String &m, ArtsOut &out)
Print error message and exit.
Definition: arts.cc:64
COMPILER
#define COMPILER
Definition: config.h:7
Verbosity::set_screen_verbosity
void set_screen_verbosity(Index v)
Definition: messages.h:71
Parameters::datapath
ArrayOfString datapath
List of paths to search for data files.
Definition: parameters.h:108
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:195
methods.h
Declaration of the class MdRecord.
wsv_aux.h
Auxiliary header stuff related to workspace variable groups.
define_md_data_raw
void define_md_data_raw()
Definition: methods.cc:191
mystring.h
This file contains the definition of String, the ARTS string class.
CREATE_OUTS
#define CREATE_OUTS
Definition: messages.h:209
arts.h
The global header file for ARTS.