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