00001 #include "FitterWorkerGroup.h"
00002 #include "Fitter.h"
00003 #include "FitAlgorithm.h"
00004 #include "FitAlgorithmMap.h"
00005
00006 #include <iomanip>
00007
00008 #include "Sct/SctNames.h"
00009 #include "Sct/IS/IOManagerIS.h"
00010 #include "Sct/ISProxy/IOManagerISProxy.h"
00011 #include "Sct/IS/IONameIS.h"
00012 #include "SctData/FitScanResult.h"
00013 #include "SctData/RawScanResult.h"
00014 #include "SctData/ConfigurationVariable.h"
00015 #include "SctData/NullVariable.h"
00016 #include "Sct/StdExceptionWrapper.h"
00017 #include "ScanResultWriter/dataTypes.h"
00018 #include "CalibrationController/IS/TestData.h"
00019 #include <boost/timer.hpp>
00020 #include "Sct/IS/IONameIS.h"
00021 #include <is/infodictionary.h>
00022
00023 using namespace std;
00024 using namespace SctService;
00025 using boost::shared_ptr;
00026 using boost::timer;
00027 using namespace SctData;
00028 using namespace Sct;
00029 using namespace Sct::IS;
00030
00031 namespace SctFitter {
00032
00033
00034 FitterWorkerGroup::FitterWorkerGroup() : m_calls(0), m_debug(false) {}
00035
00036 FitterWorkerGroup::~FitterWorkerGroup() {}
00037
00038 void FitterWorkerGroup::work(string name) throw() {
00039 using namespace SctData;
00040 timer t;
00041
00042 Sct::IS::IONameIS ioname(name);
00043
00044 if (debug()) cout << "Callback on " << name << endl;
00045
00046 try {
00047 if (ioname.getClassName()=="TestData"){
00048 boost::shared_ptr<TestData> testdata( new TestData() );
00049 ISInfoDictionary& id = Sct::SctNames::getISDictionary();
00050 ISInfo::Status result = id.findValue(name, *testdata);
00051 if (result != ISInfo::Success) {
00052 throw IsException(result,std::string("Error reading from IS server. Couldn't read: ")
00053 + name, __FILE__, __LINE__);
00054 }
00055 if (debug()) cout << "... which is a TestData" << endl;
00056 addTestData(testdata);
00057
00058 if (testdata->analysisAlgorithm==""){
00059 std::ostringstream message;
00060 message << "Your TestRequest script [" << name
00061 << "] has not requested an AnalysisAlgorithm.";
00062 Sct::SctNames::Mrs() << "FITTING_SERVICE" << MRS_TEXT(message.str()) << MRS_WARNING << ENDM;
00063 }
00064 } else if (ioname.getClassName()=="SctData::RawScanResult"){
00065
00066 std::string requestedAlgorithm("");
00067
00068 boost::shared_ptr<const TestData> td = findTestData(ioname.getUniqueID().getRunNumber(),
00069 ioname.getUniqueID().getScanNumber());
00070 if (td.get()) {
00071 requestedAlgorithm = td->fitAlgorithm;
00072 if (debug()) cout << "Requested algorithm = " << requestedAlgorithm << std::endl;
00073 }else{
00074 std::ostringstream message;
00075 message << "No test matching object " << name;
00076 Sct::SctNames::Mrs() << "FITTING_SERVICE" << MRS_TEXT(message.str()) << MRS_WARNING << ENDM;
00077 }
00078
00079 if (requestedAlgorithm=="NONE") {
00080 if (debug()) cout << "Will not fit [" << name << "]" << std::endl;
00081 return;
00082 }
00083
00084
00085 shared_ptr<const Serializable> ob ( IOManagerIS::instance().read(name) );
00086
00087 shared_ptr<const RawScanResult> raw = dynamic_pointer_cast<const RawScanResult>(ob);
00088 if (!raw) throw InvalidArgumentError("Fitter::work(): Not a RawScanResult", __FILE__, __LINE__);
00089
00090 Fitter::instance().addIOTime(t.elapsed());
00091 t.restart();
00092
00093
00094 Fitter::instance().setLastScanName(raw->getUniqueID());
00095
00096
00097 if (requestedAlgorithm=="") {
00098 requestedAlgorithm = raw->getHeader().getVariable().getVariableName();
00099 std::ostringstream message;
00100 message << "Guessing that algorithm used should be " << requestedAlgorithm;
00101 Sct::SctNames::Mrs() << "FITTING_SERVICE" << MRS_TEXT(message.str()) << MRS_INFORMATION << ENDM;
00102 }
00103
00104 const FitAlgorithm& alg = FitAlgorithmMap::instance().getAlgorithm(requestedAlgorithm);
00105 std::auto_ptr<SctData::FitScanResult> fitted = alg.doFit(*raw);
00106
00107 Fitter::instance().incrementFitsDone();
00108 m_calls++;
00109 Fitter::instance().scanDone(t.elapsed());
00110 t.restart();
00111
00112
00113 Sct::IS::IOParamsIS params(Sct::SctNames::getFittedDataName());
00114 Sct::ISProxy::IOManagerISProxy::instance().write(*fitted, ¶ms);
00115 Fitter::instance().addIOTime(t.elapsed());
00116 } else {
00117 std::cout << "Callback for unknown type: [" << name << "]" << std::endl;
00118 }
00119 } catch (Sct::InvalidArgumentError& e) {
00120 e.sendToMrs();
00121 Fitter::instance().incrementFitErrors();
00122 } catch(Sct::Throwable& e) {
00123 e.sendToMrs(MRS_ERROR);
00124 Fitter::instance().incrementFitErrors();
00125 } catch(std::exception& e) {
00126 StdExceptionWrapper sew(e);
00127 sew.sendToMrs(MRS_ERROR);
00128 Fitter::instance().incrementFitErrors();
00129 } catch(...) {
00130 Error e("uncaught unknown exception", __FILE__, __LINE__);
00131 e.sendToMrs(MRS_ERROR);
00132 Fitter::instance().incrementFitErrors();
00133 }
00134 }
00135
00136 void FitterWorkerGroup::setDebug(bool value){
00137 std::cout << "Debugging on" << std::endl;
00138 m_debug=value;
00139 }
00140
00141 bool FitterWorkerGroup::debug() const{
00142 return m_debug;
00143 }
00144
00145 shared_ptr<const TestData> FitterWorkerGroup::findTestData(unsigned long run, unsigned long scan){
00146 boost::recursive_mutex::scoped_lock lock(m_testAccess);
00147 for (std::list<boost::shared_ptr<const TestData> >::iterator i=m_tests.begin();
00148 i!= m_tests.end(); ++i){
00149
00150 if (!(*i).get()) {
00151 i=m_tests.erase(i); continue;
00152 }
00153 if (run == (*i)->runNumber &&
00154 scan >= (*i)->startScanNumber &&
00155 scan < ((*i)->startScanNumber+(*i)->nScans) ){
00156 return (*i);
00157 }
00158 }
00159 shared_ptr<const TestData> null;
00160 return null;
00161 }
00162
00163 void FitterWorkerGroup::printTests(ostream& os) const{
00164 boost::recursive_mutex::scoped_lock lock(m_testAccess);
00165 os << setw(8) << "Run" << setw(8) << "Scan" << setw(8) << "NScans"
00166 << setw(26) << "Name" << setw(26) << "FitAlg" << endl;
00167 os << "--------------------------------------------------------------------------------" << endl;
00168 for (std::list<boost::shared_ptr<const TestData> >::const_iterator i=m_tests.begin();
00169 i!= m_tests.end(); ++i){
00170 if ((*i).get()) {
00171 os << setw(8) << (*i)->runNumber << setw(8) << (*i)->startScanNumber
00172 << setw(8) << (*i)->nScans << setw(26) << (*i)->testName;
00173 os << setw(26) << (((*i)->fitAlgorithm=="")?"[guess]":(*i)->fitAlgorithm) << endl;
00174 } else{
00175 os << "\t --> Null pointer to test! <-- \n";
00176 }
00177 }
00178 os << "--------------------------------------------------------------------------------" << endl;
00179 }
00180
00181 void FitterWorkerGroup::addTestData(boost::shared_ptr<const TestData> td){
00182 using namespace boost;
00183 recursive_mutex::scoped_lock lock(m_testAccess);
00184 shared_ptr<const TestData> previous=findTestData(td->runNumber, td->startScanNumber);
00185 if (previous.get()) {
00186 if (debug()) cout << "Replacing TestData for "
00187 << td->runNumber << "." << td->startScanNumber << endl;
00188
00189 previous=td;
00190 } else{
00191 if (debug()) cout << "Adding TestData for "
00192 << td->runNumber << "." << td->startScanNumber << endl;
00193
00194 m_tests.push_back(td);
00195 }
00196 }
00197
00198 }