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