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 (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;
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
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
00267 return failure;
00268 };
00269
00270 bool RunControl::configureAction() {
00271 cout << "CC configureAction" << endl;
00272 try {
00273
00274
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
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 }