00001 #include "AnalysisWorkerGroup.h"
00002 #include "AnalysisAlgorithm.h"
00003 #include "AnalysisAlgorithmMap.h"
00004 #include "AnalysisService.h"
00005 #include "DcsInterface.h"
00006
00007 #include "Sct/IS/IOManagerIS.h"
00008 #include "Sct/ISProxy/IOManagerISProxy.h"
00009 #include "Sct/IS/IONameIS.h"
00010 #include "Sct/StdExceptionWrapper.h"
00011 #include "Sct/SctNames.h"
00012 #include "Sct/UniqueID.h"
00013 #include "SctData/TestResult.h"
00014 #include "SctData/DcsData.h"
00015
00016 #include "CalibrationController/IS/TestData.h"
00017 #include <boost/timer.hpp>
00018 #include <iomanip>
00019 #include <is/info.h>
00020 #include <is/infodictionary.h>
00021 #include <is/infoiterator.h>
00022 #include <is/inforeceiver.h>
00023 #include <is/infoT.h>
00024
00025 using namespace SctService;
00026 using namespace boost;
00027 using namespace std;
00028 using namespace Sct;
00029 using namespace Sct::IS;
00030 using namespace SctData;
00031
00032 namespace SctAnalysis {
00033
00034
00035 AnalysisWorkerGroup::TestAlgs::TestAlgs(boost::shared_ptr<const TestData> testdata) : m_testdata(testdata){
00036 bool dcsProblemsReported=false;
00037 for (unsigned imodule=0; imodule<m_testdata->modules_size; ++imodule){
00038
00039 try{
00040 const std::string& module = m_testdata->modules[imodule];
00041 boost::shared_ptr<AnalysisAlgorithm> alg = findAlgorithm(module);
00042 if (!alg.get()) continue;
00043 alg->checkTestResultExists();
00044
00045
00046 try{
00047 if (!AnalysisService::instance().getDcsInterface().getConfigurationInterface().empty()) {
00048 shared_ptr<SctData::DcsData> dcs (AnalysisService::instance().getDcsInterface().getData(module) );
00049
00050 alg->getTestResult()->setDcsData(dcs);
00051 }
00052 }catch(Sct::Throwable& e){
00053 if (!dcsProblemsReported) {
00054 e.sendToMrs(MRS_DIAGNOSTIC);
00055 dcsProblemsReported=true;
00056 }
00057 }catch(std::exception& e){
00058 if (!dcsProblemsReported) {
00059 StdExceptionWrapper(e,__FILE__,__LINE__).sendToMrs(MRS_DIAGNOSTIC);
00060 dcsProblemsReported=true;
00061 }
00062 }
00063 }catch(Sct::Throwable& e){
00064 e.sendToMrs();
00065 }
00066 }
00067 }
00068
00069 AnalysisWorkerGroup::TestAlgs::~TestAlgs() {
00070 boost::recursive_mutex::scoped_lock lock(m_access);
00071
00072
00073
00074
00075 m_algorithms.clear();
00076 }
00077
00078 void AnalysisWorkerGroup::TestAlgs::removeAlgorithm(shared_ptr<AnalysisAlgorithm> alg) {
00079 boost::recursive_mutex::scoped_lock lock(m_access);
00080 list<shared_ptr<AnalysisAlgorithm> >::iterator it =
00081 find(m_algorithms.begin(), m_algorithms.end(), alg);
00082
00083 if ( it != m_algorithms.end() )
00084 m_algorithms.erase(it);
00085 }
00086
00087 shared_ptr<const TestData>AnalysisWorkerGroup::TestAlgs::getTest() const{
00088 if (!m_testdata.get()) throw Sct::InvariantViolatedError("Attempt to retrieve null TestData - object is not properly constructed",__FILE__,__LINE__);
00089 return m_testdata;
00090 }
00091
00092 ostream& AnalysisWorkerGroup::TestAlgs::printStatus(ostream& os) const throw() {
00093 boost::recursive_mutex::scoped_lock lock(m_access);
00094 os << setw(26) << getTest()->testName
00095 << setw(8) << getTest()->runNumber
00096 << setw(8) << getTest()->startScanNumber
00097 << setw(8) << getTest()->nScans
00098 << setw(26) << getTest()->analysisAlgorithm
00099 << endl;
00100
00101 return os;
00102 }
00103
00104 shared_ptr<AnalysisAlgorithm> AnalysisWorkerGroup::TestAlgs::findAlgorithm(const string& modulename) {
00105 boost::recursive_mutex::scoped_lock lock(m_access);
00106 shared_ptr<AnalysisAlgorithm> alg;
00107 for (list<shared_ptr<AnalysisAlgorithm> >::const_iterator it=m_algorithms.begin();
00108 it != m_algorithms.end();
00109 ++it) {
00110 if ( (*it)->getModuleName()==modulename ) {
00111 alg=(*it);
00112 break;
00113 }
00114 }
00115 if (!alg) {
00116 alg=addAlgorithm(modulename);
00117 }
00118 return alg;
00119 }
00120
00121 shared_ptr<AnalysisAlgorithm> AnalysisWorkerGroup::TestAlgs::addAlgorithm(const string& modulename) {
00122 boost::recursive_mutex::scoped_lock lock(m_access);
00123 shared_ptr<AnalysisAlgorithm> alg = AnalysisAlgorithmMap::instance().getAlgorithm(getTest(), modulename);
00124 m_algorithms.push_back(alg);
00125 return alg;
00126 }
00127
00128
00129
00130
00131 ostream& AnalysisWorkerGroup::printStatus(ostream& os) const throw() {
00132 boost::recursive_mutex::scoped_lock lock(m_tests_access);
00133 os << "\t === Analysis Service ===\n" << endl;
00134 os << "AnalysisWorkerGroup tests:" << endl;
00135 unsigned ntest=0;
00136 os << setw(26) << "TestName"
00137 << setw(8) << "Run"
00138 << setw(8) << "Scan"
00139 << setw(8) << "NScans"
00140 << setw(26) << "AnalysisAlg"
00141 << endl;
00142 os << "----------------------------------------------------------------"<<endl;
00143 for (list<shared_ptr<TestAlgs> >::const_iterator it = m_tests.begin();
00144 it != m_tests.end() ; ++it ) {
00145 (*it)->printStatus(os);
00146 ++ntest;
00147 }
00148 os << "----------------------------------------------------------------"<<endl;
00149 os << endl;
00150 os << "\tWorkers=" << nWorkers() << "\t (Busy=" << busy() << ")"
00151 << "\tQueue =" << queueSize();
00152 if (isFifo()) {
00153 os << " [FIFO]\n";
00154 }else{
00155 os << " [FILO]\n";
00156 }
00157 os <<"Total number of tests = " << ntest << endl;
00158 return os;
00159 }
00160
00161 void AnalysisWorkerGroup::addTest(shared_ptr<const TestData> testdata) {
00162 boost::recursive_mutex::scoped_lock lock(m_tests_access);
00163 m_tests.push_back(shared_ptr<TestAlgs>(new TestAlgs(testdata) ) );
00164 }
00165
00166 void AnalysisWorkerGroup::removeTestsUpTo(shared_ptr<const TestData> testdata) {
00167 boost::recursive_mutex::scoped_lock lock(m_tests_access);
00168 list<shared_ptr<TestAlgs> >::iterator it = m_tests.begin();
00169
00170 while( it != m_tests.end() ) {
00171 if ((*it)->getTest()->runNumber==testdata->runNumber
00172 && (*it)->getTest()->startScanNumber<=testdata->startScanNumber) {
00173
00174 cout << "Deleting old test for run "
00175 << (*it)->getTest()->runNumber << ", start scan "
00176 << (*it)->getTest()->startScanNumber
00177 << endl;
00178 it=m_tests.erase(it);
00179 } else {
00180 ++it;
00181 }
00182 }
00183 }
00184
00185 shared_ptr<AnalysisWorkerGroup::TestAlgs> AnalysisWorkerGroup::findTest(const TestData& testdata) const throw() {
00186 return findTest(testdata.runNumber, testdata.startScanNumber);
00187 }
00188
00189 shared_ptr<AnalysisWorkerGroup::TestAlgs> AnalysisWorkerGroup::findTest(const unsigned long runno, const unsigned long scanno) const throw() {
00190 boost::recursive_mutex::scoped_lock lock(m_tests_access);
00191 shared_ptr<AnalysisWorkerGroup::TestAlgs> talgs;
00192 for (list<shared_ptr<TestAlgs> >::const_iterator it = m_tests.begin();
00193 it != m_tests.end();
00194 ++it ) {
00195 shared_ptr<const TestData> td=(*it)->getTest();
00196 if ( runno == td->runNumber &&
00197 scanno >= td->startScanNumber &&
00198 scanno < td->startScanNumber + td->nScans) {
00199 talgs=*it;
00200
00201 }
00202 }
00203 return talgs;
00204 }
00205
00206
00207
00208
00209 void AnalysisWorkerGroup::purge() throw() {
00210
00211 this->setPaused(true);
00212 while (paused() != nWorkers()) sleep(1);
00213
00214
00215 shared_ptr<IOName> s;
00216 do {s=pop(); } while(s);
00217 boost::recursive_mutex::scoped_lock lock(m_tests_access);
00218
00219
00220 cout << "Clearing tests ... " << endl;
00221 m_tests.clear();
00222 cout << " ... done clearing tests" << endl;
00223 this->setPaused(false);
00224 }
00225
00226 void AnalysisWorkerGroup::work(shared_ptr<IOName> name) throw() {
00227 using namespace SctData;
00228
00229 try {
00231 if (name->getIOName().find("TestData") != string::npos){
00232 boost::shared_ptr<TestData> testdata( new TestData() );
00233 ISInfoDictionary& id = Sct::SctNames::getISDictionary();
00234 ISInfo::Status result = id.findValue(name->getIOName().c_str(), *testdata);
00235 if (result != ISInfo::Success) {
00236 throw IsException(result,std::string("Error reading from IS server. Couldn't read: ")
00237 + name->getIOName(), __FILE__, __LINE__);
00238 }
00239 if (findTest(*testdata).get() == 0 ) {
00240 addTest(testdata);
00241 } else {
00242 throw Sct::IoException(std::string("AnalysisService::TestCallback Test already exists: ")
00243 +name->getIOName(), __FILE__, __LINE__);
00244 }
00245 return;
00246 }
00247
00248
00249 timer t;
00250 UniqueID id (name->getUniqueID());
00251 const unsigned runno = id.getRunNumber();
00252 const unsigned scanno = id.getScanNumber();
00253 const string modulename= id.getModule();
00254
00255
00256
00257
00258 shared_ptr<AnalysisWorkerGroup::TestAlgs> talgs = findTest(runno, scanno);
00259
00260
00261
00262 if (!talgs) {
00263 std::ostringstream oss; oss << "AnalysisWorker::work. No test found for run "
00264 << runno << " scan" << scanno;
00265 throw IllegalStateError(oss.str(), __FILE__, __LINE__);
00266 }
00267
00268 shared_ptr<AnalysisAlgorithm> algorithm = talgs->findAlgorithm(modulename);
00269 if (!algorithm.get()) return;
00270
00271
00272
00273 bool isfit=(name->getClassName()=="SctData::FitScanResult");
00274
00275
00276 boost::recursive_mutex::scoped_lock lock (algorithm->getMutex());
00277 if (isfit) {
00278
00279 algorithm->addFitScanResult(name);
00280 } else {
00281
00282 algorithm->addRawScanResult(name);
00283 }
00284 if (algorithm->canAnalyze()) {
00285 if (algorithm->isDone()) throw IllegalStateError("AnalysisWorker::work. Algorithm has additional, unnecessary Scan - analysis already done", __FILE__, __LINE__);
00286 algorithm->checkTestResultExists();
00287 algorithm->addOverheadTime(t.elapsed());
00288
00289 t.restart();
00290 algorithm->loadData();
00291 algorithm->addIOTime(t.elapsed());
00292
00293 t.restart();
00294 algorithm->analyze();
00295 algorithm->addAnalysisTime(t.elapsed());
00296
00297 t.restart();
00298 algorithm->finish();
00299 algorithm->addIOTime(t.elapsed());
00300 talgs->removeAlgorithm(algorithm);
00301 } else {
00302 algorithm->addOverheadTime(t.elapsed());
00303 }
00304
00305 } catch (InvalidArgumentError& e) {
00306 e.sendToMrs();
00307 } catch(Throwable& e) {
00308 e.sendToMrs(MRS_ERROR);
00309 } catch(std::exception& e) {
00310 StdExceptionWrapper sew(e);
00311 sew.sendToMrs(MRS_ERROR);
00312 } catch(...) {
00313 Error e("uncaught unknown exception", __FILE__, __LINE__);
00314 e.sendToMrs(MRS_ERROR);
00315 }
00316 }
00317
00318
00319 }