<commit_before>#include <mapnik/vertex.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_adapters.hpp>
#include <mapnik/vertex_processor.hpp>
#include "vector_tile_geometry_decoder.hpp"
#include "vector_tile_geometry_encoder.hpp"
#include <mapnik/geometry_empty.hpp>

namespace {

using namespace mapnik::geometry;

struct print
{
    void operator() (geometry_empty const&) const
    {
        std::cerr << "EMPTY" << std::endl;
    }
    void operator() (geometry_collection const& collection) const
    {
    }
    template <typename T>
    void operator() (T const& geom) const
    {
        std::cerr << boost::geometry::wkt(geom) << std::endl;
    }
};

}

struct encode_geometry
{
    vector_tile::Tile_Feature & feature_;
    unsigned tolerance_;
    unsigned path_multiplier_;
    int32_t x_;
    int32_t y_;
    encode_geometry(vector_tile::Tile_Feature & feature,
             unsigned tolerance,
             unsigned path_multiplier) :
      feature_(feature),
      tolerance_(tolerance),
      path_multiplier_(path_multiplier),
      x_(0),
      y_(0) { }

    template <typename T>
    void operator()(T & path)
    {
        mapnik::vector_tile_impl::encode_geometry(path,feature_,x_,y_,tolerance_,path_multiplier_);
    }
};

struct show_path
{
    std::string & str_;
    show_path(std::string & out) :
      str_(out) {}

    template <typename T>
    void operator()(T & path)
    {
        unsigned cmd = -1;
        double x = 0;
        double y = 0;
        std::ostringstream s;
        path.rewind(0);
        while ((cmd = path.vertex(&x, &y)) != mapnik::SEG_END)
        {
            switch (cmd)
            {
                case mapnik::SEG_MOVETO: s << "move_to("; break;
                case mapnik::SEG_LINETO: s << "line_to("; break;
                case mapnik::SEG_CLOSE: s << "close_path("; break;
                default: std::clog << "unhandled cmd " << cmd << "\n"; break;
            }
            s << x << "," << y << ")\n";
        }
        str_ += s.str();
    }
};

std::string compare(mapnik::geometry::geometry const& g,
                    unsigned tolerance=0,
                    unsigned path_multiplier=1)
{
    // encode
    vector_tile::Tile_Feature feature;
    encode_geometry ap(feature,tolerance,path_multiplier);
    if (g.is<mapnik::geometry::point>() || g.is<mapnik::geometry::multi_point>())
    {
        feature.set_type(vector_tile::Tile_GeomType_POINT);
    }
    else if (g.is<mapnik::geometry::line_string>() || g.is<mapnik::geometry::multi_line_string>())
    {
        feature.set_type(vector_tile::Tile_GeomType_LINESTRING);
    }
    else if (g.is<mapnik::geometry::polygon>() || g.is<mapnik::geometry::multi_polygon>())
    {
        feature.set_type(vector_tile::Tile_GeomType_POLYGON);
    }
    mapnik::util::apply_visitor(mapnik::geometry::vertex_processor<encode_geometry>(ap),g);

    // decode
    auto g2 = mapnik::vector_tile_impl::decode_geometry(feature,0.0,0.0,1.0,1.0);
    //mapnik::util::apply_visitor(print(), g2);
    using decode_path_type = mapnik::geometry::vertex_processor<show_path>;
    std::string out;
    show_path sp(out);
    mapnik::util::apply_visitor(decode_path_type(sp), g2);
    return out;

}
<commit_msg>refactor encoding util to get access to parts<commit_after>#include <mapnik/vertex.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/geometry_adapters.hpp>
#include <mapnik/vertex_processor.hpp>
#include "vector_tile_geometry_decoder.hpp"
#include "vector_tile_geometry_encoder.hpp"
#include <mapnik/geometry_empty.hpp>

namespace {

using namespace mapnik::geometry;

struct print
{
    void operator() (geometry_empty const&) const
    {
        std::cerr << "EMPTY" << std::endl;
    }
    void operator() (geometry_collection const& collection) const
    {
    }
    template <typename T>
    void operator() (T const& geom) const
    {
        std::cerr << boost::geometry::wkt(geom) << std::endl;
    }
};

}

struct encode_geometry
{
    vector_tile::Tile_Feature & feature_;
    unsigned tolerance_;
    unsigned path_multiplier_;
    int32_t x_;
    int32_t y_;
    encode_geometry(vector_tile::Tile_Feature & feature,
             unsigned tolerance,
             unsigned path_multiplier) :
      feature_(feature),
      tolerance_(tolerance),
      path_multiplier_(path_multiplier),
      x_(0),
      y_(0) { }

    template <typename T>
    void operator()(T & path)
    {
        mapnik::vector_tile_impl::encode_geometry(path,feature_,x_,y_,tolerance_,path_multiplier_);
    }
};

struct show_path
{
    std::string & str_;
    show_path(std::string & out) :
      str_(out) {}

    template <typename T>
    void operator()(T & path)
    {
        unsigned cmd = -1;
        double x = 0;
        double y = 0;
        std::ostringstream s;
        path.rewind(0);
        while ((cmd = path.vertex(&x, &y)) != mapnik::SEG_END)
        {
            switch (cmd)
            {
                case mapnik::SEG_MOVETO: s << "move_to("; break;
                case mapnik::SEG_LINETO: s << "line_to("; break;
                case mapnik::SEG_CLOSE: s << "close_path("; break;
                default: std::clog << "unhandled cmd " << cmd << "\n"; break;
            }
            s << x << "," << y << ")\n";
        }
        str_ += s.str();
    }
};

vector_tile::Tile_Feature geometry_to_feature(mapnik::geometry::geometry const& g,
                                              unsigned tolerance=0,
                                              unsigned path_multiplier=1)
{
    vector_tile::Tile_Feature feature;
    encode_geometry ap(feature,tolerance,path_multiplier);
    if (g.is<mapnik::geometry::point>() || g.is<mapnik::geometry::multi_point>())
    {
        feature.set_type(vector_tile::Tile_GeomType_POINT);
    }
    else if (g.is<mapnik::geometry::line_string>() || g.is<mapnik::geometry::multi_line_string>())
    {
        feature.set_type(vector_tile::Tile_GeomType_LINESTRING);
    }
    else if (g.is<mapnik::geometry::polygon>() || g.is<mapnik::geometry::multi_polygon>())
    {
        feature.set_type(vector_tile::Tile_GeomType_POLYGON);
    }
    else
    {
        throw std::runtime_error("could not detect valid geometry type");
    }
    mapnik::util::apply_visitor(mapnik::geometry::vertex_processor<encode_geometry>(ap),g);
    return feature;
}

std::string decode_to_path_string(mapnik::geometry::geometry const& g)
{
    //mapnik::util::apply_visitor(print(), g2);
    using decode_path_type = mapnik::geometry::vertex_processor<show_path>;
    std::string out;
    show_path sp(out);
    mapnik::util::apply_visitor(decode_path_type(sp), g);
    return out;
}

