00001 #include "CalibrationControllerImpl.h"
00002 #include "ScanLibraryImpl.h"
00003 #include "TestLibraryImpl.h"
00004 #include "SequenceLibraryImpl.h"
00005 #include "SequenceRequestWorker.h"
00006 #include "RunController.h"
00007 #include "SctApiAccessException.h"
00008 #include "ipc/SequenceRequest.h"
00009 #include "scripts/DefaultSequence.h"
00010 #include "scripts/DefaultTest.h"
00011 #include "Sequence.h"
00012 #include "Test.h"
00013 #include "SctApiCall.h"
00014 #include "ConfigUpdater/ConfigUpdaterManager.h"
00015
00016 #include "Sct/SctNames.h"
00017 #include "Sct/LogicErrors.h"
00018 #include "Sct/IoExceptions.h"
00019 #include "Sct/ISUtilities.h"
00020 #include "Sct/CorbaExceptionWrapper.h"
00021 #include "Sct/StdExceptionWrapper.h"
00022 #include "Sct/IS/IOManagerIS.h"
00023 #include "Sct/IS/IONameIS.h"
00024 #include "Sct/OmniMarshalling.h"
00025 #include "SctData/TestResult.h"
00026 #include "Sct/UniqueID.h"
00027 #include <ipc/server.h>
00028 #include <is/infoT.h>
00029 #include <is/infodictionary.h>
00030 #include <is/infoiterator.h>
00031 #include <is/inforeceiver.h>
00032
00033 #include <boost/utility.hpp>
00034 #include <unistd.h>
00035 #include <iostream>
00036 #include "Sct/BugReport.h"
00037 #include "Sct/CorbaExceptionWrapper.h"
00038 #include "Sct/MultiMessageDebugStream.h"
00039
00040 #ifndef __Sct_SctApi_H_
00041 #include "Sct_SctApi/SctApi.hh"
00042 #endif
00043
00044
00045 using namespace std;
00046 using namespace Sct;
00047 using namespace SctData;
00048
00049 namespace SctCalibrationController {
00050
00051 using namespace Scripts;
00052
00053 CalibrationControllerImpl::CalibrationControllerImpl(RunControl& rc) : rc(rc), runNumber(0),
00054 nextScanNumber(0), abortNow(false), abortRightNow(false) {
00055 status.currentScanIndex = 0;
00056 publish();
00057 updateStatus();
00058 }
00059
00060 CalibrationControllerImpl::~CalibrationControllerImpl() {
00061 withdraw();
00062
00063
00064 string name = SctNames::getControlDataName();
00065 name += ".Status";
00066 ISInfoDictionary& is = SctNames::getISDictionary();
00067 is.remove(name.c_str());
00068 inst->_destroy();
00069 }
00070
00071 Sct_SctApi::SctApiIPC_ptr CalibrationControllerImpl::getApi() {
00072 if (CORBA::is_nil(m_api)){
00073
00074 m_api=SctNames::getPartition().lookup<Sct_SctApi::SctApiIPC>(Sct_SctApi::SctApiIPC::instanceName);
00075 if (CORBA::is_nil(m_api)) {
00076 SctNames::Mrs() << "CC" << MRS_TEXT("Calibration Controller failed to find SctApi") << MRS_ERROR << ENDM;
00077 } else {
00078 SctNames::Mrs() << "CC" << MRS_TEXT("Calibration Controller refreshed SctApi handle") << MRS_DIAGNOSTIC << ENDM;
00079 }
00080 }
00081 Sct_SctApi::SctApiIPC_ptr ret = Sct_SctApi::SctApiIPC::_duplicate(m_api);
00082 if (CORBA::is_nil(ret)) {
00083 SctNames::Mrs() << "CC" << MRS_TEXT("Calibration Controller failed to duplicate handle") << MRS_ERROR << ENDM;
00084 };
00085 return ret;
00086 }
00087
00088 void CalibrationControllerImpl::setApi(Sct_SctApi::SctApiIPC_ptr api) {
00089 this->m_api = Sct_SctApi::SctApiIPC::_duplicate(api);
00090 }
00091
00092 void CalibrationControllerImpl::reset() {
00093 SctNames::Mrs() << "CC_RESET" << MRS_TEXT("Calibration controller was reset") << MRS_DIAGNOSTIC << ENDM;
00094 status.status = status.LOADED;
00095 updateStatus();
00096 m_api = Sct_SctApi::SctApiIPC::_nil();
00097 }
00098
00099 void CalibrationControllerImpl::sctApiError(SctApiAccessException& e) {
00100 rc.sctApiError(e.what());
00101 updateStatus();
00102 }
00103
00104 void CalibrationControllerImpl::takeControl(unsigned int runNumber) {
00105 if (status.status != status.LOADED || CORBA::is_nil(m_api) )
00106 return;
00107 this->runNumber = runNumber;
00108 nextScanNumber = 0;
00109 status.status = status.INCONTROL;
00110
00111 SctNames::Mrs() << "CC_START" << MRS_TEXT("Calibration Controller taking control") << MRS_INFORMATION << ENDM;
00112 updateStatus();
00113 }
00114
00115 void CalibrationControllerImpl::giveupControl() {
00116 if (status.status == status.INCONTROL) {
00117 SctNames::Mrs() << "CC_END" << MRS_TEXT("Calibration Controller giving up control") << MRS_INFORMATION << ENDM;
00118
00119 status.status = status.LOADED;
00120 updateStatus();
00121 }
00122 }
00123
00124 bool CalibrationControllerImpl::isInControl() {
00125 return status.status == status.INCONTROL;
00126 }
00127
00128 bool CalibrationControllerImpl::isBusy() {
00129 return status.status == status.BUSY;
00130 }
00131
00132 void CalibrationControllerImpl::setBusy(bool busy) {
00133 if (busy && status.status == status.INCONTROL)
00134 status.status = status.BUSY;
00135 else if (!busy && status.status == status.BUSY)
00136 status.status = status.INCONTROL;
00137 updateStatus();
00138 }
00139
00140 unsigned int CalibrationControllerImpl::getRunNumber() const {
00141 return runNumber;
00142 }
00143
00144 unsigned int CalibrationControllerImpl::getNextScanNumber() const {
00145 return nextScanNumber;
00146 }
00147
00148 void CalibrationControllerImpl::setNextScanNumber(unsigned int scanNumber) {
00149 nextScanNumber = scanNumber;
00150 Sct_SctApi::SctApiIPC_var api = getApi();
00151 APICALL(api, setScanNumber(scanNumber), "setScanNumber failed in setNextScanNumber")
00152 }
00153
00154 void CalibrationControllerImpl::abort() {
00156 if (status.status != status.BUSY) return;
00157
00158 abortNow = true;
00159
00160 SctNames::Mrs() << "CC_ABORT" << MRS_TEXT("User requested abort Sequence") << MRS_INFORMATION << ENDM;
00161
00162
00163
00164 try{
00165 Sct_SctApi::SctApiIPC_var api = getApi();
00166 ipc::servant::info_var info = api->information();
00167 }catch(CORBA::Exception& e){
00168 abortRightNow = true;
00169 }
00170 }
00171
00172 void CalibrationControllerImpl::executeSequence(Sct_CalibrationController::SequenceRequest_ptr sr) {
00173 SctNames::Mrs() << "CC_SEQ_START" << MRS_TEXT("Calibration Controller starting sequence") << MRS_INFORMATION << ENDM;
00174
00175 string name;
00176 Sct_SctApi::SctApiIPC_var api = getApi();
00177
00178 try {
00179 if (CORBA::is_nil(sr)) {
00180 throw Sct::IllegalStateError("Null Sequence pointer ", __FILE__, __LINE__);
00181 };
00182
00183 APIRETCALL(api, nextScanNumber, getScanNumber(), "Couldn't synchronise scan numbers")
00184
00185 CORBA::String_var corbaname = sr->startSequence(api);
00186 name = corbaname;
00187 std::cout << "CC: name of sequence is : " << name << std::endl;
00188 } catch (SctApiAccessException& e) {
00189 sctApiError(e);
00190 throw;
00191 } catch (CorbaExceptionWrapper& e) {
00192 e.sendToMrs();
00193 return;
00194 }
00195
00196 shared_ptr<Sequence> s;
00197 try {
00198 sctConf::ModuleList_var mlist;
00199 std::cout << "CC Getting module List" << std::endl;
00200 APIRETCALL(api, mlist, getModuleList(), "Couldn't get module list")
00201 std::cout << "CC Got module List" << std::endl;
00202
00203 list<string> list = copyCorbaToList<sctConf::ModuleList, string>(&(mlist.in()));
00204 s = Sequence::create(name, runNumber, nextScanNumber, list);
00205
00206 status.currentSequence = s->getUniqueID();
00207 updateStatus();
00208
00209 Sct_CalibrationController::TestRequest_var tr = Sct_CalibrationController::TestRequest::_nil();
00210 unsigned long index = 0;
00211
00212 do {
00213 tr = sr->getNextTest(index);
00214 if (!CORBA::is_nil(tr)) {
00215 unsigned firstScanInTest = getNextScanNumber();
00216 unsigned runNumber = getRunNumber();
00217 s->addTest(executeTest(tr, s));
00218
00219
00220 if (s->getTest(index)->getData().status != TestData::COMPLETED) {
00221 SctNames::Mrs() << "CC_SEQ_END" << MRS_TEXT("Calibration Controller aborting sequence") << MRS_INFORMATION << ENDM;
00222 s->setStatus(SequenceData::ABORTED);
00223 return;
00224 }
00225 {
00226 Sct_SctApi::BankList banks;
00227 banks.length(1);
00228 banks[0]=Sct_SctApi::SCAN_CONFIG;
00229 APICALL(api, copyABCDModules(Sct_SctApi::CALIBRATION_CONFIG, banks), "copyABCDModules failed before update");
00230 APICALL(api, getABCDModules(Sct_SctApi::CALIBRATION_CONFIG), "getABCDModules failed before update");
00231 }
00232 if (tr->canFeedback()) {
00233
00234 Sct_SctApi::BankList banks;
00235 banks.length(2);
00236 banks[0]=Sct_SctApi::CALIBRATION_CONFIG;
00237 banks[1]=Sct_SctApi::SCAN_CONFIG;
00238
00239
00240 APICALL(api, setAutoUpdateBanks(banks), "setAutoUpdateBanks failed");
00241
00242 std::list<std::string> moduleList = s->getModuleList();
00243 applyChanges(runNumber, firstScanInTest, moduleList);
00244 APICALL(api, setABCDModules(banks), "setABCDModules failed after update");
00245 }
00246 {
00247
00248 Sct_SctApi::BankList banks;
00249 banks.length(0);
00250 APICALL(api, setAutoUpdateBanks(banks), "setAutoUpdateBanks failed");
00251 }
00252 }
00253 ++index;
00254 } while (!CORBA::is_nil(tr));
00255 SctNames::Mrs() << "CC_SEQ_END" << MRS_TEXT("Calibration Controller ending sequence") << MRS_INFORMATION << ENDM;
00256 sr->endSequence();
00257 s->setStatus(SequenceData::COMPLETED);
00258 } catch (SctApiAccessException& e) {
00259 sctApiError(e);
00260 throw;
00261 } catch (Throwable& e) {
00262 e.sendToMrs(MRS_INFORMATION);
00263 if (s) s->setStatus(SequenceData::ABORTED);
00264 } catch (std::exception& e){
00265 StdExceptionWrapper(e,__FILE__,__LINE__).sendToMrs(MRS_INFORMATION);
00266 if (s) s->setStatus(SequenceData::ABORTED);
00267 } catch (...){
00268 SctNames::Mrs() << "CC_SEQ_ERROR" << MRS_TEXT("Calibration Controller caught unknown exception during sequence")
00269 << MRS_ERROR << ENDM;
00270 if (s) s->setStatus(SequenceData::ABORTED);
00271 }
00272 }
00273 void CalibrationControllerImpl::applyChanges(const unsigned long runNumber, const unsigned long scanNumber, const std::list<std::string>& modulelist ) {
00274 Sct_SctApi::SctApiIPC_var api = getApi();
00275
00276 cout << "Update option = " << status.updateOption << endl;
00277
00278 bool printed=false;
00279 while (status.updateOption=="WAIT") {
00280 if (!printed)
00281 cerr << "CalibrationController awaiting instructions as to whether to apply changes" << endl;
00282 printed=true;
00283 }
00284
00285
00286 if (status.updateOption!="UPDATE")
00287 return;
00288
00289 cout << "updating " << modulelist.size() << "" << " modules" << endl;
00290
00291 std::ostringstream regexp;
00292 regexp << ".*TestResult\\." << runNumber << "\\." << scanNumber << "\\..*";
00293 cout << "Cal Controller looking for " << regexp.str() << endl;
00294
00295 unsigned nprinted=0;
00296
00297
00298 std::list<std::string> mylist=modulelist;
00299
00300 while (!mylist.empty() && status.updateOption=="UPDATE") {
00301 ISInfoIterator ii(SctNames::getPartition(),
00302 SctNames::getTestDataName().c_str(),
00303 regexp.str().c_str() );
00304
00305 while (ii() && status.updateOption=="UPDATE") {
00306 if (nprinted<10)
00307 cout << " checking " << ii.name() << endl;
00308
00309
00310
00311 Sct::IS::IONameIS isname(ii.name());
00312 std::string moduleName=isname.getUniqueID().getModule();
00313
00314
00315 std::list<string>::iterator it = std::find( mylist.begin(), mylist.end(), moduleName);
00316
00317 if ( it != mylist.end() ) {
00318 shared_ptr<const Serializable> ob ( Sct::IS::IOManagerIS::instance().read(ii.name()) );
00319 shared_ptr<const SctData::TestResult> testResult = boost::dynamic_pointer_cast<const SctData::TestResult>(ob);
00320 if (!testResult)
00321 throw Sct::InvalidArgumentError("Fitter::applyChangesCallback not a SctData::TestResult.", __FILE__, __LINE__);
00322
00323 cout << "about to update " << moduleName << endl;
00324 ConfigUpdaterManager::instance().update(*testResult, api);
00325
00326 it=mylist.erase(it);
00327 }
00328 }
00329
00330 usleep(500000);
00331
00332 if (nprinted<10) {
00333 cout << "Cal Controller waiting for TestResults (have "
00334 << mylist.size() << " still to go)" << endl;
00335 }
00336 nprinted ++;
00337 }
00338 }
00339
00340 void CalibrationControllerImpl::updateWith(const char * testResultInIs, bool force){
00341 setBusy(true);
00342 try{
00343 Sct_SctApi::SctApiIPC_var api = getApi();
00344 shared_ptr<const TestResult> tr = dynamic_pointer_cast<const TestResult> ( Sct::IS::IOManagerIS::instance().read(testResultInIs) );
00345 if (!tr.get()) throw Sct::IoException(string("Couldnt retrieve ")+testResultInIs , __FILE__, __LINE__);
00346 ConfigUpdaterManager::instance().update(*tr, api, force);
00347 }catch(Sct::Throwable& e){
00348 e.sendToMrs();
00349 }catch(std::exception& e){
00350 Sct::StdExceptionWrapper(e, __FILE__, __LINE__).sendToMrs();
00351 }
00352 setBusy(false);
00353 }
00354
00355 void CalibrationControllerImpl::setUpdateOption(Sct_CalibrationController::CalibrationController::UpdateOption opt) {
00356 cout << "CalibrationContrllerImpl: resetting update option to " << opt;
00357 switch (opt) {
00358 case Sct_CalibrationController::CalibrationController::update : {
00359 status.updateOption="UPDATE";
00360 SctNames::Mrs() << "CC_UPDATE_CHANGE"
00361 << MRS_TEXT("CalibrationControllerImpl setting updateOption=UPDATE") << MRS_DIAGNOSTIC << ENDM;
00362 break;
00363 }
00364 case Sct_CalibrationController::CalibrationController::noupdate : {
00365 status.updateOption="NOUPDATE";
00366 SctNames::Mrs() << "CC_UPDATE_CHANGE"
00367 << MRS_TEXT("CalibrationControllerImpl setting updateOption=NOUPDATE") << MRS_DIAGNOSTIC << ENDM;
00368 break;
00369 }
00370 case Sct_CalibrationController::CalibrationController::wait : {
00371 status.updateOption="WAIT";
00372 SctNames::Mrs() << "CC_UPDATE_CHANGE"
00373 << MRS_TEXT("CalibrationControllerImpl setting updateOption=WAIT") << MRS_DIAGNOSTIC << ENDM;
00374 break;
00375 }
00376 default : {
00377 IllegalStateError e("CalibrationControllerImpl updateOption UNKNOWN", __FILE__, __LINE__);
00378 e.sendToMrs(MRS_DIAGNOSTIC);
00379 break;
00380 }
00381 }
00382 updateStatus();
00383 }
00384
00386 void listScanOptions(Sct_SctApi::Scan_ptr scan, ostream& os){
00387 os << "SCAN:";
00388 using namespace Sct_SctApi;
00389 for (unsigned ioption=0; ioption<(int)Scan::endoptions; ++ioption){
00390 int value = scan->getOption(Scan::ScanOptions(ioption));
00391 if(value){
00392 string name;
00393 switch (ioption){
00394 case Scan::full: name="full"; break;
00395 case Scan::bits32: name="bits32"; break;
00396 case Scan::loopCalLine: name="loopCalLine"; break;
00397 case Scan::distSlave: name="distSlave"; break;
00398 case Scan::debug: name="debug"; break;
00399 case Scan::tim: name="tim"; break;
00400 case Scan::nth: name="nth"; break;
00401 case Scan::nth_rem: name="nth_rem"; break;
00402 case Scan::enableDataMode: name="enableDataMode"; break;
00403 case Scan::ccode: name="ccode"; break;
00404 case Scan::ope: name="ope"; break;
00405 default: name= "unknown option!"; break;
00406 }
00407 os << "," << name << "=" << value;
00408 }
00409 }
00410 os << ";";
00411 }
00412
00413 auto_ptr<Test> CalibrationControllerImpl::executeTest(Sct_CalibrationController::TestRequest_ptr tr, shared_ptr<const Sequence> s) {
00414 TestData data;
00415 ostringstream testdataoptions;
00416
00417 if (CORBA::is_nil(tr)) {
00418 throw IllegalStateError("Test request pointer was nill", __FILE__, __LINE__);
00419 };
00420
00421 SctNames::Mrs() << "CC_TEST_START" << MRS_TEXT("Calibration Controller starting test") << MRS_INFORMATION << ENDM;
00422 Sct_SctApi::SctApiIPC_var api = getApi();
00423
00424
00425
00426 data.runNumber = runNumber;
00427 data.startScanNumber = nextScanNumber;
00428
00429 data.fitAlgorithm = tr->getFitAlgorithm();
00430 data.analysisAlgorithm = tr->getAnalysisAlgorithm();
00431
00432 {
00433 Sct_CalibrationController::TestPoints_var testPointsOut;
00434 {
00435
00436 CORBA::String_var testNameOut;
00437 CORBA::UShort testVariableOut;
00438
00439
00440 {
00441 Sct_SctApi::BankList banks;
00442 banks.length(1);
00443 banks[0]=Sct_SctApi::SCAN_CONFIG;
00444 APICALL(api, setAutoUpdateBanks(banks), "setAutoUpdateBanks failed");
00445 }
00446
00447 CORBA::ULong nScansOut;
00448 tr->startTest(api, testNameOut, testVariableOut, nScansOut, testPointsOut);
00449 if (CORBA::is_nil(tr)) {
00450 throw IllegalStateError("Test request pointer was accidentally made nill at ", __FILE__, __LINE__);
00451 };
00452 data.testName = testNameOut;
00453 data.testVariable = testVariableOut;
00454 data.nScans = nScansOut;
00455 };
00456
00457 data.testPoints = new double[testPointsOut->length()];
00458 data.testPoints_size = testPointsOut->length();
00459 for (unsigned int i=0; i<testPointsOut->length(); ++i) {
00460 data.testPoints[i] = testPointsOut[i];
00461 }
00462 };
00463
00464 auto_ptr<Test> test (new Test(data, s->getModuleList()));
00465
00466 status.currentTest = test->getUniqueID();
00467 updateStatus();
00468
00469 bool full_mode_scans=false;
00470
00471 try {
00472 unsigned int i=0;
00473 bool errorFlag=false;
00474 for (; i<data.nScans; ++i) {
00475 Sct_CalibrationController::ScanRequest_var scan = tr->getNextScan(i);
00476 if (CORBA::is_nil(scan)) {
00477 throw IllegalStateError("getNextScan returned zero!", __FILE__, __LINE__);
00478 };
00479 if (CORBA::is_nil(scan->getScanCorba())) {
00480 throw IllegalStateError("ScanRequest.getScan returned zero!", __FILE__, __LINE__);
00481 };
00482
00483 test->addScan(scan->getScanCorba());
00484 if (abortNow) {
00485 abortNow = false;
00486 abortRightNow = false;
00487 break;
00488 }
00489 try{
00490 full_mode_scans |= (scan->getScanCorba()->getOption(::Sct_SctApi::Scan::full));
00491 listScanOptions(scan->getScanCorba(), testdataoptions);
00492 test->setOptions(testdataoptions.str());
00493 std::cout << "scan options : " << data.options << std::endl;
00494 executeScan(scan, i);
00495 }catch(CORBA::Exception& e){
00496 throw CorbaExceptionWrapper(e,"Exception in executeScan", __FILE__, __LINE__);
00497 }
00498 }
00499 if (i == data.nScans && !errorFlag) {
00500 SctNames::Mrs() << "CC_TEST_END" << MRS_TEXT("Calibration Controller ending test") << MRS_INFORMATION << ENDM;
00501 test->setStatus(TestData::COMPLETED);
00502 } else {
00503 SctNames::Mrs() << "CC_TEST_ABORT" << MRS_TEXT("Calibration Controller aborting test") << MRS_INFORMATION << ENDM;
00504 test->setStatus(TestData::ABORTED);
00505 const TestData& testData = test->getData();
00506 setNextScanNumber(testData.startScanNumber + testData.nScans * (full_mode_scans?3:1));
00507 }
00508 } catch (SctApiAccessException& e) {
00509 sctApiError(e);
00510 throw;
00511 } catch (CorbaExceptionWrapper& e) {
00512 SctNames::Mrs() << "CC_TEST_ABORT" << MRS_TEXT("Calibration Controller aborting test") << MRS_INFORMATION << ENDM;
00513 test->setStatus(TestData::ABORTED);
00514 e.sendToMrs(MRS_INFORMATION);
00515
00516
00517 const TestData& testData = test->getData();
00518 setNextScanNumber(testData.startScanNumber + testData.nScans * (full_mode_scans?3:1) );
00519 }
00520
00521
00522 try {
00523 tr->endTest();
00524 } catch (CorbaExceptionWrapper& e) {
00525 e.sendToMrs(MRS_DIAGNOSTIC);
00526 }
00527
00528 try{
00529
00530 Sct_SctApi::BankList banks;
00531 banks.length(0);
00532 APICALL(api, setAutoUpdateBanks(banks), "setAutoUpdateBanks failed");
00533 } catch (SctApiAccessException& e) {
00534 sctApiError(e);
00535 e.sendToMrs(MRS_ERROR);
00536 }
00537
00538
00539 try {
00540 APICALL(api, sendABCDModules(Sct_SctApi::PHYSICS_CONFIG), "sendABCDModules failed")
00541 } catch (SctApiAccessException& e) {
00542 sctApiError(e);
00543 e.sendToMrs(MRS_ERROR);
00544 }
00545 return test;
00546 }
00547
00548 void CalibrationControllerImpl::executeScan(Sct_CalibrationController::ScanRequest_ptr scan, unsigned int index) {
00549 Sct_SctApi::SctApiIPC_var api = getApi();
00550 ++nextScanNumber;
00551 SctNames::Mrs() << "CC_SCAN_START" << MRS_TEXT("Calibration Controller starting scan") << MRS_INFORMATION << ENDM;
00552
00553 status.currentScanIndex = index;
00554 updateStatus();
00555
00556 if ( scan->isRawCorba() ){
00557 APICALL(api, doRawScan(scan->getScanCorba(), scan->delayCorba(), scan->widthCorba(), scan->configureModulesCorba(), scan->clockByTwoCorba() ), "doRawScan failed");
00558 }else{
00559 APICALL(api, doScan(scan->getScanCorba() ), "doScan failed");
00560 }
00561
00562
00563
00564
00565
00566
00567
00568 {
00569
00570 bool hasFinScanning;
00571 APIRETCALL(api, hasFinScanning, hasFinishedScanning(), "Couldn't determine whether or not scanning had finished!");
00572 while (!hasFinScanning) {
00573 usleep(500000);
00574 if (abortRightNow) {
00575 abortRightNow = false;
00576 abortNow = false;
00577 IoException erm("Abort called and SctApi not responding, doScan failed", __FILE__, __LINE__);
00578 throw erm;
00579 }
00580 APIRETCALL(api, hasFinScanning, hasFinishedScanning(), "Couldn't determine whether or not scanning had finished later on!");
00581 };
00582 };
00583
00584 SctNames::Mrs() << "CC_SCAN_END" << MRS_TEXT("Calibration Controller ending scan") << MRS_INFORMATION << ENDM;
00585 }
00586
00587 CalibrationControllerImpl & CalibrationControllerImpl::initialize(RunControl& rc) {
00588 inst = new CalibrationControllerImpl(rc);
00589 return *inst;
00590 }
00591
00592 Sct_CalibrationController::CalibrationController_ptr CalibrationControllerImpl::instance() {
00593 if (!inst)
00594 throw InvariantViolatedError("Need to call CalibrationControllerImpl::initialize first!", __FILE__, __LINE__);
00595 return inst->_this();
00596 }
00597
00598 Sct_CalibrationController::ScanLibrary_ptr CalibrationControllerImpl::getScanLibrary() {
00599 return ScanLibraryImpl::instance();
00600 }
00601
00602 Sct_CalibrationController::TestLibrary_ptr CalibrationControllerImpl::getTestLibrary() {
00603 return TestLibraryImpl::instance();
00604 }
00605
00606 Sct_CalibrationController::SequenceLibrary_ptr CalibrationControllerImpl::getSequenceLibrary() {
00607 cout << "Get Sequence Library" << endl;
00608 return SequenceLibraryImpl::instance();
00609 }
00610
00611 void CalibrationControllerImpl::doScan(Sct_CalibrationController::ScanRequest_ptr scan) {
00612 doTest(DefaultTest::instance(scan));
00613 }
00614
00615 void CalibrationControllerImpl::doTest (Sct_CalibrationController::TestRequest_ptr t) {
00616 doSequence(DefaultSequence::instance(t));
00617 }
00618
00619 void CalibrationControllerImpl::doSequence (Sct_CalibrationController::SequenceRequest_ptr r) {
00620 if (!isInControl() || isBusy()) {
00621 SctNames::Mrs() << "SEQUENCE_NOT_DONE" << MRS_TEXT("Cant do sequence")
00622 << MRS_PARAM<int>("CC-status",status.status)
00623 << MRS_WARNING << ENDM;
00624 return;
00625 }
00626
00627 status.status = status.BUSY;
00628 updateStatus();
00629
00630 m_sequence_request_thread_group.create_thread(SequenceRequestWorker(*this, r));
00631 #warning the second argument to this func should probably inherit from the self-destructing portable adapter mixin class ...
00632 }
00633
00634 Sct_SctApi::Scan_ptr CalibrationControllerImpl::getScan(unsigned long runNumber, unsigned long scanNumber) {
00635 cerr << "CalibrationControllerImpl::getScan - Not implemented" << endl;
00636 return Sct_SctApi::Scan::_nil();
00637 }
00638
00639 void CalibrationControllerImpl::updateStatus() {
00640 string name = SctNames::getControlDataName();
00641 name += ".Status";
00642 ISUtilities::addOrUpdateOrMessage(name, status, __FILE__, __LINE__, MRS_DIAGNOSTIC);
00643 }
00644
00645 CalibrationControllerImpl * CalibrationControllerImpl::inst = 0;
00646
00647 }