00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00031 #include "arts.h"
00032 
00033 #if HAVE_CONFIG_H
00034 #include "config.h"
00035 #endif
00036 
00037 #include <algorithm>
00038 #include <map>
00039 #include "parameters.h"
00040 #include "messages.h"
00041 #include "exceptions.h"
00042 #include "file.h"
00043 #include "auto_wsv.h"
00044 #include "methods.h"
00045 #include "parser.h"
00046 #include "auto_md.h"
00047 #include "absorption.h"
00048 #include "wsv_aux.h"
00049 
00050 
00051 
00052 void define_wsv_pointers(Array<WsvP*>&    wsv_pointers,
00053                          WorkSpace&       workspace);
00054 
00055 
00057 void give_up(const String& message)
00058 {
00059   out0 << message << '\n';
00060   exit(1);
00061 }
00062 
00063 
00073 void executor(WorkSpace& workspace, const Array<MRecord>& tasklist)
00074 {
00075   
00076   extern const Array<MdRecord> md_data;
00077 
00078   
00079   extern const Array<WsvRecord> wsv_data;
00080   
00081   
00082   extern const void (*getaways[])(WorkSpace&, const MRecord&);
00083 
00084   
00085   
00086   
00087   
00088   
00089   
00090   
00091   
00092   std::vector<bool> occupied(wsv_data.nelem(),false);
00093 
00094   out3 << "\nExecuting methods:\n";
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106   for (Index i=0; i<tasklist.nelem(); ++i)
00107     {
00108       
00109       const MRecord&  mrr = tasklist[i];
00110       
00111       const MdRecord& mdd = md_data[mrr.Id()];
00112       
00113       try
00114         {
00115           out1 << "- " << mdd.Name() << '\n';
00116 
00117         
00118           { 
00119             const ArrayOfIndex& v(mdd.Input());
00120             for (Index s=0; s<v.nelem(); ++s)
00121               if (!occupied[v[s]])
00122                 give_up("Method "+mdd.Name()+" needs input variable: "+
00123                         wsv_data[v[s]].Name());
00124           }
00125 
00126           { 
00127             const ArrayOfIndex& v(mrr.Input());
00128             
00129             for (Index s=0; s<v.nelem(); ++s)
00130               if (!occupied[v[s]])
00131                 give_up("Generic Method "+mdd.Name()+" needs input variable: "+
00132                         wsv_data[v[s]].Name());
00133           }
00134 
00135           
00136           getaways[mrr.Id()]
00137             ( workspace, mrr );
00138 
00139           { 
00140             const ArrayOfIndex& v(mdd.Output());
00141             for (Index s=0; s<v.nelem(); ++s) occupied[v[s]] = true;
00142           }
00143 
00144           { 
00145             const ArrayOfIndex& v(mrr.Output());
00146             for (Index s=0; s<v.nelem(); ++s) occupied[v[s]] = true;
00147           }
00148 
00149         }
00150       catch (runtime_error x)
00151         {
00152           out0 << "Run-time error in method: " << mdd.Name() << '\n'
00153                << x.what() << '\n';
00154           exit(1);
00155         }
00156       catch (logic_error x)
00157         {
00158           out0 << "Logic error in method: " << mdd.Name() << '\n'
00159                << x.what() << '\n';
00160           exit(1);
00161         }
00162     }
00163 }
00164 
00165 
00167 void polite_goodby()
00168 {
00169   cerr << "Try `arts --help' for help.\n";
00170   exit(1);
00171 }
00172 
00180 void set_reporting_level(Index r)
00181 {
00182   
00183   extern Messages messages;
00184 
00185   if ( -1 == r )
00186     {
00187       
00188       
00189       messages.screen = 1;
00190       messages.file   = 3;
00191     }
00192   else
00193     {
00194       
00195       
00196         
00197         
00198       Index s = r / 10;
00199       Index f = r % 10;
00200       
00201 
00202       if ( s<0 || s>3 || f<0 || f>3 )
00203         {
00204           cerr << "Illegal value specified for --reporting (-r).\n"
00205                << "The specified value is " << r << ", which would be\n"
00206                << "interpreted as screen=" << s << ", file=" << f << ".\n"
00207                << "Only values of 0-3 are allowed for screen and file.\n";
00208           exit(1);
00209         }
00210       messages.screen = s;
00211       messages.file   = f;
00212     }
00213 }
00214 
00215 
00223 void option_methods(const String& methods)
00224 {
00225   
00226   extern const Array<MdRecord>  md_data;
00227   extern const Array<WsvRecord> wsv_data;
00228   
00229   extern const std::map<String, Index> WsvMap;
00230   extern const ArrayOfString wsv_group_names;
00231 
00232   
00233   
00234   Index hitcount;
00235 
00236   
00237 
00238   if ( "all" == methods )
00239     {
00240       cout
00241         << "\n*--------------------------------------------------------------*\n"
00242         << "Complete list of ARTS workspace methods:\n"
00243         << "----------------------------------------------------------------\n";
00244       for ( Index i=0; i<md_data.nelem(); ++i )
00245         {
00246           cout << "- " << md_data[i].Name() << '\n';
00247         }
00248       cout
00249         << "*--------------------------------------------------------------*\n\n";
00250       return;
00251     }
00252 
00253   
00254   
00255 
00256   
00257   map<String, Index>::const_iterator mi =
00258     WsvMap.find(methods);
00259   if ( mi != WsvMap.end() )
00260     {
00261       
00262       Index wsv_key = mi->second;
00263 
00264       
00265       hitcount = 0;
00266       cout 
00267         << "\n*--------------------------------------------------------------*\n"
00268         << "Generic methods that can generate " << wsv_data[wsv_key].Name() 
00269         << ":\n"
00270         << "----------------------------------------------------------------\n";
00271       for ( Index i=0; i<md_data.nelem(); ++i )
00272         {
00273           
00274           
00275           
00276           if ( count( md_data[i].GOutput().begin(),
00277                       md_data[i].GOutput().end(),
00278                       wsv_data[wsv_key].Group() ) )
00279             {
00280               cout << "- " << md_data[i].Name() << '\n';
00281               ++hitcount;
00282             }
00283         }
00284       if ( 0==hitcount )
00285         cout << "none\n";
00286 
00287       
00288       hitcount = 0;
00289       cout 
00290         << "\n----------------------------------------------------------------\n"
00291         << "Specific methods that can generate " << wsv_data[wsv_key].Name() 
00292         << ":\n"
00293         << "----------------------------------------------------------------\n";
00294       for ( Index i=0; i<md_data.nelem(); ++i )
00295         {
00296           
00297           
00298           
00299           if ( count( md_data[i].Output().begin(),
00300                       md_data[i].Output().end(),
00301                       wsv_key ) ) 
00302             {
00303               cout << "- " << md_data[i].Name() << '\n';
00304               ++hitcount;
00305             }
00306         }
00307       if ( 0==hitcount )
00308         cout << "none\n";
00309 
00310       cout
00311         << "*--------------------------------------------------------------*\n\n";
00312 
00313       return;
00314     }
00315 
00316   
00317 
00318   
00319   
00320   
00321   Index group_key =
00322     find( wsv_group_names.begin(),
00323           wsv_group_names.end(),
00324           methods ) - wsv_group_names.begin();
00325 
00326   
00327   
00328   if ( group_key != wsv_group_names.nelem() )
00329     {
00330       
00331       hitcount = 0;
00332       cout 
00333         << "\n*--------------------------------------------------------------*\n"
00334         << "Generic methods that can generate variables of group " 
00335         << wsv_group_names[group_key] << ":\n"
00336         << "----------------------------------------------------------------\n";
00337       for ( Index i=0; i<md_data.nelem(); ++i )
00338         {
00339           
00340           
00341           
00342           if ( count( md_data[i].GOutput().begin(),
00343                       md_data[i].GOutput().end(),
00344                       group_key ) )
00345             {
00346               cout << "- " << md_data[i].Name() << '\n';
00347               ++hitcount;
00348             }
00349         }
00350       if ( 0==hitcount )
00351         cout << "none\n";
00352 
00353       cout
00354         << "*--------------------------------------------------------------*\n\n";
00355 
00356       return;
00357     }
00358 
00359   
00360   
00361   cerr << "The name " << methods << " matches neither `all',\n"
00362        << "nor the name of a workspace variable, nor the name\n"
00363        << "of a workspace variable group.\n";
00364   exit(1);
00365 }
00366 
00374 void option_input(const String& input)
00375 {
00376   
00377   extern const Array<MdRecord>  md_data;
00378   extern const Array<WsvRecord> wsv_data;
00379   
00380   extern const std::map<String, Index> WsvMap;
00381   extern const ArrayOfString wsv_group_names;
00382 
00383   
00384   
00385   Index hitcount;
00386 
00387   
00388   
00389 
00390   
00391   map<String, Index>::const_iterator mi =
00392     WsvMap.find(input);
00393   if ( mi != WsvMap.end() )
00394     {
00395       
00396       Index wsv_key = mi->second;
00397 
00398       
00399       hitcount = 0;
00400       cout 
00401       << "\n*--------------------------------------------------------------*\n"
00402       << "Generic methods that can use " << wsv_data[wsv_key].Name() << ":\n"
00403       << "----------------------------------------------------------------\n";
00404       for ( Index i=0; i<md_data.nelem(); ++i )
00405         {
00406           
00407           
00408           
00409           if ( count( md_data[i].GInput().begin(),
00410                       md_data[i].GInput().end(),
00411                       wsv_data[wsv_key].Group() ) )
00412             {
00413               cout << "- " << md_data[i].Name() << '\n';
00414               ++hitcount;
00415             }
00416         }
00417       if ( 0==hitcount )
00418         cout << "none\n";
00419 
00420       
00421       hitcount = 0;
00422       cout 
00423       << "\n----------------------------------------------------------------\n"
00424       << "Specific methods that require " << wsv_data[wsv_key].Name() 
00425       << ":\n"
00426       << "----------------------------------------------------------------\n";
00427       for ( Index i=0; i<md_data.nelem(); ++i )
00428         {
00429           
00430           
00431           
00432           if ( count( md_data[i].Input().begin(),
00433                       md_data[i].Input().end(),
00434                       wsv_key ) ) 
00435             {
00436               cout << "- " << md_data[i].Name() << '\n';
00437               ++hitcount;
00438             }
00439         }
00440       if ( 0==hitcount )
00441         cout << "none\n";
00442 
00443       cout
00444         << "*--------------------------------------------------------------*\n\n";
00445 
00446       return;
00447     }
00448 
00449   
00450 
00451   
00452   
00453   
00454   Index group_key =
00455     find( wsv_group_names.begin(),
00456           wsv_group_names.end(),
00457           input ) - wsv_group_names.begin();
00458 
00459   
00460   
00461   if ( group_key != wsv_group_names.nelem() )
00462     {
00463       
00464       hitcount = 0;
00465       cout
00466       << "\n*--------------------------------------------------------------*\n"
00467       << "Generic methods that require a variable of group " 
00468       << wsv_group_names[group_key] << ":\n"
00469       << "----------------------------------------------------------------\n";
00470       for ( Index i=0; i<md_data.nelem(); ++i )
00471         {
00472           
00473           
00474           
00475           if ( count( md_data[i].GInput().begin(),
00476                       md_data[i].GInput().end(),
00477                       group_key ) )
00478             {
00479               cout << "- " << md_data[i].Name() << '\n';
00480               ++hitcount;
00481             }
00482         }
00483       if ( 0==hitcount )
00484         cout << "none\n";
00485 
00486       cout
00487         << "*--------------------------------------------------------------*\n\n";
00488 
00489       return;
00490     }
00491 
00492   
00493   
00494   cerr << "The name " << input << " matches neither the name of a\n"
00495        << "workspace variable, nor the name of a workspace variable group.\n";
00496   exit(1);
00497 }
00498 
00499 
00507 void option_workspacevariables(const String& workspacevariables)
00508 {
00509   
00510   extern const Array<MdRecord>  md_data;
00511   extern const Array<WsvRecord> wsv_data;
00512   extern const std::map<String, Index> MdMap;
00513   
00514   extern const ArrayOfString wsv_group_names;
00515 
00516   
00517   
00518   Index hitcount;
00519 
00520   
00521 
00522   if ( "all" == workspacevariables )
00523     {
00524       cout
00525         << "\n*--------------------------------------------------------------*\n"
00526         << "Complete list of ARTS workspace variables:\n"
00527         << "----------------------------------------------------------------\n";
00528       for ( Index i=0; i<wsv_data.nelem(); ++i )
00529         {
00530           cout << "- " << wsv_data[i].Name() << '\n';
00531         }
00532       cout
00533         << "*--------------------------------------------------------------*\n\n";
00534       return;
00535     }
00536 
00537 
00538   
00539   map<String, Index>::const_iterator mi =
00540     MdMap.find(workspacevariables);
00541   if ( mi != MdMap.end() )
00542     {
00543       
00544       
00545       
00546       const MdRecord& mdr = md_data[mi->second];
00547       
00548       
00549       hitcount = 0;
00550       cout
00551       << "\n*--------------------------------------------------------------*\n"
00552       << "Generic workspace variables required by " << mdr.Name()
00553       << " are of type:\n"
00554       << "----------------------------------------------------------------\n";
00555       for ( Index i=0; i<mdr.GInput().nelem(); ++i )
00556         {
00557           cout << "- " << wsv_group_names[mdr.GInput()[i]] << "\n";
00558           ++hitcount;
00559         }
00560       if ( 0==hitcount )
00561         cout << "none\n";
00562 
00563       
00564       hitcount = 0;
00565       cout 
00566       << "\n----------------------------------------------------------------\n"
00567       << "Specific workspace variables required by " << mdr.Name() << ":\n"
00568       << "----------------------------------------------------------------\n";
00569       for ( Index i=0; i<mdr.Input().nelem(); ++i )
00570         {
00571           cout << "- " << wsv_data[mdr.Input()[i]].Name() << '\n';
00572           ++hitcount;
00573         }
00574       if ( 0==hitcount )
00575         cout << "none\n";
00576 
00577       cout
00578         << "*--------------------------------------------------------------*\n\n";
00579 
00580       return;
00581     }
00582 
00583   
00584   cerr << "The name " << workspacevariables << " matches neither `all',\n" 
00585        << "nor the name of a workspace method.\n";
00586   exit(1);
00587 }
00588 
00589 
00595 void option_describe(const String& describe)
00596 {
00597   
00598   extern const Array<MdRecord>  md_data;
00599   extern const Array<WsvRecord> wsv_data;
00600   extern const std::map<String, Index> MdMap;
00601   extern const std::map<String, Index> WsvMap;
00602   
00603 
00604   
00605   
00606 
00607   
00608   map<String, Index>::const_iterator i =
00609     MdMap.find(describe);
00610   if ( i != MdMap.end() )
00611     {
00612       
00613       cout << md_data[i->second] << '\n';
00614       return;
00615     }
00616 
00617   
00618   
00619 
00620   
00621   i = WsvMap.find(describe);
00622   if ( i != WsvMap.end() )
00623     {
00624       
00625       
00626       cout << wsv_data[i->second] << '\n';
00627       return;
00628     }
00629 
00630   
00631   cerr << "The name " << describe
00632        << " matches neither method nor variable.\n";
00633   exit(1);      
00634 }
00635 
00636 
00638 
00648 void check_built_headers()
00649 {
00650   
00651   
00652   extern const ArrayOfString wsv_group_names;
00653   extern const Array<WsvRecord> wsv_data;
00654 
00655   
00656   assert( N_WSV_GROUPS == wsv_group_names.nelem() );
00657   assert( N_WSV        == wsv_data.nelem()        );
00658 
00659 }
00660 
00675 int main (int argc, char **argv)
00676 {
00677   extern const Parameters parameters; 
00678                                       
00679 
00680   
00681   if ( get_parameters(argc, argv) )
00682     {
00683       
00684       polite_goodby();
00685     }
00686 
00687   
00688   if (parameters.help)
00689     {
00690       
00691       cerr << '\n' << parameters.usage << "\n\n";
00692       cerr << parameters.helptext << "\n\n";
00693       return(0);
00694     }
00695 
00696   if (parameters.version)
00697     {
00698       extern const String full_name;
00699       
00700       cerr << "This is " << full_name
00701 #ifdef HDF_SUPPORT
00702            << " with HDF support."
00703 #endif // HDF_SUPPORT
00704            << '\n'
00705            << "Compiled on " << OS_NAME << " " << OS_VERSION
00706            << " with "
00707            << ((sizeof (Numeric) == sizeof (double)) ? "double" : "float")
00708            << " precision." << endl
00709            << "Compile flags: " << COMPILE_FLAGS << endl;
00710       return(0);
00711     }
00712 
00713 
00714 
00715   
00716   
00717 
00718 
00719   
00720   define_md_data();
00721 
00722   
00723   define_wsv_group_names();
00724 
00725   
00726   define_wsv_data();
00727 
00728   
00729   {
00730     
00731     
00732     
00733     
00734     
00735     extern WorkSpace workspace;
00736     extern Array<WsvP*> wsv_pointers;
00737     define_wsv_pointers(wsv_pointers,workspace);
00738   }
00739 
00740   
00741   define_md_map();
00742 
00743   
00744   define_wsv_map();
00745 
00746 
00747   
00748   
00749   
00750   define_species_data();
00751 
00752   
00753   define_species_map();
00754 
00755   
00756   define_lineshape_data();
00757   define_lineshape_norm_data();
00758 
00759   
00760   
00761   
00762   
00763   
00764   extern const ArrayOfString wsv_group_names;
00765 
00766   
00767   
00768 
00769 
00770   
00771   
00772   
00773   
00774   if ( "" != parameters.methods )
00775     {
00776       option_methods(parameters.methods);
00777       return(0);
00778     }
00779 
00780   
00781   
00782   
00783   if ( "" != parameters.input )
00784     {
00785       option_input(parameters.input);
00786       return(0);
00787     }
00788   
00789   
00790   
00791   
00792   
00793   if ( "" != parameters.workspacevariables )
00794     {
00795       option_workspacevariables(parameters.workspacevariables);
00796       return(0);
00797     }
00798 
00799   
00800   
00801   if ( "" != parameters.describe )
00802     {
00803       option_describe(parameters.describe);
00804       return(0);
00805     }
00806 
00807   
00808   
00809   
00810   if ( parameters.groups )
00811     {
00812       cout
00813         << "\n*--------------------------------------------------------------*\n"
00814         << "Complete list of ARTS workspace variable groups:\n"
00815         << "----------------------------------------------------------------\n";
00816       for ( Index i=0; i<wsv_group_names.nelem(); ++i )
00817         {
00818           cout << "- " << wsv_group_names[i] << '\n';
00819         }
00820       cout
00821         << "*--------------------------------------------------------------*\n\n";
00822       return(0);
00823     }
00824 
00825 
00826   
00827   
00828   
00829   if ( 0 == parameters.controlfiles.nelem() )
00830     {
00831       cerr << "You must specify at least one control file name.\n";
00832       polite_goodby();
00833     }
00834 
00835   
00836   
00837   if ( "" == parameters.basename )
00838     {
00839       extern String out_basename;
00840       out_basename = parameters.controlfiles[0];
00841       
00842       String::size_type p = out_basename.rfind('.');
00843       
00844       out_basename.erase(p);
00845     }
00846   else
00847     {
00848       extern String out_basename;
00849       out_basename = parameters.basename;
00850     }
00851 
00852   
00853   
00854   set_reporting_level(parameters.reporting);
00855 
00856 
00857   
00858   
00859   
00860   
00861   try
00862     {
00863       extern const String out_basename;     
00864       extern ofstream report_file;      
00865 
00866       
00867       open_output_file(report_file, out_basename+".rep");
00868     }
00869   catch (runtime_error x)
00870     {
00871       cerr << x.what() << '\n'
00872            << "I have to be able to write to my report file.";
00873       exit(1);
00874     }
00875 
00876   
00877   
00878   
00879   
00880   
00881   try
00882     {
00883       
00884       extern WorkSpace workspace;
00885       
00886       
00887 
00888       {
00889         
00890         
00891         
00892         
00893   
00894         extern const String full_name;
00895 
00896         out1 << full_name << '\n';
00897       }
00898 
00899 
00900       
00901       
00902       Array<MRecord> tasklist;
00903 
00904       
00905       SourceText text;
00906         
00907       
00908       out3 << "\nReading control files:\n";
00909       for ( Index i=0; i<parameters.controlfiles.nelem(); ++i )
00910         {
00911           out3 << "- " << parameters.controlfiles[i] << '\n';
00912           text.AppendFile(parameters.controlfiles[i]);
00913         }
00914 
00915       
00916       parse_main(tasklist, text);
00917 
00918       
00919       executor(workspace, tasklist);
00920 
00921     }
00922   catch (runtime_error x)
00923     {
00924       out0 << x.what() << '\n';
00925       exit(1);
00926     }
00927 
00928   out1 << "Goodbye.\n";
00929   return(0);
00930 }