std::string compare(mapnik::geometry::geometry const& g,
                    unsigned tolerance=0,
                    unsigned path_multiplier=1)
{
    vector_tile::Tile_Feature feature = geometry_to_feature(g,tolerance,path_multiplier);
    auto g2 = mapnik::vector_tile_impl::decode_geometry(feature,0.0,0.0,1.0,1.0);
    return decode_to_path_string(g2);
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

template<typename Scalar>
void test_first_aligned_helper(Scalar *array, int size)
{
  const int packet_size = sizeof(Scalar) * ei_packet_traits<Scalar>::size;
  VERIFY(((size_t(array) + sizeof(Scalar) * ei_first_aligned(array, size)) % packet_size) == 0);
}

template<typename Scalar>
void test_none_aligned_helper(Scalar *array, int size)
{
  VERIFY(ei_packet_traits<Scalar>::size == 1 || ei_first_aligned(array, size) == size);
}

struct some_non_vectorizable_type { float x; };

void test_first_aligned()
{
  EIGEN_ALIGN16 float array_float[100];
  test_first_aligned_helper(array_float, 50);
  test_first_aligned_helper(array_float+1, 50);
  test_first_aligned_helper(array_float+2, 50);
  test_first_aligned_helper(array_float+3, 50);
  test_first_aligned_helper(array_float+4, 50);
  test_first_aligned_helper(array_float+5, 50);

  EIGEN_ALIGN16 double array_double[100];
  test_first_aligned_helper(array_double, 50);
  test_first_aligned_helper(array_double+1, 50);
  test_first_aligned_helper(array_double+2, 50);

  double *array_double_plus_4_bytes = (double*)(size_t(array_double)+4);
  test_none_aligned_helper(array_double_plus_4_bytes, 50);
  test_none_aligned_helper(array_double_plus_4_bytes+1, 50);

  some_non_vectorizable_type array_nonvec[100];
  test_first_aligned_helper(array_nonvec, 100);
  test_none_aligned_helper(array_nonvec, 100);
}
<commit_msg>Fixed more warnings.<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

template<typename Scalar>
void test_first_aligned_helper(Scalar *array, int size)
{
  const int packet_size = sizeof(Scalar) * ei_packet_traits<Scalar>::size;
  VERIFY(((size_t(array) + sizeof(Scalar) * ei_first_aligned(array, size)) % packet_size) == 0);
}

template<typename Scalar>
void test_none_aligned_helper(Scalar *array, int size)
{
  // Suppress 'unreferenced formal parameter's warnings.
  (void)array;
  (void)size;
  VERIFY(ei_packet_traits<Scalar>::size == 1 || ei_first_aligned(array, size) == size);
}

struct some_non_vectorizable_type { float x; };

void test_first_aligned()
{
  EIGEN_ALIGN16 float array_float[100];
  test_first_aligned_helper(array_float, 50);
  test_first_aligned_helper(array_float+1, 50);
  test_first_aligned_helper(array_float+2, 50);
  test_first_aligned_helper(array_float+3, 50);
  test_first_aligned_helper(array_float+4, 50);
  test_first_aligned_helper(array_float+5, 50);

  EIGEN_ALIGN16 double array_double[100];
  test_first_aligned_helper(array_double, 50);
  test_first_aligned_helper(array_double+1, 50);
  test_first_aligned_helper(array_double+2, 50);

  double *array_double_plus_4_bytes = (double*)(size_t(array_double)+4);
  test_none_aligned_helper(array_double_plus_4_bytes, 50);
  test_none_aligned_helper(array_double_plus_4_bytes+1, 50);

  some_non_vectorizable_type array_nonvec[100];
  test_first_aligned_helper(array_nonvec, 100);
  test_none_aligned_helper(array_nonvec, 100);
}
<|endoftext|>


<commit_before>//
// async_client.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/asio/ssl.hpp>
#include <fstream>

using boost::asio::ip::tcp;

class client
{
public:
    client(boost::asio::io_service& io_service,
           const std::string& server, const std::string& path, const std::string& b64ImgStr)
            : resolver_(io_service),
              ctx(io_service, boost::asio::ssl::context::method::sslv23_client),
              socket_(io_service, ctx)
    {
        ctx.set_default_verify_paths();
        /*ctx.set_options(boost::asio::ssl::context::default_workarounds
                        | boost::asio::ssl::context::no_sslv2
                        | boost::asio::ssl::context::no_sslv3);*/
        //socket_.set_verify_mode(boost::asio::ssl::verify_none);
        //ctx.load_verify_file("ca.pem");
        // Form the request. We specify the "Connection: close" header so that the
        // server will close the socket after transmitting the response. This will
        // allow us to treat all data up until the EOF as the content.
        std::ostream request_stream(&request_);
        request_stream << "PATH " << path << " HTTP/1.1\r\n";
        request_stream << "Host: " << server << "\r\n";
        request_stream << "content-type: application/json;charset=UTF-8\r\n";
        request_stream << "content-length: " << std::to_string(b64ImgStr.length()) << "\r\n";
        request_stream << "Connection: close\r\n\r\n";

        request_stream << "{\"httpMethod\":\"POST\",\"pathWithQueryString\":\"/mxnet-test-dev-hello\",\"body\":\"{\\\"b64Img\\\": \\\""
                       << b64ImgStr << "\\\"}\",\"headers\":{},\"stageVariables\":{},\"withAuthorization\":false}\r\n";
        //request_stream << "Accept: */*\r\n";

        // Start an asynchronous resolve to translate the server and service names
        // into a list of endpoints.
        tcp::resolver::query query(server, "https");
        resolver_.async_resolve(query,
                                boost::bind(&client::handle_resolve, this,
                                            boost::asio::placeholders::error,
                                            boost::asio::placeholders::iterator));
    }

private:
    void handle_resolve(const boost::system::error_code& err,
                        tcp::resolver::iterator endpoint_iterator)
    {
        if (!err)
        {
            socket_.set_verify_mode(boost::asio::ssl::verify_peer);
            socket_.set_verify_callback(
                    boost::bind(&client::verify_certificate, this, _1, _2));
            // Attempt a connection to the first endpoint in the list. Each endpoint
            // will be tried until we successfully establish a connection.
            tcp::endpoint endpoint = *endpoint_iterator;
            socket_.lowest_layer().async_connect(endpoint,
                                  boost::bind(&client::handle_connect, this,
                                              boost::asio::placeholders::error, ++endpoint_iterator));
        }
        else
        {
            std::cout << "Error: " << err.message() << "\n";
        }
        //-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOPENSSL_INCLUDE_DIR==/usr/local/opt/openssl/lib
    }

    bool verify_certificate(bool preverified,
                            boost::asio::ssl::verify_context& ctx)
    {
        // The verify callback can be used to check whether the certificate that is
        // being presented is valid for the peer. For example, RFC 2818 describes
        // the steps involved in doing this for HTTPS. Consult the OpenSSL
        // documentation for more details. Note that the callback is called once
        // for each certificate in the certificate chain, starting from the root
        // certificate authority.

        // In this example we will simply print the certificate's subject name.
        char subject_name[256];
        X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
        X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
        std::cout << "Verifying " << subject_name << "\n";

        return preverified;
    }

    void handle_connect(const boost::system::error_code& err,
                        tcp::resolver::iterator endpoint_iterator)
    {
        if (!err)
        {
            socket_.async_handshake(boost::asio::ssl::stream_base::handshake_type::client);
            // The connection was successful. Send the request.
            boost::asio::async_write(socket_, request_,
                                     boost::bind(&client::handle_write_request, this,
                                                 boost::asio::placeholders::error));
        }
        else if (endpoint_iterator != tcp::resolver::iterator())
        {
            // The connection failed. Try the next endpoint in the list.
            socket_.lowest_layer().close();
            tcp::endpoint endpoint = *endpoint_iterator;
            socket_.lowest_layer().async_connect(endpoint,
                                  boost::bind(&client::handle_connect, this,
                                              boost::asio::placeholders::error, ++endpoint_iterator));
        }
        else
        {
            std::cout << "Error: " << err.message() << "\n";
        }
    }

    void handle_write_request(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Read the response status line. The response_ streambuf will
            // automatically grow to accommodate the entire line. The growth may be
            // limited by passing a maximum size to the streambuf constructor.
            boost::asio::async_read_until(socket_, response_, "\r\n",
                                          boost::bind(&client::handle_read_status_line, this,
                                                      boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error: " << err.message() << "\n";
        }
    }

    void handle_read_status_line(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Check that response is OK.
            std::istream response_stream(&response_);
            std::string http_version;
            response_stream >> http_version;
            unsigned int status_code;
            response_stream >> status_code;
            std::string status_message;
            std::getline(response_stream, status_message);
            if (!response_stream || http_version.substr(0, 5) != "HTTP/")
            {
                std::cout << "Invalid response\n";
                return;
            }
            if (status_code != 200)
            {
                std::cout << "Response returned with status code ";
                std::cout << status_code << "\n";
                return;
            }

            // Read the response headers, which are terminated by a blank line.
            boost::asio::async_read_until(socket_, response_, "\r\n\r\n",
                                          boost::bind(&client::handle_read_headers, this,
                                                      boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error: " << err << "\n";
        }
    }

    void handle_read_headers(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Process the response headers.
            std::istream response_stream(&response_);
            std::string header;
            while (std::getline(response_stream, header) && header != "\r")
                std::cout << header << "\n";
            std::cout << "\n";

            // Write whatever content we already have to output.
            if (response_.size() > 0)
                std::cout << &response_;

            // Start reading remaining data until EOF.
            boost::asio::async_read(socket_, response_,
                                    boost::asio::transfer_at_least(1),
                                    boost::bind(&client::handle_read_content, this,
                                                boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error: " << err << "\n";
        }
    }

    void handle_read_content(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Write all of the data that has been read so far.
            std::cout << &response_;

            // Continue reading remaining data until EOF.
            boost::asio::async_read(socket_, response_,
                                    boost::asio::transfer_at_least(1),
                                    boost::bind(&client::handle_read_content, this,
                                                boost::asio::placeholders::error));
        }
        else if (err != boost::asio::error::eof)
        {
            std::cout << "Error: " << err << "\n";
        }
    }

    tcp::resolver resolver_;
    // https://stackoverflow.com/questions/40036854/creating-a-https-request-using-boost-asio-and-openssl
    // http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/overview/ssl.html
    boost::asio::ssl::context ctx;
    boost::asio::ssl::stream<tcp::socket> socket_;
    boost::asio::streambuf request_;
    boost::asio::streambuf response_;
};

int main(int argc, char* argv[])
{
    try
    {
        if (argc != 4)
        {
            std::cout << "Usage: async_client <server> <path> <fileContainingPostBody>\n";
            std::cout << "Example:\n";
            std::cout << "  async_client www.boost.org /LICENSE_1_0.txt\n";
            return 1;
        }

        boost::asio::io_service io_service;
        std::ifstream b64File(argv[3]);
        std::stringstream b64ImgStream;
        b64ImgStream << b64File.rdbuf();
        std::string b64ImgStr = b64ImgStream.str();
        //client c(io_service, "www.deelay.me", "/1000/hmpg.net");
        client c(io_service, argv[1], argv[2], b64ImgStr);
        io_service.run();
        std::cout << "should print first\n";
    }
    catch (std::exception& e)
    {
        std::cout << "Exception: " << e.what() << "\n";
    }

    return 0;
}
<commit_msg>ssl handshake works, now need to do base64<commit_after>//
// async_client.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/asio/ssl.hpp>
#include <fstream>

using boost::asio::ip::tcp;

class client
{
public:
    client(boost::asio::io_service& io_service,
           const std::string& server, const std::string& path, const std::string& b64ImgStr)
            : resolver_(io_service),
              ctx(io_service, boost::asio::ssl::context::method::tlsv12_client),
              socket_(io_service, ctx)
    {
        SSL_set_tlsext_host_name(socket_.native_handle(),server.c_str());
        ctx.set_default_verify_paths();
        /*ctx.set_options(boost::asio::ssl::context::default_workarounds
                        | boost::asio::ssl::context::no_sslv2
                        | boost::asio::ssl::context::no_sslv3
                        | boost::asio::ssl::context::no_tlsv1
                        | boost::asio::ssl::context::no_tlsv1_1);*/
        //socket_.set_verify_mode(boost::asio::ssl::verify_none);
        //ctx.load_verify_file("ca.pem");
        // Form the request. We specify the "Connection: close" header so that the
        // server will close the socket after transmitting the response. This will
        // allow us to treat all data up until the EOF as the content.
        std::ostream request_stream(&request_);
        request_stream << "PATH " << path << " HTTP/1.1\r\n";
        request_stream << "Host: " << server << "\r\n";
        request_stream << "content-type: application/json;charset=UTF-8\r\n";
        request_stream << "content-length: " << std::to_string(b64ImgStr.length()) << "\r\n";
        request_stream << "Connection: close\r\n\r\n";

        request_stream << "{\"httpMethod\":\"POST\",\"pathWithQueryString\":\"/mxnet-test-dev-hello\",\"body\":\"{\\\"b64Img\\\": \\\""
                       << b64ImgStr << "\\\"}\",\"headers\":{},\"stageVariables\":{},\"withAuthorization\":false}\r\n";
        //request_stream << "Accept: */*\r\n";

        // Start an asynchronous resolve to translate the server and service names
        // into a list of endpoints.
        tcp::resolver::query query(server, "https");
        resolver_.async_resolve(query,
                                boost::bind(&client::handle_resolve, this,
                                            boost::asio::placeholders::error,
                                            boost::asio::placeholders::iterator));
    }

private:

    void handle_resolve(const boost::system::error_code& err,
                        tcp::resolver::iterator endpoint_iterator)
    {
        if (!err)
        {
            std::cout << "Resolve OK" << "\n";
            socket_.set_verify_mode(boost::asio::ssl::verify_peer);
            socket_.set_verify_callback(
                    boost::bind(&client::verify_certificate, this, _1, _2));

            boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
                                       boost::bind(&client::handle_connect, this,
                                                   boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error resolve: " << err.message() << "\n";
        }
    }

    bool verify_certificate(bool preverified,
                            boost::asio::ssl::verify_context& ctx)
    {
        // The verify callback can be used to check whether the certificate that is
        // being presented is valid for the peer. For example, RFC 2818 describes
        // the steps involved in doing this for HTTPS. Consult the OpenSSL
        // documentation for more details. Note that the callback is called once
        // for each certificate in the certificate chain, starting from the root
        // certificate authority.

        // In this example we will simply print the certificate's subject name.
        char subject_name[256];
        X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
        X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
        std::cout << "Verifying " << subject_name << "\n";

        return preverified;
    }

    void handle_connect(const boost::system::error_code& err)
    {
        if (!err)
        {
            std::cout << "Connect OK " << "\n";
            socket_.async_handshake(boost::asio::ssl::stream_base::client,
                                    boost::bind(&client::handle_handshake, this,
                                                boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Connect failed: " << err.message() << "\n";
        }
    }
// a2fqn2y3y2.execute-api.us-east-1.amazonaws.com /prod/mxnet-test-dev-hello /Users/durst/dev/F16-17/vass/mxnet-serverless/testimg.jpg
    void handle_handshake(const boost::system::error_code& error)
    {
        if (!error)
        {
            std::cout << "Handshake OK " << "\n";
            std::cout << "Request: " << "\n";
            const char* header=boost::asio::buffer_cast<const char*>(request_.data());
            std::cout << header << "\n";

            // The handshake was successful. Send the request.
            boost::asio::async_write(socket_, request_,
                                     boost::bind(&client::handle_write_request, this,
                                                 boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Handshake failed: " << error.message() << "\n";
        }
    }

    void handle_write_request(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Read the response status line. The response_ streambuf will
            // automatically grow to accommodate the entire line. The growth may be
            // limited by passing a maximum size to the streambuf constructor.
            boost::asio::async_read_until(socket_, response_, "\r\n",
                                          boost::bind(&client::handle_read_status_line, this,
                                                      boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error write req: " << err.message() << "\n";
        }
    }

    void handle_read_status_line(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Check that response is OK.
            std::istream response_stream(&response_);
            std::string http_version;
            response_stream >> http_version;
            unsigned int status_code;
            response_stream >> status_code;
            std::string status_message;
            std::getline(response_stream, status_message);
            if (!response_stream || http_version.substr(0, 5) != "HTTP/")
            {
                std::cout << "Invalid response\n";
                return;
            }
            if (status_code != 200)
            {
                std::cout << "Response returned with status code ";
                std::cout << status_code << "\n";
                return;
            }
            std::cout << "Status code: " << status_code << "\n";

            // Read the response headers, which are terminated by a blank line.
            boost::asio::async_read_until(socket_, response_, "\r\n\r\n",
                                          boost::bind(&client::handle_read_headers, this,
                                                      boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error: " << err.message() << "\n";
        }
    }

    void handle_read_headers(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Process the response headers.
            std::istream response_stream(&response_);
            std::string header;
            while (std::getline(response_stream, header) && header != "\r")
                std::cout << header << "\n";
            std::cout << "\n";

            // Write whatever content we already have to output.
            if (response_.size() > 0)
                std::cout << &response_;

            // Start reading remaining data until EOF.
            boost::asio::async_read(socket_, response_,
                                    boost::asio::transfer_at_least(1),
                                    boost::bind(&client::handle_read_content, this,
                                                boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error: " << err << "\n";
        }
    }

    void handle_read_content(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Write all of the data that has been read so far.
            std::cout << &response_;

            // Continue reading remaining data until EOF.
            boost::asio::async_read(socket_, response_,
                                    boost::asio::transfer_at_least(1),
                                    boost::bind(&client::handle_read_content, this,
                                                boost::asio::placeholders::error));
        }
        else if (err != boost::asio::error::eof)
        {
            std::cout << "Error: " << err << "\n";
        }
    }

    /*
    void handle_resolve(const boost::system::error_code& err,
                        tcp::resolver::iterator endpoint_iterator)
    {
        if (!err)
        {
            socket_.set_verify_mode(boost::asio::ssl::verify_peer);
            socket_.set_verify_callback(
                    boost::bind(&client::verify_certificate, this, _1, _2));
            // Attempt a connection to the first endpoint in the list. Each endpoint
            // will be tried until we successfully establish a connection.
            tcp::endpoint endpoint = *endpoint_iterator;
            socket_.lowest_layer().async_connect(endpoint,
                                  boost::bind(&client::handle_connect, this,
                                              boost::asio::placeholders::error, ++endpoint_iterator));
        }
        else
        {
            std::cout << "Error: " << err.message() << "\n";
        }
        //-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DOPENSSL_INCLUDE_DIR==/usr/local/opt/openssl/lib
    }

    bool verify_certificate(bool preverified,
                            boost::asio::ssl::verify_context& ctx)
    {
        // The verify callback can be used to check whether the certificate that is
        // being presented is valid for the peer. For example, RFC 2818 describes
        // the steps involved in doing this for HTTPS. Consult the OpenSSL
        // documentation for more details. Note that the callback is called once
        // for each certificate in the certificate chain, starting from the root
        // certificate authority.

        // In this example we will simply print the certificate's subject name.
        char subject_name[256];
        X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
        X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
        std::cout << "Verifying " << subject_name << "\n";

        return preverified;
    }

    void handle_connect(const boost::system::error_code& err,
                        tcp::resolver::iterator endpoint_iterator)
    {
        if (!err)
        {
            //socket_.async_handshake(boost::asio::ssl::stream_base::handshake_type::client);
            // The connection was successful. Send the request.
            boost::asio::async_write(socket_, request_,
                                     boost::bind(&client::handle_write_request, this,
                                                 boost::asio::placeholders::error));
        }
        else if (endpoint_iterator != tcp::resolver::iterator())
        {
            // The connection failed. Try the next endpoint in the list.
            socket_.lowest_layer().close();
            tcp::endpoint endpoint = *endpoint_iterator;
            socket_.lowest_layer().async_connect(endpoint,
                                  boost::bind(&client::handle_connect, this,
                                              boost::asio::placeholders::error, ++endpoint_iterator));
        }
        else
        {
            std::cout << "Error: " << err.message() << "\n";
        }
    }

    void handle_write_request(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Read the response status line. The response_ streambuf will
            // automatically grow to accommodate the entire line. The growth may be
            // limited by passing a maximum size to the streambuf constructor.
            boost::asio::async_read_until(socket_, response_, "\r\n",
                                          boost::bind(&client::handle_read_status_line, this,
                                                      boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error: " << err.message() << "\n";
        }
    }

    void handle_read_status_line(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Check that response is OK.
            std::istream response_stream(&response_);
            std::string http_version;
            response_stream >> http_version;
            unsigned int status_code;
            response_stream >> status_code;
            std::string status_message;
            std::getline(response_stream, status_message);
            if (!response_stream || http_version.substr(0, 5) != "HTTP/")
            {
                std::cout << "Invalid response\n";
                return;
            }
            if (status_code != 200)
            {
                std::cout << "Response returned with status code ";
                std::cout << status_code << "\n";
                return;
            }

            // Read the response headers, which are terminated by a blank line.
            boost::asio::async_read_until(socket_, response_, "\r\n\r\n",
                                          boost::bind(&client::handle_read_headers, this,
                                                      boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error: " << err << "\n";
        }
    }

    void handle_read_headers(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Process the response headers.
            std::istream response_stream(&response_);
            std::string header;
            while (std::getline(response_stream, header) && header != "\r")
                std::cout << header << "\n";
            std::cout << "\n";

            // Write whatever content we already have to output.
            if (response_.size() > 0)
                std::cout << &response_;

            // Start reading remaining data until EOF.
            boost::asio::async_read(socket_, response_,
                                    boost::asio::transfer_at_least(1),
                                    boost::bind(&client::handle_read_content, this,
                                                boost::asio::placeholders::error));
        }
        else
        {
            std::cout << "Error: " << err << "\n";
        }
    }

    void handle_read_content(const boost::system::error_code& err)
    {
        if (!err)
        {
            // Write all of the data that has been read so far.
            std::cout << &response_;

            // Continue reading remaining data until EOF.
            boost::asio::async_read(socket_, response_,
                                    boost::asio::transfer_at_least(1),
                                    boost::bind(&client::handle_read_content, this,
                                                boost::asio::placeholders::error));
        }
        else if (err != boost::asio::error::eof)
        {
            std::cout << "Error: " << err << "\n";
        }
    }
     */

    tcp::resolver resolver_;
    // https://stackoverflow.com/questions/40036854/creating-a-https-request-using-boost-asio-and-openssl
    // http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/overview/ssl.html
    boost::asio::ssl::context ctx;
    boost::asio::ssl::stream<tcp::socket> socket_;
    boost::asio::streambuf request_;
    boost::asio::streambuf response_;
};

int main(int argc, char* argv[])
{
    try
    {
        if (argc != 4)
        {
            std::cout << "Usage: async_client <server> <path> <fileContainingPostBody>\n";
            std::cout << "Example:\n";
            std::cout << "  async_client www.boost.org /LICENSE_1_0.txt\n";
            return 1;
        }

        boost::asio::io_service io_service;
        std::ifstream b64File(argv[3]);
        std::stringstream b64ImgStream;
        b64ImgStream << b64File.rdbuf();
        std::string b64ImgStr = b64ImgStream.str();
        //client c(io_service, "www.deelay.me", "/1000/hmpg.net");
        client c(io_service, argv[1], argv[2], b64ImgStr);
        io_service.run();
        std::cout << "should print first\n";
    }
    catch (std::exception& e)
    {
        std::cout << "Exception: " << e.what() << "\n";
    }

    return 0;
}
<|endoftext|>


<commit_before>//
// This class contains the secondary correction
// for the central region
//
#include "AliCentralCorrSecondaryMap.h"
#include <TBrowser.h>
#include <TH2D.h>
#include <AliLog.h>
#include <iostream>

//____________________________________________________________________
AliCentralCorrSecondaryMap::AliCentralCorrSecondaryMap()
  : fArray(),
    fVertexAxis(0,0,0)
{
  //
  // Default constructor
  //
  fArray.SetOwner(kTRUE);
  fArray.SetName("rings");
  fVertexAxis.SetName("vtxAxis");
  fVertexAxis.SetTitle("v_{z} [cm]");

}
//____________________________________________________________________
AliCentralCorrSecondaryMap::AliCentralCorrSecondaryMap(const
					       AliCentralCorrSecondaryMap& o)
  : TObject(o),
    fArray(o.fArray),
    fVertexAxis(o.fVertexAxis.GetNbins(), o.fVertexAxis.GetXmin(),
		o.fVertexAxis.GetXmax())
{
  //
  // Copy constructor
  //
  // Parameters:
  //    o Object to copy from
  //
  fVertexAxis.SetName("vtxAxis");
  fVertexAxis.SetTitle("v_{z} [cm]");
}
//____________________________________________________________________
AliCentralCorrSecondaryMap::~AliCentralCorrSecondaryMap()
{
  //
  // Destructor
  //
  //
  fArray.Clear();
}
//____________________________________________________________________
AliCentralCorrSecondaryMap&
AliCentralCorrSecondaryMap::operator=(const AliCentralCorrSecondaryMap& o)
{
  //
  // Assignment operator
  //
  // Parameters:
  //    o Object to assign from
  //
  // Return:
  //    Reference to this object
  //
  fArray        = o.fArray;
  SetVertexAxis(o.fVertexAxis);

  return *this;
}
//____________________________________________________________________
TH2D*
AliCentralCorrSecondaryMap::GetCorrection(Double_t v) const
{
  //
  // Get the acceptance correction @f$ a_{r,v}@f$
  //
  // Parameters:
  //    d  Detector number (1-3)
  //    r  Ring identifier (I or O)
  //    v  Primary interaction point @f$z@f$ coordinate
  //
  // Return:
  //    The correction @f$ a_{r,v}@f$
  //
  Int_t b = FindVertexBin(v);
  if (b <= 0) return 0;
  return GetCorrection(UShort_t(b));
}
//____________________________________________________________________
TH2D*
AliCentralCorrSecondaryMap::GetCorrection(UShort_t b) const
{
  //
  // Get the acceptance correction @f$ a_{r,v}@f$
  //
  // Parameters:
  //    d  Detector number (1-3)
  //    r  Ring identifier (I or O)
  //    b  Bin corresponding to the primary interaction point
  //           @f$z@f$ coordinate (1 based)
  //
  // Return:
  //    The correction @f$ a_{r,v}@f$
  //

  TObject* o = fArray.At(b-1);
  if (!o) {
    AliWarning(Form("No dead channels map found for SPD in vertex bin %d",
		    b));
    return 0;
  }
  return static_cast<TH2D*>(o);
}

//____________________________________________________________________
Int_t
AliCentralCorrSecondaryMap::FindVertexBin(Double_t v) const
{
  //
  // Find the vertex bin that corresponds to the passed vertex
  //
  // Parameters:
  //    vertex The interaction points @f$z@f$-coordinate
  //
  // Return:
  //    Vertex bin in @f$[1,N_{\mbox{vertex}}]@f$ or negative if
  // out of range
  //
  if (fVertexAxis.GetNbins() <= 0) {
    AliWarning("No vertex array defined");
    return 0;
  }
  Int_t bin = const_cast<TAxis&>(fVertexAxis).FindBin(v);
  if (bin <= 0 || bin > fVertexAxis.GetNbins()) {
    AliWarning(Form("vertex %+8.4f out of range [%+8.4f,%+8.4f]",
		    v, fVertexAxis.GetXmin(), fVertexAxis.GetXmax()));
    return 0;
  }
  return bin;
}

//____________________________________________________________________
Bool_t
AliCentralCorrSecondaryMap::SetCorrection(UShort_t b, TH2D*  h)
{
  //
  // Set the acceptance correction @f$ a_{r,v}(\eta)@f$
  // Note, that the object takes ownership of the passed pointer.
  //
  // Parameters:
  //    d    Detector number (1-3)
  //    r    Ring identifier (I or O)
  //    b    Bin corresponding to the primary interaction point
  //             @f$z@f$ coordinate  (1 based)
  //    h    @f$ a_{r,v}(\eta)@f$
  //
  // Return:
  //    true if operation succeeded
  //

  if (b <= 0 || b > fVertexAxis.GetNbins()) {
    AliWarning(Form("Vertex bin %3d out of range [1,%3d]",
		    b, fVertexAxis.GetNbins()));
    return false;
  }
  h->SetName(Form("SPD_vtxbin%03d", b));
  h->SetTitle(Form("SecondaryMap correction for SPD "
		   "in vertex bin %d [%+8.4f,%+8.4f]",
		   b, fVertexAxis.GetBinLowEdge(b),
		   fVertexAxis.GetBinUpEdge(b)));
  h->SetXTitle("#eta");
  h->SetYTitle("dN_{ch}/d#eta / sum_i N_{ch,i}");
  h->SetFillStyle(3001);
  h->SetDirectory(0);
  h->SetStats(0);
  fArray.AddAtAndExpand(h, b-1);
  return kTRUE;
}
//____________________________________________________________________
Bool_t
AliCentralCorrSecondaryMap::SetCorrection(Double_t v, TH2D*  h)
{
  //
  // Set the acceptance correction @f$ a_{r,v}(\eta)@f$.
  // Note, that the object takes ownership of the passed pointer.
  //
  // Parameters:
  //    d    Detector number (1-3)
  //    r    Ring identifier (I or O)
  //    v    Primary interaction point @f$z@f$ coordinate
  //    h    @f$ a_{r,v}(\eta)@f$
  //
  // Return:
  //    true if operation succeeded
  //
  Int_t b = FindVertexBin(v);
  if (b <= 0 || b > fVertexAxis.GetNbins()) {
    AliWarning(Form("Vertex %+8.4f out of range [%+8.4f,%+8.4f]",
		    v, fVertexAxis.GetXmin(), fVertexAxis.GetXmax()));
    return false;
  }
  return SetCorrection( UShort_t(b), h);
}
//____________________________________________________________________
void
AliCentralCorrSecondaryMap::Browse(TBrowser* b)
{
  //
  // Browse this object in the browser
  //
  // Parameters:
  //    b
  //
  b->Add(&fArray);
  b->Add(&fVertexAxis);
}
//____________________________________________________________________
void
AliCentralCorrSecondaryMap::Print(Option_t* option) const
{
  //
  // Print this object
  //
  // Parameters:
  //    option
  //
  std::cout << "  SecondaryMap correction" << std::endl;
  std::cout << "   " << std::flush;
  fArray.Print(option);
  std::cout << "   " << std::flush;
  fVertexAxis.Print(option);
}

//____________________________________________________________________
//
// EOF
//
<commit_msg>Minor things<commit_after>//
// This class contains the secondary correction
// for the central region
//
#include "AliCentralCorrSecondaryMap.h"
#include <TBrowser.h>
#include <TH2D.h>
#include <AliLog.h>
#include <iostream>

//____________________________________________________________________
AliCentralCorrSecondaryMap::AliCentralCorrSecondaryMap()
  : fArray(),
    fVertexAxis(0,0,0)
{
  //
  // Default constructor
  //
  fArray.SetOwner(kTRUE);
  fArray.SetName("rings");
  fVertexAxis.SetName("vtxAxis");
  fVertexAxis.SetTitle("v_{z} [cm]");

}
//____________________________________________________________________
AliCentralCorrSecondaryMap::AliCentralCorrSecondaryMap(const
					       AliCentralCorrSecondaryMap& o)
  : TObject(o),
    fArray(o.fArray),
    fVertexAxis(o.fVertexAxis.GetNbins(), o.fVertexAxis.GetXmin(),
		o.fVertexAxis.GetXmax())
{
  //
  // Copy constructor
  //
  // Parameters:
  //    o Object to copy from
  //
  fVertexAxis.SetName("vtxAxis");
  fVertexAxis.SetTitle("v_{z} [cm]");
}
//____________________________________________________________________
AliCentralCorrSecondaryMap::~AliCentralCorrSecondaryMap()
{
  //
  // Destructor
  //
  //
  fArray.Clear();
}
//____________________________________________________________________
AliCentralCorrSecondaryMap&
AliCentralCorrSecondaryMap::operator=(const AliCentralCorrSecondaryMap& o)
{
  //
  // Assignment operator
  //
  // Parameters:
  //    o Object to assign from
  //
  // Return:
  //    Reference to this object
  //
  fArray        = o.fArray;
  SetVertexAxis(o.fVertexAxis);

  return *this;
}
//____________________________________________________________________
TH2D*
AliCentralCorrSecondaryMap::GetCorrection(Double_t v) const
{
  //
  // Get the acceptance correction @f$ a_{r,v}@f$
  //
  // Parameters:
  //    d  Detector number (1-3)
  //    r  Ring identifier (I or O)
  //    v  Primary interaction point @f$z@f$ coordinate
  //
  // Return:
  //    The correction @f$ a_{r,v}@f$
  //
  Int_t b = FindVertexBin(v);
  if (b <= 0) return 0;
  return GetCorrection(UShort_t(b));
}
//____________________________________________________________________
TH2D*
AliCentralCorrSecondaryMap::GetCorrection(UShort_t b) const
{
  //
  // Get the acceptance correction @f$ a_{r,v}@f$
  //
  // Parameters:
  //    d  Detector number (1-3)
  //    r  Ring identifier (I or O)
  //    b  Bin corresponding to the primary interaction point
  //           @f$z@f$ coordinate (1 based)
  //
  // Return:
  //    The correction @f$ a_{r,v}@f$
  //

  TObject* o = fArray.At(b-1);
  if (!o) {
    AliWarning(Form("No dead channels map found for SPD in vertex bin %d",
		    b));
    return 0;
  }
  return static_cast<TH2D*>(o);
}

//____________________________________________________________________
Int_t
AliCentralCorrSecondaryMap::FindVertexBin(Double_t v) const
{
  //
  // Find the vertex bin that corresponds to the passed vertex
  //
  // Parameters:
  //    vertex The interaction points @f$z@f$-coordinate
  //
  // Return:
  //    Vertex bin in @f$[1,N_{\mbox{vertex}}]@f$ or negative if
  // out of range
  //
  if (fVertexAxis.GetNbins() <= 0) {
    AliWarning("No vertex array defined");
    return 0;
  }
  Int_t bin = const_cast<TAxis&>(fVertexAxis).FindBin(v);
  if (bin <= 0 || bin > fVertexAxis.GetNbins()) {
    AliWarning(Form("vertex %+8.4f out of range [%+8.4f,%+8.4f]",
		    v, fVertexAxis.GetXmin(), fVertexAxis.GetXmax()));
    return 0;
  }
  return bin;
}

//____________________________________________________________________
Bool_t
AliCentralCorrSecondaryMap::SetCorrection(UShort_t b, TH2D*  h)
{
  //
  // Set the acceptance correction @f$ a_{r,v}(\eta)@f$
  // Note, that the object takes ownership of the passed pointer.
  //
  // Parameters:
  //    d    Detector number (1-3)
  //    r    Ring identifier (I or O)
  //    b    Bin corresponding to the primary interaction point
  //             @f$z@f$ coordinate  (1 based)
  //    h    @f$ a_{r,v}(\eta)@f$
  //
  // Return:
  //    true if operation succeeded
  //

  if (b <= 0 || b > fVertexAxis.GetNbins()) {
    AliWarning(Form("Vertex bin %3d out of range [1,%3d]",
		    b, fVertexAxis.GetNbins()));
    return false;
  }
  h->SetName(Form("SPD_vtxbin%03d", b));
  h->SetTitle(Form("SecondaryMap correction for SPD "
		   "in vertex bin %d [%+8.4f,%+8.4f]",
		   b, fVertexAxis.GetBinLowEdge(b),
		   fVertexAxis.GetBinUpEdge(b)));
  h->SetXTitle("#eta");
  h->SetYTitle("dN_{ch}/d#eta / sum_i N_{ch,i}");
  h->SetFillStyle(3001);
  h->SetDirectory(0);
  h->SetStats(0);
  fArray.AddAtAndExpand(h, b-1);
  return kTRUE;
}
//____________________________________________________________________
Bool_t
AliCentralCorrSecondaryMap::SetCorrection(Double_t v, TH2D*  h)
{
  //
  // Set the acceptance correction @f$ a_{r,v}(\eta)@f$.
  // Note, that the object takes ownership of the passed pointer.
  //
  // Parameters:
  //    d    Detector number (1-3)
  //    r    Ring identifier (I or O)
  //    v    Primary interaction point @f$z@f$ coordinate
  //    h    @f$ a_{r,v}(\eta)@f$
  //
  // Return:
  //    true if operation succeeded
  //
  Int_t b = FindVertexBin(v);
  if (b <= 0 || b > fVertexAxis.GetNbins()) {
    AliWarning(Form("Vertex %+8.4f out of range [%+8.4f,%+8.4f]",
		    v, fVertexAxis.GetXmin(), fVertexAxis.GetXmax()));
    return false;
  }
  return SetCorrection( UShort_t(b), h);
}
//____________________________________________________________________
void
AliCentralCorrSecondaryMap::Browse(TBrowser* b)
{
  //
  // Browse this object in the browser
  //
  // Parameters:
  //    b
  //
  b->Add(&fArray);
  b->Add(&fVertexAxis);
}
//____________________________________________________________________
void
AliCentralCorrSecondaryMap::Print(Option_t* /* option */) const
{
  //
  // Print this object
  //
  // Parameters:
  //    option
  //
  std::cout << "  SecondaryMap correction\n"
	    << "   # of vertex bins: "  << fVertexAxis.GetNbins() << "\n"
	    << "   Vertex range:     [" << fVertexAxis.GetXmin()
	    << "," << fVertexAxis.GetXmax() << "]\n"
	    << "   Histograms:\n"
	    << "    ";
  TIter next(&fArray);
  TObject* o = 0;
  while ((o = next())) std::cout << o->GetName() << " ";
  std::cout << std::endl;
}

//____________________________________________________________________
//
// EOF
//
<|endoftext|>


<commit_before>
//
// A WebAssembly shell, loads a .wast file (WebAssembly in S-Expression format)
// and executes it. This provides similar functionality as the reference
// interpreter, like assert_* calls, so it can run the spec test suite.
//

#include <setjmp.h>

#include "wasm-s-parser.h"
#include "wasm-interpreter.h"
#include "wasm-validator.h"
#include "pass.h"

using namespace cashew;
using namespace wasm;

// Globals

MixedArena globalAllocator;

IString ASSERT_RETURN("assert_return"),
        ASSERT_TRAP("assert_trap"),
        ASSERT_INVALID("assert_invalid"),
        STDIO("stdio"),
        PRINT("print"),
        INVOKE("invoke");

//
// Implementation of the shell interpreter execution environment
//

struct ShellExternalInterface : ModuleInstance::ExternalInterface {
  char *memory;

  ShellExternalInterface() : memory(nullptr) {}

  void init(Module& wasm) override {
    memory = (char*)malloc(wasm.memory.initial);
    // apply memory segments
    for (auto segment : wasm.memory.segments) {
      memcpy(memory + segment.offset, segment.data, segment.size);
    }
  }

  Literal callImport(Import *import, ModuleInstance::LiteralList& arguments) override {
    if (import->module == STDIO && import->base == PRINT) {
      for (auto argument : arguments) {
        std::cout << argument << '\n';
      }
      return Literal();
    }
    std::cout << "callImport " << import->name.str << "\n";
    abort();
  }

  Literal load(Load* load, size_t addr) override {
    // ignore align - assume we are on x86 etc. which does that
    switch (load->type) {
      case i32: {
        switch (load->bytes) {
          case 1: return load->signed_ ? (int32_t)*((int8_t*)(memory+addr))  : (int32_t)*((uint8_t*)(memory+addr));
          case 2: return load->signed_ ? (int32_t)*((int16_t*)(memory+addr)) : (int32_t)*((uint16_t*)(memory+addr));
          case 4: return load->signed_ ? (int32_t)*((int32_t*)(memory+addr)) : (int32_t)*((uint32_t*)(memory+addr));
          default: abort();
        }
        break;
      }
      case i64: {
        switch (load->bytes) {
          case 1: return load->signed_ ? (int64_t)*((int8_t*)(memory+addr))  : (int64_t)*((uint8_t*)(memory+addr));
          case 2: return load->signed_ ? (int64_t)*((int16_t*)(memory+addr)) : (int64_t)*((uint16_t*)(memory+addr));
          case 4: return load->signed_ ? (int64_t)*((int32_t*)(memory+addr)) : (int64_t)*((uint32_t*)(memory+addr));
          case 8: return load->signed_ ? (int64_t)*((int64_t*)(memory+addr)) : (int64_t)*((uint64_t*)(memory+addr));
          default: abort();
        }
        break;
      }
      case f32: return *((float*)(memory+addr));
      case f64: return *((double*)(memory+addr));
      default: abort();
    }
  }

  void store(Store* store, size_t addr, Literal value) override {
    // ignore align - assume we are on x86 etc. which does that
    switch (store->type) {
      case i32: {
        switch (store->bytes) {
          case 1: *((int8_t*)(memory+addr)) = value.geti32(); break;
          case 2: *((int16_t*)(memory+addr)) = value.geti32(); break;
          case 4: *((int32_t*)(memory+addr)) = value.geti32(); break;
          default: abort();
        }
        break;
      }
      case i64: {
        switch (store->bytes) {
          case 1: *((int8_t*)(memory+addr)) = value.geti64(); break;
          case 2: *((int16_t*)(memory+addr)) = value.geti64(); break;
          case 4: *((int32_t*)(memory+addr)) = value.geti64(); break;
          case 8: *((int64_t*)(memory+addr)) = value.geti64(); break;
          default: abort();
        }
        break;
      }
      case f32: *((float*)(memory+addr)) = value.getf32(); break;
      case f64: *((double*)(memory+addr)) = value.getf64(); break;
      default: abort();
    }
  }

  void growMemory(size_t oldSize, size_t newSize) override {
    memory = (char*)realloc(memory, newSize);
  }

  jmp_buf trapState;

  void trap(const char* why) override {
    std::cerr << "[trap " << why << "]\n";
    longjmp(trapState, 1);
  }
};

//
// An invocation into a module
//

struct Invocation {
  ModuleInstance* instance;
  IString name;
  ModuleInstance::LiteralList arguments;

  Invocation(Element& invoke, ModuleInstance* instance, SExpressionWasmBuilder& builder) : instance(instance) {
    assert(invoke[0]->str() == INVOKE);
    name = invoke[1]->str();
    for (size_t j = 2; j < invoke.size(); j++) {
      Expression* argument = builder.parseExpression(*invoke[j]);
      arguments.push_back(argument->dyn_cast<Const>()->value);
    }
  }

  Literal invoke() {
    return instance->callExport(name, arguments);
  }
};

//
// main
//

int main(int argc, char **argv) {
  debug = getenv("BINARYEN_DEBUG") ? getenv("BINARYEN_DEBUG")[0] - '0' : 0;

  char *infile = nullptr;
  bool print_before = false;
  bool print_after = false;
  std::vector<std::string> passes;

  for (size_t i = 1; i < argc; i++) {
    char* curr = argv[i];
    if (curr[0] == '-') {
      std::string arg = curr;
      if (arg == "-print-before") {
        print_before = true;
      } else if (arg == "-print-after") {
        print_after = true;
      } else if (arg == "--help") {
        std::cout << "\n";
        std::cout << "binaryen shell\n";
        std::cout << "--------------\n\n";
        std::cout << "options:\n";
        std::cout << "  -print-before : print modules before processing them\n";
        std::cout << "  -print-after  : print modules after processing them\n";
        std::cout << "\n";
        std::cout << "passes:\n";
        auto allPasses = PassRegistry::get()->getRegisteredNames();
        for (auto& name : allPasses) {
          std::cout << "  -" << name << " : " << PassRegistry::get()->getPassDescription(name) << "\n";
        }
        std::cout << "\n";
        exit(0);
      } else {
        // otherwise, assumed to be a pass
        const char* name = curr + 1;
        auto check = PassRegistry::get()->createPass(name);
        if (!check) {
          printf("error: invalid option %s\n", curr);
          exit(1);
        }
        delete check;
        passes.push_back(name);
      }
    } else {
      if (infile) {
        printf("error: too many input files provided.\n");
        exit(1);
      }
      infile = curr;
    }
  }

  if (!infile) {
    printf("error: no input file provided.\n");
    exit(1);
  }

  if (debug) std::cerr << "loading '" << infile << "'...\n";
  FILE *f = fopen(infile, "r");
  if (!f) {
    printf("error: could not open input file: %s\n", infile);
    exit(1);
  }
  fseek(f, 0, SEEK_END);
  int size = ftell(f);
  char *input = new char[size+1];
  rewind(f);
  int num = fread(input, 1, size, f);
  // On Windows, ftell() gives the byte position (\r\n counts as two bytes), but when
  // reading, fread() returns the number of characters read (\r\n is read as one char \n, and counted as one),
  // so return value of fread can be less than size reported by ftell, and that is normal.
  assert((num > 0 || size == 0) && num <= size);
  fclose(f);
  input[num] = 0;

  if (debug) std::cerr << "parsing text to s-expressions...\n";
  SExpressionParser parser(input);
  Element& root = *parser.root;
  if (debug) std::cout << root << '\n';

  // A .wast may have multiple modules, with some asserts after them
  bool checked = false;
  size_t i = 0;
  while (i < root.size()) {
    if (debug) std::cerr << "parsing s-expressions to wasm...\n";
    Module wasm;
    SExpressionWasmBuilder builder(wasm, *root[i], [&]() { abort(); });
    i++;

    auto interface = new ShellExternalInterface();
    auto instance = new ModuleInstance(wasm, interface);

    if (print_before) {
      Colors::bold(std::cout);
      std::cout << "printing before:\n";
      Colors::normal(std::cout);
      std::cout << wasm;
    }

    MixedArena moreModuleAllocations;

    if (passes.size() > 0) {
      if (debug) std::cerr << "running passes...\n";
      PassRunner passRunner(&moreModuleAllocations);
      for (auto& passName : passes) {
        passRunner.add(passName);
      }
      passRunner.run(&wasm);
    }

    if (print_after) {
      Colors::bold(std::cout);
      std::cout << "printing after:\n";
      Colors::normal(std::cout);
      std::cout << wasm;
    }

    // run asserts
    while (i < root.size()) {
      Element& curr = *root[i];
      IString id = curr[0]->str();
      if (id == MODULE) break;
      checked = true;
      Colors::red(std::cerr);
      std::cerr << i << '/' << (root.size()-1);
      Colors::green(std::cerr);
      std::cerr << " CHECKING: ";
      Colors::normal(std::cerr);
      std::cerr << curr << '\n';
      if (id == ASSERT_INVALID) {
        // a module invalidity test
        Module wasm;
        bool invalid = false;
        jmp_buf trapState;
        if (setjmp(trapState) == 0) {
          SExpressionWasmBuilder builder(wasm, *curr[1], [&]() {
            invalid = true;
            longjmp(trapState, 1);
          });
        }
        if (!invalid) {
          // maybe parsed ok, but otherwise incorrect
          invalid = !WasmValidator().validate(wasm);
        }
        assert(invalid);
      } else if (id == INVOKE) {
        Invocation invocation(curr, instance, builder);
        invocation.invoke();
      } else {
        // an invoke test
        Invocation invocation(*curr[1], instance, builder);
        bool trapped = false;
        Literal result;
        if (setjmp(interface->trapState) == 0) {
          result = invocation.invoke();
        } else {
          trapped = true;
        }
        if (id == ASSERT_RETURN) {
          assert(!trapped);
          Literal expected;
          if (curr.size() >= 3) {
            expected = builder.parseExpression(*curr[2])->dyn_cast<Const>()->value;
          }
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          assert(expected == result);
        }
        if (id == ASSERT_TRAP) assert(trapped);
      }
      i++;
    }
  }

  if (checked) {
    Colors::green(std::cerr);
    Colors::bold(std::cerr);
    std::cerr << "all checks passed.\n";
    Colors::normal(std::cerr);
  }
}

<commit_msg>add printing in module validity tests<commit_after>
//
// A WebAssembly shell, loads a .wast file (WebAssembly in S-Expression format)
// and executes it. This provides similar functionality as the reference
// interpreter, like assert_* calls, so it can run the spec test suite.
//

#include <setjmp.h>
#include <memory>

#include "wasm-s-parser.h"
#include "wasm-interpreter.h"
#include "wasm-validator.h"
#include "pass.h"

using namespace cashew;
using namespace wasm;

// Globals

MixedArena globalAllocator;

IString ASSERT_RETURN("assert_return"),
        ASSERT_TRAP("assert_trap"),
        ASSERT_INVALID("assert_invalid"),
        STDIO("stdio"),
        PRINT("print"),
        INVOKE("invoke");

//
// Implementation of the shell interpreter execution environment
//

struct ShellExternalInterface : ModuleInstance::ExternalInterface {
  char *memory;

  ShellExternalInterface() : memory(nullptr) {}

  void init(Module& wasm) override {
    memory = (char*)malloc(wasm.memory.initial);
    // apply memory segments
    for (auto segment : wasm.memory.segments) {
      memcpy(memory + segment.offset, segment.data, segment.size);
    }
  }

  Literal callImport(Import *import, ModuleInstance::LiteralList& arguments) override {
    if (import->module == STDIO && import->base == PRINT) {
      for (auto argument : arguments) {
        std::cout << argument << '\n';
      }
      return Literal();
    }
    std::cout << "callImport " << import->name.str << "\n";
    abort();
  }

  Literal load(Load* load, size_t addr) override {
    // ignore align - assume we are on x86 etc. which does that
    switch (load->type) {
      case i32: {
        switch (load->bytes) {
          case 1: return load->signed_ ? (int32_t)*((int8_t*)(memory+addr))  : (int32_t)*((uint8_t*)(memory+addr));
          case 2: return load->signed_ ? (int32_t)*((int16_t*)(memory+addr)) : (int32_t)*((uint16_t*)(memory+addr));
          case 4: return load->signed_ ? (int32_t)*((int32_t*)(memory+addr)) : (int32_t)*((uint32_t*)(memory+addr));
          default: abort();
        }
        break;
      }
      case i64: {
        switch (load->bytes) {
          case 1: return load->signed_ ? (int64_t)*((int8_t*)(memory+addr))  : (int64_t)*((uint8_t*)(memory+addr));
          case 2: return load->signed_ ? (int64_t)*((int16_t*)(memory+addr)) : (int64_t)*((uint16_t*)(memory+addr));
          case 4: return load->signed_ ? (int64_t)*((int32_t*)(memory+addr)) : (int64_t)*((uint32_t*)(memory+addr));
          case 8: return load->signed_ ? (int64_t)*((int64_t*)(memory+addr)) : (int64_t)*((uint64_t*)(memory+addr));
          default: abort();
        }
        break;
      }
      case f32: return *((float*)(memory+addr));
      case f64: return *((double*)(memory+addr));
      default: abort();
    }
  }

  void store(Store* store, size_t addr, Literal value) override {
    // ignore align - assume we are on x86 etc. which does that
    switch (store->type) {
      case i32: {
        switch (store->bytes) {
          case 1: *((int8_t*)(memory+addr)) = value.geti32(); break;
          case 2: *((int16_t*)(memory+addr)) = value.geti32(); break;
          case 4: *((int32_t*)(memory+addr)) = value.geti32(); break;
          default: abort();
        }
        break;
      }
      case i64: {
        switch (store->bytes) {
          case 1: *((int8_t*)(memory+addr)) = value.geti64(); break;
          case 2: *((int16_t*)(memory+addr)) = value.geti64(); break;
          case 4: *((int32_t*)(memory+addr)) = value.geti64(); break;
          case 8: *((int64_t*)(memory+addr)) = value.geti64(); break;
          default: abort();
        }
        break;
      }
      case f32: *((float*)(memory+addr)) = value.getf32(); break;
      case f64: *((double*)(memory+addr)) = value.getf64(); break;
      default: abort();
    }
  }

  void growMemory(size_t oldSize, size_t newSize) override {
    memory = (char*)realloc(memory, newSize);
  }

  jmp_buf trapState;

  void trap(const char* why) override {
    std::cerr << "[trap " << why << "]\n";
    longjmp(trapState, 1);
  }
};

//
// An invocation into a module
//

struct Invocation {
  ModuleInstance* instance;
  IString name;
  ModuleInstance::LiteralList arguments;

  Invocation(Element& invoke, ModuleInstance* instance, SExpressionWasmBuilder& builder) : instance(instance) {
    assert(invoke[0]->str() == INVOKE);
    name = invoke[1]->str();
    for (size_t j = 2; j < invoke.size(); j++) {
      Expression* argument = builder.parseExpression(*invoke[j]);
      arguments.push_back(argument->dyn_cast<Const>()->value);
    }
  }

  Literal invoke() {
    return instance->callExport(name, arguments);
  }
};

//
// main
//

int main(int argc, char **argv) {
  debug = getenv("BINARYEN_DEBUG") ? getenv("BINARYEN_DEBUG")[0] - '0' : 0;

  char *infile = nullptr;
  bool print_before = false;
  bool print_after = false;
  std::vector<std::string> passes;

  for (size_t i = 1; i < argc; i++) {
    char* curr = argv[i];
    if (curr[0] == '-') {
      std::string arg = curr;
      if (arg == "-print-before") {
        print_before = true;
      } else if (arg == "-print-after") {
        print_after = true;
      } else if (arg == "--help") {
        std::cout << "\n";
        std::cout << "binaryen shell\n";
        std::cout << "--------------\n\n";
        std::cout << "options:\n";
        std::cout << "  -print-before : print modules before processing them\n";
        std::cout << "  -print-after  : print modules after processing them\n";
        std::cout << "\n";
        std::cout << "passes:\n";
        auto allPasses = PassRegistry::get()->getRegisteredNames();
        for (auto& name : allPasses) {
          std::cout << "  -" << name << " : " << PassRegistry::get()->getPassDescription(name) << "\n";
        }
        std::cout << "\n";
        exit(0);
      } else {
        // otherwise, assumed to be a pass
        const char* name = curr + 1;
        auto check = PassRegistry::get()->createPass(name);
        if (!check) {
          printf("error: invalid option %s\n", curr);
          exit(1);
        }
        delete check;
        passes.push_back(name);
      }
    } else {
      if (infile) {
        printf("error: too many input files provided.\n");
        exit(1);
      }
      infile = curr;
    }
  }

  if (!infile) {
    printf("error: no input file provided.\n");
    exit(1);
  }

  if (debug) std::cerr << "loading '" << infile << "'...\n";
  FILE *f = fopen(infile, "r");
  if (!f) {
    printf("error: could not open input file: %s\n", infile);
    exit(1);
  }
  fseek(f, 0, SEEK_END);
  int size = ftell(f);
  char *input = new char[size+1];
  rewind(f);
  int num = fread(input, 1, size, f);
  // On Windows, ftell() gives the byte position (\r\n counts as two bytes), but when
  // reading, fread() returns the number of characters read (\r\n is read as one char \n, and counted as one),
  // so return value of fread can be less than size reported by ftell, and that is normal.
  assert((num > 0 || size == 0) && num <= size);
  fclose(f);
  input[num] = 0;

  if (debug) std::cerr << "parsing text to s-expressions...\n";
  SExpressionParser parser(input);
  Element& root = *parser.root;
  if (debug) std::cout << root << '\n';

  // A .wast may have multiple modules, with some asserts after them
  bool checked = false;
  size_t i = 0;
  while (i < root.size()) {
    if (debug) std::cerr << "parsing s-expressions to wasm...\n";
    Module wasm;
    SExpressionWasmBuilder builder(wasm, *root[i], [&]() { abort(); });
    i++;

    auto interface = new ShellExternalInterface();
    auto instance = new ModuleInstance(wasm, interface);

    if (print_before) {
      Colors::bold(std::cout);
      std::cout << "printing before:\n";
      Colors::normal(std::cout);
      std::cout << wasm;
    }

    MixedArena moreModuleAllocations;

    if (passes.size() > 0) {
      if (debug) std::cerr << "running passes...\n";
      PassRunner passRunner(&moreModuleAllocations);
      for (auto& passName : passes) {
        passRunner.add(passName);
      }
      passRunner.run(&wasm);
    }

    if (print_after) {
      Colors::bold(std::cout);
      std::cout << "printing after:\n";
      Colors::normal(std::cout);
      std::cout << wasm;
    }

    // run asserts
    while (i < root.size()) {
      Element& curr = *root[i];
      IString id = curr[0]->str();
      if (id == MODULE) break;
      checked = true;
      Colors::red(std::cerr);
      std::cerr << i << '/' << (root.size()-1);
      Colors::green(std::cerr);
      std::cerr << " CHECKING: ";
      Colors::normal(std::cerr);
      std::cerr << curr << '\n';
      if (id == ASSERT_INVALID) {
        // a module invalidity test
        Module wasm;
        bool invalid = false;
        jmp_buf trapState;
        std::unique_ptr<SExpressionWasmBuilder> builder;
        if (setjmp(trapState) == 0) {
          builder = std::unique_ptr<SExpressionWasmBuilder>(new SExpressionWasmBuilder(wasm, *curr[1], [&]() {
            invalid = true;
            longjmp(trapState, 1);
          }));
        }
        if (print_before || print_after) {
          Colors::bold(std::cout);
          std::cout << "printing in module invalidity test:\n";
          Colors::normal(std::cout);
          std::cout << wasm;
        }
        if (!invalid) {
          // maybe parsed ok, but otherwise incorrect
          invalid = !WasmValidator().validate(wasm);
        }
        assert(invalid);
      } else if (id == INVOKE) {
        Invocation invocation(curr, instance, builder);
        invocation.invoke();
      } else {
        // an invoke test
        Invocation invocation(*curr[1], instance, builder);
        bool trapped = false;
        Literal result;
        if (setjmp(interface->trapState) == 0) {
          result = invocation.invoke();
        } else {
          trapped = true;
        }
        if (id == ASSERT_RETURN) {
          assert(!trapped);
          Literal expected;
          if (curr.size() >= 3) {
            expected = builder.parseExpression(*curr[2])->dyn_cast<Const>()->value;
          }
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          assert(expected == result);
        }
        if (id == ASSERT_TRAP) assert(trapped);
      }
      i++;
    }
  }

  if (checked) {
    Colors::green(std::cerr);
    Colors::bold(std::cerr);
    std::cerr << "all checks passed.\n";
    Colors::normal(std::cerr);
  }
}

<|endoftext|>


<commit_before>void DrawMNN()
{
  gROOT->LoadMacro("MakeRawProduction.C+g");

  RawProduction::Output output;

  const char* example1 = "kMB/pt003_hPi0M11";
  TCanvas* canv = new TCanvas(example1, example1);
  gStyle->SetOptFit(1);
  TH1* hist = output.GetHistogram(example1);
  hist->SetAxisRange(0.05, 0.3);
  hist->Draw();
  canv->SaveAs("imgs/kMB_pt003_hPi0M11");

  const char* example2 = "kMB/pt003_hPi0M12";
  TCanvas* canv = new TCanvas(example2, example2);
  gStyle->SetOptFit(1);
  TH1* hist = output.GetHistogram(example2);
  hist->SetAxisRange(0.05, 0.3);
  hist->Draw();
  canv->SaveAs(Form("imgs/kMB_pt003_hPi0M11", example2));

  TStringToken triggers("kMB kCentral kSemiCentral kPHOSPb", " ");
  while(triggers.NextToken()) {
    canv = new TCanvas(Form("cMean_%s", triggers.Data()), Form("cMean_%s", triggers.Data()));

    RawProduction::TriggerBin triggerBin(triggers);
    TH1* hM11 = output.GetHistogram("M_M11", triggerBin);
    TH1* hM12 = output.GetHistogram("M_M12", triggerBin);
    TH1* hM13 = output.GetHistogram("M_M13", triggerBin);
    TH1* hM22 = output.GetHistogram("M_M22", triggerBin);
    TH1* hM23 = output.GetHistogram("M_M23", triggerBin);
    TH1* hM33 = output.GetHistogram("M_M33", triggerBin);

    hM12->SetMarkerStyle(24);
    hM12->SetMarkerColor(kCyan+1);
    hM12->SetLineColor(kCyan+1);
    hM12->GetYaxis()->SetRangeUser(0.12, 0.15);
    hM12->SetTitle("#pi^{0} Peak Mean");
    gStyle->SetOptStat(0);
    hM12->Draw();

    hM13->SetMarkerStyle(25);
    hM13->SetMarkerColor(kMagenta);
    hM13->SetLineColor(kMagenta);
    hM13->Draw("same");

    hM23->SetMarkerStyle(26);
    hM23->SetMarkerColor(kYellow+1);
    hM23->SetLineColor(kYellow+1);
    hM23->Draw("same");

    hM11->SetMarkerStyle(21);
    hM11->SetMarkerColor(1);
    hM11->SetLineColor(1);
    hM11->GetYaxis()->SetRangeUser(0.12, 0.15);
    hM11->Draw("same");

    hM22->SetMarkerStyle(22);
    hM22->SetMarkerColor(kRed);
    hM22->SetLineColor(kRed);
    hM22->Draw("same");

    hM33->SetMarkerStyle(23);
    hM33->SetMarkerColor(kGreen);
    hM33->SetLineColor(kGreen);
    hM33->Draw("same");

    TLegend* leg = new TLegend(0.8,0.6,0.95,0.95);
    leg->AddEntry(hM11, "M11", "lep");
    leg->AddEntry(hM22, "M22", "lep");
    leg->AddEntry(hM33, "M33", "lep");
    leg->AddEntry(hM12, "M12", "lep");
    leg->AddEntry(hM13, "M13", "lep");
    leg->AddEntry(hM23, "M23", "lep");
    leg->Draw();

    canv->SaveAs(Form("imgs/MNN_Mean_%s.pdf", triggers.Data()));

    canv = new TCanvas(Form("cWidth_%s", triggers.Data()), Form("cWidth_%s", triggers.Data()));

    TH1* hW11 = output.GetHistogram("W_M11", triggerBin);
    TH1* hW12 = output.GetHistogram("W_M12", triggerBin);
    TH1* hW13 = output.GetHistogram("W_M13", triggerBin);
    TH1* hW22 = output.GetHistogram("W_M22", triggerBin);
    TH1* hW23 = output.GetHistogram("W_M23", triggerBin);
    TH1* hW33 = output.GetHistogram("W_M33", triggerBin);

    hW12->SetMarkerStyle(24);
    hW12->SetMarkerColor(kCyan+1);
    hW12->SetLineColor(kCyan+1);
    hW12->GetYaxis()->SetRangeUser(0., 0.02);
    hW12->SetTitle("#pi^{0} Peak Width");
    gStyle->SetOptStat(0);
    hW12->Draw();

    hW13->SetMarkerStyle(25);
    hW13->SetMarkerColor(kMagenta);
    hW13->SetLineColor(kMagenta);
    hW13->Draw("same");

    hW23->SetMarkerStyle(26);
    hW23->SetMarkerColor(kYellow+1);
    hW23->SetLineColor(kYellow+1);
    hW23->Draw("same");

    hW11->SetMarkerStyle(21);
    hW11->SetMarkerColor(1);
    hW11->SetLineColor(1);
    hW11->GetYaxis()->SetRangeUser(0.12, 0.15);
    hW11->Draw("same");

    hW22->SetMarkerStyle(22);
    hW22->SetMarkerColor(kRed);
    hW22->SetLineColor(kRed);
    hW22->Draw("same");

    hW33->SetMarkerStyle(23);
    hW33->SetMarkerColor(kGreen);
    hW33->SetLineColor(kGreen);
    hW33->Draw("same");

    leg = new TLegend(0.8,0.6,0.95,0.95);
    leg->AddEntry(hW11, "W11", "lep");
    leg->AddEntry(hW22, "W22", "lep");
    leg->AddEntry(hW33, "W33", "lep");
    leg->AddEntry(hW12, "W12", "lep");
    leg->AddEntry(hW13, "W13", "lep");
    leg->AddEntry(hW23, "W23", "lep");
    leg->Draw();

    canv->SaveAs(Form("imgs/MNN_Width_%s.pdf", triggers.Data()));
  }
}
<commit_msg>Added legends to PHOS DrawMNN.C<commit_after>void DrawMNN()
{
  gROOT->LoadMacro("MakeRawProduction.C+g");

  RawProduction::Output output;

  const char* example1 = "kMB/pt003_hPi0M11";
  TCanvas* canv = new TCanvas(example1, example1);
  gStyle->SetOptFit(1);
  TH1* hist = output.GetHistogram(example1);
  hist->SetAxisRange(0.05, 0.3);
  hist->Draw();
  canv->SaveAs("imgs/kMB_pt003_hPi0M11.pdf");

  const char* example2 = "kMB/pt003_hPi0M12";
  TCanvas* canv = new TCanvas(example2, example2);
  gStyle->SetOptFit(1);
  TH1* hist = output.GetHistogram(example2);
  hist->SetAxisRange(0.05, 0.3);
  hist->Draw();
  canv->SaveAs(Form("imgs/kMB_pt003_hPi0M12.pdf", example2));

  TStringToken triggers("kMB kCentral kSemiCentral kPHOSPb", " ");
  while(triggers.NextToken()) {
    canv = new TCanvas(Form("cMean_%s", triggers.Data()), Form("cMean_%s", triggers.Data()));

    RawProduction::TriggerBin triggerBin(triggers);
    TH1* hM11 = output.GetHistogram("M_M11", triggerBin);
    TH1* hM12 = output.GetHistogram("M_M12", triggerBin);
    TH1* hM13 = output.GetHistogram("M_M13", triggerBin);
    TH1* hM22 = output.GetHistogram("M_M22", triggerBin);
    TH1* hM23 = output.GetHistogram("M_M23", triggerBin);
    TH1* hM33 = output.GetHistogram("M_M33", triggerBin);

    hM12->SetMarkerStyle(24);
    hM12->SetMarkerColor(kCyan+1);
    hM12->SetLineColor(kCyan+1);
    hM12->GetYaxis()->SetRangeUser(0.12, 0.15);
    hM12->SetTitle(Form("#pi^{0} Peak Mean, %s", triggers.Data()));
    hM12->GetYaxis()->SetTitle("Peak Mean");
    hM12->GetXaxis()->SetTitle("p_T");
    gStyle->SetOptStat(0);
    hM12->Draw();

    hM13->SetMarkerStyle(25);
    hM13->SetMarkerColor(kMagenta);
    hM13->SetLineColor(kMagenta);
    hM13->Draw("same");

    hM23->SetMarkerStyle(26);
    hM23->SetMarkerColor(kYellow+1);
    hM23->SetLineColor(kYellow+1);
    hM23->Draw("same");

    hM11->SetMarkerStyle(21);
    hM11->SetMarkerColor(1);
    hM11->SetLineColor(1);
    hM11->GetYaxis()->SetRangeUser(0.12, 0.15);
    hM11->Draw("same");

    hM22->SetMarkerStyle(22);
    hM22->SetMarkerColor(kRed);
    hM22->SetLineColor(kRed);
    hM22->Draw("same");

    hM33->SetMarkerStyle(23);
    hM33->SetMarkerColor(kGreen);
    hM33->SetLineColor(kGreen);
    hM33->Draw("same");

    TLegend* leg = new TLegend(0.8,0.6,0.95,0.95);
    leg->AddEntry(hM11, "M11", "lep");
    leg->AddEntry(hM22, "M22", "lep");
    leg->AddEntry(hM33, "M33", "lep");
    leg->AddEntry(hM12, "M12", "lep");
    leg->AddEntry(hM13, "M13", "lep");
    leg->AddEntry(hM23, "M23", "lep");
    leg->Draw();

    canv->SaveAs(Form("imgs/MNN_Mean_%s.pdf", triggers.Data()));

    canv = new TCanvas(Form("cWidth_%s", triggers.Data()), Form("cWidth_%s", triggers.Data()));

    TH1* hW11 = output.GetHistogram("W_M11", triggerBin);
    TH1* hW12 = output.GetHistogram("W_M12", triggerBin);
    TH1* hW13 = output.GetHistogram("W_M13", triggerBin);
    TH1* hW22 = output.GetHistogram("W_M22", triggerBin);
    TH1* hW23 = output.GetHistogram("W_M23", triggerBin);
    TH1* hW33 = output.GetHistogram("W_M33", triggerBin);

    hW12->SetMarkerStyle(24);
    hW12->SetMarkerColor(kCyan+1);
    hW12->SetLineColor(kCyan+1);
    hW12->GetYaxis()->SetRangeUser(0., 0.012);
    hW12->SetTitle(Form("#pi^{0} Peak Width, %s", triggers.Data()));
    hM12->GetYaxis()->SetTitle("Peak Width");
    hM12->GetXaxis()->SetTitle("p_T");
    gStyle->SetOptStat(0);
    hW12->Draw();

    hW13->SetMarkerStyle(25);
    hW13->SetMarkerColor(kMagenta);
    hW13->SetLineColor(kMagenta);
    hW13->Draw("same");

    hW23->SetMarkerStyle(26);
    hW23->SetMarkerColor(kYellow+1);
    hW23->SetLineColor(kYellow+1);
    hW23->Draw("same");

    hW11->SetMarkerStyle(21);
    hW11->SetMarkerColor(1);
    hW11->SetLineColor(1);
    hW11->GetYaxis()->SetRangeUser(0.12, 0.15);
    hW11->Draw("same");

    hW22->SetMarkerStyle(22);
    hW22->SetMarkerColor(kRed);
    hW22->SetLineColor(kRed);
    hW22->Draw("same");

    hW33->SetMarkerStyle(23);
    hW33->SetMarkerColor(kGreen);
    hW33->SetLineColor(kGreen);
    hW33->Draw("same");

    leg = new TLegend(0.8,0.6,0.95,0.95);
    leg->AddEntry(hW11, "M11", "lep");
    leg->AddEntry(hW22, "M22", "lep");
    leg->AddEntry(hW33, "M33", "lep");
    leg->AddEntry(hW12, "M12", "lep");
    leg->AddEntry(hW13, "M13", "lep");
    leg->AddEntry(hW23, "M23", "lep");
    leg->Draw();

    canv->SaveAs(Form("imgs/MNN_Width_%s.pdf", triggers.Data()));
  }
}
<|endoftext|>