CalibrationControllerImpl.cpp

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 //#include <ilu/iluxport.h>
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     //Remove status from IS:
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     // get new handle...
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     //Notify MRS
00160     SctNames::Mrs() << "CC_ABORT" << MRS_TEXT("User requested abort Sequence") << MRS_INFORMATION << ENDM;
00161 
00162     //See if SctApi is responding, if not, then abortRightNow!
00163     //Use pid as an example...
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 //First up, synchronise our scanNumber with SctApi's
00183       APIRETCALL(api, nextScanNumber, getScanNumber(), "Couldn't synchronise scan numbers")
00184       //The call startSequence
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;    //Drop through
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         //Check we didn't fail somewhere
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; //All done!
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                     // Save any changes that have been made (into the CALIBRATION and SCAN banks)
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             // keep CALIBRATION and SCAN bank up to date if possible.
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           // no longer keep banks up to date
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;  //Drop through
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     //status.updateOption can be changed by other IPC method
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     // make another list which we can remove things from:
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             // make an IONameIS which allows us to interpret the IS name
00311             Sct::IS::IONameIS isname(ii.name());
00312             std::string moduleName=isname.getUniqueID().getModule();
00313 
00314             // look for the module name in our list
00315             std::list<string>::iterator it = std::find( mylist.begin(), mylist.end(), moduleName);
00316             // if its there, then update that module, and remove it from our list.
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         } // end of loop over currently available TestResult
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     //AJB APICALL(api, setABCDModules(banks contains Sct_SctApi::CALIBRATION_CONFIG), "setABCDModules failed")
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         //TestRequestAdapter tra(tr);
00436         CORBA::String_var testNameOut;
00437         CORBA::UShort testVariableOut;
00438     
00439     //Keep SCAN bank up to date
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;    //Drop through
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     //Try an increment the scan number to the end of the test
00517     const TestData& testData = test->getData();
00518     setNextScanNumber(testData.startScanNumber + testData.nScans * (full_mode_scans?3:1) );
00519     }
00520 
00521     //End the test
00522     try {
00523         tr->endTest();
00524     } catch (CorbaExceptionWrapper& e) {
00525     e.sendToMrs(MRS_DIAGNOSTIC);
00526     }
00527 
00528     try{
00529       // Stop keeping the scan bank up to date.
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     //Reset the module configurations to the original
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     // Perhaps the next few lines could be replaced by an APICALL to awaitScan ??   CGL: 2004/01/24
00563     // No, awaitScan has no timeout, or other get out (except at CORBA level)
00564     // CalibrationController may want to give more feedback here about what is going on. BJG: 2004/01/25
00565     // Also would be place to put APICALL to abortScan, once implemented properly? 
00566 
00567 
00568     {
00569       // nInitialSleeps no longer needed
00570       bool hasFinScanning;
00571       APIRETCALL(api, hasFinScanning, hasFinishedScanning(), "Couldn't determine whether or not scanning had finished!");
00572       while (!hasFinScanning) {
00573     usleep(500000); // check 2 times per second, or thereabouts.
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;  // set back to INCONTROL by the SequenceRequestWorker
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 }

Generated on Mon Feb 6 14:01:17 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6