ARTS 2.5.11 (git: 6827797f)
main.cc
Go to the documentation of this file.
1
14#include "arts.h"
15#include <memory>
16
17#ifdef ENABLE_DOCSERVER
18#include <unistd.h>
19#endif
20
21#include <algorithm>
22#include <chrono>
23#include <filesystem>
24#include <map>
25
26#include "absorption.h"
27#include "agenda_record.h"
28#include "arts_omp.h"
29#include "auto_md.h"
30#include "docserver.h"
31#include "exceptions.h"
32#include "file.h"
33#include "global_data.h"
34#include "messages.h"
35#include "methods.h"
36#include "mystring.h"
37#include "parameters.h"
38#include "parser.h"
40#include "workspace.h"
41#include "workspace_ng.h"
42#include "wsv_aux.h"
43#include "wsv_aux_operator.h"
44
47 cerr << "Try `arts --help' for help.\n";
48 arts_exit();
49}
50
64void set_reporting_level(Index r) {
66
67 if (-1 == r) {
68 // Reporting was not specified, set default. (No output from
69 // agendas (except main of course), only the important stuff to
70 // the screen, nothing to the file.)
74 } else {
75 // Reporting was specified. Check consistency and set report
76 // level accordingly.
77
78 // Separate the three digits:
82
84 cerr << "Illegal value specified for --reporting (-r).\n"
85 << "The specified value is " << r << ", which would be\n"
86 << "interpreted as:\n"
87 << "Verbosity for agendas: "
89 << "Verbosity for screen: "
91 << "Verbosity for report file: "
93 << "Only values of 0-3 are allowed for each verbosity.\n";
94 arts_exit();
95 }
96 }
97}
98
106void option_methods(Workspace& workspace, const String& methods) {
107 // Make global data visible:
109 extern const Parameters parameters;
111
112 // This is used to count the number of matches to a query, so
113 // that `none' can be output if necessary
114 Index hitcount;
115
116 // First check if the user gave the special name `all':
117
118 if ("all" == methods) {
119 if (!parameters.plain) {
120 cout
121 << "\n*-------------------------------------------------------------------*\n"
122 << "Complete list of ARTS workspace methods:\n"
123 << "---------------------------------------------------------------------\n";
124 }
125 for (Index i = 0; i < md_data_raw.nelem(); ++i) {
126 if (!parameters.plain) cout << "- ";
127 cout << md_data_raw[i].Name() << "\n";
128 }
129
130 if (!parameters.plain)
131 cout
132 << "*-------------------------------------------------------------------*\n\n";
133
134 return;
135 }
136
137 // Ok, so the user has probably specified a workspace variable or
138 // workspace variable group.
139
140 // Check if the user gave the name of a specific variable.
141 auto mi = workspace.WsvMap_ptr->find(methods);
142 if (mi != workspace.WsvMap_ptr->end()) {
143 // If we are here, then the given name matches a variable.
144 Index wsv_key = mi->second;
145
146 // List generic methods:
147 hitcount = 0;
148 cout
149 << "\n*-------------------------------------------------------------------*\n"
150 << "Generic and supergeneric methods that can generate "
151 << (*workspace.wsv_data_ptr)[wsv_key].Name() << ":\n"
152 << "---------------------------------------------------------------------\n";
153 for (Index i = 0; i < md_data_raw.nelem(); ++i) {
154 // Get handle on method record:
155 const MdRecord& mdd = md_data_raw[i];
156
157 // This if statement checks whether GOutType, the list
158 // of output variable types contains the group of the
159 // requested variable.
160 // The else clause picks up methods with supergeneric input.
161 if (count(mdd.GOutType().begin(),
162 mdd.GOutType().end(),
163 (*workspace.wsv_data_ptr)[wsv_key].Group())) {
164 cout << "- " << mdd.Name() << "\n";
165 ++hitcount;
166 } else if (count(mdd.GOutType().begin(),
167 mdd.GOutType().end(),
168 get_wsv_group_id("Any"))) {
169 for (Index j = 0; j < mdd.GOutType().nelem(); j++) {
170 if (mdd.GOutType()[j] == get_wsv_group_id("Any")) {
171 if (mdd.GOutSpecType()[j].nelem()) {
172 if (count(mdd.GOutSpecType()[j].begin(),
173 mdd.GOutSpecType()[j].end(),
174 (*workspace.wsv_data_ptr)[wsv_key].Group())) {
175 cout << "- " << mdd.Name() << "\n";
176 ++hitcount;
177 }
178 } else {
179 cout << "- " << mdd.Name() << "\n";
180 ++hitcount;
181 }
182 }
183 }
184 }
185 }
186 if (0 == hitcount) cout << "none\n";
187
188 // List specific methods:
189 hitcount = 0;
190 cout
191 << "\n---------------------------------------------------------------------\n"
192 << "Specific methods that can generate "
193 << (*workspace.wsv_data_ptr)[wsv_key].Name() << ":\n"
194 << "---------------------------------------------------------------------\n";
195 for (Index i = 0; i < md_data_raw.nelem(); ++i) {
196 // Get handle on method record:
197 const MdRecord& mdd = md_data_raw[i];
198
199 // This if statement checks whether Output, the list
200 // of output variables contains the workspace
201 // variable key.
202 if (count(mdd.Out().begin(), mdd.Out().end(), wsv_key)) {
203 cout << "- " << mdd.Name() << "\n";
204 ++hitcount;
205 }
206 }
207 if (0 == hitcount) cout << "none\n";
208
209 cout
210 << "*-------------------------------------------------------------------*\n\n";
211
212 return;
213 }
214
215 // Check if the user gave the name of a variable group.
216
217 // We use the find algorithm from the STL to do this. It
218 // returns an iterator, so to get the index we take the
219 // difference to the begin() iterator.
220 Index group_key =
221 find(wsv_groups.begin(), wsv_groups.end(), methods) -
222 wsv_groups.begin();
223
224 // group_key == wsv_goup_names.nelem() indicates that a
225 // group with this name was not found.
226 if (group_key != wsv_groups.nelem()) {
227 // List generic methods:
228 hitcount = 0;
229 cout
230 << "\n*-------------------------------------------------------------------*\n"
231 << "Generic and supergeneric methods that can generate variables of group "
232 << wsv_groups[group_key] << ":\n"
233 << "---------------------------------------------------------------------\n";
234 for (Index i = 0; i < md_data_raw.nelem(); ++i) {
235 // Get handle on method record:
236 const MdRecord& mdd = md_data_raw[i];
237
238 // This if statement checks whether GOutType, the list
239 // of output variable types contains the
240 // requested group.
241 // The else clause picks up methods with supergeneric input.
242 if (count(mdd.GOutType().begin(), mdd.GOutType().end(), group_key)) {
243 cout << "- " << mdd.Name() << "\n";
244 ++hitcount;
245 } else if (count(mdd.GOutType().begin(),
246 mdd.GOutType().end(),
247 get_wsv_group_id("Any"))) {
248 for (Index j = 0; j < mdd.GOutType().nelem(); j++) {
249 if (mdd.GOutType()[j] == get_wsv_group_id("Any")) {
250 if (mdd.GOutSpecType()[j].nelem()) {
251 if (count(mdd.GOutSpecType()[j].begin(),
252 mdd.GOutSpecType()[j].end(),
253 group_key)) {
254 cout << "- " << mdd.Name() << "\n";
255 ++hitcount;
256 }
257 } else {
258 cout << "- " << mdd.Name() << "\n";
259 ++hitcount;
260 }
261 }
262 }
263 }
264 }
265 if (0 == hitcount) cout << "none\n";
266
267 cout
268 << "*-------------------------------------------------------------------*\n\n";
269
270 return;
271 }
272
273 // If we are here it means that what the user specified is neither
274 // `all', nor a variable, nor a variable group.
275 cerr << "The name " << methods << " matches neither `all',\n"
276 << "nor the name of a workspace variable, nor the name\n"
277 << "of a workspace variable group.\n";
278 arts_exit();
279}
280
288void option_input(const String& input) {
289 // Make global data visible:
292
293 // Ok, so the user has probably specified a workspace variable or
294 // workspace variable group.
295
296 // Check if the user gave the name of a specific variable.
297 auto mi = global_data::WsvMap.find(input);
298 if (mi != global_data::WsvMap.end()) {
299 // This is used to count the number of matches to a query, so
300 // that `none' can be output if necessary
301 Index hitcount = 0;
302
303 // If we are here, then the given name matches a variable.
304 Index wsv_key = mi->second;
305
306 // List generic methods:
307 cout
308 << "\n*-------------------------------------------------------------------*\n"
309 << "Generic and supergeneric methods that can use "
310 << global_data::wsv_data[wsv_key].Name() << ":\n"
311 << "---------------------------------------------------------------------\n";
312 for (Index i = 0; i < md_data_raw.nelem(); ++i) {
313 // Get handle on method record:
314 const MdRecord& mdd = md_data_raw[i];
315
316 // This if statement checks whether GInType, the list
317 // of input variable types contains the group of the
318 // requested variable.
319 // The else clause picks up methods with supergeneric input.
320 if (count(mdd.GInType().begin(),
321 mdd.GInType().end(),
322 global_data::wsv_data[wsv_key].Group())) {
323 cout << "- " << mdd.Name() << "\n";
324 ++hitcount;
325 } else if (count(mdd.GInType().begin(),
326 mdd.GInType().end(),
327 get_wsv_group_id("Any"))) {
328 for (Index j = 0; j < mdd.GInType().nelem(); j++) {
329 if (mdd.GInType()[j] == get_wsv_group_id("Any")) {
330 if (mdd.GInSpecType()[j].nelem()) {
331 if (count(mdd.GInSpecType()[j].begin(),
332 mdd.GInSpecType()[j].end(),
333 global_data::wsv_data[wsv_key].Group())) {
334 cout << "- " << mdd.Name() << "\n";
335 ++hitcount;
336 }
337 } else {
338 cout << "- " << mdd.Name() << "\n";
339 ++hitcount;
340 }
341 }
342 }
343 }
344 }
345 if (0 == hitcount) cout << "none\n";
346
347 // List specific methods:
348 hitcount = 0;
349 cout
350 << "\n---------------------------------------------------------------------\n"
351 << "Specific methods that require "
352 << global_data::wsv_data[wsv_key].Name() << ":\n"
353 << "---------------------------------------------------------------------\n";
354 for (Index i = 0; i < md_data_raw.nelem(); ++i) {
355 // Get handle on method record:
356 const MdRecord& mdd = md_data_raw[i];
357
358 // This if statement checks whether Output, the list
359 // of output variables contains the workspace
360 // variable key.
361 if (count(mdd.In().begin(), mdd.In().end(), wsv_key)) {
362 cout << "- " << mdd.Name() << "\n";
363 ++hitcount;
364 }
365 }
366 if (0 == hitcount) cout << "none\n";
367
368 cout
369 << "*-------------------------------------------------------------------*\n\n";
370
371 return;
372 }
373
374 // Check if the user gave the name of a variable group.
375
376 // We use the find algorithm from the STL to do this. It
377 // returns an iterator, so to get the index we take the
378 // difference to the begin() iterator.
379 Index group_key =
380 find(wsv_groups.begin(), wsv_groups.end(), input) -
381 wsv_groups.begin();
382
383 // group_key == wsv_goup_names.nelem() indicates that a
384 // group with this name was not found.
385 if (group_key != wsv_groups.nelem()) {
386 // This is used to count the number of matches to a query, so
387 // that `none' can be output if necessary
388 Index hitcount = 0;
389
390 // List generic methods:
391 cout
392 << "\n*-------------------------------------------------------------------*\n"
393 << "Generic and supergeneric methods that require a variable of group "
394 << wsv_groups[group_key] << ":\n"
395 << "---------------------------------------------------------------------\n";
396 for (Index i = 0; i < md_data_raw.nelem(); ++i) {
397 // Get handle on method record:
398 const MdRecord& mdd = md_data_raw[i];
399
400 // This if statement checks whether GOutType, the list
401 // of output variable types contains the
402 // requested group.
403 // The else clause picks up methods with supergeneric input.
404 if (count(mdd.GInType().begin(), mdd.GInType().end(), group_key)) {
405 cout << "- " << mdd.Name() << "\n";
406 ++hitcount;
407 } else if (count(mdd.GInType().begin(),
408 mdd.GInType().end(),
409 get_wsv_group_id("Any"))) {
410 for (Index j = 0; j < mdd.GInType().nelem(); j++) {
411 if (mdd.GInType()[j] == get_wsv_group_id("Any")) {
412 if (mdd.GInSpecType()[j].nelem()) {
413 if (count(mdd.GInSpecType()[j].begin(),
414 mdd.GInSpecType()[j].end(),
415 group_key)) {
416 cout << "- " << mdd.Name() << "\n";
417 ++hitcount;
418 }
419 } else {
420 cout << "- " << mdd.Name() << "\n";
421 ++hitcount;
422 }
423 }
424 }
425 }
426 }
427 if (0 == hitcount) cout << "none\n";
428
429 cout
430 << "*-------------------------------------------------------------------*\n\n";
431
432 return;
433 }
434
435 // If we are here it means that what the user specified is neither
436 // a variable nor a variable group.
437 cerr << "The name " << input << " matches neither the name of a\n"
438 << "workspace variable, nor the name of a workspace variable group.\n";
439 arts_exit();
440}
441
449void option_workspacevariables(const String& workspacevariables) {
450 // Make global data visible:
452 using global_data::MdMap;
453 extern const Parameters parameters;
455
456 // This is used to count the number of matches to a query, so
457 // that `none' can be output if necessary
458 Index hitcount;
459
460 // First check for `all':
461
462 if ("all" == workspacevariables) {
463 if (!parameters.plain) {
464 cout
465 << "\n*-------------------------------------------------------------------*\n"
466 << "Complete list of ARTS workspace variables:\n"
467 << "---------------------------------------------------------------------\n";
468 }
469
470 for (Index i = 0; i < global_data::wsv_data.nelem(); ++i) {
471 if (!parameters.plain) cout << "- ";
472 cout << global_data::wsv_data[i].Name() << "\n";
473 }
474
475 if (!parameters.plain)
476 cout
477 << "*-------------------------------------------------------------------*\n\n";
478 return;
479 }
480
481 // Now check if the user gave the name of a method.
482 auto mi = MdMap.find(workspacevariables);
483 if (mi != MdMap.end()) {
484 // If we are here, then the given name matches a method.
485 // Assign the data record for this method to a local
486 // variable for easier access:
487 const MdRecord& mdr = md_data[mi->second];
488
489 // List generic variables required by this method.
490 hitcount = 0;
491 cout
492 << "\n*-------------------------------------------------------------------*\n"
493 << "Generic workspace variables required by " << mdr.Name()
494 << " are of type:\n"
495 << "---------------------------------------------------------------------\n";
496 for (Index i = 0; i < mdr.GInType().nelem(); ++i) {
497 cout << "- " << wsv_groups[mdr.GInType()[i]] << "\n";
498 ++hitcount;
499 }
500 if (0 == hitcount) cout << "none\n";
501
502 // List specific variables required by this method.
503 hitcount = 0;
504 cout
505 << "\n---------------------------------------------------------------------\n"
506 << "Specific workspace variables required by " << mdr.Name() << ":\n"
507 << "---------------------------------------------------------------------\n";
508 for (Index i = 0; i < mdr.In().nelem(); ++i) {
509 cout << "- " << global_data::wsv_data[mdr.In()[i]].Name() << "\n";
510 ++hitcount;
511 }
512 if (0 == hitcount) cout << "none\n";
513
514 cout
515 << "*-------------------------------------------------------------------*\n\n";
516
517 return;
518 }
519
520 // If we are here, then the user specified nothing that makes sense.
521 cerr << "The name " << workspacevariables << " matches neither `all',\n"
522 << "nor the name of a workspace method.\n";
523 arts_exit();
524}
525
531void option_describe(const String& describe) {
532 // Make global data visible:
535
536 // Let's first assume it is a method that the user wants to have
537 // described.
538
539 // Find method id:
540 auto i = MdRawMap.find(describe);
541 if (i != MdRawMap.end()) {
542 // If we are here, then the given name matches a method.
543 cout << md_data_raw[i->second] << "\n";
544 return;
545 }
546
547 // Ok, let's now assume it is a variable that the user wants to have
548 // described.
549
550 // Find wsv id:
551 i = global_data::WsvMap.find(describe);
552 if (i != global_data::WsvMap.end()) {
553 // If we are here, then the given name matches a workspace
554 // variable.
555 cout << global_data::wsv_data[i->second] << "\n";
556 return;
557 }
558
559 // If we are here, then the given name does not match anything.
560 cerr << "The name " << describe << " matches neither method nor variable.\n";
561 arts_exit();
562}
563
564template <typename TimePoint>
565std::time_t to_time_t(TimePoint time_point) {
566 auto tp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
567 time_point - TimePoint::clock::now() + std::chrono::system_clock::now());
568 return std::chrono::system_clock::to_time_t(tp);
569}
570
576String arts_mod_time(std::string_view filename) {
577 ostringstream os;
578 try {
579 if (std::filesystem::is_regular_file(filename)) {
580 auto modtime = to_time_t(std::filesystem::last_write_time(filename));
581 os << " (compiled " << std::put_time(std::localtime(&modtime), "%F %T")
582 << ")\n";
583 }
584 } catch (const std::exception&) {
585 // Don't crash if we can't get the modification time.
586 }
587 return os.str();
588}
589
591 std::chrono::high_resolution_clock::time_point arts_realtime_start) {
592 const auto arts_realtime_end = std::chrono::high_resolution_clock::now();
593 return std::chrono::duration<double, std::ratio<1>>(arts_realtime_end -
594 arts_realtime_start)
595 .count();
596}
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 const auto arts_realtime_start = std::chrono::high_resolution_clock::now();
618
619 //---------------< 1. Get command line parameters >---------------
620 if (get_parameters(argc, argv)) {
621 // Print an error message and exit:
623 }
624
625 //----------< 2. Evaluate the command line parameters >----------
626 if (parameters.help) {
627 // Just print a help message and then exit.
628 cout << "\n" << parameters.usage << "\n\n";
629 cout << parameters.helptext << "\n\n";
630 arts_exit(EXIT_SUCCESS);
631 }
632
633 ostringstream osfeatures;
634 {
635 osfeatures << "Compiler: " << String(COMPILER) << endl;
636
637 if (String(COMPILER) != "Xcode")
638 osfeatures << "Compile flags: " << COMPILE_FLAGS << endl;
639
640 osfeatures << "Features in this build: " << endl
641 << " Numeric precision: "
642 << ((sizeof(Numeric) == sizeof(double)) ? "double" : "float")
643 << endl
644 << " OpenMP support: "
645#ifdef _OPENMP
646 << "enabled" << endl
647#else
648 << "disabled" << endl
649#endif
650 << " Documentation server: "
651#ifdef ENABLE_DOCSERVER
652 << "enabled" << endl
653#else
654 << "disabled" << endl
655#endif
656 << " Zipped XML support: "
657#ifdef ENABLE_ZLIB
658 << "enabled" << endl
659#else
660 << "disabled" << endl
661#endif
662 << " NetCDF support: "
663#ifdef ENABLE_NETCDF
664 << "enabled" << endl
665#else
666 << "disabled" << endl
667#endif
668 << " Fortran support: "
669#ifdef FORTRAN_COMPILER
670 << "enabled (" << FORTRAN_COMPILER << ")" << endl
671#else
672 << "disabled" << endl
673#endif
674 << " Legacy Fortran Disort:"
675#ifdef ENABLE_DISORT
676 << "enabled" << endl
677#else
678 << "disabled" << endl
679#endif
680 << " RT4 support: "
681#ifdef ENABLE_RT4
682 << "enabled" << endl
683#else
684 << "disabled" << endl
685#endif
686 << " FASTEM support: "
687#ifdef ENABLE_FASTEM
688 << "enabled" << endl
689#else
690 << "disabled" << endl
691#endif
692 << " OEM support: "
693#ifdef OEM_SUPPORT
694 << "enabled" << endl
695 << " MPI support for OEM: "
696#ifdef ENABLE_MPI
697 << "enabled" << endl
698#else
699 << "disabled" << endl
700#endif
701#else
702 << "disabled" << endl
703#endif
704 << " Tmatrix support: "
705#ifdef ENABLE_TMATRIX
706#ifdef ENABLE_TMATRIX_QUAD
707 << "enabled (quad-precision)" << endl
708#else
709 << "enabled (double-precision)" << endl
710#endif
711#else
712 << "disabled" << endl
713#endif
714 << " IPO/LTO support: "
715#ifdef IPO_SUPPORTED
716 << "enabled" << endl
717#else
718 << "disabled" << endl
719#endif
720 << endl;
721
722 osfeatures << "Include search paths: " << endl;
723 for (auto& path : parameters.includepath) {
724 osfeatures << " " << path << endl;
725 }
726
727 osfeatures << "Data searchpaths: " << endl;
728 for (auto& path : parameters.datapath) {
729 osfeatures << " " << path << endl;
730 }
731 }
732
733 if (parameters.version) {
734 cout << arts_get_version_string() << arts_mod_time(argv[0]) << endl;
735 cout << osfeatures.str();
736 arts_exit(EXIT_SUCCESS);
737 }
738
740#ifdef _OPENMP
741 omp_set_num_threads((int)parameters.numthreads);
742#else
743 cerr << "Ignoring commandline option --numthreads/-n.\n"
744 << "This option only works with an OpenMP enabled ARTS build.\n";
745#endif
746 }
747
748 // For the next couple of options we need to have the workspce and
749 // method lookup data.
750
751 // Initialize the wsv group name array:
753
754 // Initialize the wsv data:
756
757 // Initialize WsvMap:
759
760 // Initialize the md data:
762
763 // Expand supergeneric methods:
765
766 // Initialize MdMap:
768
769 // Initialize MdRawMap (needed by parser and online docu).
771
772 // Initialize the agenda lookup data:
774
775 // Initialize AgendaMap:
777
778 // Check that agenda information in wsv_data and agenda_data is consistent:
780
781 // Initialize memory handler.
783
784 auto workspace_shared = Workspace::create();
785
786 Workspace& workspace=*workspace_shared;
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_groups.nelem(); ++i) {
852 if (!parameters.plain) cout << "- ";
853 cout << wsv_groups[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) {
865 arts_exit(0);
866 }
867#endif
868
869 // Ok, we are past all the special options. This means the user
870 // wants to get serious and really do a calculation. Check if we
871 // have at least one control file:
872 if (0 == parameters.controlfiles.nelem()) {
873 cerr << "You must specify at least one control file name.\n";
875 }
876
877 // Set the basename according to the first control file, if not
878 // explicitly specified.
879 if ("" == parameters.basename) {
880 extern String out_basename;
881 ArrayOfString fileparts;
882 parameters.controlfiles[0].split(fileparts, "/");
883 out_basename = fileparts[fileparts.nelem() - 1];
884 // Find the last . in the name
885 String::size_type p = out_basename.rfind(".arts");
886
887 if (String::npos == p) {
888 // This is an error handler for the case that somebody gives
889 // a supposed file name that does not contain the extension
890 // ".arts"
891
892 cerr << "The controlfile must have the extension .arts.\n";
894 }
895
896 // Kill everything starting from the `.'
897 out_basename.erase(p);
898 } else {
899 extern String out_basename;
901 }
902
903 // Set the global reporting level, either from reporting command line
904 // option or default.
906
907 // Keep around a global copy of the verbosity levels at launch, so that
908 // verbosityInit() can be used to reset them in the control file
910 Verbosity verbosity;
911 verbosity = verbosity_at_launch;
912 verbosity.set_main_agenda(true);
913
915
916 //--------------------< Open report file >--------------------
917 // This one needs its own little try block, because we have to
918 // write error messages to cerr directly since the report file
919 // will not exist.
920 try {
921 extern String out_basename; // Basis for file name
922 extern ofstream report_file; // Report file pointer
923 ostringstream report_file_ext;
924
925 report_file_ext << ".rep";
926 open_output_file(report_file, out_basename + report_file_ext.str());
927 } catch (const std::runtime_error& x) {
928 cerr << x.what() << "\n"
929 << "I have to be able to write to my report file.\n";
930 arts_exit();
931 }
932
933 // Now comes the global try block. Exceptions caught after this
934 // one are general stuff like file opening errors.
935 try {
936 out1 << "Executing ARTS.\n";
937
938 // Output command line:
939 out1 << "Command line:\n";
940 for (Index i = 0; i < argc; ++i) {
941 out1 << argv[i] << " ";
942 }
943 out1 << "\n";
944
945 // Output full program name (with version number):
946 out1 << "Version: " << arts_get_version_string() << arts_mod_time(argv[0])
947 << "\n";
948
949 // Output more details about the compilation:
950 out2 << osfeatures.str() << "\n";
951
952 // Output some OpenMP specific information on output level 2:
953#ifdef _OPENMP
954 out2 << "Running with OpenMP, "
955 << "maximum number of threads = " << arts_omp_get_max_threads()
956 << ".\n";
957#else
958 out2 << "Running without OpenMP.\n";
959#endif
960
961 // Output a short hello from each thread to out3:
962#ifdef _OPENMP
963#pragma omp parallel default(none) shared(out3)
964 {
965 ostringstream os;
966 int tn = arts_omp_get_thread_num();
967 os << " Thread " << tn << ": ready.\n";
968 out3 << os.str();
969 }
970#endif
971 out2 << "\n";
972
973 time_t rawtime;
974 struct tm* timeinfo;
975
976 time(&rawtime);
977 timeinfo = localtime(&rawtime);
978 out2 << "Run started: " << asctime(timeinfo) << "\n";
979
980 // Output verbosity settings. This is not too interesting, it
981 // goes only to out3.
982 out3 << "Verbosity settings: Agendas: "
983 << verbosity.get_agenda_verbosity() << "\n"
984 << " Screen: "
985 << verbosity.get_screen_verbosity() << "\n"
986 << " Report file: "
987 << verbosity.get_file_verbosity() << "\n";
988
989 out3 << "\nReading control files:\n";
990 for (Index i = 0; i < parameters.controlfiles.nelem(); ++i) {
991 try {
992 out3 << "- " << parameters.controlfiles[i] << "\n";
993
994 // The list of methods to execute and their keyword data from
995 // the control file.
996 Agenda tasklist{workspace};
997
998 // Call the parser to parse the control text:
999 ArtsParser arts_parser(tasklist, parameters.controlfiles[i], verbosity);
1000
1001 arts_parser.parse_tasklist();
1002
1003 tasklist.set_name("Arts");
1004
1005 tasklist.set_main_agenda();
1006
1007 // Execute main agenda:
1008 Arts2(workspace, tasklist, verbosity);
1009 } catch (const std::exception& x) {
1010 ostringstream os;
1011 os << "Run-time error in controlfile: " << parameters.controlfiles[i]
1012 << '\n'
1013 << x.what();
1014 throw runtime_error(os.str());
1015 }
1016 }
1017 } catch (const std::runtime_error& x) {
1018 out1 << "This run took " << fixed << setprecision(2)
1019 << get_arts_runtime_in_sec(arts_realtime_start) << "s\n";
1020
1021 arts_exit_with_error_message(x.what(), out0);
1022 }
1023
1024 out1 << "This run took " << fixed << setprecision(2)
1025 << get_arts_runtime_in_sec(arts_realtime_start) << "s\n";
1026
1027 out1 << "Everything seems fine. Goodbye.\n";
1028 arts_exit(EXIT_SUCCESS);
1029}
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:27
void arts_exit_with_error_message(const String &m, ArtsOut &out)
Print error message and exit.
Definition: arts.cc:47
void arts_exit(int status)
This is the exit function of ARTS.
Definition: arts.cc:25
The global header file for ARTS.
void define_wsv_groups()
Define the array of workspace variable group names.
Definition: groups.cc:47
std::string_view arts_get_version_string()
int arts_omp_get_max_threads()
Wrapper for omp_get_max_threads.
Definition: arts_omp.cc:29
int arts_omp_get_thread_num()
Wrapper for omp_get_thread_num.
Definition: arts_omp.cc:59
Header file for helper functions for OpenMP.
The Agenda class.
Definition: agenda_class.h:52
Index nelem() const ARTS_NOEXCEPT
Definition: array.h:75
void parse_tasklist()
Public interface to the main function of the parser.
Definition: parser.cc:37
All information for one workspace method.
Definition: methods.h:21
const ArrayOfIndex & In() const
Definition: methods.h:76
const String & Name() const
Definition: methods.h:68
const ArrayOfIndex & GOutType() const
Definition: methods.h:73
const ArrayOfArrayOfIndex & GInSpecType() const
Definition: methods.h:79
const ArrayOfArrayOfIndex & GOutSpecType() const
Definition: methods.h:74
const ArrayOfIndex & Out() const
Definition: methods.h:71
const ArrayOfIndex & GInType() const
Definition: methods.h:78
Structure to hold all command line Parameters.
Definition: parameters.h:25
bool check_docs
Flag to check built-in documentation.
Definition: parameters.h:116
ArrayOfString includepath
List of paths to search for include files.
Definition: parameters.h:89
String helptext
Longer message explaining the options.
Definition: parameters.h:57
String usage
Short message how to call the program.
Definition: parameters.h:55
bool version
Display version information.
Definition: parameters.h:61
ArrayOfString datapath
List of paths to search for data files.
Definition: parameters.h:91
String workspacevariables
If this is given the argument ‘all’, it simply prints a list of all workspace variables.
Definition: parameters.h:99
String baseurl
Baseurl for the docserver.
Definition: parameters.h:110
String input
This is complementary to the methods switch.
Definition: parameters.h:95
ArrayOfString controlfiles
The filenames of the controlfiles.
Definition: parameters.h:73
bool plain
Generate plain help out suitable for script processing.
Definition: parameters.h:106
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:65
bool groups
Print a list of all workspace variable groups.
Definition: parameters.h:104
bool help
Only display the help text.
Definition: parameters.h:59
Index reporting
This should be a two digit integer.
Definition: parameters.h:81
Index numthreads
The maximum number of threads to use.
Definition: parameters.h:87
Index docserver
Port to use for the docserver.
Definition: parameters.h:108
bool daemon
Flag to run the docserver in the background.
Definition: parameters.h:112
String describe
Print the description String of the given workspace variable or method.
Definition: parameters.h:102
String methods
If this is given the argument ‘all’, it simply prints a list of all methods.
Definition: parameters.h:85
Index get_screen_verbosity() const
Definition: messages.h:48
void set_main_agenda(bool main_agenda)
Definition: messages.h:55
Index get_agenda_verbosity() const
Definition: messages.h:47
void set_screen_verbosity(Index v)
Definition: messages.h:53
bool valid() const
Check if artsmessages contains valid message levels.
Definition: messages.h:43
void set_agenda_verbosity(Index v)
Definition: messages.h:52
Index get_file_verbosity() const
Definition: messages.h:49
void set_file_verbosity(Index v)
Definition: messages.h:54
Workspace class.
Definition: workspace_ng.h:36
std::shared_ptr< wsv_data_type > wsv_data_ptr
Definition: workspace_ng.h:59
static std::shared_ptr< Workspace > create()
Creates a new Workspace, it has to be created as a shared pointer.
std::shared_ptr< WsvMap_type > WsvMap_ptr
Definition: workspace_ng.h:62
static const Index npos
Define npos:
Definition: mystring.h:192
#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:84
void run_docserver(Index, const String &, bool)
Definition: docserver.cc:2062
Declarations for the arts documentation server.
The declarations of all the exception classes.
void open_output_file(ofstream &file, const std::string_view name)
Open a file for writing.
Definition: file.cc:63
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:346
void Arts2(Workspace &ws, const Agenda &input_agenda, const Verbosity &verbosity)
WORKSPACE METHOD: Arts2.
Definition: m_agenda.cc:193
void set_reporting_level(Index r)
Set the reporting level.
Definition: main.cc:64
void option_workspacevariables(const String &workspacevariables)
React to option ‘workspacevariables’.
Definition: main.cc:449
std::time_t to_time_t(TimePoint time_point)
Definition: main.cc:565
void option_methods(Workspace &workspace, const String &methods)
React to option ‘methods’.
Definition: main.cc:106
double get_arts_runtime_in_sec(std::chrono::high_resolution_clock::time_point arts_realtime_start)
Definition: main.cc:590
void option_input(const String &input)
React to option ‘input’.
Definition: main.cc:288
String arts_mod_time(std::string_view filename)
This function returns the modification time of the arts executable as a string.
Definition: main.cc:576
void polite_goodby()
Remind the user of –help and exit return value 1.
Definition: main.cc:46
void option_describe(const String &describe)
React to option ‘describe’.
Definition: main.cc:531
int main()
Verbosity verbosity_at_launch
The global message verbosity settings:
Definition: messages.cc:17
String out_basename
The basename for the report file and for all other output files.
Definition: messages.cc:25
ofstream report_file
The report file.
Definition: messages.cc:28
Declarations having to do with the four output streams.
#define CREATE_OUTS
Definition: messages.h:191
void define_md_data_raw()
Definition: methods.cc:170
Declaration of the class MdRecord.
void define_md_raw_map()
Define MdRawMap.
Definition: methods_aux.cc:494
void define_md_map()
Define MdMap.
Definition: methods_aux.cc:458
void expand_md_data_raw_to_md_data()
Expand supergeneric methods.
Definition: methods_aux.cc:395
This file contains the definition of String, the ARTS string class.
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:199
const ArrayOfGroupRecord wsv_groups
The names associated with Wsv groups as Strings.
Definition: global_data.h:74
const Array< MdRecord > md_data_raw
Lookup information for workspace methods.
Definition: methods.cc:22
Array< WsvRecord > wsv_data
Definition: workspace.cc:22
WorkspaceMemoryHandler workspace_memory_handler
The workspace memory handler Defined in workspace_ng.cc.
Definition: workspace_ng.cc:20
const Array< MdRecord > md_data
Lookup information for workspace methods.
Definition: methods_aux.cc:33
std::map< String, Index > WsvMap
Definition: workspace.cc:24
const map< String, Index > MdMap
The map associated with md_data.
Definition: methods_aux.cc:24
const map< String, Index > MdRawMap
The map associated with md_data_raw.
Definition: methods_aux.cc:26
bool get_parameters(int argc, char **argv)
Get the command line parameters.
Definition: parameters.cc:54
Parameters parameters
Holds the command line parameters.
Definition: parameters.cc:24
This file contains header information for the dealing with command line parameters.
void define_wsv_data()
Definition: workspace.cc:29
void define_wsv_map()
Definition: workspace.cc:5728
This file contains the Workspace class.
Auxiliary header stuff related to workspace variable groups.