ARTS  2.3.1285(git:92a29ea9-dirty)
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.)
86  verbosity_at_launch.set_agenda_verbosity(0);
87  verbosity_at_launch.set_screen_verbosity(1);
88  verbosity_at_launch.set_file_verbosity(0);
89  } else {
90  // Reporting was specified. Check consistency and set report
91  // level accordingly.
92 
93  // Separate the three digits:
94  verbosity_at_launch.set_agenda_verbosity(r / 100);
95  verbosity_at_launch.set_screen_verbosity((r % 100) / 10);
96  verbosity_at_launch.set_file_verbosity(r % 10);
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: "
103  << verbosity_at_launch.get_agenda_verbosity() << "\n"
104  << "Verbosity for screen: "
105  << verbosity_at_launch.get_screen_verbosity() << "\n"
106  << "Verbosity for report file: "
107  << verbosity_at_launch.get_file_verbosity() << "\n"
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) {
828  option_methods(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) {
836  option_input(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) {
852  option_describe(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;
929  out_basename = parameters.basename;
930  }
931 
932  // Set the global reporting level, either from reporting command line
933  // option or default.
934  set_reporting_level(parameters.reporting);
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
939  Verbosity verbosity;
940  verbosity = verbosity_at_launch;
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 }
String arts_mod_time(String)
This function returns the modification time of the arts executable as a string.
Definition: main.cc:595
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
bool daemon
Flag to run the docserver in the background.
Definition: parameters.h:129
ArrayOfString controlfiles
The filenames of the controlfiles.
Definition: parameters.h:90
void define_md_map()
Define MdMap.
Definition: methods_aux.cc:473
void option_input(const String &input)
React to option `input&#39;.
Definition: main.cc:305
void polite_goodby()
Remind the user of –help and exit return value 1.
Definition: main.cc:61
Index get_agenda_verbosity() const
Definition: messages.h:65
#define COMPILE_FLAGS
Definition: config.h:4
The Agenda class.
Definition: agenda_class.h:44
Index nelem() const
Number of elements.
Definition: array.h:195
#define ARTS_FULL_VERSION
Definition: auto_version.h:1
void arts_exit(int status)
This is the exit function of ARTS.
Definition: arts.cc:42
String baseurl
Baseurl for the docserver.
Definition: parameters.h:127
void option_methods(const String &methods)
React to option `methods&#39;.
Definition: main.cc:121
Declarations having to do with the four output streams.
bool check_docs
Flag to check built-in documentation.
Definition: parameters.h:133
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
String describe(ConstTensor7View x)
Describe Tensor7.
Definition: describe.cc:38
Declarations for the arts documentation server.
#define FORTRAN_COMPILER
Definition: config.h:10
void initialize()
Reset the size of the workspace.
Definition: workspace_ng.h:111
int arts_omp_get_thread_num()
Wrapper for omp_get_thread_num.
Definition: arts_omp.cc:76
bool groups
Print a list of all workspace variable groups.
Definition: parameters.h:121
void parse_tasklist()
Public interface to the main function of the parser.
Definition: parser.cc:50
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:42
void initialize()
Initialization dispatch functions.
int arts_omp_get_max_threads()
Wrapper for omp_get_max_threads.
Definition: arts_omp.cc:46
const ArrayOfIndex & Out() const
Definition: methods.h:91
void option_describe(const String &describe)
React to option `describe&#39;.
Definition: main.cc:548
void set_agenda_verbosity(Index v)
Definition: messages.h:70
const map< String, Index > MdRawMap
The map associated with md_data_raw.
Definition: methods_aux.cc:41
This file contains basic functions to handle ASCII files.
Structure to hold all command line Parameters.
Definition: parameters.h:42
String methods
If this is given the argument `all&#39;, it simply prints a list of all methods.
Definition: parameters.h:102
All information for one workspace method.
Definition: methods.h:41
void set_reporting_level(Index r)
Set the reporting level.
Definition: main.cc:79
void define_species_map()
String input
This is complementary to the methods switch.
Definition: parameters.h:112
const String & Name() const
Definition: methods.h:88
ArrayOfString includepath
List of paths to search for include files.
Definition: parameters.h:106
void define_agenda_map()
void define_agenda_data()
Definition: agendas.cc:44
const map< String, Index > MdMap
The map associated with md_data.
Definition: methods_aux.cc:39
This file contains the Workspace class.
ArrayOfString datapath
List of paths to search for data files.
Definition: parameters.h:108
WorkspaceMemoryHandler workspace_memory_handler
The workspace memory handler Defined in workspace_ng.cc.
void expand_md_data_raw_to_md_data()
Expand supergeneric methods.
Definition: methods_aux.cc:410
Index numthreads
The maximum number of threads to use.
Definition: parameters.h:104
The global header file for ARTS.
Parameters parameters
Holds the command line parameters.
Definition: parameters.cc:41
_CS_string_type str() const
Definition: sstream.h:491
bool help
Only display the help text.
Definition: parameters.h:76
static void define_wsv_data()
Define workspace variables.
Definition: workspace.cc:39
#define CREATE_OUTS
Definition: messages.h:209
const ArrayOfIndex & In() const
Definition: methods.h:96
void set_file_verbosity(Index v)
Definition: messages.h:72
void set_main_agenda(bool main_agenda)
Definition: messages.h:73
The declarations of all the exception classes.
Index reporting
This should be a two digit integer.
Definition: parameters.h:98
bool check_agenda_data()
Check that agendas.cc and workspace.cc are consistent.
std::vector< Method > methods()
#define COMPILER
Definition: config.h:7
ofstream report_file
The report file.
Definition: messages.cc:45
const ArrayOfArrayOfIndex & GInSpecType() const
Definition: methods.h:99
void option_workspacevariables(const String &workspacevariables)
React to option `workspacevariables&#39;.
Definition: main.cc:466
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
Index docserver
Port to use for the docserver.
Definition: parameters.h:125
Declarations required for the calculation of absorption coefficients.
int main(int argc, char **argv)
This is the main function of ARTS.
Definition: main.cc:612
String usage
Short message how to call the program.
Definition: parameters.h:72
void define_species_data()
void arts_exit_with_error_message(const String &m, ArtsOut &out)
Print error message and exit.
Definition: arts.cc:64
void define_md_raw_map()
Define MdRawMap.
Definition: methods_aux.cc:509
This can be used to make arrays out of anything.
Definition: array.h:40
void open_output_file(ofstream &file, const String &name)
Open a file for writing.
Definition: file.cc:93
const ArrayOfIndex & GOutType() const
Definition: methods.h:93
void define_wsv_group_names()
Define the array of workspace variable group names.
Definition: groups.cc:77
const ArrayOfString wsv_group_names
The names associated with Wsv groups as Strings.
Definition: global_data.h:93
void set_name(const String &nname)
Set agenda name.
static map< String, Index > WsvMap
Global map associated with wsv_data.
Definition: workspace_ng.h:61
Index get_file_verbosity() const
Definition: messages.h:67
bool get_parameters(int argc, char **argv)
Get the command line parameters.
Definition: parameters.cc:71
void define_md_data_raw()
Definition: methods.cc:191
void set_main_agenda()
Definition: agenda_class.h:88
String workspacevariables
If this is given the argument `all&#39;, it simply prints a list of all workspace variables.
Definition: parameters.h:116
Workspace class.
Definition: workspace_ng.h:40
const ArrayOfArrayOfIndex & GOutSpecType() const
Definition: methods.h:94
const Array< MdRecord > md_data
Lookup information for workspace methods.
Verbosity verbosity_at_launch
The global message verbosity settings:
Definition: messages.cc:34
bool version
Display version information.
Definition: parameters.h:78
static void define_wsv_map()
Map WSV names to indices.
Definition: workspace_ng.cc:48
const ArrayOfIndex & GInType() const
Definition: methods.h:98
static const Index npos
Define npos:
Definition: mystring.h:106
Index get_screen_verbosity() const
Definition: messages.h:66
Header file for helper functions for OpenMP.
This file contains header information for the dealing with command line parameters.
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
bool valid() const
Check if artsmessages contains valid message levels.
Definition: messages.h:61
bool plain
Generate plain help out suitable for script processing.
Definition: parameters.h:123
Declaration of the class MdRecord.
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:280
Declarations for AgRecord, storing lookup information for one agenda.
This file contains the definition of String, the ARTS string class.
void Arts2(Workspace &ws, const Agenda &input_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: Arts2.
Definition: m_agenda.cc:231
const Array< MdRecord > md_data_raw
Lookup information for workspace methods.
Definition: methods.cc:39
void set_screen_verbosity(Index v)
Definition: messages.h:71
String describe
Print the description String of the given workspace variable or method.
Definition: parameters.h:119
Auxiliary header stuff related to workspace variable groups.
String helptext
Longer message explaining the options.
Definition: parameters.h:74