00001 #include "AnalysisService.h"
00002 #include "AnalysisAlgorithmMap.h"
00003 #include "AnalysisAlgorithm.h"
00004 #include "AnalysisWorkerGroup.h"
00005 #include "AnalysisArguments.h"
00006 #include "DcsInterface.h"
00007 #include "ConfigurationInterface.h"
00008
00009 #include "Sct/SctNames.h"
00010 #include "Sct/StdExceptionWrapper.h"
00011 #include "Sct/IpcObjectException.h"
00012 #include "Sct/IS/IOManagerIS.h"
00013 #include "Sct/IS/IONameIS.h"
00014 #include "Sct/ConfigurationException.h"
00015 #include "Sct/DestroyingDeleter.h"
00016 #include "Sct/UnsupportedOperationError.h"
00017 #include "sctConf/configuration.h"
00018 #include "SctData/TestResult.h"
00019 #include "sctConfIPC/configipc.h"
00020 #include "CalibrationController/IS/TestData.h"
00021
00022 #include <ipc/core.h>
00023 #include <boost/scoped_ptr.hpp>
00024
00025 using namespace Sct;
00026 using namespace Sct::IS;
00027 using namespace SctData;
00028 using boost::scoped_ptr;
00029
00030 namespace SctAnalysis {
00031
00032 AnalysisService::~AnalysisService(){
00033 }
00034
00035 void AnalysisService::shutdown(){
00036 if (workergroup) workergroup->stop();
00037 getServer().stop();
00038 }
00039
00040 AnalysisService::AnalysisService(AnalysisArguments args) :
00041 IPCNamedObject<POA_AnalysisServiceI::AnalysisServiceInterface,
00042 ipc::multi_thread>(
00043 SctNames::getPartition(),
00044 args.instanceName()),
00045 dcsinterface(0), infoReceiver(new ISInfoReceiver(SctNames::getPartition())), m_args(args) {
00046 if (!infoReceiver.get())
00047 throw ConfigurationException("AnalysisService::AnalysisService can't make infoReceiver ", __FILE__, __LINE__) ;
00048 std::cout << "Making DcsInterface ... " << std::endl;
00049 try{
00050 boost::shared_ptr<SctConfiguration::Configuration> configipc(new SctConfiguration::ConfigIPC);
00051 boost::shared_ptr<ConfigurationInterface> config_local (new ConfigurationInterface(configipc));
00052 dcsinterface = new DcsInterface(config_local);
00053 config_local->update();
00054 }catch(std::exception &e){
00055 SctNames::Mrs() << MRS_TEXT("I wont be able to save DCS information as I dont know the configuration")
00056 << "ANALYSIS_NO_DCS" << MRS_DIAGNOSTIC << ENDM;
00057 }
00058 try{
00059 setFitStrategy(m_args.getStrategyName());
00060 }catch(Throwable& e){
00061 e.sendToMrs();
00062 setFitStrategy("RootFitStrategy");
00063 }
00064 getFitStrategy().setOptions(m_args.getFitOptions());
00065 workergroup = new AnalysisWorkerGroup();
00066 workergroup->reportTo(m_args.getISStatusName());
00067 }
00068
00069 IPCServer& AnalysisService::getServer() throw() {
00070 static IPCServer server;
00071 return server;
00072 }
00073
00074 const std::string AnalysisService::getOutputISServerName(){
00075 return m_args.getOutputISServer();
00076 }
00077
00078 void AnalysisService::run() {
00079
00080 workergroup->go(m_args.getNWorkers());
00081
00082 if (m_args.recoveryMode()) recover();
00083 const list<SctService::Arguments::Subscription>& theList=m_args.getInputISServers();
00084
00085
00086 for (list<SctService::Arguments::Subscription>::const_iterator i=theList.begin();
00087 i!=theList.end(); ++i){
00088 ISInfo::Status s = infoReceiver->subscribe((*i).server.c_str(),
00089 (*i).regexp.c_str(), generalCallback);
00090 if (s!=ISInfo::Success){
00091 std::ostringstream oss;
00092 oss << "Analysis service could not subscribed to [" << (*i).server
00093 << "] to receive [" << (*i).regexp << "]";
00094 SctNames::Mrs() << "ANALYSIS_SUBSCRIBE" << MRS_TEXT(oss.str()) << MRS_ERROR << ENDM;
00095 }else{
00096 std::ostringstream oss;
00097 oss << "Analysis service subscribed to [" << (*i).server
00098 << "] to receive [" << (*i).regexp << "]";
00099 SctNames::Mrs() << "ANALYSIS_SUBSCRIBE" << MRS_TEXT(oss.str()) << MRS_INFORMATION << ENDM;
00100 }
00101 }
00102 }
00103
00104 CORBA::Short AnalysisService::busy() {
00105 boost::recursive_mutex::scoped_lock lock(m_status_access);
00106 return workergroup->busy();
00107 }
00108
00109 CORBA::Short AnalysisService::queueLength() {
00110 boost::recursive_mutex::scoped_lock lock(m_status_access);
00111 return workergroup->busy();
00112 }
00113
00114 char* AnalysisService::status() throw() {
00115 boost::recursive_mutex::scoped_lock lock(m_status_access);
00116 ostringstream os;
00117 workergroup->printStatus(os);
00118 os << "\n" << AnalysisAlgorithmMap::instance().getAllStatus() << endl;
00119 if (dcsinterface){
00120 os << "AnalysisService : DCS INFORMATION" << endl;
00121 dcsinterface->printStatus(os);
00122 }
00123
00124 const unsigned length = os.str().length()+1;
00125 char *statusMessage = new char[length];
00126
00127 strcpy(statusMessage, os.str().c_str());
00128 return statusMessage;
00129 }
00130
00131 void AnalysisService::analyzeModule(const char* testname, const char* modulename) throw() {
00132 try {
00133 shared_ptr<TestData> testdata( new TestData() );
00134 ISInfoDictionary& id = SctNames::getISDictionary();
00135 ISInfo::Status result = id.findValue(testname, *testdata);
00136
00137 if (result != ISInfo::Success) {
00138 string os = "Error reading from IS server. Couldn't get: ";
00139 os += testname;
00140 throw IsException(result, os, __FILE__, __LINE__);
00141 }
00142
00143 if (workergroup->findTest(*testdata).get() == 0 ) {
00144 workergroup->addTest(testdata);
00145 }
00146
00147 for (unsigned iscan=testdata->startScanNumber;
00148 iscan<(testdata->startScanNumber + testdata->nScans);
00149 ++iscan ) {
00150 {
00151 ostringstream name_raw;
00153 name_raw << "SctData::RawScanResult." << testdata->runNumber << "." << iscan << "." << modulename;
00154
00155 ISInfoIterator rawIter(SctNames::getPartition(), SctNames::getEventDataName().c_str(), name_raw.str().c_str());
00156 while ( rawIter() ) {
00157 try {
00158
00159 workergroup->push(shared_ptr<IOName>(new IONameIS(rawIter.name())));
00160 } catch ( Sct::Throwable& e) {
00161 e.sendToMrs(MRS_ERROR);
00162 }
00163 }
00164 } {
00165 ostringstream name_fit;
00167 name_fit << "SctData::FitScanResult." << testdata->runNumber << "." << iscan << "." << modulename;
00168
00169 ISInfoIterator fitIter(SctNames::getPartition(), SctNames::getFittedDataName().c_str(), name_fit.str().c_str());
00170 while ( fitIter() ) {
00171 try {
00172
00173 workergroup->push(shared_ptr<IOName>(new IONameIS(fitIter.name())));
00174 } catch ( Sct::Throwable& e) {
00175 e.sendToMrs(MRS_ERROR);
00176 }
00177 }
00178 }
00179 }
00180 } catch (Throwable& e) {
00181 e.sendToMrs(MRS_ERROR);
00182 return;
00183 }
00184 }
00185
00186 void AnalysisService::purge() throw() {
00187 try {
00188 cout << "Doing purge" << endl;
00189 workergroup->purge();
00190 cout << "Memory purge completed" << endl;
00191 } catch (Throwable& e) {
00192 e.sendToMrs(MRS_ERROR);
00193 return;
00194 }
00195 }
00196
00197 void AnalysisService::analyze(const char* name) throw() {
00198 analyzeModule(name, "*");
00199 }
00200
00201 void AnalysisService::generalCallback(ISCallbackInfo * isc){
00202 try{
00203 IONameIS name(isc->name());
00204 if (name.getClassName()=="TestData"){
00205 testDataCallback(isc);
00206 }else if (name.getClassName()=="SctData::RawScanResult"
00207 || name.getClassName()=="SctData::FitScanResult") {
00208 scanResultCallback(isc);
00209 }
00210 }catch(Sct::Throwable& e){
00211 e.sendToMrs();
00212 }
00213 }
00214
00215 void AnalysisService::scanResultCallback(ISCallbackInfo * isc) {
00216 try {
00217 if (isc->reason() != ISInfoCreated )
00218 return;
00219 instance().workergroup->push(shared_ptr<IOName>(new IONameIS(isc->name())));
00220 } catch(Sct::Throwable& e) {
00221 e.sendToMrs(MRS_ERROR);
00222 }
00223 }
00224
00225 void AnalysisService::testDataCallback(ISCallbackInfo * isc) {
00226 try {
00227 shared_ptr<TestData> testdata( new TestData() );
00228 isc->value(*testdata);
00229
00230 if (isc->reason() == ISInfoCreated ) {
00231 instance().workergroup->push(shared_ptr<IOName>(new IONameIS(isc->name())));
00232 } else if (isc->reason() == ISInfoUpdated && testdata->status == TestData::ABORTED) {
00233 instance().workergroup->removeTestsUpTo(testdata);
00234
00235 } else if (isc->reason() == ISInfoDeleted ) {
00236 instance().workergroup->removeTestsUpTo(testdata);
00237 }
00238 } catch (Sct::Throwable& e) {
00239 e.sendToMrs(MRS_ERROR);
00240 }
00241 }
00242
00243 void AnalysisService::setFitStrategy(const string& name) throw(LogicError) {
00244 SctNames::Mrs() << "ANALYSIS_FIT_STRATEGY" << MRS_PARAM<const char*>("Strategy", name.c_str())
00245 << MRS_INFORMATION << ENDM;
00246 fitStrategy = SctFitter::FitStrategyFactory::instance().getStrategy(name);
00247 }
00248
00249 SctFitter::FitStrategy& AnalysisService::getFitStrategy() const throw(LogicError) {
00250 if (!fitStrategy)
00251 throw InvariantViolatedError("Fitter::getStrategy() no fit strategy defined", __FILE__, __LINE__);
00252 return *fitStrategy;
00253 }
00254
00255 AnalysisService& AnalysisService::instance() {
00256 if (!service) throw Sct::IllegalStateError("Attempt to use uninitialised analysis", __FILE__, __LINE__);
00257 return *service;
00258 }
00259
00260 AnalysisService& AnalysisService::initialize(AnalysisArguments args) {
00261 service = new AnalysisService(args);
00262 return *service;
00263 }
00264
00265 DcsInterface& AnalysisService::getDcsInterface(){
00266 if (!dcsinterface){
00267 throw ConfigurationException("Cant return dcsinterface",__FILE__, __LINE__);
00268 }else{
00269 return *dcsinterface;
00270 }
00271 }
00272
00273 void AnalysisService::recover(){
00274 SctNames::Mrs() << "ANALYSIS_RECOVERY" << MRS_TEXT("Analysis recovery started in recovery mode") << ENDM;
00275 Sct::UnsupportedOperationError("Recovery not implimented", __FILE__, __LINE__).sendToMrs(MRS_DIAGNOSTIC);
00276 }
00277
00278
00279 AnalysisService* AnalysisService::service=0;
00280
00281 }