The code.ill.fr has been recreated and upgraded with the latest version this weekend, If you encounter any problem please inform the Helpdesk.

Commit 732e4f2f authored by legoc's avatar legoc
Browse files

Added gnuplot application.

parent 2811a30b
......@@ -44,6 +44,17 @@ AC_ARG_ENABLE(cameo,
esac],[cameo=false])
AM_CONDITIONAL([CAMEO], [test "$cameo" = true])
AC_ARG_ENABLE(gnuplot,
[ --enable-gnuplot compile Gnuplot applications],
[case "${enableval}" in
yes) gnuplot=true ;;
no) gnuplot=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-gnuplot) ;;
esac],[gnuplot=false])
AM_CONDITIONAL([GNUPLOT], [test "$gnuplot" = true])
AC_SUBST(LIBRARY_VERSION)
ROOT_LDFLAGS=`root-config --glibs`
......@@ -55,22 +66,26 @@ AC_SUBST(ROOT_CFLAGS)
AX_BOOST_BASE([1.41],, [AC_MSG_ERROR([Boost 1.41 required])])
AM_COND_IF([CAMEO], [AC_CAMEO])
AM_COND_IF([GNUPLOT], [AC_GNUPLOT])
LST_CXXFLAGS="$BOOST_CPPFLAGS \
$ZMQ_CFLAGS \
$PROTOBUF_CFLAGS \
$CAMEO_CFLAGS"
$CAMEO_CFLAGS \
$GNUPLOT_CFLAGS"
LST_LDFLAGS="$BOOST_LDFLAGS \
$ZMQ_LDFLAGS \
$PROTOBUF_LDFLAGS \
$CAMEO_LDFLAGS"
$CAMEO_LDFLAGS \
$GNUPLOT_LDFLAGS"
LST_LIBS="$BOOST_SYSTEM_LIB \
$BOOST_THREAD_LIB \
$ZMQ_LIB \
$PROTOBUF_LIB \
$CAMEO_LIBS"
$CAMEO_LIBS \
$GNUPLOT_LIBS"
AC_SUBST(LST_CXXFLAGS)
AC_SUBST(LST_LDFLAGS)
......@@ -90,5 +105,6 @@ AC_CONFIG_FILES([
src/lstdpp128/apps/nomad/Makefile
src/lstdpp128/apps/root/Makefile
src/lstdpp128/apps/cameo/Makefile
src/lstdpp128/apps/gnuplot/Makefile
])
AC_OUTPUT
###############################################################################
# Version 02/12/2016
# defines GNUPLOT_CFLAGS, GNUPLOT_LDFLAGS, GNUPLOT_LIBS
#
AC_DEFUN([AC_GNUPLOT],
[
GNUPLOT_CFLAGS=
GNUPLOT_LDFLAGS=
GNUPLOT_LIBS=-lboost_iostreams
AC_SUBST(GNUPLOT_CFLAGS)
AC_SUBST(GNUPLOT_LDFLAGS)
AC_SUBST(GNUPLOT_LIBS)
])
......@@ -10,4 +10,9 @@ if CAMEO
CAMEODIR = cameo
endif
SUBDIRS = common $(NOMADDIR) $(ROOTDIR) $(CAMEODIR)
\ No newline at end of file
if GNUPLOT
GNUPLOT = gnuplot
endif
SUBDIRS = common $(NOMADDIR) $(ROOTDIR) $(CAMEODIR) $(GNUPLOT)
\ No newline at end of file
bin_PROGRAMS = \
lstplot128
libs = ../../liblstdpp128.la
lstplot128_SOURCES = \
Plot.cpp
lstplot128_CPPFLAGS = $(LST_CXXFLAGS)
lstplot128_LDFLAGS = $(LST_LDFLAGS)
lstplot128_LDADD = $(libs) $(LST_LIBS)
/*
* 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://www.osor.eu/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 <stdint.h>
#include <fstream>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <boost/tuple/tuple.hpp>
#include <boost/lexical_cast.hpp>
#define GNUPLOT_ENABLE_PTY
#include "gnuplot-iostream.h"
#include "../../EventData.h"
#include "../../Reader.h"
using namespace std;
using namespace lstdpp128;
const int BUFFER_SIZE = 1 << 10;
std::vector<int32_t> split(const std::string& content) {
vector<int32_t> result;
int lastIndex = 0;
int index = content.find(',');
while (index != string::npos) {
istringstream is(content.substr(lastIndex, index - lastIndex));
int32_t value;
is >> value;
result.push_back(value);
lastIndex = index + 1;
index = content.find(',', lastIndex);
}
istringstream is(content.substr(lastIndex));
int32_t value;
is >> value;
result.push_back(value);
return result;
}
//energy, q-short, q-long, Pos. X, Pos. Y, A, A+B, 0-cross
enum DataInfo {
ENERGY = 0,
Q_SHORT = 1,
Q_LONG = 2,
Q_RATIO = 3,
POSITION_X = 4,
POSITION_Y = 5,
A = 6,
AplusB = 7,
ZERO_CROSSING = 8
};
std::string dataInfoString(DataInfo dataInfo) {
switch (dataInfo) {
case ENERGY:
return "Energy";
case Q_SHORT:
return "QShort";
case Q_LONG:
return "QLong";
case Q_RATIO:
return "QRatio";
case POSITION_X:
return "PositionX";
case POSITION_Y:
return "PositionY";
case A:
return "A";
case AplusB:
return "A+B";
case ZERO_CROSSING:
return "Zero Crossing";
}
return 0;
}
double eventData(Event const & event, DataInfo dataInfo) {
switch (dataInfo) {
case ENERGY:
return eventEnergy(event);
case Q_SHORT:
return eventQShort(event);
case Q_LONG:
return eventQLong(event);
case Q_RATIO:
return eventQRatio(event);
case POSITION_X:
return eventPositionX(event);
case POSITION_Y:
return eventPositionY(event);
case A:
return eventA(event);
case AplusB:
return eventAplusB(event);
case ZERO_CROSSING:
return eventZeroCrossing(event);
}
return 0;
}
DataInfo selectDataInfo(BoardType type) {
vector<DataInfo> dataInfos;
if (boardHasEnergy(type)) {
dataInfos.push_back(ENERGY);
}
if (boardHasQ(type)) {
dataInfos.push_back(Q_SHORT);
dataInfos.push_back(Q_LONG);
dataInfos.push_back(Q_RATIO);
}
if (boardHasPositionXY(type)) {
dataInfos.push_back(POSITION_X);
dataInfos.push_back(POSITION_Y);
}
if (boardHasAB(type)) {
dataInfos.push_back(A);
dataInfos.push_back(AplusB);
}
if (boardHasZeroCrossing(type)) {
dataInfos.push_back(ZERO_CROSSING);
}
if (dataInfos.size() == 1) {
return dataInfos.front();
}
// Select the data to plot.
cout << "Event data:" << endl;
for (int i = 1; i <= dataInfos.size(); ++i) {
cout << i << ": " << dataInfoString(dataInfos[i - 1]) << endl;
}
int id = 0;
while (true) {
cout << "Select the data to plot:";
cin >> id;
if (id >= 1 && id <= dataInfos.size()) {
break;
}
}
return dataInfos[id - 1];
}
void process(int32_t * buffer, int32_t size, int32_t crate, int32_t board, int32_t channel, int numberOfEvents, DataInfo dataInfo, int32_t& eventId, vector<boost::tuple<double, double> >& rollOverToPlot, vector<boost::tuple<double, double> >& timestampToPlot) {
// reading next block
int32_t index = 0;
int32_t nbIndex = size;
int32_t * bufferPtr = buffer;
while (index < nbIndex) {
// reading event
Event event;
if (readEvent(event, bufferPtr + index)) {
bool display = ((crate == -1 || (crate == event.crate))
&& (board == -1 || (board == event.board))
&& (channel == -1 || (channel == event.channel)));
if (display && ((numberOfEvents == -1) || (numberOfEvents > 0 && eventId < numberOfEvents))) {
rollOverToPlot.push_back(boost::make_tuple(eventId, event.rollover));
timestampToPlot.push_back(boost::make_tuple(eventId, event.timestamp));
eventId++;
}
} else {
cout << "problem with event " << hex << " " << setw(8) << setfill('0') << (uint32_t)(*(bufferPtr + index))
<< " " << setw(8) << setfill('0') << (uint32_t)(*(bufferPtr + index + 1))
<< " " << setw(8) << setfill('0') << (uint32_t)(*(bufferPtr + index + 2))
<< " " << setw(8) << setfill('0') << (uint32_t)(*(bufferPtr + index + 3))
<< setw(0) << setfill(' ') << dec << endl;
}
index += 4;
}
}
void plotRollOver(vector<boost::tuple<double, double> > const & rollOverToPlot) {
Gnuplot gpPlot;
gpPlot << "set title 'ROLL OVER'\n";
gpPlot << "unset key\n";
gpPlot << "plot '-' w histep\n";
gpPlot.send(rollOverToPlot);
}
void plotTimestamp(vector<boost::tuple<double, double> > const & timestampToPlot) {
Gnuplot gpPlot;
gpPlot << "set title 'TIME'\n";
gpPlot << "unset key\n";
gpPlot << "plot '-' w histep\n";
gpPlot.send(timestampToPlot);
}
int main(int argc, char * argv[]) {
if (argc < 2) {
cerr << "usage : lstplot128 <file> <filter> [number of events]" << endl;
cerr << " filter is [crate,board,channel]" << endl;
return EXIT_FAILURE;
}
string fileName = argv[1];
int32_t crate = -1;
int32_t board = -1;
int32_t channel = -1;
int numberOfEvents = -1;
if (argc >= 3) {
string valuesString(argv[2]);
valuesString = valuesString.substr(1, valuesString.length() - 2);
vector<int32_t> values = split(valuesString);
cout << "filter:" << endl;
if (values.size() > 0) {
crate = values[0];
cout << "crate " << crate << endl;
}
if (values.size() > 1) {
board = values[1];
cout << "board " << board << endl;
}
if (values.size() > 2) {
channel = values[2];
cout << "channel " << channel << endl;
}
cout << endl;
}
else {
cerr << "please specify a filter [crate,board,channel]" << endl;
exit(0);
}
if (argc >= 4) {
istringstream is(argv[3]);
is >> numberOfEvents;
cout << "reading " << numberOfEvents << " events" << endl;
}
Reader reader(BUFFER_SIZE);
bool success = reader.open(fileName);
if (!success) {
return EXIT_FAILURE;
}
cout << listModeContext << endl;
// Search for the type of the board.
BoardIterator b;
BoardType boardType;
bool found = false;
while (!b.end()) {
if (b.crate() == crate && b.board() == board) {
boardType = (*b).boardType;
found = true;
break;
}
++b;
}
if (!found) {
cerr << "please select a valid board" << endl;
exit(0);
}
// Select the data to plot.
DataInfo dataInfo = selectDataInfo(boardType);
// events
int32_t eventId = 0;
vector<boost::tuple<double, double> > rollOverToPlot;
vector<boost::tuple<double, double> > timestampToPlot;
vector<boost::tuple<double, double> > dataToPlot;
// reading
while (true) {
// reading next block
int32_t size = reader.read();
if (size == 0) {
break;
}
// processing
process(reader.buffer(), size, crate, board, channel, numberOfEvents, dataInfo, eventId, rollOverToPlot, timestampToPlot);
// Exit the loop.
if (numberOfEvents > 0 && eventId > numberOfEvents) {
break;
}
}
cout << "number of events " << dataToPlot.size() << endl;
plotRollOver(rollOverToPlot);
plotTimestamp(timestampToPlot);
// plot the data.
// Gnuplot gpPlot;
//
// gpPlot << "set title '" << dataInfoString(dataInfo) << "'\n";
// gpPlot << "unset key\n";
// gpPlot << "plot '-' w histep\n";
// gpPlot.send(dataToPlot);
return EXIT_SUCCESS;
}
// vim:foldmethod=marker
/*
Copyright (c) 2013 Daniel Stahlke (dan@stahlke.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* A C++ interface to gnuplot.
* Web page: http://www.stahlke.org/dan/gnuplot-iostream
* Documentation: https://gitorious.org/gnuplot-iostream/pages/Home
*
* The whole library consists of this monolithic header file, for ease of installation (the
* Makefile and *.cc files are only for examples and tests).
*
* TODO:
* What version of boost is currently required?
* Callbacks via gnuplot's 'bind' function. This would allow triggering user functions when
* keys are pressed in the gnuplot window. However, it would require a PTY reader thread.
* Maybe temporary files read in a thread can replace PTY stuff.
*/
#ifndef GNUPLOT_IOSTREAM_H
#define GNUPLOT_IOSTREAM_H
// {{{1 Includes and defines
#define GNUPLOT_IOSTREAM_VERSION 2
#ifndef GNUPLOT_ENABLE_CXX11
# define GNUPLOT_ENABLE_CXX11 (__cplusplus >= 201103)
#endif
// C system includes
#include <cstdio>
#ifdef GNUPLOT_ENABLE_PTY
# include <termios.h>
# include <unistd.h>
# include <pty.h>
// include <util.h>
#endif // GNUPLOT_ENABLE_PTY
// C++ system includes
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <utility>
#include <iomanip>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cmath>
#if GNUPLOT_ENABLE_CXX11
# include <tuple>
#endif
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/version.hpp>
#include <boost/utility.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/bool.hpp>
// This is the version of boost which has v3 of the filesystem libraries by default.
#if BOOST_VERSION >= 104600
# define GNUPLOT_USE_TMPFILE
# include <boost/filesystem.hpp>
#endif // BOOST_VERSION
// This is used because VS2008 doesn't have stdint.h.
#include <boost/cstdint.hpp>
// Note: this is here for reverse compatibility. The new way to enable blitz support is to
// just include the gnuplot-iostream.h header after you include the blitz header (likewise for
// armadillo).
//#ifdef GNUPLOT_ENABLE_BLITZ
//# include <blitz/array.h>
//#endif
#ifdef BOOST_STATIC_ASSERT_MSG
# define GNUPLOT_STATIC_ASSERT_MSG(cond, msg) BOOST_STATIC_ASSERT_MSG((cond), msg)
#else
# define GNUPLOT_STATIC_ASSERT_MSG(cond, msg) BOOST_STATIC_ASSERT((cond))
#endif
// If this is defined, warn about use of deprecated functions.
#ifdef GNUPLOT_DEPRECATE_WARN
# ifdef __GNUC__
# define GNUPLOT_DEPRECATE(msg) __attribute__ ((deprecated(msg)))
# elif defined(_MSC_VER)
# define GNUPLOT_DEPRECATE(msg) __declspec(deprecated(msg))
# else
# define GNUPLOT_DEPRECATE(msg)
# endif
#else
# define GNUPLOT_DEPRECATE(msg)
#endif
// Patch for Windows by Damien Loison
#ifdef _WIN32
# include <windows.h>
# define GNUPLOT_PCLOSE _pclose
# define GNUPLOT_POPEN _popen
# define GNUPLOT_FILENO _fileno
#else
# define GNUPLOT_PCLOSE pclose
# define GNUPLOT_POPEN popen
# define GNUPLOT_FILENO fileno
#endif
#ifdef _WIN32
# define GNUPLOT_ISNAN _isnan
#else
// cppreference.com says std::isnan is only for C++11. However, this seems to work on Linux
// and I am assuming that if isnan exists in math.h then std::isnan exists in cmath.
# define GNUPLOT_ISNAN std::isnan
#endif
// MSVC gives a warning saying that fopen and getenv are not secure. But they are secure.
// Unfortunately their replacement functions are not simple drop-in replacements. The best
// solution is to just temporarily disable this warning whenever fopen or getenv is used.
// http://stackoverflow.com/a/4805353/1048959
#if defined(_MSC_VER) && _MSC_VER >= 1400
# define GNUPLOT_MSVC_WARNING_4996_PUSH \
__pragma(warning(push)) \
__pragma(warning(disable:4996))
# define GNUPLOT_MSVC_WARNING_4996_POP \
__pragma(warning(pop))
#else
# define GNUPLOT_MSVC_WARNING_4996_PUSH
# define GNUPLOT_MSVC_WARNING_4996_POP
#endif
#ifndef GNUPLOT_DEFAULT_COMMAND
#ifdef _WIN32
// "pgnuplot" is considered deprecated according to the Internet. It may be faster. It
// doesn't seem to handle binary data though.