Commit 05119a03 authored by Locatelli's avatar Locatelli
Browse files

Implement offscreen serializer

parent 133b632b
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/../NomadServer/src -I/usr/include/python3.5m -I/usr/include/x86_64-linux-gnu/qt5/QtWidgets -I/usr/include/x86_64-linux-gnu/qt5 -I/usr/include/x86_64-linux-gnu/qt5/QtGui -I/usr/include/x86_64-linux-gnu/qt5/QtCore
bin_PROGRAMS = ploty2 mplplot test test2
bin_PROGRAMS = ploty2 mplplot offmplplot test test2
QT = \
view/qt/QtColorMapWidget.cpp \
......@@ -30,7 +30,14 @@ PLOT = \
plot/PlotHisto.cpp \
plot/PlotToolBar.cpp \
plot/PlotWindow.cpp \
plot/PropertyPlot.cpp
plot/offscreen/OffScreenEmptyPlot.cpp \
plot/offscreen/OffScreenPlot.cpp \
plot/offscreen/OffScreenPlot1D.cpp \
plot/offscreen/OffScreenPlot2D.cpp \
plot/property/PropertyEmptyPlot.cpp \
plot/property/PropertyPlot.cpp \
plot/property/PropertyPlot1D.cpp \
plot/property/PropertyPlot2D.cpp
PROTOBUF = \
protobuf/generated/AcquisitionSerializer.pb.cc \
......@@ -91,6 +98,23 @@ mplplot_LDADD = $(LIBS) $(RM_LIBS) \
$(BOOST_FILESYSTEM_LIB) \
$(BOOST_THREAD_LIB)
offmplplot_SOURCES = \
mainoffscreenplot.cpp \
manager/ServerRequesterManager.cpp \
manager/ServerSubscriberManager.cpp \
$(PLOT) \
$(PROTOBUF) \
$(DATACONT) \
$(MPLCPP) \
$(QT)
offmplplot_CPPFLAGS = $(RM_CXXFLAGS) -DOFFSCREEN -DTRACEDEBUG
offmplplot_LDFLAGS = $(RM_LDFLAGS)
offmplplot_LDADD = $(LIBS) $(RM_LIBS) \
$(BOOST_SYSTEM_LIB) \
$(BOOST_FILESYSTEM_LIB) \
$(BOOST_THREAD_LIB)
test_SOURCES = \
maintest.cpp
......
This diff is collapsed.
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include <iostream>
#include <termios.h>
#include <unistd.h>
#include <fstream>
#include <cstdlib>
#include <signal.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include "Common.h"
#include "protobuf/generated/AcquisitionSerializer.pb.h"
#include "view/mpl/MplFigure.h"
#include "Trace.h"
#include "Error.h"
#include "view/mpl/Mpl.h"
#include "plot/offscreen/OffScreenEmptyPlot.h"
#include "plot/offscreen/OffScreenPlot1D.h"
#include "plot/offscreen/OffScreenPlot2D.h"
#include "manager/ServerRequesterManager.h"
using namespace std;
using namespace cameo;
unique_ptr<application::Instance> nomadserver; //! Instance of nomad server
/*!
* \brief crash handler method
* \param[in] sig the signal number which calling this method
*/
void crash_handler(int32 sig) {
}
/*!
* \brief main program function
* \return error code
*/
int32 main(int32 argc, char* argv[]) {
for (int32 i = 0; i < argc; ++i) {
DBGMSG(argv[i]);
}
if (argc < 4) {
Error("mainoffscreenplot", "Missing arguments need 5 got", argc);
return EXIT_FAILURE;
}
// Create and init the Matplolib module
view::mpl::Mpl* mpl = new view::mpl::Mpl();
// Init cameo application
int32 err = EXIT_SUCCESS;
application::This::init(1, &argv[3]);
{
// Get nomad server instance
nomadserver = getNomadInstance(application::This::getServer());
if (nomadserver.get() == 0) {
Error("mainoffscreenplot", "No nomad server instance");
err = EXIT_FAILURE;
goto exit;
}
DBGMSG("Connected to " << *nomadserver);
// create a requester on the nomad server database
unique_ptr<application::Requester> requesterdb = application::Requester::create(*nomadserver, "database");
if (requesterdb.get() == 0) {
Error("mainoffscreenplot", "Connection problem on database");
err = EXIT_FAILURE;
goto exit;
}
DBGMSG("Created requester " << *requesterdb);
// Manage application signal
// signal(SIGABRT, crash_handler);
signal(SIGHUP, crash_handler);
// signal(SIGSEGV, crash_handler);
signal(SIGPIPE, crash_handler);
signal(SIGINT, crash_handler);
// Init the nomad server requester manager
manager::ServerRequesterManager::getInstance()->init(requesterdb.get());
// Set cameo application running
application::This::setRunning();
boost::filesystem::path pbfile = getenv("HOME");
pbfile += "/offscreenImages/log/pb/";
pbfile += argv[2];
pbfile.replace_extension("pb");
DBGMSG("file : " << pbfile.string().c_str());
ifstream inputMessage(pbfile.string().c_str(), fstream::binary);
if (inputMessage.is_open() == false) {
Error("mainoffscreenplot", "Failed to open temporary file wich contains proto::PlotPropertyDataMessage", argv[2]);
err = EXIT_FAILURE;
} else {
uint32 size = boost::filesystem::file_size(pbfile);
char buffer[size];
inputMessage.read(buffer, size);
buffer::Data data;
data.ParseFromArray(buffer, size);
DBGMSG("buffer = " << size);
DBGMSG("numor = " << data.numor());
DBGMSG("dataxArray = " << data.xdata_size());
DBGMSG("datayArray = " << data.ydata_size());
DBGMSG("datazArray = " << data.zdata_size());
inputMessage.close();
view::mpl::MplFigure* figure = new view::mpl::MplFigure();
ostringstream plotkey;
plotkey << argv[2];
if ((data.xdata_size() > 0) && (data.ydata_size() > 0) && (data.zdata_size() > 0)) {
// 2D
for (int32 i = 0; i < data.xdata_size(); ++i) {
try {
plot::offscreen::OffScreenPlot2D plot(figure, plotkey.str(), mpl, i, &data);
plot.display();
plot.save();
} catch (Error& e) {
Error("mainoffscreenplot", "Failed create 2d plot", plotkey.str());
}
}
} else if ((data.xdata_size() > 0) && (data.ydata_size() > 0)) {
// 1D
for (int32 i = 0; i < data.xdata_size(); ++i) {
try {
plot::offscreen::OffScreenPlot1D plot(figure, plotkey.str(), mpl, i, &data);
plot.display();
plot.save();
} catch (Error& e) {
Error("mainoffscreenplot", "Failed create 1d plot", plotkey.str());
}
}
} else {
try {
plot::offscreen::OffScreenEmptyPlot plot(figure, plotkey.str(), mpl, 0, &data);
plot.display();
plot.save();
} catch (Error& e) {
Error("mainoffscreenplot", "Failed create empty plot", plotkey.str());
}
}
delete figure;
// delete file
boost::filesystem::remove(pbfile);
}
DBGMSG("ServerRequester::resetInstance");
// Clean manager
manager::ServerRequesterManager::resetInstance();
}
exit: delete mpl;
// Terminate cameo application
application::This::terminate();
return err;
}
......@@ -41,16 +41,12 @@ using namespace cameo;
* constructor
*/
OffScreenPlotManager::OffScreenPlotManager() {
m_ScanDataPlot = nullptr;
m_DataPlot = nullptr;
}
/*
* constructor
*/
OffScreenPlotManager::~OffScreenPlotManager() {
delete m_ScanDataPlot;
delete m_DataPlot;
}
/*
......@@ -102,31 +98,14 @@ void OffScreenPlotManager::loop(application::Subscriber* subscriber) {
* savePlot
*/
void OffScreenPlotManager::savePlot(const string& pbfilename) {
boost::filesystem::path pbfile = getenv("HOME");
pbfile += "/offscreenImages/log/pb/";
pbfile += pbfilename;
pbfile.replace_extension("pb");
DBGMSG("file : " << pbfile.string().c_str());
ifstream inputMessage(pbfile.string().c_str(), fstream::binary);
if (inputMessage.is_open() == false) {
// TODO Error
return;
// Start mplplot process with files name as arguments
vector<string> args;
args.push_back(pbfilename);
shared_ptr<cameo::application::Instance> offplot = application::This::getServer().start("offmplplot", args);
if (!offplot->exists()) {
Error("OffScreenPlotManager","savePlot", "unable to start offmplplot cameo instance", *offplot);
}
uint32 size = boost::filesystem::file_size(pbfile);
char buffer[size];
inputMessage.read(buffer, size);
buffer::Data data;
data.ParseFromArray(buffer, size);
DBGMSG("buffer = " << size);
DBGMSG("numor = " << data.numor());
DBGMSG("dataxArray = " << data.xdata_size());
DBGMSG("datayArray = " << data.ydata_size());
DBGMSG("datazArray = " << data.zdata_size());
inputMessage.close();
// delete file
boost::filesystem::remove(pbfile);
}
}
......@@ -67,9 +67,6 @@ private:
static OffScreenPlotManager* m_Instance; //! Pointer of singleton instance
plot::Plot* m_DataPlot; //!
plot::Plot1D* m_ScanDataPlot; //!
};
}
......
......@@ -133,7 +133,6 @@ void PlotManager::displayPropertyPlot(const proto::Message& message, const proto
ofstream file1(filename1.str().c_str(), ios::binary);
if (file1.is_open() == true) {
DBGMSG("create file : " << filename1.str());
file1.write(part1.c_str(), part1.size());
file1.close();
......@@ -143,7 +142,6 @@ void PlotManager::displayPropertyPlot(const proto::Message& message, const proto
ofstream file2(filename2.str().c_str(), ios::binary);
if (file2.is_open() == true) {
DBGMSG("create file : " << filename2.str());
file2.write(part2.c_str(), part2.size());
file2.close();
......@@ -153,15 +151,12 @@ void PlotManager::displayPropertyPlot(const proto::Message& message, const proto
args.push_back(filename2.str());
shared_ptr<cameo::application::Instance> plot = application::This::getServer().start("mplplot", args);
if (!plot->exists()) {
DBGMSG("Unable to start plot");
Error("PlotManager","displayPropertyPlot", "unable to start mplplot cameo instance", *plot);
return;
}
DBGMSG("starting mplplot : " << plot);
// Check that Ploty is really running by waiting for the status update.
plot->waitFor(application::RUNNING);
m_PlotsProcesses[plotMessage.plotkey()] = plot;
DBGMSG("mplplot started : " << plot);
} else {
Error("PlotManager","displayPropertyPlot", "couldn't managed to create temporary file", filename2.str());
......
......@@ -39,7 +39,7 @@ public:
/*!
* \brief Unsusbscribe property events
*/
virtual void unsubscribeUpdate() {
void unsubscribeUpdate() {
ServerSubscriberManager::getInstance()->unregisterUpdater(this);
}
......
......@@ -103,7 +103,7 @@ int32 ServerSubscriberManager::loop() {
for (auto iter : m_Updaters) {
it = find(iter.second.begin(), iter.second.end(), id);
if (it != iter.second.end()) {
DBGMSG("--> " << messagePropertyChanged.databaseid() << " " << messagePropertyChanged.propertyid() << " : " << iter.first);
// DBGMSG("--> " << messagePropertyChanged.databaseid() << " " << messagePropertyChanged.propertyid() << " : " << iter.first);
return id;
}
}
......
......@@ -17,28 +17,20 @@
*/
#include "plot/EmptyPlot.h"
#include "view/mpl/Mpl.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <algorithm>
#include "PlotWindow.h"
#include "datacontainer/PropertyPlotDataContainer.h"
#include "Trace.h"
using namespace std;
using namespace datacontainer;
namespace plot {
/*
* constructor
*/
EmptyPlot::EmptyPlot(const std::string& plotkey, PropertyPlotDataContainer* plotContainer, view::mpl::Mpl* mpl,
EmptyPlot::EmptyPlot(const std::string& plotkey, view::mpl::Mpl* mpl,
PlotWindow* plotwindow) :
PropertyPlot(plotkey, plotContainer, mpl, plotwindow) {
Plot(plotkey, mpl, plotwindow) {
}
/*
......@@ -47,50 +39,19 @@ EmptyPlot::EmptyPlot(const std::string& plotkey, PropertyPlotDataContainer* plot
EmptyPlot::~EmptyPlot() {
}
/*
* display
*/
void EmptyPlot::display() throw (Error) {
///////////////////////////////////////////////////////////////////////////////////////
//// Subscribe on property events
//// Set Title
////
subscribeUpdate();
}
/*
* subscribeUpdate
*/
void EmptyPlot::subscribeUpdate() {
// Subcribes on all data for getting new plot type
vector<int32> ids;
for (int32 id : m_DataCont->dataXIds) {
ids.push_back(id);
}
for (int32 id : m_DataCont->dataYIds) {
ids.push_back(id);
}
for (int32 id : m_DataCont->dataZIds) {
ids.push_back(id);
}
PropertyPlot::subscribeUpdate(ids);
}
/*
* updatePlot
*/
void EmptyPlot::update(int32 id) {
DBGMSG("update id : " << id);
plot::PlotType ptype = m_DataCont->getPlotType();
if (ptype != plot::PLOT_1D) {
DBGMSG("Get new Plot Type: " << ptype);
if (m_EndOfPlot == false) {
unsubscribeUpdate();
m_EndOfPlot = true;
m_PlotWindow->switchPlot();
return;
}
string title = getTitle();
try {
m_Mpl->title(title);
} catch (Error &e) {
Warning("EmptyPlot", "display", "Failed to set window title", title);
}
}
......
......@@ -19,7 +19,7 @@
#ifndef EMPTYPLOT_H
#define EMPTYPLOT_H
#include "plot/PropertyPlot.h"
#include "plot/Plot.h"
namespace plot {
......@@ -28,19 +28,17 @@ class PlotWindow;
/*!
* \brief EmptyPlot control class
*/
class EmptyPlot: public PropertyPlot {
class EmptyPlot: public Plot {
public:
/*!
* \brief constructor
* \param[in] plotkey The unique plot key string
* \param[in] plotContainer The property plot data info container
* \param[in] mpl The mpl object
* \param[in] plotwindow The plot window object which containing this plot
*/
EmptyPlot(const std::string& plotkey, datacontainer::PropertyPlotDataContainer* plotContainer, view::mpl::Mpl* mpl,
PlotWindow* plotwindow);
EmptyPlot(const std::string& plotkey, view::mpl::Mpl* mpl, PlotWindow* plotwindow);
/*!
* \brief destructor
......@@ -53,12 +51,6 @@ public:
*/
virtual void display() throw (Error);
/*!
* \brief update server property event
* \param[in] id The property id event from nomad server
*/
virtual void update(int32 id);
/*!
* \brief reset the limit after zoom back
* \throws Error
......@@ -86,13 +78,6 @@ public:
*/
virtual void aspectRatio(bool state) throw (Error);
private:
/*!
* \brief Susbscribe for property events on nomad server
*/
virtual void subscribeUpdate();
};
}
......
......@@ -36,14 +36,6 @@ Plot::Plot(const std::string& plotkey, view::mpl::Mpl* mpl, PlotWindow* plotwind
* destructor
*/
Plot::~Plot() {
unsubscribeUpdate();
}
/*
* unsubscribeUpdate
*/
void Plot::unsubscribeUpdate() {
manager::ServerSubscriberManager::getInstance()->unregisterUpdater(this);
}
}
......@@ -24,7 +24,6 @@
#include <cmath>
#include <common/base/BaseTypes.h>
#include "manager/ServerSubscriber.h"
#include "Error.h"
namespace view {
......@@ -40,7 +39,7 @@ class PlotWindow;
/*!
* \brief Mother class for plot control
*/
class Plot: public manager::ServerSubscriber {
class Plot {
public:
......@@ -98,7 +97,7 @@ public:
* \return The z value
* \throws Error
*/
virtual float64 getZData(const std::string& axisname, float64& x, float64& y) const throw (Error) {
virtual float64 getZDataValue(const std::string& axisname, float64& x, float64& y) const throw (Error) {
// No z data by default
return std::nanf("");
}
......@@ -106,9 +105,10 @@ public:
protected:
/*!
* \brief Unsusbscribe property events
* \brief Get title to give for the plot
* \return The title string
*/
virtual void unsubscribeUpdate();
virtual std::string getTitle() = 0;
std::string m_PlotKey; //! Unique Plot key
......
......@@ -33,12 +33,9 @@ namespace plot {
/*
* constructor
*/
Plot1D::Plot1D(const std::string& plotkey, PropertyPlotDataContainer* plotContainer, view::mpl::Mpl* mpl,
PlotWindow* plotwindow) :
PropertyPlot(plotkey, plotContainer, mpl, plotwindow), m_MplPlot1D(mpl, plotwindow) {
Plot1D::Plot1D(const std::string& plotkey, view::mpl::Mpl* mpl, PlotWindow* plotwindow, view::mpl::MplFigure* figure) :
Plot(plotkey, mpl, plotwindow), m_MplPlot1D(mpl, figure) {
m_NbPlots = 0;
m_PlotXArraysChanged = false;
m_PlotYArraysChanged = false;
}
/*
......@@ -63,26 +60,12 @@ void Plot1D::display() throw (Error) {
///////////////////////////////////////////////////////////////////////////////////////
//// Set Title
////
string title;
if (m_DataCont->numorId != 0) {
try {
title = ServerRequesterManager::getInstance()->getStringPropertyValue(m_DataCont->numorId);
} catch (Error&) {
Warning("Plot1D", "display", "Failed to set get numor title property value ");
}
} else if (m_DataCont->titleId != 0) {
try {
title = ServerRequesterManager::getInstance()->getStringPropertyValue(m_DataCont->titleId);
} catch (Error&) {
Warning("Plot1D", "display", "Failed to set get title property value ");
}
} else {
title = m_DataCont->title;
}
string title = getTitle();
try {
m_MplPlot1D.title(title);
m_PlotWindow->setWindowTitle(title);
if (m_PlotWindow != nullptr) {
m_PlotWindow->setWindowTitle(title);
}
} catch (Error &e) {
Warning("Plot1D", "display", "Failed to set window title", title);
}
......@@ -90,56 +73,23 @@ void Plot1D::display() throw (Error) {
///////////////////////////////////////////////////////////////////////////////////////
//// Fill x and y arrays
////
m_NbPlots = 0;
if (m_DataCont->hasx) {
m_NbPlots = (uint32) m_DataCont->dataXIds.size();
} else if (m_DataCont->hasy) {
m_NbPlots = (uint32) m_DataCont->dataYIds.size();
} else if (m_DataCont->hasz) {
m_NbPlots = (uint32) m_DataCont->dataZIds.size();
}
m_PlotXIds.resize(m_NbPlots);
m_NbPlots = getNbPlots();
m_PlotXPropertyTypes.resize(m_NbPlots);
m_PlotXArrays.resize(m_NbPlots);
m_PlotYIds.resize(m_NbPlots);
m_PlotYPropertyTypes.resize(m_NbPlots);
m_PlotYArrays.resize(m_NbPlots);
for (uint32 i = 0; i < m_NbPlots; ++i) {
////
//// Get x and y arrays id
////
if (m_DataCont->hasx) {
m_PlotXIds[i] = m_DataCont->dataXIds[i];
m_PlotXPropertyTypes[i] = m_DataCont->dataXPropertyTypes[m_DataCont->dataXIds[i]];
}
if (m_DataCont->hasy) {
m_PlotYIds[i] = m_DataCont->dataYIds[i];
m_PlotYPropertyTypes[i] = m_DataCont->dataYPropertyTypes[