ARTS 2.5.4 (git: 4c0d3b4d)
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
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
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
305void 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
466void option_workspacevariables(const String& workspacevariables) {
467 // Make global data visible:
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:
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
586String 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
612int 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:
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 << endl;
725
726 osfeatures << "Include search paths: " << endl;
727 for (auto& path : parameters.includepath) {
728 osfeatures << " " << path << endl;
729 }
730
731 osfeatures << "Data searchpaths: " << endl;
732 for (auto& path : parameters.datapath) {
733 osfeatures << " " << path << endl;
734 }
735 }
736
737 if (parameters.version) {
738 cout << ARTS_FULL_VERSION << arts_mod_time(argv[0]) << endl;
739 cout << osfeatures.str();
740 arts_exit(EXIT_SUCCESS);
741 }
742
744#ifdef _OPENMP
745 omp_set_num_threads((int)parameters.numthreads);
746#else
747 cerr << "Ignoring commandline option --numthreads/-n.\n"
748 << "This option only works with an OpenMP enabled ARTS build.\n";
749#endif
750 }
751
752 // For the next couple of options we need to have the workspce and
753 // method lookup data.
754
755 // Initialize the wsv group name array:
757
758 // Initialize the wsv data:
760
761 // Initialize WsvMap:
763
764 // Initialize the md data:
766
767 // Expand supergeneric methods:
769
770 // Initialize MdMap:
772
773 // Initialize MdRawMap (needed by parser and online docu).
775
776 // Initialize the agenda lookup data:
778
779 // Initialize AgendaMap:
781
782 // Check that agenda information in wsv_data and agenda_data is consistent:
784
785 // Initialize memory handler.
787
788 // Make all global data visible:
790
791 // Now we are set to deal with the more interesting command line
792 // switches.
793#ifdef ENABLE_DOCSERVER
795 // Check built-in docs and then exit
796 const auto broken_links = Docserver::list_broken_description_links();
797 const size_t nbroken = std::get<0>(broken_links);
798 for (auto&& s : std::get<1>(broken_links)) {
799 std::cout << s << std::endl;
800 }
801 std::cout << std::endl
802 << nbroken << " broken link" << (nbroken == 1 ? "" :"s")
803 << " found." << std::endl;
804 arts_exit(nbroken ? EXIT_FAILURE : EXIT_SUCCESS);
805 }
806#endif
807
808 // React to option `methods'. If given the argument `all', it
809 // should simply prints a list of all methods. If given the name of
810 // a variable, it should print all methods that produce this
811 // variable as output.
812 if ("" != parameters.methods) {
814 arts_exit(EXIT_SUCCESS);
815 }
816
817 // React to option `input'. Given the name of a variable (or group)
818 // it should print all methods that need this variable (or group) as
819 // input.
820 if ("" != parameters.input) {
822 arts_exit(EXIT_SUCCESS);
823 }
824
825 // React to option `workspacevariables'. If given the argument `all',
826 // it should simply prints a list of all variables. If given the
827 // name of a method, it should print all variables that are needed
828 // by that method.
829 if ("" != parameters.workspacevariables) {
831 arts_exit(EXIT_SUCCESS);
832 }
833
834 // React to option `describe'. This should print the description
835 // String of the given workspace variable or method.
836 if ("" != parameters.describe) {
838 arts_exit(EXIT_SUCCESS);
839 }
840
841 // React to option `groups'. This should simply print a list of all
842 // workspace variable groups.
843 if (parameters.groups) {
844 if (!parameters.plain) {
845 cout
846 << "\n*-------------------------------------------------------------------*\n"
847 << "Complete list of ARTS workspace variable groups:\n"
848 << "---------------------------------------------------------------------\n";
849 }
850
851 for (Index i = 0; i < wsv_group_names.nelem(); ++i) {
852 if (!parameters.plain) cout << "- ";
853 cout << wsv_group_names[i] << "\n";
854 }
855
856 if (!parameters.plain)
857 cout
858 << "*-------------------------------------------------------------------*\n\n";
859 arts_exit(EXIT_SUCCESS);
860 }
861
862#ifdef ENABLE_DOCSERVER
863 if (0 != parameters.docserver) {
864 if (parameters.daemon) {
865 int pid = fork();
866 if (!pid) {
867 Docserver docserver(parameters.docserver, parameters.baseurl);
868 docserver.launch(parameters.daemon);
869 arts_exit(0);
870 } else {
871 cout << "Docserver daemon started with PID: " << pid << endl;
872 arts_exit(0);
873 }
874 } else {
875 Docserver docserver(parameters.docserver, parameters.baseurl);
876 cout << "Starting the arts documentation server." << endl;
877 docserver.launch(parameters.daemon);
878 arts_exit(0);
879 }
880 }
881#endif
882
883 // Ok, we are past all the special options. This means the user
884 // wants to get serious and really do a calculation. Check if we
885 // have at least one control file:
886 if (0 == parameters.controlfiles.nelem()) {
887 cerr << "You must specify at least one control file name.\n";
889 }
890
891 // Set the basename according to the first control file, if not
892 // explicitly specified.
893 if ("" == parameters.basename) {
894 extern String out_basename;
895 ArrayOfString fileparts;
896 parameters.controlfiles[0].split(fileparts, "/");
897 out_basename = fileparts[fileparts.nelem() - 1];
898 // Find the last . in the name
899 String::size_type p = out_basename.rfind(".arts");
900
901 if (String::npos == p) {
902 // This is an error handler for the case that somebody gives
903 // a supposed file name that does not contain the extension
904 // ".arts"
905
906 cerr << "The controlfile must have the extension .arts.\n";
908 }
909
910 // Kill everything starting from the `.'
911 out_basename.erase(p);
912 } else {
913 extern String out_basename;
915 }
916
917 // Set the global reporting level, either from reporting command line
918 // option or default.
920
921 // Keep around a global copy of the verbosity levels at launch, so that
922 // verbosityInit() can be used to reset them in the control file
924 Verbosity verbosity;
925 verbosity = verbosity_at_launch;
926 verbosity.set_main_agenda(true);
927
929
930 //--------------------< Open report file >--------------------
931 // This one needs its own little try block, because we have to
932 // write error messages to cerr directly since the report file
933 // will not exist.
934 try {
935 extern String out_basename; // Basis for file name
936 extern ofstream report_file; // Report file pointer
937 ostringstream report_file_ext;
938
939 report_file_ext << ".rep";
940 open_output_file(report_file, out_basename + report_file_ext.str());
941 } catch (const std::runtime_error& x) {
942 cerr << x.what() << "\n"
943 << "I have to be able to write to my report file.\n";
944 arts_exit();
945 }
946
947 // Now comes the global try block. Exceptions caught after this
948 // one are general stuff like file opening errors.
949 try {
950 out1 << "Executing ARTS.\n";
951
952 // Output command line:
953 out1 << "Command line:\n";
954 for (Index i = 0; i < argc; ++i) {
955 out1 << argv[i] << " ";
956 }
957 out1 << "\n";
958
959 // Output full program name (with version number):
960 out1 << "Version: " << ARTS_FULL_VERSION << arts_mod_time(argv[0]) << "\n";
961
962 // Output more details about the compilation:
963 out2 << osfeatures.str() << "\n";
964
965 // Output some OpenMP specific information on output level 2:
966#ifdef _OPENMP
967 out2 << "Running with OpenMP, "
968 << "maximum number of threads = " << arts_omp_get_max_threads()
969 << ".\n";
970#else
971 out2 << "Running without OpenMP.\n";
972#endif
973
974 // Output a short hello from each thread to out3:
975#ifdef _OPENMP
976#pragma omp parallel default(none) shared(out3)
977 {
978 ostringstream os;
979 int tn = arts_omp_get_thread_num();
980 os << " Thread " << tn << ": ready.\n";
981 out3 << os.str();
982 }
983#endif
984 out2 << "\n";
985
986 time_t rawtime;
987 struct tm* timeinfo;
988
989 time(&rawtime);
990 timeinfo = localtime(&rawtime);
991 out2 << "Run started: " << asctime(timeinfo) << "\n";
992
993 // Output verbosity settings. This is not too interesting, it
994 // goes only to out3.
995 out3 << "Verbosity settings: Agendas: "
996 << verbosity.get_agenda_verbosity() << "\n"
997 << " Screen: "
998 << verbosity.get_screen_verbosity() << "\n"
999 << " Report file: "
1000 << verbosity.get_file_verbosity() << "\n";
1001
1002 out3 << "\nReading control files:\n";
1003 for (Index i = 0; i < parameters.controlfiles.nelem(); ++i) {
1004 try {
1005 out3 << "- " << parameters.controlfiles[i] << "\n";
1006
1007 // The list of methods to execute and their keyword data from
1008 // the control file.
1009 Agenda tasklist;
1010
1011 Workspace workspace;
1012
1013 // Call the parser to parse the control text:
1014 ArtsParser arts_parser(tasklist, parameters.controlfiles[i], verbosity);
1015
1016 arts_parser.parse_tasklist();
1017
1018 tasklist.set_name("Arts");
1019
1020 tasklist.set_main_agenda();
1021
1022 //tasklist.find_unused_variables();
1023
1024 workspace.initialize();
1025
1026 // Execute main agenda:
1027 Arts2(workspace, tasklist, verbosity);
1028 } catch (const std::exception& x) {
1029 ostringstream os;
1030 os << "Run-time error in controlfile: " << parameters.controlfiles[i]
1031 << '\n'
1032 << x.what();
1033 throw runtime_error(os.str());
1034 }
1035 }
1036 } catch (const std::runtime_error& x) {
1037#ifdef TIME_SUPPORT
1038 struct tms arts_cputime_end;
1039 clock_t arts_realtime_end;
1040 long clktck = 0;
1041
1042 clktck = sysconf(_SC_CLK_TCK);
1043 arts_realtime_end = times(&arts_cputime_end);
1044 if (clktck > 0 && arts_realtime_start != (clock_t)-1 &&
1045 arts_realtime_end != (clock_t)-1) {
1046 out1 << "This run took " << fixed << setprecision(2)
1047 << (Numeric)(arts_realtime_end - arts_realtime_start) /
1048 (Numeric)clktck
1049 << "s (" << fixed << setprecision(2)
1050 << (Numeric)(
1051 (arts_cputime_end.tms_stime - arts_cputime_start.tms_stime) +
1052 (arts_cputime_end.tms_utime - arts_cputime_start.tms_utime)) /
1053 (Numeric)clktck
1054 << "s CPU time)\n";
1055 }
1056#endif
1057
1058 arts_exit_with_error_message(x.what(), out0);
1059 }
1060
1061#ifdef TIME_SUPPORT
1062 struct tms arts_cputime_end;
1063 clock_t arts_realtime_end;
1064 long clktck = 0;
1065
1066 clktck = sysconf(_SC_CLK_TCK);
1067 arts_realtime_end = times(&arts_cputime_end);
1068 if (clktck > 0 && arts_realtime_start != (clock_t)-1 &&
1069 arts_realtime_end != (clock_t)-1) {
1070 out1 << "This run took " << fixed << setprecision(2)
1071 << (Numeric)(arts_realtime_end - arts_realtime_start) / (Numeric)clktck
1072 << "s (" << fixed << setprecision(2)
1073 << (Numeric)(
1074 (arts_cputime_end.tms_stime - arts_cputime_start.tms_stime) +
1075 (arts_cputime_end.tms_utime - arts_cputime_start.tms_utime)) /
1076 (Numeric)clktck
1077 << "s CPU time)\n";
1078 }
1079#endif
1080
1081 out1 << "Everything seems fine. Goodbye.\n";
1082 arts_exit(EXIT_SUCCESS);
1083}
Declarations required for the calculation of absorption coefficients.
void define_agenda_map()
bool check_agenda_data()
Check that agendas.cc and workspace.cc are consistent.
Declarations for AgRecord, storing lookup information for one agenda.
void define_agenda_data()
Definition: agendas.cc:44
void arts_exit_with_error_message(const String &m, ArtsOut &out)
Print error message and exit.
Definition: arts.cc:64
void arts_exit(int status)
This is the exit function of ARTS.
Definition: arts.cc:42
The global header file for ARTS.
void define_wsv_group_names()
Define the array of workspace variable group names.
Definition: groups.cc:77
int arts_omp_get_max_threads()
Wrapper for omp_get_max_threads.
Definition: arts_omp.cc:46
int arts_omp_get_thread_num()
Wrapper for omp_get_thread_num.
Definition: arts_omp.cc:76
Header file for helper functions for OpenMP.
#define ARTS_FULL_VERSION
Definition: auto_version.h:1
The Agenda class.
Definition: agenda_class.h:51
void set_main_agenda()
Definition: agenda_class.h:88
void set_name(const String &nname)
Set agenda name.
Index nelem() const ARTS_NOEXCEPT
Number of elements.
Definition: array.h:197
void parse_tasklist()
Public interface to the main function of the parser.
Definition: parser.cc:51
All information for one workspace method.
Definition: methods.h:41
const ArrayOfIndex & In() const
Definition: methods.h:96
const String & Name() const
Definition: methods.h:88
const ArrayOfIndex & GOutType() const
Definition: methods.h:93
const ArrayOfArrayOfIndex & GInSpecType() const
Definition: methods.h:99
const ArrayOfArrayOfIndex & GOutSpecType() const
Definition: methods.h:94
const ArrayOfIndex & Out() const
Definition: methods.h:91
const ArrayOfIndex & GInType() const
Definition: methods.h:98
Structure to hold all command line Parameters.
Definition: parameters.h:42
bool check_docs
Flag to check built-in documentation.
Definition: parameters.h:133
ArrayOfString includepath
List of paths to search for include files.
Definition: parameters.h:106
String helptext
Longer message explaining the options.
Definition: parameters.h:74
String usage
Short message how to call the program.
Definition: parameters.h:72
bool version
Display version information.
Definition: parameters.h:78
ArrayOfString datapath
List of paths to search for data files.
Definition: parameters.h:108
String workspacevariables
If this is given the argument ‘all’, it simply prints a list of all workspace variables.
Definition: parameters.h:116
String baseurl
Baseurl for the docserver.
Definition: parameters.h:127
String input
This is complementary to the methods switch.
Definition: parameters.h:112
ArrayOfString controlfiles
The filenames of the controlfiles.
Definition: parameters.h:90
bool plain
Generate plain help out suitable for script processing.
Definition: parameters.h:123
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
bool groups
Print a list of all workspace variable groups.
Definition: parameters.h:121
bool help
Only display the help text.
Definition: parameters.h:76
Index reporting
This should be a two digit integer.
Definition: parameters.h:98
Index numthreads
The maximum number of threads to use.
Definition: parameters.h:104
Index docserver
Port to use for the docserver.
Definition: parameters.h:125
bool daemon
Flag to run the docserver in the background.
Definition: parameters.h:129
String describe
Print the description String of the given workspace variable or method.
Definition: parameters.h:119
String methods
If this is given the argument ‘all’, it simply prints a list of all methods.
Definition: parameters.h:102
Index get_screen_verbosity() const
Definition: messages.h:66
void set_main_agenda(bool main_agenda)
Definition: messages.h:73
Index get_agenda_verbosity() const
Definition: messages.h:65
void set_screen_verbosity(Index v)
Definition: messages.h:71
bool valid() const
Check if artsmessages contains valid message levels.
Definition: messages.h:61
void set_agenda_verbosity(Index v)
Definition: messages.h:70
Index get_file_verbosity() const
Definition: messages.h:67
void set_file_verbosity(Index v)
Definition: messages.h:72
void initialize()
Initialization dispatch functions.
Workspace class.
Definition: workspace_ng.h:40
void initialize()
Reset the size of the workspace.
Definition: workspace_ng.h:111
static void define_wsv_data()
Define workspace variables.
Definition: workspace.cc:39
static void define_wsv_map()
Map WSV names to indices.
Definition: workspace_ng.cc:48
static Array< WsvRecord > wsv_data
Global WSV data.
Definition: workspace_ng.h:58
static map< String, Index > WsvMap
Global map associated with wsv_data.
Definition: workspace_ng.h:61
static const Index npos
Define npos:
Definition: mystring.h:107
#define COMPILE_FLAGS
Definition: config.h:4
#define COMPILER
Definition: config.h:7
#define FORTRAN_COMPILER
Definition: config.h:10
#define ARTS_ASSERT(condition,...)
Definition: debug.h:83
String describe(ConstTensor7View x)
Describe Tensor7.
Definition: describe.cc:38
Declarations for the arts documentation server.
The declarations of all the exception classes.
void open_output_file(ofstream &file, const String &name)
Open a file for writing.
Definition: file.cc:93
This file contains basic functions to handle ASCII files.
Index get_wsv_group_id(const String &name)
Returns the id of the given group.
Definition: groups.cc:228
void Arts2(Workspace &ws, const Agenda &input_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: Arts2.
Definition: m_agenda.cc:231
void set_reporting_level(Index r)
Set the reporting level.
Definition: main.cc:79
int main(int argc, char **argv)
This is the main function of ARTS.
Definition: main.cc:612
void option_workspacevariables(const String &workspacevariables)
React to option ‘workspacevariables’.
Definition: main.cc:466
void option_input(const String &input)
React to option ‘input’.
Definition: main.cc:305
String arts_mod_time(String)
This function returns the modification time of the arts executable as a string.
Definition: main.cc:595
void option_methods(const String &methods)
React to option ‘methods’.
Definition: main.cc:121
void polite_goodby()
Remind the user of –help and exit return value 1.
Definition: main.cc:61
void option_describe(const String &describe)
React to option ‘describe’.
Definition: main.cc:548
std::vector< Method > methods()
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
Verbosity verbosity_at_launch
The global message verbosity settings:
Definition: messages.cc:34
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:42
ofstream report_file
The report file.
Definition: messages.cc:45
Declarations having to do with the four output streams.
#define CREATE_OUTS
Definition: messages.h:209
void define_md_data_raw()
Definition: methods.cc:191
Declaration of the class MdRecord.
void define_md_raw_map()
Define MdRawMap.
Definition: methods_aux.cc:509
void define_md_map()
Define MdMap.
Definition: methods_aux.cc:473
void expand_md_data_raw_to_md_data()
Expand supergeneric methods.
Definition: methods_aux.cc:410
This file contains the definition of String, the ARTS string class.
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:287
Index nelem(const Lines &l)
Number of lines.
constexpr Rational end(Rational Ju, Rational Jl, Polarization type) noexcept
Gives the largest M for a polarization type of this transition.
Definition: zeemandata.h:113
const Array< MdRecord > md_data_raw
Lookup information for workspace methods.
Definition: methods.cc:39
WorkspaceMemoryHandler workspace_memory_handler
The workspace memory handler Defined in workspace_ng.cc.
Definition: workspace_ng.cc:31
const Array< MdRecord > md_data
Lookup information for workspace methods.
Definition: methods_aux.cc:48
const map< String, Index > MdMap
The map associated with md_data.
Definition: methods_aux.cc:39
const map< String, Index > MdRawMap
The map associated with md_data_raw.
Definition: methods_aux.cc:41
const ArrayOfString wsv_group_names
The names associated with Wsv groups as Strings.
Definition: global_data.h:90
bool get_parameters(int argc, char **argv)
Get the command line parameters.
Definition: parameters.cc:71
Parameters parameters
Holds the command line parameters.
Definition: parameters.cc:41
This file contains header information for the dealing with command line parameters.
This file contains the Workspace class.
Auxiliary header stuff related to workspace variable groups.