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

Fitter.cpp

00001 #include "Fitter.h"
00002 #include "../src/FitStrategy.h"
00003 #include "FitterWorkerGroup.h"
00004 #include "ThresholdFitAlgorithm.h"
00005 #include "ThresholdFitAlgorithm2.h"
00006 
00007 #include "Sct/SctNames.h"
00008 #include "Sct/SctParameters.h"
00009 #include "Sct/DestroyingDeleter.h"
00010 #include "Sct/StdExceptionWrapper.h"
00011 #include "Sct/IS/IONameIS.h"
00012 
00013 #include <iostream>
00014 #include <vector>
00015 #include <cassert>
00016 #include <ctime>
00017 #include <string>
00018 #include <TMath.h>
00019 #include <boost/timer.hpp>
00020 
00021 using namespace std;
00022 using namespace Sct;
00023 using namespace SctData;
00024 using namespace boost;
00025 
00026 namespace SctFitter {
00027 void doFits(ISCallbackInfo * isc);
00028 
00029 Fitter* Fitter::fitter=0;
00030 
00031 Fitter& Fitter::instance() {
00032     if (!fitter)
00033       throw Sct::IllegalStateError("Attempt to use uninitialised Fitter", __FILE__, __LINE__);
00034     return *fitter;
00035 }
00036 
00037 Fitter& Fitter::initialize(FitterArguments args) throw(ConfigurationException) {
00038     fitter = new Fitter(args);
00039     return *fitter;
00040 }
00041 
00042   void Fitter::shutdown(){
00043     if (workergroup) workergroup->stop();
00044     getFitterServer().stop();
00045   }
00046 
00047   Fitter::Fitter(FitterArguments args) throw(ConfigurationException) : 
00048     IPCNamedObject<POA_FitterI::FitterInterface>(
00049                          SctNames::getPartition(),
00050                          args.instanceName()),
00051     m_nFitsDone(0), m_nFitErrors(0), m_nScans(0), m_scanTimeTaken(0), m_ioTimeTaken(0), m_scan("No last scan"), 
00052     m_fitStrategy(0), workergroup(0), m_args(args)  
00053   {
00054     std::cout << "Fitting Service " << m_args.print() << endl;
00055     Sct::SctNames::Mrs() << "FITTER_START" << MRS_PARAM<const char*>("Name",m_args.instanceName().c_str()) 
00056              << MRS_INFORMATION << ENDM;
00057     auto_ptr<ISInfoReceiver> ir(new ISInfoReceiver(SctNames::getPartition()));
00058     if (!ir.get())
00059         throw ConfigurationException("Fitter::initialize can't make infoReceiver ", __FILE__, __LINE__) ;
00060     m_infoReceiver  = ir;
00061     try{
00062       internal_setFitStrategy(m_args.getStrategyName());
00063     }catch(Sct::Throwable& e){
00064       std::string defaultStrategy("RootFitStrategy");
00065       e.sendToMrs(MRS_DIAGNOSTIC);
00066       internal_setFitStrategy(defaultStrategy);
00067     }
00068     workergroup = new FitterWorkerGroup();
00069     workergroup->reportTo(m_args.getISStatusName());
00070     updateSubscriptions();
00071     useAnalyticAlgorithm(m_args.analytic());
00072     internal_setFitOptions(m_args.getFitOptions());
00073   }
00074 
00075 Fitter::~Fitter() throw() {}
00076 
00077 
00078 std::string Fitter::getOutputIsServer() const{
00079   return m_args.getOutputISServer();
00080 }
00081 
00082 IPCServer& Fitter::getFitterServer() throw() {
00083   static IPCServer fitterServer;
00084     return fitterServer;
00085 }
00086 
00087 
00088 
00089 void Fitter::go() throw(IsException) {
00090   workergroup->go(m_args.getNWorkers());
00091   if (m_args.recoveryMode()) fitAll();
00092 }
00093 
00094 void Fitter::updateSubscriptions(){
00095   if (workergroup) workergroup->setPaused(true);
00096   recursive_mutex::scoped_lock scoped_lock(counterMutex);
00097  
00098   const std::list<SctService::Arguments::Subscription>& input=m_args.getInputISServers();
00099   for (std::list<SctService::Arguments::Subscription>::const_iterator i=input.begin(); 
00100        i!=input.end(); ++i){
00101     try{
00102       ISInfo::Status s=m_infoReceiver->subscribe((*i).server.c_str(),
00103                          (*i).regexp.c_str(), doFits);
00104       if (s!=ISInfo::Success) {
00105     ostringstream os;
00106     os <<"Fitter Could not subscribe to IS server ["<<(*i).server 
00107        <<"] with regexp [" << (*i).regexp << "]";
00108     IsException(s, os.str(), __FILE__, __LINE__).sendToMrs();
00109       }else{
00110     ostringstream os;
00111     os <<"Fitter subscribed to IS server [" << (*i).server
00112        <<"] with regexp [" << (*i).regexp << "]";
00113     Sct::SctNames::Mrs() << "FIT_SUBSCRIBE" << MRS_TEXT(os.str()) << MRS_INFORMATION << ENDM;
00114       }
00115     }catch(Throwable & e){
00116       e.sendToMrs();
00117     }catch(std::exception & e){
00118       Sct::StdExceptionWrapper(e, __FILE__, __LINE__).sendToMrs();
00119     }
00120   }
00121   if (workergroup) workergroup->setPaused(false);
00122 }
00123 
00124   //infoReceiver callback function must take a static function as an argument:
00125 void Fitter::doFits(ISCallbackInfo * isc) throw(IsException, LogicError) {
00126     // find out why the callback function has been called:
00127     if (isc->reason() != ISInfoCreated && isc->reason() != ISInfoUpdated )
00128     return;
00129     
00130     // put it in the queue
00131     Fitter::instance().workergroup->push(isc->name());
00132 }
00133 
00134   //CORBA
00135 void Fitter::fit(const char* name) throw() {
00136     // put it in the queue
00137     workergroup->push(name);
00138 }
00139 
00140   //CORBA
00141 void Fitter::fitAll() throw() {
00142   std::list<string> alreadyDone;
00143   {
00144     ISInfoIterator iter(SctNames::getPartition(), getOutputIsServer(), "SctData::FitScanResult.*");
00145     while (iter()) {
00146       Sct::IS::IONameIS name(iter.name());
00147       alreadyDone.push_back(name.getUniqueID());
00148     }
00149   }
00150 
00151   const std::list<SctService::Arguments::Subscription>& input=m_args.getInputISServers();
00152   unsigned nToRecover=0;
00153   for (std::list<SctService::Arguments::Subscription>::const_iterator i=input.begin(); i!=input.end(); ++i){
00154     ISInfoIterator iter(SctNames::getPartition(), (*i).server.c_str(), 
00155             (*i).regexp.c_str());
00156     while (iter()) {
00157       Sct::IS::IONameIS name(iter.name());
00158       std::string id=name.getUniqueID();
00159       if (std::find(alreadyDone.begin(), alreadyDone.end(), id)==alreadyDone.end()){
00160     nToRecover++;
00161     workergroup->push(iter.name());
00162       }
00163     }
00164   }
00165   std::ostringstream msg;
00166   msg << "Need to fit total of " << nToRecover << " objects";
00167   SctNames::Mrs() << "FITTING_RECOVERY" << MRS_TEXT(msg.str()) << MRS_DIAGNOSTIC << ENDM;
00168 }
00169 
00170   //CORBA
00171 char* Fitter::getFitOptions() throw() {
00172     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00173     string options = "";
00174     try {
00175         options = internal_getFitStrategy().getOptions();       
00176     } catch (LogicError &e) {
00177     //Um don't do anything!
00178     }
00179     char *newOpt=new char[options.length()+1];
00180     strcpy(newOpt, options.c_str());
00181     return newOpt;
00182 }
00183 
00184   //CORBA
00185 char* Fitter::status() throw() {
00186     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00187     // Have to make a new char* because IPC wants to delete it after use!
00188     string msg = internal_status();
00189     char *statusMessage = new char[msg.length()+1];
00190     strcpy(statusMessage, msg.c_str());
00191     return statusMessage;
00192 }
00193 
00194 void Fitter::internal_setFitOptions(const string & opt) throw (LogicError) {
00195   recursive_mutex::scoped_lock scoped_lock(counterMutex);
00196   internal_getFitStrategy().setOptions(opt);
00197 }
00198 
00199   //CORBA
00200 void Fitter::setFitOptions(const char *n) throw() {
00201     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00202     string name( n );
00203     try {
00204         internal_setFitOptions(name);
00205     } catch (LogicError &e) {
00206         return;
00207     }
00208 }
00209 
00210   //CORBA
00211 void Fitter::useAnalyticAlgorithm (CORBA::Boolean use) {
00212     if (use) {
00213     ThresholdFitAlgorithm2::putInMap();
00214     } else {
00215     ThresholdFitAlgorithm::putInMap();
00216     }
00217 }
00218 
00219 bool Fitter::internal_isUsingAnalyticAlgorithm() const {
00220     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00221     return ThresholdFitAlgorithm2::isInMap();
00222 }
00223 
00224   //CORBA
00225 CORBA::Boolean Fitter::isUsingAnalyticAlgorithm() {
00226      recursive_mutex::scoped_lock scoped_lock(counterMutex);
00227    return internal_isUsingAnalyticAlgorithm();
00228 }
00229 
00230 char* Fitter::getFitStrategy() throw() {
00231     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00232     string strat;
00233     try {
00234         strat = internal_getFitStrategy().getName();
00235     } catch (LogicError &e) {
00236         e.sendToMrs();
00237     }    
00238     char *newOpt=new char[strat.length()+1];
00239     strcpy(newOpt, strat.c_str());
00240     return newOpt;
00241 }
00242 
00243   //CORBA
00244 void Fitter::setFitStrategy(const char *n) throw() {
00245     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00246     string name( n );
00247     cout <<"trying to set fit strategy "<<name<<endl;
00248     try {
00249         internal_setFitStrategy(name);
00250     } catch (LogicError& e) {
00251       std::string message("failed  to set fit strategy ");
00252       message += name;
00253       Sct::InvalidArgumentError(message, __FILE__, __LINE__).sendToMrs();
00254       return;
00255     }
00256     cout <<"set fit strategy "<<name<<endl;
00257 }
00258 
00259 const char* Fitter::internal_status() const throw() {
00260     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00261     string strategyName;
00262     try {
00263         strategyName=internal_getFitStrategy().getName();
00264     } catch (LogicError &e) {
00265         strategyName="NONE";
00266     }
00267     ostringstream oss;
00268     oss << m_args.print()<<endl;
00269     oss << "Current: \n\tStrategy=" << strategyName << endl 
00270     << "\tOptions=" << internal_getFitStrategy().getOptions() << endl
00271     << "\tAnalytic fits=" << internal_isUsingAnalyticAlgorithm() << endl;
00272     oss << "\tWorkers=" << workergroup->nWorkers() << endl
00273     << "\t  (Busy=" << workergroup->busy() << ")" << endl
00274     << "\tFits Done=" << internal_nFitsDone() << endl
00275     << "\tErrors=" << internal_nFitErrors() << endl
00276     << "\tScans Done=" << m_nScans << endl 
00277     << "\tLast scan: " << internal_lastScan() << endl; 
00278     oss << "\tQueue=" << workergroup->queueSize();
00279     if (workergroup->isFifo()){
00280       oss << " [FIFO]\n";
00281     }else{
00282       oss << " [FILO]\n";
00283     }
00284     oss << "Timing:"<<endl
00285     << "\tI/O time: " << m_ioTimeTaken << endl
00286     << "\tScan time: "<< m_scanTimeTaken << endl 
00287     << "\tApprox average time/scan/thread: " << getAverageTimePerScan() << endl;
00288     m_status = oss.str();
00289     return m_status.c_str();
00290 }
00291 
00292 void Fitter::incrementFitErrors() throw() {
00293     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00294     ++m_nFitErrors;
00295 }
00296 
00297 void Fitter::incrementFitsDone() throw() {
00298     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00299     ++m_nFitsDone;
00300 }
00301 
00302 void Fitter::scanDone(double time) throw() {
00303     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00304     ++m_nScans;
00305     m_scanTimeTaken += time;
00306 }
00307 
00308 void Fitter::addIOTime(double time) throw() {
00309     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00310     m_ioTimeTaken += time;
00311 }
00312 
00313 
00314 double Fitter::getAverageTimePerScan() const throw() {
00315     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00316     double time = (m_ioTimeTaken+m_scanTimeTaken)/workergroup->nWorkers();
00317     if (m_nScans > 0) time /= m_nScans;     
00318     return time;
00319 }
00320 
00321 
00322 long Fitter::internal_nFitsDone() const throw() {
00323     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00324     return m_nFitsDone;
00325 }
00326 
00327 long Fitter::internal_nFitErrors() const throw() {
00328     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00329     return m_nFitErrors;
00330 }
00331 
00332   //CORBA
00333 long Fitter::nFitsDone() throw() {
00334     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00335     return internal_nFitsDone();
00336 }
00337 
00338   //CORBA
00339 long Fitter::nFitErrors() throw() {
00340     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00341     return internal_nFitErrors();
00342 }
00343 
00344   //CORBA
00345 long Fitter::queueLength() {
00346     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00347     return workergroup->queueSize();
00348 }
00349 
00350   //CORBA
00351 long Fitter::busy() {
00352     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00353     return workergroup->busy();
00354 }
00355 
00356 const char* Fitter::internal_lastScan() const throw() {
00357     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00358     return m_scan.c_str();
00359 }
00360 
00361   //CORBA
00362 char* Fitter::lastScan() throw() {    
00363     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00364     char * message = new char[m_scan.length()+1];
00365     strcpy(message, m_scan.c_str() );
00366     return message;
00367 }
00368 
00369 bool Fitter::isFifo(){
00370   return workergroup->isFifo();
00371 }
00372 
00373 void Fitter::setFifo(bool val){
00374   workergroup->setFifo(val);
00375 }
00376 
00377 FitStrategy& Fitter::internal_getFitStrategy() const throw(LogicError) {
00378     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00379     if (!m_fitStrategy)
00380         throw InvariantViolatedError("Fitter::getStrategy() no fit strategy defined", __FILE__, __LINE__);
00381     return *m_fitStrategy;
00382 }
00383 
00384 void Fitter::internal_setFitStrategy(const string & name) throw(LogicError) {
00385     recursive_mutex::scoped_lock scoped_lock(counterMutex);
00386     m_fitStrategy = FitStrategyFactory::instance().getStrategy(name);
00387     SctNames::Mrs() << "FIT_STRATEGY" << MRS_TEXT(string("set fit strategy to ")+name) 
00388             << MRS_INFORMATION << ENDM;
00389 }
00390 
00391 } // end of namespace SctFitter

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