RunController.cpp

00001 #ifdef linux
00002 #undef linux
00003 #endif
00004 
00005 #include "SctApiCall.h"
00006 #include "RunController.h"
00007 #include "SctApiAccessException.h"
00008 #include "CalibrationControllerImpl.h"
00009 #include "ipc/CalibrationController.h"
00010 #include "Sct/SctNames.h"
00011 #include "Sct/StringStreamer.h"
00012 #include "Sct/Exception.h"
00013 #include "Sct/LogicErrors.h"
00014 #include "Sct/MultiMessageDebugStream.h"
00015 #include <rc/RunParams.h>
00016 #include <rc/Controller.h>
00017 #include <ipc/partition.h>
00018 #include <is/info.h>
00019 #include <is/infodictionary.h>
00020 #include <is/infoiterator.h>
00021 #include <is/inforeceiver.h>
00022 #include <is/infoT.h> // for ISInfoInt
00023 #include <pmg/pmg_initSync.h>
00024 #include <iostream>
00025 #include <fstream>
00026 //inserted
00027 #include <signal.h>
00028 #include "cmdl/cmdargs.h"
00029 #include "dal/implementation.h"
00030 #include "config/Configuration.h"
00031 #include "sctConfIPC/configipc.h"
00032 #include "dal/util.h"
00033 #include "Sct/ApplicationStartupDebugTools.h"
00034 #include "Sct/MultiMessageDebugStream.h"
00035 
00036 using namespace std;
00037 using namespace Sct;
00038 
00039 
00041 
00042 inline std::string str(const char * word)
00043 {
00044   return word ? word : "";
00045 } 
00046 
00047 extern "C" void signalHandler(int)
00048 {
00049   CS::ClipsServer * that = CS::ClipsServer::instance();
00050   if ( that ) that->stop();
00051 }
00053 
00054 int main(int argc, char** argv) {
00055 
00056     // USAGE COMMENT: 
00057     // In tdaq-01-02-00 this program is usually called as follows:
00058     // AppStartupDbgTools: [ApplicationStartupDebugTools::announceStartOfMain called by [/home/sctroddq/sctsw/SctRodDaq/installed/i686-slc3-gcc323-opt/bin/CalibrationController -n CalibrationController --oks -P SCTRootSegmentController -s SCTSegment -n CalibrationController] in File[/home/sctroddq/sctsw/SctRodDaq/CalibrationController/src/RunController.cpp] at Line[59] with additional Message[].]
00059     // and the parameters after the --oks (which is probably a throwback to old times) are "invented" by the DSA supervisor.
00060 
00061     using namespace SctCalibrationController;
00062 
00063     cout << "Starting Calibration controller" << endl;
00064     setExceptionHandlers(argv[0]);
00065        
00066     IPCCore::init(argc,argv);
00067     Sct::ApplicationStartupDebugTools::announceStartOfMain(argc, argv, __FILE__, __LINE__);
00068     SctNames::Mrs() << "CCRC" << MRS_TEXT("CCRC::main done IPCCore::init") << MRS_DIAGNOSTIC << ENDM;    
00069 
00070 
00072    CmdArgStr    partition  ('p',"partition","partition",  "Name of the IPC partition (default $TDAQ_PARTITION)");
00073    CmdArgStr    parentName ('P',"parentname", "parentname", "Name of the parent");
00074    CmdArgStr    segName    ('s',"segmentname", "segmentname", "Name of the segment");
00075    CmdArgStr    name       ('n',"name",     "controller", "Name of the controller",CmdArg::isREQ);
00076    CmdArgStr    data       ('d',"data",     "db-name",    "Configuration DB name");
00077    CmdArgStr    rules      ('R',"rules",    "rules",      "CLIPS rulesbase (default Controller:TransitionTable)");
00078    CmdArgStr    server     ('z',"server",   "is-server",  "Name of the IS server (default RunCtrl)");
00079    CmdArgInt    verbosity  ('v',"verbosity","level",      "Output level (default 0 )");
00080    CmdArgBool   oks        ('O',"oks"                     ,"Load Configuration from OKS");
00081    CmdArgBool   rdb        ('Q',"rdb"                     ,"Load Configuration from RDB");
00082    CmdArgBool   none       ('N',"none"                    ,"Do not load Configuration");
00083    
00084    partition=std::getenv("TDAQ_PARTITION");
00085    server="RunCtrl";
00086    verbosity=0;
00087 
00088    CmdLine  cmd(*argv,&partition,&parentName,&segName,&name,&data,&rules,&server,&verbosity,&oks,&rdb,&none,NULL);
00089    cmd.description("An empty run controller that has just empty user routines.");
00090    
00091    CmdArgvIter  argvIter(--argc,++argv);
00092    if (cmd.parse(argvIter)) 
00093    {
00094       std::cerr << "ERROR [rc_empty_controller] Error parsing command line." << std::endl ;
00095       return EXIT_FAILURE;
00096    }
00097 
00098    signal(SIGINT,  signalHandler);
00099    signal(SIGTERM, signalHandler);
00100 
00101    IPCPartition p(partition);
00102 
00103    std::auto_ptr<ConfigurationImpl> configImpl
00104    (
00105       none ? 0 : daq::core::create_config_implementation
00106          (   
00107             oks ? daq::core::OksDB_Implementation :
00108             rdb ? daq::core::RdbDB_Implementation :
00109                   daq::core::DefaultDB_Implementation
00110          )
00111    );
00112     
00113    std::auto_ptr<Configuration> config(none ? 0 : new Configuration(str(data), configImpl.get()));
00114    if (config.get()) 
00115    {
00116      const daq::core::Partition * part = daq::core::get_partition(*(config.get()), str(partition));
00117      if(part)
00118        config->register_converter(new daq::core::SubstituteVariables(*(config.get()), *part));
00119    } 
00120       
00122 
00123     RunControl& user = RunControl::instance();
00124     cout << "Instance created" << endl;
00125 
00127     RC::Controller   controller(p,user,str(name),str(parentName),str(segName),str(rules),config.get(),str(server),
00128                 verbosity);
00130 
00131     {
00132       Sct::MultiMessageDebugStream m(true,false,true);
00133       m << "Calibration controller about to sent pmg_initSync()";
00134     };      
00135     pmg_initSync();
00136     controller.run();
00137     cout << "All over" << endl;
00138 
00139     return controller.exitStatus();
00140 }
00141 
00142 namespace SctCalibrationController {
00143 
00144 RunControl::RunControl() : cc(CalibrationControllerImpl::initialize(*this)) {
00145 }
00146     
00147 RunControl& RunControl::instance() {
00148     static RunControl rc;
00149     return rc;
00150 }
00151 
00152 int RunControl::getRunNumber() {
00153   if (m_isInfoDictionary.get()) {
00154     
00155     RunParams runParams; 
00156     runParams.run_number = defaultRunNumber;
00157     SctNames::Mrs() << "RC_DEBUG" << MRS_TEXT(Sct::StringStreamer<< "Before I make any attempt to see the run number my runParams.run_number holds defaultRunNumber="<< runParams.run_number)<< MRS_INFORMATION << ENDM;
00158     const ISInfo::Status isStatus = m_isInfoDictionary->getValue("RunParams.RunParams",runParams);
00159     if (isStatus!=ISInfo::Success){
00160       SctNames::Mrs() << "RC_DEBUG" << MRS_TEXT("The attempt to get the run params was unsuccessful.  Could not determine run number.  Using default one (probably wrong!)")<< MRS_ERROR << ENDM;
00161       return defaultRunNumber;
00162     }
00163     SctNames::Mrs() << "RC_DEBUG" << MRS_TEXT(Sct::StringStreamer<<"After I make any attempt to see the run number my runParams.run_number holds "<< runParams.run_number)<< MRS_INFORMATION << ENDM;
00164     return runParams.run_number;
00165   } else {
00166     SctNames::Mrs() << "RC_getRunNumber" << MRS_TEXT("The CalibrationController's RunController failed to find the Information Service so a default run-number is being returned in place of the correct one!") << MRS_INFORMATION << ENDM;
00167     return defaultRunNumber;
00168   };
00169 };
00170   
00171 bool RunControl::loadAction () {
00172   // first reload the module configuration
00173   try{
00174     SctConfiguration::ConfigIPC config;
00175     config.loadConfiguration("");
00176   }catch(Throwable&e){
00177     e.sendToMrs(MRS_WARNING);
00178   }catch(CORBA::Exception& e){
00179     SctNames::Mrs() << "RC_INIT" << MRS_TEXT("Could not connect to config-server") << MRS_ERROR << ENDM;
00180     return false;  // if the config-server isnt going that's bad
00181   }
00182 
00183     api = SctNames::getPartition().lookup<Sct_SctApi::SctApiIPC>(Sct_SctApi::SctApiIPC::instanceName);
00184     if (CORBA::is_nil(api)) {
00185     SctNames::Mrs() << "RC_INIT" << MRS_TEXT("RunController failed to find SctApi") << MRS_ERROR << ENDM;
00186     return false;
00187     }
00188     cc.setApi(api);
00189 
00190     SctNames::Mrs() << "RC_loadAction" << MRS_TEXT("Trying to get isInfoDictionary ...")<< MRS_INFORMATION << ENDM;
00191     m_isInfoDictionary = boost::shared_ptr<ISInfoDictionary>(new ISInfoDictionary(SctNames::getPartition()));
00192     if (!m_isInfoDictionary.get()) {
00193       SctNames::Mrs() << "RC_INIT" << MRS_TEXT(Sct::StringStreamer<< "RunController failed to find Information Server in partition "<< SctNames::getPartition().name()<<".  This means numbers like the run number will be set to default (probably incorrect) values!") << MRS_ERROR << ENDM;
00194     } else {
00195       SctNames::Mrs() << "RC_INIT" << MRS_TEXT(Sct::StringStreamer<< "RunController succeeded in finding Information Server in partition "<< SctNames::getPartition().name()<< ".  This means numbers like the run number should be correct.") << MRS_INFORMATION << ENDM;
00196     };
00197     
00198     try { 
00199       if (CORBA::is_nil(api)) { throw InvalidArgumentError("Null pointer to SctApi", __FILE__, __LINE__); } 
00200       try {
00201     const int rn=getRunNumber();        
00202     SctNames::Mrs() << "RC_INIT" << MRS_TEXT(Sct::StringStreamer<< "RunController found runNumber="<<rn) 
00203             << MRS_INFORMATION << ENDM;
00204 
00205     (api)->initialiseAll(rn);
00206     // wait for the initialisation to complete!
00207     do {
00208       usleep(500000);
00209     } while(!api->isInitialised());
00210 
00211     Sct_SctApi::BankList l;
00212     l.length(2);
00213     l[0]=Sct_SctApi::PHYSICS_CONFIG;
00214     l[1]=Sct_SctApi::CALIBRATION_CONFIG;
00215     (api)->setABCDModules(l);
00216       } catch (const CORBA::Exception & exe) { 
00217     throw raiseSctApiException(exe, "SctApi failed to initialiseAll", __FILE__, __LINE__);
00218       }
00219     } catch(SctApiAccessException& e) {
00220       e.sendToMrs(MRS_ERROR);
00221       return false;
00222     }
00223     SctNames::Mrs() << "RC_INIT" << MRS_TEXT("CC RunController initialised SctApi") << MRS_DIAGNOSTIC << ENDM;
00224     
00225     return true;
00226 }
00227 
00228   std::string RunControl::getRunType() const {
00229     
00230     RunParams runParams;
00231     ISInfoDictionary& is = SctNames::getISDictionary();
00232     ISInfo::Status isStatus;
00233     
00234     isStatus = is.findValue("RunParams.RunParams", runParams);
00235     
00236     if (isStatus!=ISInfo::Success){
00237       Sct::MultiMessageDebugStream m(true,true,true);
00238       m.severity(MRS_ERROR);
00239       m << "CalibrationController failed to find RunParameters at line " << __LINE__ << " in " << __FILE__ << " so can't tell which RunType should be entered (eg Physics/Calibration)";
00240       m.flush();
00241       return "";
00242     }
00243     
00244     const std::string run_type = runParams.run_type; // Will be a string like "Physics" or "Calibration" or perhaps even "Cosmics" ?
00245     
00246     return run_type;
00247   };
00248 
00249   bool RunControl::sendRunTypeToSctApi() const {
00250     const bool success=true;
00251     const bool failure=!success;
00252 
00253     std::string run_type = this->getRunType();
00254     Sct::MultiMessageDebugStream m(true,false,true);
00255     if (run_type == "Physics") {
00256       m << "Configuring according to Physics run mode";
00257       m.flush();
00258       APICALL(api, changeRunMode(Sct_SctApi::PHYSICS_RUN_TYPE), "SctApi failed to changeRunMode to PHYSICS_RUN_TYPE for Physics mode");
00259       // Bruce says this line should not be here: APICALL(api, timWriteRegister(0, 0, 0, 0x3f00), "SctApi failed to set the tim up to use external triggers for Physics mode");   
00260       return success;
00261     } else if (run_type == "Calibration") {
00262       m << "Configuring according to Calibration run mode";
00263       m.flush();
00264       APICALL(api, changeRunMode(Sct_SctApi::CALIBRATION_RUN_TYPE), "SctApi failed to changeRunMode to CALIBRATION_RUN_RTPE for Calibration mode");
00265       return success;
00266     } else {
00267       m.severity(MRS_WARNING);
00268       m << "The run-type '" << run_type << "' is not recognised by the CalibrationController at line " << __LINE__ << " of " << __FILE__ << ".  If this mode needs any special configuration settings, they will not have been taken into account!";
00269       m.flush();
00270       return failure;
00271     };
00272     // should not be able to get here
00273     return failure;
00274   };
00275 
00276 bool RunControl::configureAction() {
00277     cout << "CC configureAction" << endl;
00278     try {
00279 
00280       // send PHYSICS to all
00281       APICALL(api, configureAllModules(), "SctApi failed to configureAllModules");
00282       
00283     } catch(SctApiAccessException& e) {
00284         e.sendToMrs(MRS_ERROR);
00285         return false;
00286     }
00287 
00288     
00289     SctNames::Mrs() << "RC_CONFIG" << MRS_TEXT("CC RunController configured SctApi") << MRS_DIAGNOSTIC << ENDM;
00290     return true;
00291 }
00292 
00294 bool RunControl::prepareAction() {
00295     cout << "CC prepare action" << endl;
00296     if (CORBA::is_nil(api)) {
00297     cout << "Can't enter PREPARE as we don't have the api" << endl;
00298     return false;
00299     }
00300 
00301     RunParams runParams;
00302     ISInfoDictionary& is = SctNames::getISDictionary();
00303     ISInfo::Status isStatus;
00304 
00305     isStatus = is.findValue("RunParams.RunParams", runParams);
00306 
00307     if (isStatus!=ISInfo::Success){
00308       SctNames::Mrs() << "RC_PREPARE" << MRS_TEXT("CalibrationController failed to find RunParameters") << MRS_ERROR << ENDM;
00309       return false;
00310     }
00311 
00312     try {
00313         APICALL(api, setRunNumber(runParams.run_number), "Failed to set run number")
00314         APICALL(api, setScanNumber(0), "Failed to set scan number")
00315         cout << "New Run, setting run number and scan number: " << runParams.run_number << "  " << 0 << endl;
00316     // set run mode based on RunParams.run_type
00317     this->sendRunTypeToSctApi();
00318         cc.takeControl(runParams.run_number);
00319     } catch (SctApiAccessException& e) {
00320         e.sendToMrs(MRS_ERROR);
00321         return false;
00322     }
00323     return true;
00324 }
00325 
00327 bool RunControl::stopEFAction() {
00328     cout << "CC exit stopFE action" << endl;
00329     cc.giveupControl();
00330     return true;
00331 }
00332 
00333 bool RunControl::unloadAction () {
00334     cout << "CC unloadaction" << endl;
00335 
00336     try {
00337         APICALL(api, shutdownAll(), "Could not shutdown all")
00338     } catch (SctApiAccessException& e) {
00339         e.sendToMrs(MRS_ERROR);
00340         return false;
00341     }
00342     cc.reset();
00343 
00344     return true;
00345 }
00346 
00347 bool RunControl::resetAction () {
00348     cout << "CC resetAction" << endl;
00349     cc.reset();
00350     return true;
00351 }
00352 
00353 void RunControl::sctApiError(const string& reason) {
00354   SctNames::Mrs() << "CC_API_ERROR" << MRS_PARAM<const char*>("reason",reason.c_str()) 
00355           << MRS_TEXT("Calibration Controller found error with SctApi") << MRS_WARNING << ENDM;
00356     this->raiseError("API_ERROR");
00357     cc.giveupControl();
00358 }
00359 
00360 }

Generated on Mon Feb 6 14:01:26 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6