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 recursive_mutex::scoped_lock lock(m_testAccess);
00049 boost::shared_ptr<TestData> testdata( new TestData() );
00050 ISInfoDictionary& id = Sct::SctNames::getISDictionary();
00051 ISInfo::Status result = id.findValue(name, *testdata);
00052 if (result != ISInfo::Success) {
00053 throw IsException(result,std::string("Error reading from IS server. Couldn't read: ")
00054 + name, __FILE__, __LINE__);
00055 }
00056 if (debug()) cout << "... which is a TestData" << endl;
00057 addTestData(testdata);
00058
00059 if (testdata->analysisAlgorithm==""){
00060 std::ostringstream message;
00061 message << "Your TestRequest script [" << name
00062 << "] has not requested an AnalysisAlgorithm.";
00063 Sct::SctNames::Mrs() << "FITTING_SERVICE" << MRS_TEXT(message.str()) << MRS_WARNING << ENDM;
00064 }
00065 } else if (ioname.getClassName()=="SctData::RawScanResult"){
00066
00067
00068 std::string requestedAlgorithm("");
00069 {
00070
00071 recursive_mutex::scoped_lock lock(m_testAccess);
00072
00073
00074 boost::shared_ptr<const TestData> td = findTestData(ioname.getUniqueID().getRunNumber(),
00075 ioname.getUniqueID().getScanNumber());
00076 if (td.get()) {
00077 requestedAlgorithm = td->fitAlgorithm;
00078 if (debug()) cout << "Requested algorithm = " << requestedAlgorithm << std::endl;
00079 }else{
00080 std::ostringstream message;
00081 message << "No test matching object " << name;
00082 Sct::SctNames::Mrs() << "FITTING_SERVICE" << MRS_TEXT(message.str()) << MRS_WARNING << ENDM;
00083 if (debug()) std::cout << message.str() << std::endl;
00084 }
00085
00086 if (requestedAlgorithm=="NONE") {
00087 if (debug()) cout << "Will not fit [" << name << "]" << std::endl;
00088 return;
00089 }
00090 }
00091
00092
00093 shared_ptr<const Serializable> ob ( IOManagerIS::instance().read(name) );
00094
00095 shared_ptr<const RawScanResult> raw = dynamic_pointer_cast<const RawScanResult>(ob);
00096 if (!raw) throw InvalidArgumentError("Fitter::work(): Not a RawScanResult", __FILE__, __LINE__);
00097
00098 Fitter::instance().addIOTime(t.elapsed());
00099 t.restart();
00100
00101
00102 Fitter::instance().setLastScanName(raw->getUniqueID());
00103
00104
00105 if (requestedAlgorithm=="") {
00106 requestedAlgorithm = raw->getHeader().getVariable().getVariableName();
00107 std::ostringstream message;
00108 message << "Guessing that algorithm used should be " << requestedAlgorithm;
00109 Sct::SctNames::Mrs() << "FITTING_SERVICE" << MRS_TEXT(message.str()) << MRS_INFORMATION << ENDM;
00110 }
00111
00112 const FitAlgorithm& alg = FitAlgorithmMap::instance().getAlgorithm(requestedAlgorithm);
00113 std::auto_ptr<SctData::FitScanResult> fitted = alg.doFit(*raw);
00114
00115 Fitter::instance().incrementFitsDone();
00116 m_calls++;
00117 Fitter::instance().scanDone(t.elapsed());
00118 t.restart();
00119
00120
00121 Sct::IS::IOParamsIS params(Sct::SctNames::getFittedDataName());
00122 Sct::ISProxy::IOManagerISProxy::instance().write(*fitted, ¶ms);
00123 Fitter::instance().addIOTime(t.elapsed());
00124 } else {
00125 std::cout << "Callback for unknown type: [" << name << "]" << std::endl;
00126 }
00127 } catch (Sct::InvalidArgumentError& e) {
00128 e.sendToMrs();
00129 Fitter::instance().incrementFitErrors();
00130 } catch(Sct::Throwable& e) {
00131 e.sendToMrs(MRS_ERROR);
00132 Fitter::instance().incrementFitErrors();
00133 } catch(std::exception& e) {
00134 StdExceptionWrapper sew(e);
00135 sew.sendToMrs(MRS_ERROR);
00136 Fitter::instance().incrementFitErrors();
00137 } catch(...) {
00138 Error e("uncaught unknown exception", __FILE__, __LINE__);
00139 e.sendToMrs(MRS_ERROR);
00140 Fitter::instance().incrementFitErrors();
00141 }
00142 }
00143
00144 void FitterWorkerGroup::setDebug(bool value){
00145 std::cout << "Debugging on" << std::endl;
00146 m_debug=value;
00147 }
00148
00149 bool FitterWorkerGroup::debug() const{
00150 return m_debug;
00151 }
00152
00153 shared_ptr<const TestData>& FitterWorkerGroup::findTestData(unsigned long run, unsigned long scan){
00154 boost::recursive_mutex::scoped_lock lock(m_testAccess);
00155 for (std::list<boost::shared_ptr<const TestData> >::iterator i=m_tests.begin();
00156 i!= m_tests.end(); ++i){
00157
00158 if (!(*i).get()) {
00159 i=m_tests.erase(i); continue;
00160 }
00161 int results_per_scan = ((*i)->options.find("full")==std::string::npos ? 1 :3);
00162 if (run == (*i)->runNumber &&
00163 scan >= (*i)->startScanNumber &&
00164 scan < ((*i)->startScanNumber+(*i)->nScans * results_per_scan) ){
00165 return (*i);
00166 }
00167 }
00168 shared_ptr<const TestData> null;
00169 return null;
00170 }
00171
00172 void FitterWorkerGroup::printTests(ostream& os) const{
00173 boost::recursive_mutex::scoped_lock lock(m_testAccess);
00174 os << setw(8) << "Run" << setw(8) << "Scan" << setw(8) << "NScans"
00175 << setw(26) << "Name" << setw(26) << "FitAlg" << endl;
00176 os << "--------------------------------------------------------------------------------" << endl;
00177 for (std::list<boost::shared_ptr<const TestData> >::const_iterator i=m_tests.begin();
00178 i!= m_tests.end(); ++i){
00179 if ((*i).get()) {
00180 os << setw(8) << (*i)->runNumber << setw(8) << (*i)->startScanNumber
00181 << setw(8) << (*i)->nScans << setw(26) << (*i)->testName;
00182 os << setw(26) << (((*i)->fitAlgorithm=="")?"[guess]":(*i)->fitAlgorithm) << endl;
00183 os << "\toptions=[" << (*i)->options << "]" << std::endl;
00184 } else{
00185 os << "\t --> Null pointer to test! <-- \n";
00186 }
00187 }
00188 os << "--------------------------------------------------------------------------------" << endl;
00189 }
00190
00191 void FitterWorkerGroup::addTestData(boost::shared_ptr<const TestData> td){
00192 using namespace boost;
00193 recursive_mutex::scoped_lock lock(m_testAccess);
00194 shared_ptr<const TestData>& previous=findTestData(td->runNumber, td->startScanNumber);
00195 if (previous.get()) {
00196 if (debug()) {
00197 cout << "Replacing TestData for "
00198 << td->runNumber << "." << td->startScanNumber << endl
00199 << " options = " << td->options << std::endl;
00200 }
00201
00202 previous=td;
00203 if (debug()) printTests(std::cout);
00204 } else{
00205 if (debug()) {
00206 cout << "Adding TestData for "
00207 << td->runNumber << "." << td->startScanNumber << endl
00208 << " options = " << td->options << std::endl;
00209 }
00210
00211 m_tests.push_back(td);
00212 }
00213 }
00214
00215 }