Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

AnalysisWorkerGroup.cpp

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 //TestAlgs methods
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     // make dcs snapshots of all modules in test
00033     try{
00034       const std::string& module = m_testdata->modules[imodule];
00035       boost::shared_ptr<AnalysisAlgorithm> alg = findAlgorithm(module);
00036       alg->checkTestResultExists();
00037 
00038       // try to get DcsInformation for this module
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     //We need to explicitly delete the list here so the lock is in force
00066     //Note that this just removes the pointer..actual deletion will only occur
00067     //if noone else has grabbed a reference to the object
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 //AnalysisWorkerGroup methods
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() ) { // no ++it here since we need to delete it in the function!
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);   // erase returns ++it
00159         } else {
00160             ++it;                   // increment ourselves
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             //      cout << "found test for run " << runno<< ", scan " << scanno << endl;
00181         }
00182     }
00183     return talgs;
00184 }
00185 
00186 
00187 
00188 
00189 void AnalysisWorkerGroup::purge() throw() {
00190     //Stop the workers from trying to get on with things
00191     this->setPaused(true);
00192     while (paused() != nWorkers()) sleep(1);
00193     
00194     // Clear the queue.
00195     shared_ptr<IOName> s;
00196     do {s=pop(); } while(s);
00197     boost::recursive_mutex::scoped_lock lock(m_tests_access);
00198 
00199     // Clear the test data.
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       // (2) Other case is callback for scan data 
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         //      cout << "run="<< runno << ", scan="<< scanno << ", modulename="<<modulename
00236         //       << ", classname="<<isname.getClassName()<<endl;
00237 
00238         shared_ptr<AnalysisWorkerGroup::TestAlgs> talgs = findTest(runno, scanno);
00239 
00240         //      cout << "Found test" << endl;
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         // Get a testresult. Add a new testresult if one dosen't exist for this module
00248         shared_ptr<AnalysisAlgorithm> algorithm = talgs->findAlgorithm(modulename);
00249 
00250         //      cout << "algorithm.get()=" << algorithm.get() << endl;
00251 
00252         bool isfit=(name->getClassName()=="SctData::FitScanResult");
00253 
00254         // lock the approprate result and do your stuff, analysis-algorithm.
00255         boost::recursive_mutex::scoped_lock lock (algorithm->getMutex());
00256         if (isfit) {
00257             //      cout << "got fit from queue" << endl;
00258             algorithm->addFitScanResult(name);
00259         } else {
00260             //      cout << "got raw from queue" << endl;
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 }// end of namespace SctAnalysis

Generated on Fri Sep 16 18:01:48 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5