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>
00023 #include <pmg/pmg_initSync.h>
00024 #include <iostream>
00025 #include <fstream>
00026
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
00057
00058
00059
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
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;
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
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;
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
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
00273 return failure;
00274 };
00275
00276 bool RunControl::configureAction() {
00277 cout << "CC configureAction" << endl;
00278 try {
00279
00280
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
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 }