Skip to content

Commit

Permalink
finished with documentation first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
daemacles committed Mar 20, 2015
1 parent b873e78 commit eee476f
Show file tree
Hide file tree
Showing 15 changed files with 627 additions and 238 deletions.
38 changes: 13 additions & 25 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,33 @@ cmake_minimum_required (VERSION 2.6)

set (PROJECT_NAME cpp-matplotlib)

SET (CMAKE_C_COMPILER "/usr/bin/clang-3.5")
SET (CMAKE_CXX_COMPILER "/usr/bin/clang++-3.5")
# If you want to use clang, uncomment these.
#SET (CMAKE_C_COMPILER "/usr/bin/clang-3.5")
#SET (CMAKE_CXX_COMPILER "/usr/bin/clang++-3.5")

project (${PROJECT_NAME})
set (EXAMPLE_BIN ${PROJECT_NAME}-example)

include_directories ("${PROJECT_SOURCE_DIR}/src")

add_executable (${PROJECT_NAME} src/main.cc)
add_executable (${EXAMPLE_BIN} src/main.cc)

## Support for Clang's CompilationDatabase system
set (CMAKE_EXPORT_COMPILE_COMMANDS 1)

## Set optional features. This will show up as a preprocessor variable
## USE_MY_LIBRARY in source.
#option (USE_MY_LIBRARY
# "Use the provided library" ON)

## Compile and create a library. STATIC is default unless BUILD_SHARED_LIBS
## is on.
add_library (cpp_plot src/cpp_plot.cc src/ReqRepConnection.cc)
add_library (ipython_protocol src/ipython_protocol.cc)
set (EXTRA_LIBS ${EXTRA_LIBS} cpp_plot ipython_protocol)

#if (USE_MY_LIBRARY)

## Search for include files here as well
#include_directories ("${PROJECT_SOURCE_DIR}/some_sub_path")

## Run Cmake also in this dir
#add_subdirectory (some_sub_path)

#set (EXTRA_LIBS ${EXTRA_LIBS} LibraryName)
add_library (cpp_plot
src/cpp_plot.cc
src/RequestSink.cc
src/ipython_protocol.cc)

#endif (USE_MYMATH)
set (EXTRA_LIBS ${EXTRA_LIBS} cpp_plot)

## Libraries to link with
target_link_libraries (${PROJECT_NAME}
zmq jsoncpp uuid ssl crypto
${EXTRA_LIBS})
target_link_libraries (${EXAMPLE_BIN}
${EXTRA_LIBS}
zmq jsoncpp uuid ssl crypto)

SET (CMAKE_C_FLAGS "-Wall -std=c11 -Wextra -Werror")
SET (CMAKE_C_FLAGS_DEBUG "${CMAKE_CFLAGS} -g")
Expand Down
82 changes: 72 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,65 @@
# Contents

