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