Commit f0997f35 authored by yannick legoc's avatar yannick legoc
Browse files

Clarified the RemoteMatlab inheritance

parent e6db32f1
<module name="remotetas">
<controller class="tas::RemoteMatlab"/>
<controller class="tas::RemoteMatlabReq"/>
<controller class="tas::RemoteMatlabPub"/>
<include path="$(NOMAD_HOME)/../NomadModules/src"/>
......
......@@ -16,18 +16,14 @@
* limitations under the Licence.
*/
#include "RemoteMatlab.h"
#include <InstrumentManager/InstrumentManager.h>
#include <controllers/common/acquisition/Count.h>
#include <controllers/common/scanlegacy/ScanInfo.h>
#include <ics/Utilities/Calculations.h>
#include <common/connection/RestJsonHttpConnection.h>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <fstream>
#include <iostream>
#include <common/base/ServerProperties.h>
#include "RemoteMatlab.h"
namespace tas {
......@@ -35,13 +31,8 @@ using namespace std;
using namespace common;
using namespace boost;
using namespace cameo;
using boost::property_tree::ptree;
const std::string RemoteMatlab::TYPE = "tas_remote_matlab";
const std::string RemoteMatlab::MATLAB_APPLICATION = "matlab";
const std::string RemoteMatlab::NUMOR_RESPONDER = "tas_numor";
const int32 RemoteMatlab::LOG_TYPE = 1;
const int32 RemoteMatlab::LIVE_TYPE = 2;
const std::string RemoteMatlab::TYPE = "tas_base_matlab";
RemoteMatlab::RemoteMatlab(const std::string& name) :
utilities::ImageData(name),
......@@ -51,288 +42,42 @@ RemoteMatlab::RemoteMatlab(const std::string& name) :
initialized.init(this, NOSAVE, "initialized");
test.init(this, SAVE, "test");
testNumor.init(this, SAVE, "test_numor");
active.init(this, SAVE, "active");
scanController.init(this, "scan");
countSpy.init(this, "acquisition_spy");
experimentData.assign(InstrumentManager::getInstance()->getFirstExperimentControllerByType("title"));
const char* weblog = getenv("NOMAD_SENDDATA");
if (weblog != 0) {
m_nomadSendData = string(weblog);
to_lower(m_nomadSendData);
}
}
RemoteMatlab::RemoteMatlab(const RemoteMatlab& controller) :
utilities::ImageData(controller),
controller::Start(this) {
}
RemoteMatlab::~RemoteMatlab() {
// Stop the remote application.
m_matlabApplication->stop();
// Wait for the termination
application::State state = m_matlabApplication->waitFor();
cout << "Matlab application terminated with state " << application::toString(state) << endl;
}
void RemoteMatlab::postConfiguration() {
registerUpdater(scanController->serializerEvent, &RemoteMatlab::updateNumor, this);
//registerUpdater(scanController->getCount()->statusMessage, &RemoteMatlab::updateCountStatusMessage, this);
registerUpdater(countSpy->statusMessage, &RemoteMatlab::updateCountStatusMessage, this);
if (serverEndpoint() == "") {
m_server.reset(new Server(application::This::getServer().getEndpoint()));
} else {
m_server.reset(new Server(serverEndpoint()));
}
initialized = initApplication();
}
bool RemoteMatlab::initApplication() {
// Do not initialize if it is already done
if (initialized()) {
return true;
}
try {
// Start the Matlab server
if (!m_server->isAvailable(1000)) {
cout << "Matlab server is not available" << endl;
return false;
}
cout << "Matlab server is connected" << endl;
m_matlabApplication = m_server->connect(MATLAB_APPLICATION);
if (m_matlabApplication->exists()) {
// The application exists from a previous server session
m_matlabApplication->kill();
application::State state = m_matlabApplication->waitFor();
cout << "Terminated matlab application " << state << endl;
}
m_matlabApplication = m_server->start(MATLAB_APPLICATION);
if (!m_matlabApplication->exists()) {
cout << "No matlab application" << endl;
return false;
}
// Create the requester.
m_requester = application::Requester::create(*m_matlabApplication, NUMOR_RESPONDER);
if (m_requester.get() == 0) {
cout << "requester error" << endl;
return false;
}
// Application initialized.
initialized = true;
return true;
} catch (...) {
// Currently an exception can occur during isAvailable.
cout << "Unexpected exception during matlab connection" << endl;
}
return false;
}
void RemoteMatlab::updateNumor() {
// Send the numor to be computed if there is something to serialize
if (scanController->serializerEvent()) {
// Send the numor
if (test()) {
sendNumor(testNumor(), false);
} else {
sendNumor(scanController->numor(), false);
}
}
}
void RemoteMatlab::updateCountStatusMessage() {
if ((countSpy->statusMessage() == "Close data") && scanController->getScanInfo()->running()) {
cout << "Send the numor for live refresh" << endl;
// Send the numor
if (test()) {
sendNumor(testNumor(), true);
} else {
sendNumor(scanController->numor(), true);
}
}
}
void RemoteMatlab::sendNumor(int32 numor, bool live) {
if (!initApplication()) {
return;
}
// Get the content of the numor.
string numorName = lexical_cast<string>(numor);
size_t size = numorName.size();
if (size < 6) {
string prefix(6 - size, '0');
numorName = prefix + numorName;
}
LogStream logStream = log(Level::s_Info).property(scanController->logAcquisitionType)
.property(scanController->logNumor)
.property(scanController->logSubtitle);
logStream << numorName << " in Q" << image(numor, "q") << endlog;
string numorFileName(common::ServerProperties::getInstance()->getNomadDataPath());
numorFileName += numorName;
ifstream numorFile;
numorFile.open(numorFileName.c_str());
stringstream stream;
stream << numorFile.rdbuf();
// Serialize the request.
proto::NumorRequest request;
if (live) {
request.mutable_info()->set_type(proto::NumorInfo_Type_LIVE);
} else {
request.mutable_info()->set_type(proto::NumorInfo_Type_LOG);
}
request.mutable_info()->set_propid(getProposalId());
request.mutable_info()->set_proposal(getProposalName());
request.mutable_info()->set_instrid(getInstrumentId());
request.mutable_info()->set_instrument(getInstrumentName());
request.mutable_info()->set_sampid(getSampleId());
request.mutable_info()->set_sample(getSampleName());
request.mutable_info()->set_cycle(getCycleId());
request.mutable_info()->set_imageid(getImageName());
request.mutable_info()->set_numor(lexical_cast<string>(numor));
request.set_content(stream.str());
// Send the message.
m_requester->sendBinary(request.SerializeAsString());
cout << "Sent numor request " << numor << endl;
// Wait for the response synchronously.
// Note that responses can be processed asynchronously if the server is able to.
string data;
m_requester->receiveBinary(data);
proto::NumorResponse response;
response.ParseFromString(data);
if (response.mutable_info()->type() == proto::NumorInfo_Type_LOG) {
sendImageToFluentd(response);
} else {
setContentFromBinaryData(response.image());
}
}
void RemoteMatlab::start() {
// Send the numor
sendNumor(testNumor(), true);
}
void RemoteMatlab::sendImageToFluentd(const proto::NumorResponse& response) {
// Encode the JSON message
ptree message;
message.put("id", Date().toString());
message.put("mt", "acq");
message.put("name", "numor");
message.put("type", "number");
message.put("value", response.info().numor());
message.put("output", "null");
message.put("level", "info");
message.put("propid", response.info().propid());
message.put("instrid", response.info().instrid());
message.put("sampleid", response.info().sampid());
message.put("sample", response.info().sample());
message.put("cycleid", response.info().cycle());
message.put("imagefile", response.info().imageid());
// The binary content of the image is a string and we encode it in base64
message.put("imagedata", Calculations::encodeBase64(response.image()));
stringstream os;
write_json(os, message, false);
std::string instrumentName = response.info().instrument();
boost::to_upper(instrumentName);
RestJsonHttpConnection con;
try {
con.openUrl("localhost", "8888");
//New environment variable
if (m_nomadSendData == "0") {
//if 0 send data to dev database
con.setPath(string("/oracle.forward.") + instrumentName + "_DEV");
} else if (m_nomadSendData == "1") {
//if 1 send data to prod database
con.setPath(string("/oracle.forward.") + instrumentName);
}
con.setData(os.str());
boost::property_tree::ptree response = con.send(false);
} catch (const Exception& e) {
// log to server
cerr << e.printStack() << endl;
}
}
string RemoteMatlab::getProposalId() {
string RemoteMatlab::getProposalId() const {
return experimentData->proposalId();
}
string RemoteMatlab::getProposalName() {
//Proposal name = experiment number
string RemoteMatlab::getProposalName() const {
return experimentData->experimentNumber();
}
string RemoteMatlab::getInstrumentId() {
string RemoteMatlab::getInstrumentId() const {
return experimentData->instrumentId();
}
string RemoteMatlab::getInstrumentName() {
string RemoteMatlab::getInstrumentName() const {
return experimentData->instrumentName();
}
string RemoteMatlab::getSampleId() {
string RemoteMatlab::getSampleId() const {
return experimentData->sampleId();
}
string RemoteMatlab::getSampleName() {
string RemoteMatlab::getSampleName() const {
return experimentData->chemicalFormula();
}
string RemoteMatlab::getCycleId() {
string RemoteMatlab::getCycleId() const {
return experimentData->cycleId();
}
......
......@@ -38,48 +38,26 @@ public:
static const std::string TYPE;
RemoteMatlab(const std::string& name);
RemoteMatlab(const RemoteMatlab& controller);
virtual ~RemoteMatlab();
virtual void postConfiguration();
void updateNumor();
void updateCountStatusMessage();
virtual void start();
Property<std::string> serverEndpoint;
Property<bool> initialized;
Property<bool> test;
Property<int32> testNumor;
Property<bool> active;
ControllerPtr<acquisition::ExperimentData> experimentData;
ControllerPtr<scan::GenericScan1D> scanController;
ControllerPtr<utilities::CountSpy> countSpy;
private:
bool initApplication();
void sendNumor(int32 numor, bool live);
void sendImageToFluentd(const proto::NumorResponse& response);
std::string getProposalId();
std::string getProposalName();
std::string getInstrumentId();
std::string getInstrumentName();
std::string getSampleId();
std::string getSampleName();
std::string getCycleId();
static const std::string MATLAB_APPLICATION;
static const std::string NUMOR_RESPONDER;
static const int32 LOG_TYPE;
static const int32 LIVE_TYPE;
std::auto_ptr<cameo::Server> m_server;
std::auto_ptr<cameo::application::Instance> m_matlabApplication;
std::auto_ptr<cameo::application::Requester> m_requester;
std::string m_nomadSendData;
protected:
std::string getProposalId() const;
std::string getProposalName() const;
std::string getInstrumentId() const;
std::string getInstrumentName() const;
std::string getSampleId() const;
std::string getSampleName() const;
std::string getCycleId() const;
};
}
......
......@@ -38,36 +38,18 @@ using namespace cameo;
using boost::property_tree::ptree;
const std::string RemoteMatlabPub::TYPE = "tas_remote_matlab_pub";
const std::string RemoteMatlabPub::MATLAB_APPLICATION = "matlab";
const std::string RemoteMatlabPub::MATLAB_APPLICATION = "matlabpub";
const std::string RemoteMatlabPub::NUMOR_PUBLISHER = "tas_numor";
const std::string RemoteMatlabPub::IMAGE_PUBLISHER = "tas_image";
const int32 RemoteMatlabPub::LOG_TYPE = 1;
const int32 RemoteMatlabPub::LIVE_TYPE = 2;
RemoteMatlabPub::RemoteMatlabPub(const std::string& name) :
utilities::ImageData(name),
controller::Start(this) {
serverEndpoint.init(this, SAVE, "cameo_server");
initialized.init(this, NOSAVE, "initialized");
test.init(this, SAVE, "test");
testNumor.init(this, SAVE, "test_numor");
scanController.init(this, "scan");
countSpy.init(this, "acquisition_spy");
experimentData.assign(InstrumentManager::getInstance()->getFirstExperimentControllerByType("title"));
const char* weblog = getenv("NOMAD_SENDDATA");
if (weblog != 0) {
m_nomadSendData = string(weblog);
to_lower(m_nomadSendData);
}
RemoteMatlab(name) {
}
RemoteMatlabPub::RemoteMatlabPub(const RemoteMatlabPub& controller) :
utilities::ImageData(controller),
controller::Start(this) {
RemoteMatlab(controller) {
}
RemoteMatlabPub::~RemoteMatlabPub() {
......@@ -95,8 +77,8 @@ void RemoteMatlabPub::postConfiguration() {
if (serverEndpoint() == "") {
m_server.reset(new Server(application::This::getServer().getEndpoint()));
} else {
}
else {
m_server.reset(new Server(serverEndpoint()));
}
......@@ -117,7 +99,7 @@ bool RemoteMatlabPub::initApplication() {
return false;
}
cout << "Matlab server is connected" << endl;
cout << "Matlab server is connected to " << getName() << endl;
m_matlabApplication = m_server->connect(MATLAB_APPLICATION);
if (m_matlabApplication->exists()) {
......@@ -152,8 +134,8 @@ bool RemoteMatlabPub::initApplication() {
initialized = true;
return true;
} catch (...) {
}
catch (...) {
// Currently an exception can occur during isAvailable.
cout << "Unexpected exception during matlab connection" << endl;
}
......@@ -164,11 +146,14 @@ bool RemoteMatlabPub::initApplication() {
void RemoteMatlabPub::updateNumor() {
// Send the numor to be computed if there is something to serialize
if (scanController->serializerEvent()) {
if (scanController->serializerEvent()
&& active()) {
// Send the numor
if (test()) {
sendNumor(testNumor(), false);
} else {
}
else {
sendNumor(scanController->numor(), false);
}
}
......@@ -176,14 +161,17 @@ void RemoteMatlabPub::updateNumor() {
void RemoteMatlabPub::updateCountStatusMessage() {
if ((countSpy->statusMessage() == "Close data") && scanController->getScanInfo()->running()) {
if ((countSpy->statusMessage() == "Close data")
&& scanController->getScanInfo()->running()
&& active()) {
cout << "Send the numor for live refresh" << endl;
// Send the numor
if (test()) {
sendNumor(testNumor(), true);
} else {
}
else {
sendNumor(scanController->numor(), true);
}
}
......@@ -224,7 +212,8 @@ void RemoteMatlabPub::sendNumor(int32 numor, bool live) {
proto::NumorRequest request;
if (live) {
request.mutable_info()->set_type(proto::NumorInfo_Type_LIVE);
} else {
}
else {
request.mutable_info()->set_type(proto::NumorInfo_Type_LOG);
}
......@@ -243,7 +232,7 @@ void RemoteMatlabPub::sendNumor(int32 numor, bool live) {
// Publish the message
m_publisher->sendBinary(request.SerializeAsString());
cout << "Sent numor " << numor << endl;
cout << getName() << " sent numor " << numor << endl;
}
void RemoteMatlabPub::start() {
......@@ -263,8 +252,8 @@ void RemoteMatlabPub::subscriberLoop() {
if (response.mutable_info()->type() == proto::NumorInfo_Type_LOG) {
sendImageToFluentd(response);
} else {
}
else {
setContentFromBinaryData(response.image());
}
}
......@@ -302,53 +291,23 @@ void RemoteMatlabPub::sendImageToFluentd(const proto::NumorResponse& response) {
try {
con.openUrl("localhost", "8888");
//New environment variable
if (m_nomadSendData == "0") {
//if 0 send data to dev database
// Environment variable
if (ServerProperties::getInstance()->getNomadSenddata() == "0") {
// If 0 send data to dev database.
con.setPath(string("/oracle.forward.") + instrumentName + "_DEV");
} else if (m_nomadSendData == "1") {
//if 1 send data to prod database
} else if (ServerProperties::getInstance()->getNomadSenddata() == "1") {
// If 1 send data to prod database.
con.setPath(string("/oracle.forward.") + instrumentName);
}
con.setData(os.str());
boost::property_tree::ptree response = con.send(false);
} catch (const Exception& e) {
}
catch (const Exception& e) {
// log to server
cerr << e.printStack() << endl;
}
}
string RemoteMatlabPub::getProposalId() {
return experimentData->proposalId();
}
string RemoteMatlabPub::getProposalName() {
//Proposal name = experiment number
return experimentData->experimentNumber();
}
string RemoteMatlabPub::getInstrumentId() {
return experimentData->instrumentId();
}
string RemoteMatlabPub::getInstrumentName() {
return experimentData->instrumentName();
}
string RemoteMatlabPub::getSampleId() {
return experimentData->sampleId();
}
string RemoteMatlabPub::getSampleName() {
return experimentData->chemicalFormula();
}
string RemoteMatlabPub::getCycleId() {
return experimentData->cycleId();
}
}
......@@ -19,19 +19,11 @@
#ifndef TAS_REMOTEMATLABPUB_H
#define TAS_REMOTEMATLABPUB_H
#include "controllers/common/utilities/imageviewer/ImageData.h"
#include "controllers/common/acquisition/ImageGeneratable.h"
#include "controllers/common/acquisition/ExperimentData.h"
#include "controllers/common/scanlegacy/GenericScan1D.h"
#include "controllers/common/utilities/CountSpy.h"
#include "NumorMessages.pb.h"
#include <cameo/cameo.h>
#include "RemoteMatlab.h"
namespace tas {
class RemoteMatlabPub : public utilities::ImageData,
public acquisition::ImageGeneratable,
public controller::Start {
class RemoteMatlabPub