Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

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     (api)->initialiseAll(rn);
00205     Sct_SctApi::BankList l;
00206     l.length(2);
00207     l[0]=Sct_SctApi::PHYSICS_CONFIG;
00208     l[1]=Sct_SctApi::CALIBRATION_CONFIG;
00209     (api)->setABCDModules(l);
00210       } catch (const CORBA::Exception & exe) { 
00211     throw raiseSctApiException(exe, "SctApi failed to initialiseAll", __FILE__, __LINE__);
00212       }
00213     } catch(SctApiAccessException& e) {
00214       e.sendToMrs(MRS_ERROR);
00215       return false;
00216     }
00217     SctNames::Mrs() << "RC_INIT" << MRS_TEXT("CC RunController initialised SctApi") << MRS_DIAGNOSTIC << ENDM;
00218     
00219     return true;
00220 }
00221 
00222   std::string RunControl::getRunType() const {
00223     
00224     RunParams runParams;
00225     ISInfoDictionary& is = SctNames::getISDictionary();
00226     ISInfo::Status isStatus;
00227     
00228     isStatus = is.findValue("RunParams.RunParams", runParams);
00229     
00230     if (isStatus!=ISInfo::Success){
00231       Sct::MultiMessageDebugStream m(true,true,true);
00232       m.severity(MRS_ERROR);
00233       m << "CalibrationController failed to find RunParameters at line " << __LINE__ << " in " << __FILE__ << " so can't tell which RunType should be entered (eg Physics/Calibration)";
00234       m.flush();
00235       return "";
00236     }
00237     
00238     const std::string run_type = runParams.run_type; // Will be a string like "Physics" or "Calibration" or perhaps even "Cosmics" ?
00239     
00240     return run_type;
00241   };
00242 
00243   bool RunControl::sendRunTypeToSctApi() const {
00244     const bool success=true;
00245     const bool failure=!success;
00246 
00247     std::string run_type = this->getRunType();
00248     Sct::MultiMessageDebugStream m(true,false,true);
00249     if (run_type == "Physics") {
00250       m << "Configuring according to Physics run mode";
00251       m.flush();
00252       APICALL(api, changeRunMode(Sct_SctApi::PHYSICS_RUN_TYPE), "SctApi failed to changeRunMode to PHYSICS_RUN_TYPE for Physics mode");
00253       // 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");   
00254       return success;
00255     } else if (run_type == "Calibration") {
00256       m << "Configuring according to Calibration run mode";
00257       m.flush();
00258       APICALL(api, changeRunMode(Sct_SctApi::CALIBRATION_RUN_TYPE), "SctApi failed to changeRunMode to CALIBRATION_RUN_RTPE for Calibration mode");
00259       return success;
00260     } else {
00261       m.severity(MRS_WARNING);
00262       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!";
00263       m.flush();
00264       return failure;
00265     };
00266     // should not be able to get here
00267     return failure;
00268   };
00269 
00270 bool RunControl::configureAction() {
00271     cout << "CC configureAction" << endl;
00272     try {
00273 
00274       // send PHYSICS to all
00275       APICALL(api, configureAllModules(), "SctApi failed to configureAllModules");
00276       
00277     } catch(SctApiAccessException& e) {
00278         e.sendToMrs(MRS_ERROR);
00279         return false;
00280     }
00281 
00282     
00283     SctNames::Mrs() << "RC_CONFIG" << MRS_TEXT("CC RunController configured SctApi") << MRS_DIAGNOSTIC << ENDM;
00284     return true;
00285 }
00286 
00288 bool RunControl::prepareAction() {
00289     cout << "CC prepare action" << endl;
00290     if (CORBA::is_nil(api)) {
00291     cout << "Can't enter PREPARE as we don't have the api" << endl;
00292     return false;
00293     }
00294 
00295     RunParams runParams;
00296     ISInfoDictionary& is = SctNames::getISDictionary();
00297     ISInfo::Status isStatus;
00298 
00299     isStatus = is.findValue("RunParams.RunParams", runParams);
00300 
00301     if (isStatus!=ISInfo::Success){
00302       SctNames::Mrs() << "RC_PREPARE" << MRS_TEXT("CalibrationController failed to find RunParameters") << MRS_ERROR << ENDM;
00303       return false;
00304     }
00305 
00306     try {
00307         APICALL(api, setRunNumber(runParams.run_number), "Failed to set run number")
00308         APICALL(api, setScanNumber(0), "Failed to set scan number")
00309         cout << "New Run, setting run number and scan number: " << runParams.run_number << "  " << 0 << endl;
00310     // set run mode based on RunParams.run_type
00311     this->sendRunTypeToSctApi();
00312         cc.takeControl(runParams.run_number);
00313     } catch (SctApiAccessException& e) {
00314         e.sendToMrs(MRS_ERROR);
00315         return false;
00316     }
00317     return true;
00318 }
00319 
00321 bool RunControl::stopEFAction() {
00322     cout << "CC exit stopFE action" << endl;
00323     cc.giveupControl();
00324     return true;
00325 }
00326 
00327 bool RunControl::unloadAction () {
00328     cout << "CC unloadaction" << endl;
00329 
00330     try {
00331         APICALL(api, shutdownAll(), "Could not shutdown all")
00332     } catch (SctApiAccessException& e) {
00333         e.sendToMrs(MRS_ERROR);
00334         return false;
00335     }
00336     cc.reset();
00337 
00338     return true;
00339 }
00340 
00341 bool RunControl::resetAction () {
00342     cout << "CC resetAction" << endl;
00343     cc.reset();
00344     return true;
00345 }
00346 
00347 void RunControl::sctApiError(const string& reason) {
00348   SctNames::Mrs() << "CC_API_ERROR" << MRS_PARAM<const char*>("reason",reason.c_str()) 
00349           << MRS_TEXT("Calibration Controller found error with SctApi") << MRS_WARNING << ENDM;
00350     this->raiseError("API_ERROR");
00351     cc.giveupControl();
00352 }
00353 
00354 }

Generated on Thu Dec 15 21:14:33 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5