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

Generated on Fri Jan 14 12:47:01 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5