[About](#about)
[Usage] (#usage)
[Prereqs](#prereqs)
[Building](#building)
[Example](#example)


# About

An easy-to-use library for simple plotting from C++ via a ZeroMQ bridge to
Python's Matplotlib.
an [IPython](http://ipython.org/) kernel.

# Prereqs
It provides the ability to send [NumPy](http://www.numpy.org/) array
compatible data to an IPython kernel session as well as execute arbitrary
code.

Execution of arbitrary code is "protected" by IPython's kernel HMAC signing
mechanism: only code signed by a secret key provided by IPython will run. As
of 2015-03-19 it has been tested with IPython version 1.2.1 on Ubuntu 14.04.


# Usage

Here we create some 1D data and plot it. The variable "A" will be available
for working with in the IPython session, even after the C++ program finishes.

CppMatplotlib mpl{"/path/to/kernel-NNN.json"};
mpl.Connect();

// Create a nice curve
std::vector<NumpyArray::dtype> raw_data;
double x = 0.0;
while (x < 3.14159 * 4) {
raw_data.push_back(std::sin(x));
x += 0.05;
}

// Send it to IPython for plotting
NumpyArray data("A", raw_data);
mpl.SendData(data);
mpl.RunCode("plot(A)\n"
"title('f(x) = sin(x)')\n"
"xlabel('x')\n"
"ylabel('f(x)')\n");

## Ubuntu
And the result will be ![Screenshot](screenshot.png?raw=true "Screenshot of
sin(x)")

sudo apt-get install libzmq3-dev python-zmq python-matplotlib
See [src/main.cc](src/main.cc) for a complete program.

Some sort of pyqt

sudo apt-get install python-pyside.qtcore python-pyside.qtgui
# Prereqs

## Ubuntu 14.04

sudo apt-get install ipython python-matplotlib libzmq3-dev \
libjsoncpp-dev uuid-dev libssl-dev

# Build

# Building

git clone https://bitbucket.org/james_youngquist/cpp-matplotlib.git
cd cpp-matplotlib
Expand All @@ -22,13 +68,29 @@ Some sort of pyqt
cmake ..
make

# Run (alpha demo)
## Generating the documentation

cd cpp-matplotlib
doxygen Doxyfile
# open html/index.html

# Example

In terminal 1:

python cpp-matplotlib/pyplot_listener.py
ipython kernel --pylab
# this will print out the kernel PID to connect to, NNN below.

In terminal 2:

cpp-matplotlib/build/cpp-matplotlib
# Once per kernel invocation:
export KERNEL_CONFIG=`find ~/ -name kernel-NNN.json`

# Each time you run the program
build/cpp-matplotlib-example $KERNEL_CONFIG


In terminal 3 (if desired):

ipython console --existing kernel-NNN.json

Binary file added screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 0 additions & 25 deletions src/ReqRepConnection.cc

This file was deleted.

26 changes: 0 additions & 26 deletions src/ReqRepConnection.hpp

This file was deleted.

44 changes: 44 additions & 0 deletions src/RequestSink.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// Copyright (c) 2015 Jim Youngquist
// under The MIT License (MIT)
// full text in LICENSE file in root folder of this project.
//

#include <exception>

#include "RequestSink.hpp"

RequestSink::RequestSink(const std::string &url) :
context_{1},
socket_{context_, ZMQ_REQ},
url_{url},
connected_{false}
{}

bool RequestSink::Send(const std::string &buffer) {
std::vector<uint8_t> byte_buffer(buffer.begin(), buffer.end());
return Send(byte_buffer);
}

bool RequestSink::Send(const std::vector<uint8_t> &buffer) {
zmq::message_t request((void*)&buffer[0], buffer.size(), nullptr);
socket_.send(request);

// Get the reply
zmq::message_t reply;
socket_.recv(&reply);
std::string value{reinterpret_cast<char*>(reply.data()), reply.size()};
if (value != "Success") {
std::runtime_error(value.c_str());
}

return true;
}

bool RequestSink::Connect(void) {
socket_.connect(url_.c_str());
connected_ = true;

return true;
}

65 changes: 65 additions & 0 deletions src/RequestSink.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// Copyright (c) 2015 Jim Youngquist
// under The MIT License (MIT)
// full text in LICENSE file in root folder of this project.
//

#pragma once

#include <string>
#include <vector>

#include <zmq.hpp>

//======================================================================
/** \brief This class wraps a ZeroMQ request-response socket connection.
*
* It acts as a one-way sink for data. Responses are not actually returned,
* only checked that the "request" was successfully transmitted.
*
* Usage:
\code
RequestSink conn{"tcp://hostname:port"};
conn.Connect();
conn.Send("oh my goodness!");
\endcode
*/
class RequestSink {
public:
//--------------------------------------------------
/** \brief Initializes for a connection to a valid ZeroMQ endpoint, but does
* not actually connect to it.
*
* \param url the ZeroMQ url to connect to.
*/
RequestSink(const std::string &url);

//--------------------------------------------------
/** \brief Transmits a string.
*
* \param buffer the string to send.
*
* \returns whether transmission was successful.
*/
bool Send(const std::string &buffer);

//--------------------------------------------------
/** \brief Transmits a byte vector
*
* \param buffer the bytes to send.
*
* \returns whether transmission was successful.
*/
bool Send(const std::vector<uint8_t> &buffer);

//--------------------------------------------------
/** \brief Actually connects to a Request socket.
*/
bool Connect(void);

private:
zmq::context_t context_;
zmq::socket_t socket_;
const std::string url_;
bool connected_;
};
Loading

0 comments on commit eee476f

Please sign in to comment.