<commit_before>#pragma once

#include <utility>
#include <agency/execution_categories.hpp>
#include <agency/executor_traits.hpp>
#include <agency/detail/tuple.hpp>
#include <agency/functional.hpp>
#include <agency/detail/index_tuple.hpp>
#include <agency/detail/tuple_utility.hpp>
#include <agency/detail/make_tuple_if_not_nested.hpp>
#include <agency/detail/unwrap_tuple_if_not_nested.hpp>

namespace agency
{

template<class Executor1, class Executor2>
class nested_executor
{
  public:
    using outer_executor_type = Executor1;
    using inner_executor_type = Executor2;

  private:
    using outer_traits = executor_traits<outer_executor_type>;
    using inner_traits = executor_traits<inner_executor_type>;

    using outer_execution_category = typename outer_traits::execution_category;
    using inner_execution_category = typename inner_traits::execution_category;

    using outer_index_type = typename outer_traits::index_type;
    using inner_index_type = typename inner_traits::index_type;

    // XXX move this into index_tuple.hpp?
    static auto index_cat(const outer_index_type& outer_idx, const inner_index_type& inner_idx)
      -> decltype(
           __tu::tuple_cat_apply(
             detail::index_tuple_maker{},
             detail::make_tuple_if_not_nested<outer_execution_category>(outer_idx),
             detail::make_tuple_if_not_nested<inner_execution_category>(inner_idx)
           )
         )
    {
      return __tu::tuple_cat_apply(
        detail::index_tuple_maker{},
        detail::make_tuple_if_not_nested<outer_execution_category>(outer_idx),
        detail::make_tuple_if_not_nested<inner_execution_category>(inner_idx)
      );
    }

    using outer_shape_type = typename outer_traits::shape_type;
    using inner_shape_type = typename inner_traits::shape_type;

  public:
    using execution_category =
      nested_execution_tag<
        outer_execution_category,
        inner_execution_category
      >;

    // XXX consider adding a public static make_shape() function
    using shape_type = decltype(
      detail::tuple_cat(
        detail::make_tuple_if_not_nested<outer_execution_category>(std::declval<outer_shape_type>()),
        detail::make_tuple_if_not_nested<inner_execution_category>(std::declval<inner_shape_type>())
      )
    );

    using index_type = decltype(
      index_cat(
        std::declval<outer_index_type>(),
        std::declval<inner_shape_type>()
      )
    );

    template<class T>
    using future = typename outer_traits::template future<T>;

    nested_executor() = default;

    nested_executor(const outer_executor_type& outer_ex,
                    const inner_executor_type& inner_ex)
      : outer_ex_(outer_ex),
        inner_ex_(inner_ex)
    {}

    // XXX executor adaptors like nested_executor need to implement execute to be sure we get the most efficient implementation

    // XXX think we can eliminate this function
    template<class Function>
    future<void> async_execute(Function f, shape_type shape)
    {
      // split the shape into the inner & outer portions
      auto outer_shape = this->outer_shape(shape);
      auto inner_shape = this->inner_shape(shape);

      return outer_traits::async_execute(outer_executor(), [=](outer_index_type outer_idx)
      {
        inner_traits::execute(inner_executor(), [=](inner_index_type inner_idx)
        {
          f(index_cat(outer_idx, inner_idx));
        },
        inner_shape
        );
      },
      outer_shape
      );
    }

  private:
    // this is the functor used by async_execute below
    // it takes the place of a nested, polymorphic lambda function
    template<class Function, class... InnerSharedType>
    struct async_execute_outer_functor
    {
      nested_executor&                  exec;
      Function                          f;
      inner_shape_type                  inner_shape;
      detail::tuple<InnerSharedType...> inner_shared_inits;

      template<class OuterIndex, class OuterSharedType>
      struct async_execute_inner_functor
      {
        Function f;
        OuterIndex outer_idx;
        OuterSharedType& outer_shared;

        template<class InnerIndex, class... T>
        void operator()(const InnerIndex& inner_idx, T&... inner_shared)
        {
          f(index_cat(outer_idx, inner_idx), outer_shared, inner_shared...);
        }
      };

      template<size_t... Indices, class OuterIndex, class T>
      void invoke_execute(detail::index_sequence<Indices...>, const OuterIndex& outer_idx, T& outer_shared)
      {
        inner_traits::execute(exec.inner_executor(), async_execute_inner_functor<OuterIndex,T>{f, outer_idx, outer_shared}, inner_shape, detail::get<Indices>(inner_shared_inits)...);
      }

      template<class OuterIndex, class T>
      void operator()(const OuterIndex& outer_idx, T& outer_shared)
      {
        invoke_execute(detail::index_sequence_for<InnerSharedType...>(), outer_idx, outer_shared);
      }
    };

  public:
    template<class Function, class T, class... Types>
    future<void> async_execute(Function f, shape_type shape, T outer_shared_init, Types... inner_shared_inits)
    {
      // XXX should assert on execution depth rather than size of shape_type
      static_assert(std::tuple_size<shape_type>::value == 1 + sizeof...(Types), "Number of shared arguments must be the same as the size of shape_type.");

      // split the shape into the inner & outer portions
      auto outer_shape = this->outer_shape(shape);
      auto inner_shape = this->inner_shape(shape);

      return outer_traits::async_execute(
        outer_executor(),
        async_execute_outer_functor<Function,Types...>{*this, f, inner_shape, detail::make_tuple(inner_shared_inits...)},
        outer_shape,
        outer_shared_init
      );

      // XXX gcc 4.8 can't capture parameter packs
      //using outer_shared_param_type = decay_construct_result_t<T>;

      //return outer_traits::async_execute(outer_executor(), [=](const outer_index_type& outer_idx, outer_shared_param_type& outer_shared_param)
      //{
      //  inner_traits::execute(inner_executor(), async_execute_inner_functor<Function,outer_shared_param_type>{f,outer_idx,outer_shared_param}, inner_shape, inner_shared_inits...);
      //},
      //outer_shape,
      //outer_shared_init
      //);

      // XXX use this implementation upon c++14:
      //return outer_traits::async_execute(outer_executor(), [=](const auto& outer_idx, auto& outer_shared_param)
      //{
      //  inner_traits::execute(inner_executor(), [=,&outer_shared_param](const auto& inner_idx, auto&... inner_shared_parms)
      //  {
      //    f(index_cat(outer_idx, inner_idx), outer_shared_param, inner_shared_params...);
      //  },
      //  inner_shape,
      //  inner_shared_inits...
      //  );
      //},
      //outer_shape,
      //outer_shared_init
      //);
    }

    outer_executor_type& outer_executor()
    {
      return outer_ex_;
    }

    const outer_executor_type& outer_executor() const
    {
      return outer_ex_;
    }

    inner_executor_type& inner_executor()
    {
      return inner_ex_;
    }

    const inner_executor_type& inner_executor() const
    {
      return inner_ex_;
    }

  private:
    static outer_shape_type outer_shape(const shape_type& shape)
    {
      // the outer portion is always the head of the tuple
      return __tu::tuple_head(shape);
    }

    static inner_shape_type inner_shape(const shape_type& shape)
    {
      // the inner portion is the tail of the tuple, but if the
      // inner executor is not nested, then the tuple needs to be unwrapped
      return detail::unwrap_tuple_if_not_nested<inner_execution_category>(detail::forward_tail(shape));
    }

    outer_executor_type outer_ex_;
    inner_executor_type inner_ex_;
};

} // end agency

<commit_msg>Receive shared initializers by forwarding reference in nested_executor<commit_after>#pragma once

#include <utility>
#include <agency/execution_categories.hpp>
#include <agency/executor_traits.hpp>
#include <agency/detail/tuple.hpp>
#include <agency/functional.hpp>
#include <agency/detail/index_tuple.hpp>
#include <agency/detail/tuple_utility.hpp>
#include <agency/detail/make_tuple_if_not_nested.hpp>
#include <agency/detail/unwrap_tuple_if_not_nested.hpp>

namespace agency
{

template<class Executor1, class Executor2>
class nested_executor
{
  public:
    using outer_executor_type = Executor1;
    using inner_executor_type = Executor2;

  private:
    using outer_traits = executor_traits<outer_executor_type>;
    using inner_traits = executor_traits<inner_executor_type>;

    using outer_execution_category = typename outer_traits::execution_category;
    using inner_execution_category = typename inner_traits::execution_category;

    using outer_index_type = typename outer_traits::index_type;
    using inner_index_type = typename inner_traits::index_type;

    // XXX move this into index_tuple.hpp?
    static auto index_cat(const outer_index_type& outer_idx, const inner_index_type& inner_idx)
      -> decltype(
           __tu::tuple_cat_apply(
             detail::index_tuple_maker{},
             detail::make_tuple_if_not_nested<outer_execution_category>(outer_idx),
             detail::make_tuple_if_not_nested<inner_execution_category>(inner_idx)
           )
         )
    {
      return __tu::tuple_cat_apply(
        detail::index_tuple_maker{},
        detail::make_tuple_if_not_nested<outer_execution_category>(outer_idx),
        detail::make_tuple_if_not_nested<inner_execution_category>(inner_idx)
      );
    }

    using outer_shape_type = typename outer_traits::shape_type;
    using inner_shape_type = typename inner_traits::shape_type;

  public:
    using execution_category =
      nested_execution_tag<
        outer_execution_category,
        inner_execution_category
      >;

    // XXX consider adding a public static make_shape() function
    using shape_type = decltype(
      detail::tuple_cat(
        detail::make_tuple_if_not_nested<outer_execution_category>(std::declval<outer_shape_type>()),
        detail::make_tuple_if_not_nested<inner_execution_category>(std::declval<inner_shape_type>())
      )
    );

    using index_type = decltype(
      index_cat(
        std::declval<outer_index_type>(),
        std::declval<inner_shape_type>()
      )
    );

    template<class T>
    using future = typename outer_traits::template future<T>;

    nested_executor() = default;

    nested_executor(const outer_executor_type& outer_ex,
                    const inner_executor_type& inner_ex)
      : outer_ex_(outer_ex),
        inner_ex_(inner_ex)
    {}

    // XXX executor adaptors like nested_executor need to implement execute to be sure we get the most efficient implementation

    // XXX think we can eliminate this function
    template<class Function>
    future<void> async_execute(Function f, shape_type shape)
    {
      // split the shape into the inner & outer portions
      auto outer_shape = this->outer_shape(shape);
      auto inner_shape = this->inner_shape(shape);

      return outer_traits::async_execute(outer_executor(), [=](outer_index_type outer_idx)
      {
        inner_traits::execute(inner_executor(), [=](inner_index_type inner_idx)
        {
          f(index_cat(outer_idx, inner_idx));
        },
        inner_shape
        );
      },
      outer_shape
      );
    }

  private:
    // this is the functor used by async_execute below
    // it takes the place of a nested, polymorphic lambda function
    template<class Function, class... InnerSharedType>
    struct async_execute_outer_functor
    {
      nested_executor&                  exec;
      Function                          f;
      inner_shape_type                  inner_shape;
      detail::tuple<InnerSharedType...> inner_shared_inits;

      template<class OuterIndex, class OuterSharedType>
      struct async_execute_inner_functor
      {
        Function f;
        OuterIndex outer_idx;
        OuterSharedType& outer_shared;

        template<class InnerIndex, class... T>
        void operator()(const InnerIndex& inner_idx, T&... inner_shared)
        {
          f(index_cat(outer_idx, inner_idx), outer_shared, inner_shared...);
        }
      };

      template<size_t... Indices, class OuterIndex, class T>
      void invoke_execute(detail::index_sequence<Indices...>, const OuterIndex& outer_idx, T& outer_shared)
      {
        inner_traits::execute(exec.inner_executor(), async_execute_inner_functor<OuterIndex,T>{f, outer_idx, outer_shared}, inner_shape, detail::get<Indices>(inner_shared_inits)...);
      }

      template<class OuterIndex, class T>
      void operator()(const OuterIndex& outer_idx, T& outer_shared)
      {
        invoke_execute(detail::index_sequence_for<InnerSharedType...>(), outer_idx, outer_shared);
      }
    };

  public:
    template<class Function, class T, class... Types>
    future<void> async_execute(Function f, shape_type shape, T&& outer_shared_init, Types&&... inner_shared_inits)
    {
      // XXX should assert on execution depth rather than size of shape_type
      static_assert(std::tuple_size<shape_type>::value == 1 + sizeof...(Types), "Number of shared arguments must be the same as the size of shape_type.");

      // split the shape into the inner & outer portions
      auto outer_shape = this->outer_shape(shape);
      auto inner_shape = this->inner_shape(shape);

      return outer_traits::async_execute(
        outer_executor(),
        async_execute_outer_functor<Function,typename std::decay<Types>::type...>{*this, f, inner_shape, detail::forward_as_tuple(inner_shared_inits...)},
        outer_shape,
        std::forward<T>(outer_shared_init)
      );

      // XXX gcc 4.8 can't capture parameter packs
      //using outer_shared_param_type = decay_construct_result_t<T>;

      //return outer_traits::async_execute(outer_executor(), [=](const outer_index_type& outer_idx, outer_shared_param_type& outer_shared_param)
      //{
      //  inner_traits::execute(inner_executor(), async_execute_inner_functor<Function,outer_shared_param_type>{f,outer_idx,outer_shared_param}, inner_shape, inner_shared_inits...);
      //},
      //outer_shape,
      //outer_shared_init
      //);

      // XXX use this implementation upon c++14:
      //return outer_traits::async_execute(outer_executor(), [=](const auto& outer_idx, auto& outer_shared_param)
      //{
      //  inner_traits::execute(inner_executor(), [=,&outer_shared_param](const auto& inner_idx, auto&... inner_shared_parms)
      //  {
      //    f(index_cat(outer_idx, inner_idx), outer_shared_param, inner_shared_params...);
      //  },
      //  inner_shape,
      //  inner_shared_inits...
      //  );
      //},
      //outer_shape,
      //outer_shared_init
      //);
    }

    outer_executor_type& outer_executor()
    {
      return outer_ex_;
    }

    const outer_executor_type& outer_executor() const
    {
      return outer_ex_;
    }

    inner_executor_type& inner_executor()
    {
      return inner_ex_;
    }

    const inner_executor_type& inner_executor() const
    {
      return inner_ex_;
    }

  private:
    static outer_shape_type outer_shape(const shape_type& shape)
    {
      // the outer portion is always the head of the tuple
      return __tu::tuple_head(shape);
    }

    static inner_shape_type inner_shape(const shape_type& shape)
    {
      // the inner portion is the tail of the tuple, but if the
      // inner executor is not nested, then the tuple needs to be unwrapped
      return detail::unwrap_tuple_if_not_nested<inner_execution_category>(detail::forward_tail(shape));
    }

    outer_executor_type outer_ex_;
    inner_executor_type inner_ex_;
};

} // end agency

<|endoftext|>


<commit_before>#ifndef UTIL_LANG_RANGE_HPP
#define UTIL_LANG_RANGE_HPP

#include <iterator>
#include <type_traits>

namespace util { namespace lang {

namespace detail {

template <typename T>
struct range_iter_base : std::iterator<std::input_iterator_tag, T> {
    range_iter_base(T current) : current(current) { }

    T operator *() const { return current; }

    T const* operator ->() const { return &current; }

    range_iter_base& operator ++() {
        ++current;
        return *this;
    }

    range_iter_base operator ++(int) {
        auto copy = *this;
        ++*this;
        return copy;
    }

    bool operator ==(range_iter_base const& other) const {
        return current == other.current;
    }

    bool operator !=(range_iter_base const& other) const {
        return not (*this == other);
    }

protected:
    T current;
};

} // namespace detail

template <typename T>
struct range_proxy {
    struct iter : detail::range_iter_base<T> {
        iter(T current) : detail::range_iter_base<T>(current) { }
    };

    struct step_range_proxy {
        struct iter : detail::range_iter_base<T> {
            iter(T current, T step)
                : detail::range_iter_base<T>(current), step(step) { }

            using detail::range_iter_base<T>::current;

            iter& operator ++() {
                current += step;
                return *this;
            }

            iter operator ++(int) {
                auto copy = *this;
                ++*this;
                return copy;
            }

            // Loses commutativity. Iterator-based ranges are simply broken. :-(
            bool operator ==(iter const& other) const {
                return step > 0 ? current >= other.current
                                : current < other.current;
            }

            bool operator !=(iter const& other) const {
                return not (*this == other);
            }

        private:
            T step;
        };

        step_range_proxy(T begin, T end, T step)
            : begin_(begin, step), end_(end, step) { }

        iter begin() const { return begin_; }

        iter end() const { return end_; }

    private:
        iter begin_;
        iter end_;
    };

    range_proxy(T begin, T end) : begin_(begin), end_(end) { }

    step_range_proxy step(T step) {
        return {*begin_, *end_, step};
    }

    iter begin() const { return begin_; }

    iter end() const { return end_; }

private:
    iter begin_;
    iter end_;
};

template <typename T>
struct infinite_range_proxy {
    struct iter : detail::range_iter_base<T> {
        iter(T current = T()) : detail::range_iter_base<T>(current) { }

        bool operator ==(iter const&) const { return false; }

        bool operator !=(iter const&) const { return true; }
    };

    struct step_range_proxy {
        struct iter : detail::range_iter_base<T> {
            iter(T current = T(), T step = T())
                : detail::range_iter_base<T>(current), step(step) { }

            using detail::range_iter_base<T>::current;

            iter& operator ++() {
                current += step;
                return *this;
            }

            iter operator ++(int) {
                auto copy = *this;
                ++*this;
                return copy;
            }

            bool operator ==(iter const&) const { return false; }

            bool operator !=(iter const&) const { return true; }

        private:
            T step;
        };

        step_range_proxy(T begin, T step) : begin_(begin, step) { }

        iter begin() const { return begin_; }

        iter end() const { return  iter(); }

    private:
        iter begin_;
    };

    infinite_range_proxy(T begin) : begin_(begin) { }

    step_range_proxy step(T step) {
        return step_range_proxy(*begin_, step);
    }

    iter begin() const { return begin_; }

    iter end() const { return iter(); }

private:
    iter begin_;
};

template <typename T>
range_proxy<T> range(T begin, T end) {
    return {begin, end};
}

template <typename T>
infinite_range_proxy<T> range(T begin) {
    return {begin};
}

namespace traits {

template <typename C>
struct has_size {
    template <typename T>
    static constexpr auto check(T*) ->
        typename std::is_integral<
            decltype(std::declval<T const>().size())>::type;

    template <typename>
    static constexpr auto check(...) -> std::false_type;

    using type = decltype(check<C>(0));
    static constexpr bool value = type::value;
};

} // namespace traits

template <typename C, typename = typename std::enable_if<traits::has_size<C>::value>>
auto indices(C const& cont) -> range_proxy<decltype(cont.size())> {
    return {0, cont.size()};
}

template <typename T, std::size_t N>
range_proxy<std::size_t> indices(T (&)[N]) {
    return {0, N};
}

template <typename T>
range_proxy<typename std::initializer_list<T>::size_type>
indices(std::initializer_list<T>&& cont) {
    return {0, cont.size()};
}

} } // namespace util::lang

#endif // ndef UTIL_LANG_RANGE_HPP
<commit_msg>Make range utilities usable in CUDA __device__ functions when compiled with nvcc.<commit_after>#ifndef UTIL_LANG_RANGE_HPP
#define UTIL_LANG_RANGE_HPP

#include <iterator>
#include <type_traits>

// Make these ranges usable inside CUDA C++ device code
#ifdef __CUDACC__
#define DEVICE_CALLABLE __host__ __device__
#else
#define DEVICE_CALLABLE
#endif

namespace util { namespace lang {

namespace detail {

template <typename T>
struct range_iter_base : std::iterator<std::input_iterator_tag, T> {
    DEVICE_CALLABLE
    range_iter_base(T current) : current(current) { }

    DEVICE_CALLABLE
    T operator *() const { return current; }

    DEVICE_CALLABLE
    T const* operator ->() const { return &current; }

    DEVICE_CALLABLE
    range_iter_base& operator ++() {
        ++current;
        return *this;
    }

    DEVICE_CALLABLE
    range_iter_base operator ++(int) {
        auto copy = *this;
        ++*this;
        return copy;
    }

    DEVICE_CALLABLE
    bool operator ==(range_iter_base const& other) const {
        return current == other.current;
    }

    DEVICE_CALLABLE
    bool operator !=(range_iter_base const& other) const {
        return not (*this == other);
    }

protected:
    T current;
};

} // namespace detail

template <typename T>
struct range_proxy {
    struct iter : detail::range_iter_base<T> {
        DEVICE_CALLABLE
        iter(T current) : detail::range_iter_base<T>(current) { }
    };

    struct step_range_proxy {
        struct iter : detail::range_iter_base<T> {
            DEVICE_CALLABLE
            iter(T current, T step)
                : detail::range_iter_base<T>(current), step(step) { }

            using detail::range_iter_base<T>::current;

            DEVICE_CALLABLE
            iter& operator ++() {
                current += step;
                return *this;
            }

            DEVICE_CALLABLE
            iter operator ++(int) {
                auto copy = *this;
                ++*this;
                return copy;
            }

            // Loses commutativity. Iterator-based ranges are simply broken. :-(
            DEVICE_CALLABLE
            bool operator ==(iter const& other) const {
                return step > 0 ? current >= other.current
                                : current < other.current;
            }

            DEVICE_CALLABLE
            bool operator !=(iter const& other) const {
                return not (*this == other);
            }

        private:
            T step;
        };

        DEVICE_CALLABLE
        step_range_proxy(T begin, T end, T step)
            : begin_(begin, step), end_(end, step) { }

        DEVICE_CALLABLE
        iter begin() const { return begin_; }

        DEVICE_CALLABLE
        iter end() const { return end_; }

    private:
        iter begin_;
        iter end_;
    };

    DEVICE_CALLABLE
    range_proxy(T begin, T end) : begin_(begin), end_(end) { }

    DEVICE_CALLABLE
    step_range_proxy step(T step) {
        return {*begin_, *end_, step};
    }

    DEVICE_CALLABLE
    iter begin() const { return begin_; }

    DEVICE_CALLABLE
    iter end() const { return end_; }

private:
    iter begin_;
    iter end_;
};

template <typename T>
struct infinite_range_proxy {
    struct iter : detail::range_iter_base<T> {
        DEVICE_CALLABLE
        iter(T current = T()) : detail::range_iter_base<T>(current) { }

        DEVICE_CALLABLE
        bool operator ==(iter const&) const { return false; }

        DEVICE_CALLABLE
        bool operator !=(iter const&) const { return true; }
    };

    struct step_range_proxy {
        struct iter : detail::range_iter_base<T> {
            DEVICE_CALLABLE
            iter(T current = T(), T step = T())
                : detail::range_iter_base<T>(current), step(step) { }

            using detail::range_iter_base<T>::current;

            DEVICE_CALLABLE
            iter& operator ++() {
                current += step;
                return *this;
            }

            DEVICE_CALLABLE
            iter operator ++(int) {
                auto copy = *this;
                ++*this;
                return copy;
            }

            DEVICE_CALLABLE
            bool operator ==(iter const&) const { return false; }

            DEVICE_CALLABLE
            bool operator !=(iter const&) const { return true; }

        private:
            T step;
        };

        DEVICE_CALLABLE
        step_range_proxy(T begin, T step) : begin_(begin, step) { }

        DEVICE_CALLABLE
        iter begin() const { return begin_; }

        DEVICE_CALLABLE
        iter end() const { return  iter(); }

    private:
        iter begin_;
    };

    DEVICE_CALLABLE
    infinite_range_proxy(T begin) : begin_(begin) { }

    DEVICE_CALLABLE
    step_range_proxy step(T step) {
        return step_range_proxy(*begin_, step);
    }

    DEVICE_CALLABLE
    iter begin() const { return begin_; }

    DEVICE_CALLABLE
    iter end() const { return iter(); }

private:
    iter begin_;
};

template <typename T>
DEVICE_CALLABLE
range_proxy<T> range(T begin, T end) {
    return {begin, end};
}

template <typename T>
DEVICE_CALLABLE
infinite_range_proxy<T> range(T begin) {
    return {begin};
}

namespace traits {

template <typename C>
struct has_size {
    template <typename T>
    static constexpr auto check(T*) ->
        typename std::is_integral<
            decltype(std::declval<T const>().size())>::type;

    template <typename>
    static constexpr auto check(...) -> std::false_type;

    using type = decltype(check<C>(0));
    static constexpr bool value = type::value;
};

} // namespace traits

template <typename C, typename = typename std::enable_if<traits::has_size<C>::value>>
DEVICE_CALLABLE
auto indices(C const& cont) -> range_proxy<decltype(cont.size())> {
    return {0, cont.size()};
}

template <typename T, std::size_t N>
DEVICE_CALLABLE
range_proxy<std::size_t> indices(T (&)[N]) {
    return {0, N};
}

template <typename T>
range_proxy<typename std::initializer_list<T>::size_type>
DEVICE_CALLABLE
indices(std::initializer_list<T>&& cont) {
    return {0, cont.size()};
}

} } // namespace util::lang

#endif // ndef UTIL_LANG_RANGE_HPP
<|endoftext|>


<commit_before>/*
 * Markdown.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/markdown/Markdown.hpp>

#include <iostream>

#include <boost/scoped_ptr.hpp>

#include <core/Error.hpp>
#include <core/FilePath.hpp>
#include <core/StringUtils.hpp>
#include <core/FileSerializer.hpp>

#include "MathJax.hpp"

#include "sundown/markdown.h"
#include "sundown/html.h"

namespace core {
namespace markdown {

namespace {

class SundownBuffer : boost::noncopyable
{
public:
   explicit SundownBuffer(std::size_t unit = 128)
      : pBuff_(NULL)
   {
      pBuff_ = ::bufnew(unit);
   }

   explicit SundownBuffer(const std::string& str)
   {
      pBuff_ = ::bufnew(str.length());
      if (pBuff_ != NULL)
      {
         if (grow(str.length()) == BUF_OK)
         {
            put(str);
         }
         else
         {
            ::bufrelease(pBuff_);
            pBuff_ = NULL;
         }
      }
   }

   ~SundownBuffer()
   {
      if (pBuff_)
         ::bufrelease(pBuff_);
   }

   // COPYING: prohibited (boost::noncopyable)

   bool allocated() const { return pBuff_ != NULL; }

   int grow(std::size_t size)
   {
      return ::bufgrow(pBuff_, size);
   }

   void put(const std::string& str)
   {
      ::bufput(pBuff_, str.data(), str.length());
   }

   uint8_t* data() const
   {
      return pBuff_->data;
   }

   std::size_t size() const
   {
      return pBuff_->size;
   }

   const char* c_str() const
   {
      return ::bufcstr(pBuff_);
   }

   operator buf*() const
   {
      return pBuff_;
   }

private:
   friend class SundownMarkdown;
   buf* pBuff_;
};

class SundownMarkdown : boost::noncopyable
{
public:
   SundownMarkdown(unsigned int extensions,
                   size_t maxNesting,
                   const struct sd_callbacks* pCallbacks,
                   void *pOpaque)
      : pMD_(NULL)
   {
      pMD_ = ::sd_markdown_new(extensions, maxNesting,  pCallbacks, pOpaque);
   }

   ~SundownMarkdown()
   {
      if (pMD_)
         ::sd_markdown_free(pMD_);
   }

   // COPYING: prohibited (boost::noncopyable)

   bool allocated() const { return pMD_ != NULL; }

   void render(const SundownBuffer& input, SundownBuffer* pOutput)
   {
      ::sd_markdown_render(pOutput->pBuff_,
                           input.pBuff_->data,
                           input.pBuff_->size,
                           pMD_);
   }

private:
   struct sd_markdown* pMD_;
};

Error allocationError(const ErrorLocation& location)
{
   return systemError(boost::system::errc::not_enough_memory, location);
}

Error renderMarkdown(const SundownBuffer& inputBuffer,
                     const Extensions& extensions,
                     bool smartypants,
                     struct sd_callbacks* pHtmlCallbacks,
                     struct html_renderopt* pHtmlOptions,
                     std::string* pOutput)
{
   // render markdown
   const int kMaxNesting = 16;
   int mdExt = 0;
   if (extensions.noIntraEmphasis)
      mdExt |= MKDEXT_NO_INTRA_EMPHASIS;
   if (extensions.tables)
      mdExt |= MKDEXT_TABLES;
   if (extensions.fencedCode)
      mdExt |= MKDEXT_FENCED_CODE;
   if (extensions.autolink)
      mdExt |= MKDEXT_AUTOLINK;
   if (extensions.strikethrough)
      mdExt |= MKDEXT_STRIKETHROUGH;
   if (extensions.laxSpacing)
      mdExt |= MKDEXT_LAX_SPACING;
   if (extensions.spaceHeaders)
      mdExt |= MKDEXT_SPACE_HEADERS;
   if (extensions.superscript)
      mdExt |= MKDEXT_SUPERSCRIPT;

   SundownMarkdown md(mdExt, kMaxNesting, pHtmlCallbacks, pHtmlOptions);
   if (!md.allocated())
      return allocationError(ERROR_LOCATION);
   SundownBuffer outputBuffer;
   md.render(inputBuffer, &outputBuffer);

   // do smartypants substitution if requested
   if (smartypants)
   {
      SundownBuffer smartyBuffer;
      if (!smartyBuffer.allocated())
         return allocationError(ERROR_LOCATION);

      ::sdhtml_smartypants(smartyBuffer,
                           outputBuffer.data(),
                           outputBuffer.size());

      *pOutput = smartyBuffer.c_str();
   }
   else
   {
      *pOutput = outputBuffer.c_str();
   }

   return Success();
}

} // anonymous namespace

// render markdown to HTML -- assumes UTF-8 encoding
Error markdownToHTML(const FilePath& markdownFile,
                     const Extensions& extensions,
                     const HTMLOptions& options,
                     const FilePath& htmlFile)
{
   std::string markdownOutput;
   Error error = markdownToHTML(markdownFile,
                                extensions,
                                options,
                                &markdownOutput);
   if (error)
      return error;

   return core::writeStringToFile(htmlFile,
                                  markdownOutput,
                                  string_utils::LineEndingNative);
}

// render markdown to HTML -- assumes UTF-8 encoding
Error markdownToHTML(const FilePath& markdownFile,
                     const Extensions& extensions,
                     const HTMLOptions& options,
                     std::string* pHTMLOutput)
{
   std::string markdownInput;
   Error error = core::readStringFromFile(markdownFile,
                                          &markdownInput,
                                          string_utils::LineEndingPosix);
   if (error)
      return error;

   return markdownToHTML(markdownInput, extensions, options, pHTMLOutput);
}

// render markdown to HTML -- assumes UTF-8 encoding
Error markdownToHTML(const std::string& markdownInput,
                     const Extensions& extensions,
                     const HTMLOptions& options,
                     std::string* pHTMLOutput)

{
   // exclude fenced code blocks
   std::vector<ExcludePattern> excludePatterns;
   excludePatterns.push_back(ExcludePattern(boost::regex("^`{3,}.*?$"),
                                            boost::regex("^`{3,}\\s*$")));

   // exclude inline verbatim code
   excludePatterns.push_back(ExcludePattern(boost::regex("`.+?`")));

   // exclude indented code blocks
   excludePatterns.push_back(ExcludePattern(
      boost::regex("(\\A|\\A\\s*\\n|\\n\\s*\\n)(( {4}|\\t)[^\\n]*\\n)*(( {4}|\\t)[^\\n]*)")));

   std::string input = markdownInput;
   boost::scoped_ptr<MathJaxFilter> pMathFilter;
   if (extensions.ignoreMath)
   {
      pMathFilter.reset(new MathJaxFilter(excludePatterns,
                                          &input,
                                          pHTMLOutput));
   }

   // setup input buffer
   SundownBuffer inputBuffer(input);
   if (!inputBuffer.allocated())
      return allocationError(ERROR_LOCATION);

   // render table of contents if requested
   if (options.toc)
   {
      struct sd_callbacks htmlCallbacks;
      struct html_renderopt htmlOptions;
      ::sdhtml_toc_renderer(&htmlCallbacks, &htmlOptions);
      std::string tocOutput;
      Error error = renderMarkdown(inputBuffer,
                                   extensions,
                                   options.smartypants,
                                   &htmlCallbacks,
                                   &htmlOptions,
                                   &tocOutput);
      if (error)
         return error;
      pHTMLOutput->append("
\n");
      pHTMLOutput->append("
Table of Contents
\n");
      pHTMLOutput->append(tocOutput);
      pHTMLOutput->append("
\n");
      pHTMLOutput->append("\n");
   }

   // setup html renderer
   struct sd_callbacks htmlCallbacks;
   struct html_renderopt htmlOptions;
   int htmlRenderMode = 0;
   if (options.useXHTML)
      htmlRenderMode |= HTML_USE_XHTML;
   if (options.hardWrap)
      htmlRenderMode |= HTML_HARD_WRAP;
   if (options.toc)
      htmlRenderMode |= HTML_TOC;
   if (options.safelink)
      htmlRenderMode |= HTML_SAFELINK;
   if (options.skipHTML)
      htmlRenderMode |= HTML_SKIP_HTML;
   if (options.skipStyle)
      htmlRenderMode |= HTML_SKIP_STYLE;
   if (options.skipImages)
      htmlRenderMode |= HTML_SKIP_IMAGES;
   if (options.skipLinks)
      htmlRenderMode |= HTML_SKIP_LINKS;
   if (options.escape)
      htmlRenderMode |= HTML_ESCAPE;
   ::sdhtml_renderer(&htmlCallbacks, &htmlOptions, htmlRenderMode);

   // render page
   std::string output;
   Error error = renderMarkdown(inputBuffer,
                                extensions,
                                options.smartypants,
                                &htmlCallbacks,
                                &htmlOptions,
                                &output);
   if (error)
      return error;

   // append output and return success
   pHTMLOutput->append(output);
   return Success();
}

bool isMathJaxRequired(const std::string& htmlOutput)
{
   return requiresMathjax(htmlOutput);
}

} // namespace markdown
} // namespace core

<commit_msg>Tweak regexes to account for Boost . matching \n<commit_after>/*
 * Markdown.cpp
 *
 * Copyright (C) 2009-12 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include <core/markdown/Markdown.hpp>

#include <iostream>

#include <boost/scoped_ptr.hpp>

#include <core/Error.hpp>
#include <core/FilePath.hpp>
#include <core/StringUtils.hpp>
#include <core/FileSerializer.hpp>

#include "MathJax.hpp"

#include "sundown/markdown.h"
#include "sundown/html.h"

namespace core {
namespace markdown {

namespace {

class SundownBuffer : boost::noncopyable
{
public:
   explicit SundownBuffer(std::size_t unit = 128)
      : pBuff_(NULL)
   {
      pBuff_ = ::bufnew(unit);
   }

   explicit SundownBuffer(const std::string& str)
   {
      pBuff_ = ::bufnew(str.length());
      if (pBuff_ != NULL)
      {
         if (grow(str.length()) == BUF_OK)
         {
            put(str);
         }
         else
         {
            ::bufrelease(pBuff_);
            pBuff_ = NULL;
         }
      }
   }

   ~SundownBuffer()
   {
      if (pBuff_)
         ::bufrelease(pBuff_);
   }

   // COPYING: prohibited (boost::noncopyable)

   bool allocated() const { return pBuff_ != NULL; }

   int grow(std::size_t size)
   {
      return ::bufgrow(pBuff_, size);
   }

   void put(const std::string& str)
   {
      ::bufput(pBuff_, str.data(), str.length());
   }

   uint8_t* data() const
   {
      return pBuff_->data;
   }

   std::size_t size() const
   {
      return pBuff_->size;
   }

   const char* c_str() const
   {
      return ::bufcstr(pBuff_);
   }

   operator buf*() const
   {
      return pBuff_;
   }

private:
   friend class SundownMarkdown;
   buf* pBuff_;
};

class SundownMarkdown : boost::noncopyable
{
public:
   SundownMarkdown(unsigned int extensions,
                   size_t maxNesting,
                   const struct sd_callbacks* pCallbacks,
                   void *pOpaque)
      : pMD_(NULL)
   {
      pMD_ = ::sd_markdown_new(extensions, maxNesting,  pCallbacks, pOpaque);
   }

   ~SundownMarkdown()
   {
      if (pMD_)
         ::sd_markdown_free(pMD_);
   }

   // COPYING: prohibited (boost::noncopyable)

   bool allocated() const { return pMD_ != NULL; }

   void render(const SundownBuffer& input, SundownBuffer* pOutput)
   {
      ::sd_markdown_render(pOutput->pBuff_,
                           input.pBuff_->data,
                           input.pBuff_->size,
                           pMD_);
   }

private:
   struct sd_markdown* pMD_;
};

Error allocationError(const ErrorLocation& location)
{
   return systemError(boost::system::errc::not_enough_memory, location);
}

Error renderMarkdown(const SundownBuffer& inputBuffer,
                     const Extensions& extensions,
                     bool smartypants,
                     struct sd_callbacks* pHtmlCallbacks,
                     struct html_renderopt* pHtmlOptions,
                     std::string* pOutput)
{
   // render markdown
   const int kMaxNesting = 16;
   int mdExt = 0;
   if (extensions.noIntraEmphasis)
      mdExt |= MKDEXT_NO_INTRA_EMPHASIS;
   if (extensions.tables)
      mdExt |= MKDEXT_TABLES;
   if (extensions.fencedCode)
      mdExt |= MKDEXT_FENCED_CODE;
   if (extensions.autolink)
      mdExt |= MKDEXT_AUTOLINK;
   if (extensions.strikethrough)
      mdExt |= MKDEXT_STRIKETHROUGH;
   if (extensions.laxSpacing)
      mdExt |= MKDEXT_LAX_SPACING;
   if (extensions.spaceHeaders)
      mdExt |= MKDEXT_SPACE_HEADERS;
   if (extensions.superscript)
      mdExt |= MKDEXT_SUPERSCRIPT;

   SundownMarkdown md(mdExt, kMaxNesting, pHtmlCallbacks, pHtmlOptions);
   if (!md.allocated())
      return allocationError(ERROR_LOCATION);
   SundownBuffer outputBuffer;
   md.render(inputBuffer, &outputBuffer);

   // do smartypants substitution if requested
   if (smartypants)
   {
      SundownBuffer smartyBuffer;
      if (!smartyBuffer.allocated())
         return allocationError(ERROR_LOCATION);

      ::sdhtml_smartypants(smartyBuffer,
                           outputBuffer.data(),
                           outputBuffer.size());

      *pOutput = smartyBuffer.c_str();
   }
   else
   {
      *pOutput = outputBuffer.c_str();
   }

   return Success();
}

} // anonymous namespace

// render markdown to HTML -- assumes UTF-8 encoding
Error markdownToHTML(const FilePath& markdownFile,
                     const Extensions& extensions,
                     const HTMLOptions& options,
                     const FilePath& htmlFile)
{
   std::string markdownOutput;
   Error error = markdownToHTML(markdownFile,
                                extensions,
                                options,
                                &markdownOutput);
   if (error)
      return error;

   return core::writeStringToFile(htmlFile,
                                  markdownOutput,
                                  string_utils::LineEndingNative);
}

// render markdown to HTML -- assumes UTF-8 encoding
Error markdownToHTML(const FilePath& markdownFile,
                     const Extensions& extensions,
                     const HTMLOptions& options,
                     std::string* pHTMLOutput)
{
   std::string markdownInput;
   Error error = core::readStringFromFile(markdownFile,
                                          &markdownInput,
                                          string_utils::LineEndingPosix);
   if (error)
      return error;

   return markdownToHTML(markdownInput, extensions, options, pHTMLOutput);
}

// render markdown to HTML -- assumes UTF-8 encoding
Error markdownToHTML(const std::string& markdownInput,
                     const Extensions& extensions,
                     const HTMLOptions& options,
                     std::string* pHTMLOutput)

{
   // exclude fenced code blocks
   std::vector<ExcludePattern> excludePatterns;
   excludePatterns.push_back(ExcludePattern(boost::regex("^`{3,}[^\\n]*?$"),
                                            boost::regex("^`{3,}\\s*$")));

   // exclude inline verbatim code
   excludePatterns.push_back(ExcludePattern(boost::regex("`[^\\n]+?`")));

   // exclude indented code blocks
   excludePatterns.push_back(ExcludePattern(
      boost::regex("(\\A|\\A\\s*\\n|\\n\\s*\\n)(( {4}|\\t)[^\\n]*\\n)*(( {4}|\\t)[^\\n]*)")));

   std::string input = markdownInput;
   boost::scoped_ptr<MathJaxFilter> pMathFilter;
   if (extensions.ignoreMath)
   {
      pMathFilter.reset(new MathJaxFilter(excludePatterns,
                                          &input,
                                          pHTMLOutput));
   }

   // setup input buffer
   SundownBuffer inputBuffer(input);
   if (!inputBuffer.allocated())
      return allocationError(ERROR_LOCATION);

   // render table of contents if requested
   if (options.toc)
   {
      struct sd_callbacks htmlCallbacks;
      struct html_renderopt htmlOptions;
      ::sdhtml_toc_renderer(&htmlCallbacks, &htmlOptions);
      std::string tocOutput;
      Error error = renderMarkdown(inputBuffer,
                                   extensions,
                                   options.smartypants,
                                   &htmlCallbacks,
                                   &htmlOptions,
                                   &tocOutput);
      if (error)
         return error;
      pHTMLOutput->append("
\n");
      pHTMLOutput->append("
Table of Contents
\n");
      pHTMLOutput->append(tocOutput);
      pHTMLOutput->append("
\n");
      pHTMLOutput->append("\n");
   }

   // setup html renderer
   struct sd_callbacks htmlCallbacks;
   struct html_renderopt htmlOptions;
   int htmlRenderMode = 0;
   if (options.useXHTML)
      htmlRenderMode |= HTML_USE_XHTML;
   if (options.hardWrap)
      htmlRenderMode |= HTML_HARD_WRAP;
   if (options.toc)
      htmlRenderMode |= HTML_TOC;
   if (options.safelink)
      htmlRenderMode |= HTML_SAFELINK;
   if (options.skipHTML)
      htmlRenderMode |= HTML_SKIP_HTML;
   if (options.skipStyle)
      htmlRenderMode |= HTML_SKIP_STYLE;
   if (options.skipImages)
      htmlRenderMode |= HTML_SKIP_IMAGES;
   if (options.skipLinks)
      htmlRenderMode |= HTML_SKIP_LINKS;
   if (options.escape)
      htmlRenderMode |= HTML_ESCAPE;
   ::sdhtml_renderer(&htmlCallbacks, &htmlOptions, htmlRenderMode);

   // render page
   std::string output;
   Error error = renderMarkdown(inputBuffer,
                                extensions,
                                options.smartypants,
                                &htmlCallbacks,
                                &htmlOptions,
                                &output);
   if (error)
      return error;

   // append output and return success
   pHTMLOutput->append(output);
   return Success();
}

bool isMathJaxRequired(const std::string& htmlOutput)
{
   return requiresMathjax(htmlOutput);
}

} // namespace markdown
} // namespace core

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestPStream.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkCompositeManager.h"
#include "vtkDebugLeaks.h"
#include "vtkDistributedStreamTracer.h"
#include "vtkLineSource.h"
#include "vtkLookupTable.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
#include "vtkPLOT3DReader.h"
#include "vtkPVGeometryFilter.h"
#include "vtkParallelFactory.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkStructuredGrid.h"

struct PStreamArgs_tmp
{
  int* retVal;
  int argc;
  char** argv;
};

// This will be called by all processes
void MyMain( vtkMultiProcessController *controller, void *arg )
{

  PStreamArgs_tmp* args =
    reinterpret_cast<PStreamArgs_tmp*>(arg);

  int myId = controller->GetLocalProcessId();
  int numProcs = controller->GetNumberOfProcesses();

  vtkRenderer* ren = vtkRenderer::New();
  ren->SetBackground(0.33, 0.35, 0.43);

  vtkRenderWindow* renWin = vtkRenderWindow::New();
  renWin->AddRenderer(ren);
  renWin->SetSize(400, 300);
  renWin->SetPosition(410*myId, 0);

  //camera parameters
  vtkCamera* camera = ren->GetActiveCamera();
  camera->SetPosition(-5.86786, 49.2857, 51.597);
  camera->SetFocalPoint(8.255, -3.17482e-16, 29.7631);
  camera->SetViewUp(-0.112182, -0.42918, 0.896225);
  camera->SetViewAngle(30);
  camera->SetClippingRange(10.0, 80.6592);
  camera->Dolly(1.5);

  // Create the reader, the data file name might have
  // to be changed depending on where the data files are.
  char* fname1 = vtkTestUtilities::ExpandDataFileName(args->argc, args->argv,
                                                     "Data/combxyz.bin");
  char* fname2 = vtkTestUtilities::ExpandDataFileName(args->argc, args->argv,
                                                     "Data/combq.bin");
  vtkPLOT3DReader* Plot3D0 = vtkPLOT3DReader::New();
  Plot3D0->SetFileName(fname1);
  Plot3D0->SetQFileName (fname2);
  Plot3D0->SetBinaryFile(1);
  Plot3D0->SetMultiGrid(0);
  Plot3D0->SetHasByteCount(0);
  Plot3D0->SetIBlanking(0);
  Plot3D0->SetTwoDimensionalGeometry(0);
  Plot3D0->SetForceRead(0);
  Plot3D0->SetByteOrder(0);
  delete[] fname1;
  delete[] fname2;

  vtkPVGeometryFilter* Geometry5 = vtkPVGeometryFilter::New();
  Geometry5->SetInput(Plot3D0->GetOutput());

  vtkPolyDataMapper* Mapper5 = vtkPolyDataMapper::New();
  Mapper5->SetInput(Geometry5->GetOutput());
  Mapper5->SetImmediateModeRendering(1);
  Mapper5->UseLookupTableScalarRangeOn();
  Mapper5->SetScalarVisibility(0);
  Mapper5->SetScalarModeToDefault();

  vtkActor* Actor5 = vtkActor::New();
  Actor5->SetMapper(Mapper5);
  vtkProperty* prop = Actor5->GetProperty();
  prop->SetRepresentationToSurface();
  prop->SetInterpolationToGouraud();
  prop->SetAmbient(0.15);
  prop->SetDiffuse(0.85);
  prop->SetSpecular(0.1);
  prop->SetSpecularPower(100);
  prop->SetSpecularColor(1, 1, 1);
  prop->SetColor(1, 1, 1);

  ren->AddActor(Actor5);

  vtkLineSource* LineSourceWidget0 = vtkLineSource::New();
  LineSourceWidget0->SetPoint1(13.9548, -0.47371, 31.7642);
  LineSourceWidget0->SetPoint2(6.3766, -0.5886, 26.6274);
  LineSourceWidget0->SetResolution(20);

  vtkDistributedStreamTracer* Stream0 = vtkDistributedStreamTracer::New();;
  Stream0->SetInput(Plot3D0->GetOutput());
  Stream0->SelectInputVectors("Momentum");
  Stream0->SetSource(LineSourceWidget0->GetOutput());
  Stream0->SetMaximumPropagationUnit(0);
  Stream0->SetMaximumPropagation(0.05);
  Stream0->SetInitialIntegrationStepUnit(2);
  Stream0->SetInitialIntegrationStep(0.5);
  Stream0->SetIntegrationDirection(2);
  Stream0->SetIntegratorType(0);
  Stream0->SetMaximumNumberOfSteps(2000);
  Stream0->SetTerminalSpeed(1e-12);

  vtkPVGeometryFilter* Geometry6 = vtkPVGeometryFilter::New();;
  Geometry6->SetInput(Stream0->GetOutput());

  vtkLookupTable* LookupTable1 = vtkLookupTable::New();
  LookupTable1->SetNumberOfTableValues(256);
  LookupTable1->SetHueRange(0, 0.66667);
  LookupTable1->SetSaturationRange(1, 1);
  LookupTable1->SetValueRange(1, 1);
  LookupTable1->SetTableRange(0.197813, 0.710419);
  LookupTable1->SetVectorComponent(0);
  LookupTable1->Build();

  vtkPolyDataMapper* Mapper6 = vtkPolyDataMapper::New();
  Mapper6->SetInput(Geometry6->GetOutput());
  Mapper6->SetImmediateModeRendering(1);
  Mapper6->UseLookupTableScalarRangeOn();
  Mapper6->SetScalarVisibility(1);
  Mapper6->SetScalarModeToUsePointFieldData();
  Mapper6->SelectColorArray("Density");
  Mapper6->SetLookupTable(LookupTable1);

  vtkActor* Actor6 = vtkActor::New();
  Actor6->SetMapper(Mapper6);
  prop = Actor6->GetProperty();
  prop->SetRepresentationToSurface();
  prop->SetInterpolationToGouraud();
  prop->SetAmbient(0.15);
  prop->SetDiffuse(0.85);
  prop->SetSpecular(0);
  prop->SetSpecularPower(1);
  prop->SetSpecularColor(1, 1, 1);

  ren->AddActor(Actor6);

  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);

  vtkCompositeManager* compManager = vtkCompositeManager::New();
  compManager->SetRenderWindow(renWin);
  compManager->InitializePieces();

  if (myId)
    {
    compManager->InitializeRMIs();
    controller->ProcessRMIs();
    controller->Receive(args->retVal, 1, 0, 33);
    }
  else
    {
    renWin->Render();
    *(args->retVal) =
      vtkRegressionTester::Test(args->argc, args->argv, renWin, 10);
    for (int i = 1; i < numProcs; i++)
      {
      controller->TriggerRMI(i, vtkMultiProcessController::BREAK_RMI_TAG);
      controller->Send(args->retVal, 1, i, 33);
      }
    }

  if ( *(args->retVal) == vtkRegressionTester::DO_INTERACTOR)
    {
    compManager->StartInteractor();
    }
  renWin->Delete();
  ren->Delete();
  iren->Delete();
  compManager->Delete();
  Plot3D0->Delete();
  Stream0->Delete();
  LookupTable1->Delete();
  LineSourceWidget0->Delete();
  Geometry5->Delete();
  Geometry6->Delete();
  Actor5->Delete();
  Actor6->Delete();
  Mapper5->Delete();
  Mapper6->Delete();
}

int main( int argc, char* argv[] )
{
  vtkDebugLeaks::PromptUserOff();

  vtkMultiProcessController* contr = vtkMultiProcessController::New();
  contr->Initialize(&argc, &argv);
  contr->CreateOutputWindow();

  vtkParallelFactory* pf = vtkParallelFactory::New();
  vtkObjectFactory::RegisterFactory(pf);
  pf->Delete();

  // This is repeated for the sake of MPI. This one might not
  // get called by the parent process, the first one might not
  // get called by all others.
  vtkDebugLeaks::PromptUserOff();

  // When using MPI, the number of processes is determined
  // by the external program which launches this application.
  // However, when using threads, we need to set it ourselves.
  if (contr->IsA("vtkThreadedController"))
    {
    // Set the number of processes to 2 for this example.
    contr->SetNumberOfProcesses(2);
    }

  // Added for regression test.
  // ----------------------------------------------
  int retVal;
  PStreamArgs_tmp args;
  args.retVal = &retVal;
  args.argc = argc;
  args.argv = argv;
  // ----------------------------------------------

  contr->SetSingleMethod(MyMain, &args);
  contr->SingleMethodExecute();

  contr->Finalize();
  contr->Delete();

  return !retVal;
}

<commit_msg>Removed dependency on PVGeometryFilter<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestPStream.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkCompositeManager.h"
#include "vtkDebugLeaks.h"
#include "vtkDistributedStreamTracer.h"
#include "vtkLineSource.h"
#include "vtkLookupTable.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
#include "vtkPLOT3DReader.h"
#include "vtkGeometryFilter.h"
#include "vtkParallelFactory.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkStructuredGrid.h"
#include "vtkStructuredGridOutlineFilter.h"

struct PStreamArgs_tmp
{
  int* retVal;
  int argc;
  char** argv;
};

// This will be called by all processes
void MyMain( vtkMultiProcessController *controller, void *arg )
{

  PStreamArgs_tmp* args =
    reinterpret_cast<PStreamArgs_tmp*>(arg);

  int myId = controller->GetLocalProcessId();
  int numProcs = controller->GetNumberOfProcesses();

  vtkRenderer* ren = vtkRenderer::New();
  ren->SetBackground(0.33, 0.35, 0.43);

  vtkRenderWindow* renWin = vtkRenderWindow::New();
  renWin->AddRenderer(ren);
  renWin->SetSize(400, 300);
  renWin->SetPosition(410*myId, 0);

  //camera parameters
  vtkCamera* camera = ren->GetActiveCamera();
  camera->SetPosition(-5.86786, 49.2857, 51.597);
  camera->SetFocalPoint(8.255, -3.17482e-16, 29.7631);
  camera->SetViewUp(-0.112182, -0.42918, 0.896225);
  camera->SetViewAngle(30);
  camera->SetClippingRange(10.0, 80.6592);
  camera->Dolly(1.5);

  // Create the reader, the data file name might have
  // to be changed depending on where the data files are.
  char* fname1 = vtkTestUtilities::ExpandDataFileName(args->argc, args->argv,
                                                     "Data/combxyz.bin");
  char* fname2 = vtkTestUtilities::ExpandDataFileName(args->argc, args->argv,
                                                     "Data/combq.bin");
  vtkPLOT3DReader* Plot3D0 = vtkPLOT3DReader::New();
  Plot3D0->SetFileName(fname1);
  Plot3D0->SetQFileName (fname2);
  Plot3D0->SetBinaryFile(1);
  Plot3D0->SetMultiGrid(0);
  Plot3D0->SetHasByteCount(0);
  Plot3D0->SetIBlanking(0);
  Plot3D0->SetTwoDimensionalGeometry(0);
  Plot3D0->SetForceRead(0);
  Plot3D0->SetByteOrder(0);
  delete[] fname1;
  delete[] fname2;

  vtkStructuredGridOutlineFilter* Geometry5 =
    vtkStructuredGridOutlineFilter::New();
  Geometry5->SetInput(Plot3D0->GetOutput());

  vtkPolyDataMapper* Mapper5 = vtkPolyDataMapper::New();
  Mapper5->SetInput(Geometry5->GetOutput());
  Mapper5->SetImmediateModeRendering(1);
  Mapper5->UseLookupTableScalarRangeOn();
  Mapper5->SetScalarVisibility(0);
  Mapper5->SetScalarModeToDefault();

  vtkActor* Actor5 = vtkActor::New();
  Actor5->SetMapper(Mapper5);
  vtkProperty* prop = Actor5->GetProperty();
  prop->SetRepresentationToSurface();
  prop->SetInterpolationToGouraud();
  prop->SetAmbient(0.15);
  prop->SetDiffuse(0.85);
  prop->SetSpecular(0.1);
  prop->SetSpecularPower(100);
  prop->SetSpecularColor(1, 1, 1);
  prop->SetColor(1, 1, 1);

  ren->AddActor(Actor5);

  vtkLineSource* LineSourceWidget0 = vtkLineSource::New();
  LineSourceWidget0->SetPoint1(13.9548, -0.47371, 31.7642);
  LineSourceWidget0->SetPoint2(6.3766, -0.5886, 26.6274);
  LineSourceWidget0->SetResolution(20);

  vtkDistributedStreamTracer* Stream0 = vtkDistributedStreamTracer::New();;
  Stream0->SetInput(Plot3D0->GetOutput());
  Stream0->SelectInputVectors("Momentum");
  Stream0->SetSource(LineSourceWidget0->GetOutput());
  Stream0->SetMaximumPropagationUnit(0);
  Stream0->SetMaximumPropagation(0.05);
  Stream0->SetInitialIntegrationStepUnit(2);
  Stream0->SetInitialIntegrationStep(0.5);
  Stream0->SetIntegrationDirection(2);
  Stream0->SetIntegratorType(0);
  Stream0->SetMaximumNumberOfSteps(2000);
  Stream0->SetTerminalSpeed(1e-12);

  vtkGeometryFilter* Geometry6 = vtkGeometryFilter::New();;
  Geometry6->SetInput(Stream0->GetOutput());

  vtkLookupTable* LookupTable1 = vtkLookupTable::New();
  LookupTable1->SetNumberOfTableValues(256);
  LookupTable1->SetHueRange(0, 0.66667);
  LookupTable1->SetSaturationRange(1, 1);
  LookupTable1->SetValueRange(1, 1);
  LookupTable1->SetTableRange(0.197813, 0.710419);
  LookupTable1->SetVectorComponent(0);
  LookupTable1->Build();

  vtkPolyDataMapper* Mapper6 = vtkPolyDataMapper::New();
  Mapper6->SetInput(Geometry6->GetOutput());
  Mapper6->SetImmediateModeRendering(1);
  Mapper6->UseLookupTableScalarRangeOn();
  Mapper6->SetScalarVisibility(1);
  Mapper6->SetScalarModeToUsePointFieldData();
  Mapper6->SelectColorArray("Density");
  Mapper6->SetLookupTable(LookupTable1);

  vtkActor* Actor6 = vtkActor::New();
  Actor6->SetMapper(Mapper6);
  prop = Actor6->GetProperty();
  prop->SetRepresentationToSurface();
  prop->SetInterpolationToGouraud();
  prop->SetAmbient(0.15);
  prop->SetDiffuse(0.85);
  prop->SetSpecular(0);
  prop->SetSpecularPower(1);
  prop->SetSpecularColor(1, 1, 1);

  ren->AddActor(Actor6);

  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);

  vtkCompositeManager* compManager = vtkCompositeManager::New();
  compManager->SetRenderWindow(renWin);
  compManager->InitializePieces();

  if (myId)
    {
    compManager->InitializeRMIs();
    controller->ProcessRMIs();
    controller->Receive(args->retVal, 1, 0, 33);
    }
  else
    {
    renWin->Render();
    *(args->retVal) =
      vtkRegressionTester::Test(args->argc, args->argv, renWin, 10);
    for (int i = 1; i < numProcs; i++)
      {
      controller->TriggerRMI(i, vtkMultiProcessController::BREAK_RMI_TAG);
      controller->Send(args->retVal, 1, i, 33);
      }
    }

  if ( *(args->retVal) == vtkRegressionTester::DO_INTERACTOR)
    {
    compManager->StartInteractor();
    }
  renWin->Delete();
  ren->Delete();
  iren->Delete();
  compManager->Delete();
  Plot3D0->Delete();
  Stream0->Delete();
  LookupTable1->Delete();
  LineSourceWidget0->Delete();
  Geometry5->Delete();
  Geometry6->Delete();
  Actor5->Delete();
  Actor6->Delete();
  Mapper5->Delete();
  Mapper6->Delete();
}

int main( int argc, char* argv[] )
{
  vtkDebugLeaks::PromptUserOff();

  vtkMultiProcessController* contr = vtkMultiProcessController::New();
  contr->Initialize(&argc, &argv);
  contr->CreateOutputWindow();

  vtkParallelFactory* pf = vtkParallelFactory::New();
  vtkObjectFactory::RegisterFactory(pf);
  pf->Delete();

  // This is repeated for the sake of MPI. This one might not
  // get called by the parent process, the first one might not
  // get called by all others.
  vtkDebugLeaks::PromptUserOff();

  // When using MPI, the number of processes is determined
  // by the external program which launches this application.
  // However, when using threads, we need to set it ourselves.
  if (contr->IsA("vtkThreadedController"))
    {
    // Set the number of processes to 2 for this example.
    contr->SetNumberOfProcesses(2);
    }

  // Added for regression test.
  // ----------------------------------------------
  int retVal;
  PStreamArgs_tmp args;
  args.retVal = &retVal;
  args.argc = argc;
  args.argv = argv;
  // ----------------------------------------------

  contr->SetSingleMethod(MyMain, &args);
  contr->SingleMethodExecute();

  contr->Finalize();
  contr->Delete();

  return !retVal;
}

<|endoftext|>


<commit_before>/***************************************************************************
fbellini@cern.ch - created on 25/08/2017
Configuration script for f0(980) analysis
****************************************************************************/
#ifdef __CLING__
R__ADD_INCLUDE_PATH($ALICE_PHYSICS)
#include <PWGLF/RESONANCES/macros/mini/AddMonitorOutput.C>
#endif

Bool_t ConfigF0(AliRsnMiniAnalysisTask *task,
		Bool_t                 isMC,
		AliPIDResponse::EBeamType collSys = AliPIDResponse::kPP, //=0, kPPB=1, kPBPB=2
		AliRsnCutSet           *cutsPair,             //cuts on the pair
		Bool_t                 enaMultSel = kTRUE,    //enable multiplicity axis
      		Float_t                masslow = 0.3,         //inv mass axis low edge
		Float_t                massup = 1.3,          //inv mass axis upper edge
		Int_t                  nbins = 1000,           //inv mass axis n bins
		Int_t                  aodFilterBit = 5,      //filter bit for AOD analysis
		AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutPid = AliRsnCutSetDaughterParticle::kTPCpidTOFveto3s, // pid cut set
		Float_t                nsigma = 3.0,          //nsigma of TPC PID cut
		Bool_t                 enableMonitor = kTRUE) //enable single track QA plots
{
  //-----------------------
  //General
  //-----------------------
  TString partname="f0";
  Int_t   pdgCode=9010221;
  Float_t mass = 0.990;// 2014 PDG: M = 0.990 ± 20 GeV
  RSNPID  d1 = AliRsnDaughter::kPion;
  RSNPID  d2 = AliRsnDaughter::kPion;

  //Additional options for monitoring plots
  TString monitorOpt = "NoSIGN";

  //-----------------------
  // CUTS
  //-----------------------
  //use default quality cuts std 2010 with crossed rows TPC
  Bool_t useCrossedRows = 1;
  AliRsnCutSetDaughterParticle * cutSetPi = new AliRsnCutSetDaughterParticle("cutPi", cutPid, AliPID::kPion, nsigma, aodFilterBit, useCrossedRows);
  cutSetPi->SetUse2011StdQualityCuts(kTRUE);
  Int_t icutPi = task->AddTrackCuts(cutSetPi);

  //set daughter cuts
  Int_t icut1 = icutPi;
  Int_t icut2 = icutPi;

  //monitor single-track selection based on track quality cuts only
  AliRsnCutSetDaughterParticle * cutSetQuality = new AliRsnCutSetDaughterParticle("cutQuality", AliRsnCutSetDaughterParticle::kQualityStd2011, AliPID::kPion, 10.0, aodFilterBit, useCrossedRows);
  Int_t icutQuality = task->AddTrackCuts(cutSetQuality);

  //QA plots
  if (enableMonitor){
    Printf("======== Cut monitoring enabled");
#ifdef __CINT__
   gROOT->LoadMacro("$ALICE_PHYSICS/PWGLF/RESONANCES/macros/mini/AddMonitorOutput.C");
#endif
    AddMonitorOutput(isMC, cutSetQuality->GetMonitorOutput(), monitorOpt.Data());
    AddMonitorOutput(isMC, cutSetPi->GetMonitorOutput(), monitorOpt.Data());
  }

  //-----------------------
  // OUTPUT
  //-----------------------
  /* invariant mass   */ Int_t imID   = task->CreateValue(AliRsnMiniValue::kInvMass, kFALSE);
  /* IM resolution    */ Int_t resID  = task->CreateValue(AliRsnMiniValue::kInvMassRes, kTRUE);
  /* transv. momentum */ Int_t ptID   = task->CreateValue(AliRsnMiniValue::kPt, kFALSE);
  /* centrality       */ Int_t multID = task->CreateValue(AliRsnMiniValue::kMult, kFALSE);
  /* pseudorapidity   */ Int_t etaID  = task->CreateValue(AliRsnMiniValue::kEta, kFALSE);
  /* rapidity         */ Int_t yID    = task->CreateValue(AliRsnMiniValue::kY, kFALSE);
  /* 1st daughter pt  */ Int_t fdpt   = task->CreateValue(AliRsnMiniValue::kFirstDaughterPt, kFALSE);
  /* 2nd daughter pt  */ Int_t sdpt   = task->CreateValue(AliRsnMiniValue::kSecondDaughterPt, kFALSE);
  /* 1st daughter p   */ Int_t fdp    = task->CreateValue(AliRsnMiniValue::kFirstDaughterP, kFALSE);
  /* 2nd daughter p   */ Int_t sdp    = task->CreateValue(AliRsnMiniValue::kSecondDaughterP, kFALSE);
  TString output = "HIST"; // or "SPARSE"
  TString name[6] = {"UnlikePM", "MixingPM", "LikePP", "LikeMM", "MixingPP", "MixingMM"};
  TString comp[6] = {"PAIR"    , "MIX",      "PAIR"  , "PAIR"  , "MIX"     , "MIX"     };
  Char_t charge1[6] = {'+', '+', '+', '-', '+', '-'};
  Char_t charge2[6] = {'-', '-', '+', '-', '+', '-'};

  //DATA
  for (Int_t i = 0; i < 6; i++) {
    AliRsnMiniOutput *out = task->CreateOutput(Form("f0_%s", name[i].Data()), output.Data(), comp[i].Data());
    out->SetCutID(0, icut1);
    out->SetCutID(1, icut2);
    out->SetDaughter(0, d1);
    out->SetDaughter(1, d2);
    out->SetCharge(0, charge1[i]);
    out->SetCharge(1, charge2[i]);
    out->SetMotherPDG(pdgCode);
    out->SetMotherMass(mass);
    out->SetPairCuts(cutsPair);
    // axis X: invmass
    out->AddAxis(imID, nbins, masslow, massup);
    //axis Y: mother pt
    out->AddAxis(ptID, 200, 0.0, 20.0); //default use mother pt
    //axis Z: multiplicity
    if (enaMultSel) out->AddAxis(multID, 100, 0.0, 100.0);
  }

  //Template for BG
  TString bgTemplate[7]  = {"rho", "omega", "Kstar", "antiKstar", "K0s", "phi","f2"};
  Char_t bgTemplateC1[7] = {'+', '+', '+', '+', '+', '+', '+'};
  Char_t bgTemplateC2[7] = {'-', '-', '-', '-', '-', '-', '-'};
  Int_t bgTemplatePDG[7] = {113, 223, 313, -313, 310, 333, 225};
  Int_t bgTemplateM[7]   = {775.26, 8.49, 891.66, 891.66, 497.611, 1019.461, 1275.5};
  RSNPID bgID1[7] = {AliRsnDaughter::kPion, AliRsnDaughter::kPion,AliRsnDaughter::kKaon, AliRsnDaughter::kPion, AliRsnDaughter::kPion, AliRsnDaughter::kKaon, AliRsnDaughter::kPion};
  RSNPID bgID2[7] = {AliRsnDaughter::kPion, AliRsnDaughter::kPion,AliRsnDaughter::kPion, AliRsnDaughter::kKaon, AliRsnDaughter::kPion, AliRsnDaughter::kKaon, AliRsnDaughter::kPion};

  if (isMC) {
    //TRUE RECO PAIRS - TEMPLATE FOR BG
    for (Int_t ibg = 0; ibg <7; ibg++) {
      AliRsnMiniOutput * outtempl = task->CreateOutput(Form("bg_%s", bgTemplate[ibg].Data()), output.Data(),"TRUE");
      outtempl->SetCutID(0, icut1);
      outtempl->SetCutID(1, icut2);
      outtempl->SetCharge(0, bgTemplateC1[0]);
      outtempl->SetCharge(1, bgTemplateC2[0]);
      outtempl->SetDaughter(0, bgID1[ibg]);
      outtempl->SetDaughter(1, bgID2[ibg]);
      outtempl->SetMotherPDG(bgTemplatePDG[ibg]);
      outtempl->SetMotherMass(bgTemplateM[ibg]);
      outtempl->SetPairCuts(cutsPair);
      // axis X: invmass
      outtempl->AddAxis(imID, nbins, masslow, massup);
      //axis Y: mother pt
      outtempl->AddAxis(ptID, 200, 0.0, 20.0); //default use mother pt
      // axis Z: multrality-multiplicity
      if (enaMultSel) outtempl->AddAxis(multID, 100, 0.0, 100.0);
    }
    //TRUE RECO PAIRS - MASS
    AliRsnMiniOutput * outtrue = task->CreateOutput(Form("truef0_%s", partname.Data()), output.Data(),"TRUE");
    outtrue->SetCutID(0, icut1);
    outtrue->SetCutID(1, icut2);
    outtrue->SetCharge(0, charge1[0]);
    outtrue->SetCharge(1, charge2[0]);
    outtrue->SetDaughter(0, d1);
    outtrue->SetDaughter(1, d2);
    outtrue->SetMotherPDG(pdgCode);
    outtrue->SetMotherMass(mass);
    outtrue->SetPairCuts(cutsPair);
    // axis X: invmass
    outtrue->AddAxis(imID, nbins, masslow, massup);
    //axis Y: mother pt
    outtrue->AddAxis(ptID, 200, 0.0, 20.0); //default use mother pt
    // axis Z: multiplicity
    if (enaMultSel) outtrue->AddAxis(multID, 100, 0.0, 100.0);

    //TRUE RECO PAIRS - MASS RESOLUTION
    AliRsnMiniOutput * outres = task->CreateOutput(Form("Mres_%s", partname.Data()), output.Data(),"TRUE");
    outres->SetCutID(0, icut1);
    outres->SetCutID(1, icut2);
    outres->SetCharge(0, charge1[0]);
    outres->SetCharge(1, charge2[0]);
    outres->SetDaughter(0, d1);
    outres->SetDaughter(1, d2);
    outres->SetMotherPDG(pdgCode);
    outres->SetMotherMass(mass);
    outres->SetPairCuts(cutsPair);
    // axis X: invmass resolution
    outres->AddAxis(resID, 200, -0.01, 0.01);
    //axis Y: mother pt
    outres->AddAxis(ptID, 200, 0.0, 20.0);
    // axis Z: multiplicity
    if (enaMultSel) outres->AddAxis(multID, 100, 0.0, 100.0);

    //TRUE RECO PAIRS - rapidity
    AliRsnMiniOutput * outrap = task->CreateOutput(Form("trueRap_%s", partname.Data()), output.Data(),"TRUE");
    outrap->SetCutID(0, icut1);
    outrap->SetCutID(1, icut2);
    outrap->SetCharge(0, charge1[0]);
    outrap->SetCharge(1, charge2[0]);
    outrap->SetDaughter(0, d1);
    outrap->SetDaughter(1, d2);
    outrap->SetMotherPDG(pdgCode);
    outrap->SetMotherMass(mass);
    outrap->SetPairCuts(cutsPair);
    outrap->AddAxis(ptID, 160, 0.0, 16.0);
    outrap->AddAxis(yID,  120, -0.6, 0.6);
    outrap->AddAxis(etaID, 200, -1., 1.);

    //GENERATED PAIRS
    AliRsnMiniOutput * outm = task->CreateOutput(Form("motherf0_%s", partname.Data()), output.Data(),"MOTHER");
    outm->SetDaughter(0, d1);
    outm->SetDaughter(1, d2);
    outm->SetMotherPDG(pdgCode);
    outm->SetMotherMass(mass);
    outm->SetPairCuts(cutsPair);
    outm->AddAxis(imID, nbins, masslow, massup);
    outm->AddAxis(ptID, 200, 0.0, 20.0);
    if (enaMultSel) outm->AddAxis(multID, 100, 0.0, 100.0);

    //GENERATED PAIRS
    AliRsnMiniOutput * outmy = task->CreateOutput(Form("motherRap_%s", partname.Data()), output.Data(),"MOTHER");
    outmy->SetDaughter(0, d1);
    outmy->SetDaughter(1, d2);
    outmy->SetMotherPDG(pdgCode);
    outmy->SetMotherMass(mass);
    outmy->SetPairCuts(cutsPair);
    outmy->AddAxis(ptID, 160, 0.0, 16.0);
    outmy->AddAxis(yID,  120, -0.6, 0.6);
    outmy->AddAxis(etaID, 200, -1., 1.);

    //f2 GENERATED PAIRS
    AliRsnMiniOutput * outm2 = task->CreateOutput("motherf2", output.Data(),"MOTHER");
    outm2->SetDaughter(0, d1);
    outm2->SetDaughter(1, d2);
    outm2->SetMotherPDG(bgTemplatePDG[6]);
    outm2->SetMotherMass(bgTemplateM[6]);
    outm2->SetPairCuts(cutsPair);
    outm2->AddAxis(imID, nbins, masslow, massup);
    outm2->AddAxis(ptID, 200, 0.0, 20.0);
    if (enaMultSel) outm2->AddAxis(multID, 100, 0.0, 100.0);

    //f2 GENERATED PAIRS
    AliRsnMiniOutput * outmy2 = task->CreateOutput("motherf2Rap", output.Data(),"MOTHER");
    outmy2->SetDaughter(0, d1);
    outmy2->SetDaughter(1, d2);
    outmy2->SetMotherPDG(bgTemplatePDG[6]);
    outmy2->SetMotherMass(bgTemplateM[6]);
    outmy2->SetPairCuts(cutsPair);
    outmy2->AddAxis(ptID, 160, 0.0, 16.0);
    outmy2->AddAxis(yID,  120, -0.6, 0.6);
    outmy2->AddAxis(etaID, 200, -1., 1.);
  }

  return kTRUE;
}
<commit_msg>Fixed array type<commit_after>/***************************************************************************
fbellini@cern.ch - created on 25/08/2017
Configuration script for f0(980) analysis
****************************************************************************/
#ifdef __CLING__
R__ADD_INCLUDE_PATH($ALICE_PHYSICS)
#include <PWGLF/RESONANCES/macros/mini/AddMonitorOutput.C>
#endif

Bool_t ConfigF0(AliRsnMiniAnalysisTask *task,
		Bool_t                 isMC,
		AliPIDResponse::EBeamType collSys = AliPIDResponse::kPP, //=0, kPPB=1, kPBPB=2
		AliRsnCutSet           *cutsPair,             //cuts on the pair
		Bool_t                 enaMultSel = kTRUE,    //enable multiplicity axis
      		Float_t                masslow = 0.3,         //inv mass axis low edge
		Float_t                massup = 1.3,          //inv mass axis upper edge
		Int_t                  nbins = 1000,           //inv mass axis n bins
		Int_t                  aodFilterBit = 5,      //filter bit for AOD analysis
		AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutPid = AliRsnCutSetDaughterParticle::kTPCpidTOFveto3s, // pid cut set
		Float_t                nsigma = 3.0,          //nsigma of TPC PID cut
		Bool_t                 enableMonitor = kTRUE) //enable single track QA plots
{
  //-----------------------
  //General
  //-----------------------
  TString partname="f0";
  Int_t   pdgCode=9010221;
  Float_t mass = 0.990;// 2014 PDG: M = 0.990 ± 20 GeV
  RSNPID  d1 = AliRsnDaughter::kPion;
  RSNPID  d2 = AliRsnDaughter::kPion;

  //Additional options for monitoring plots
  TString monitorOpt = "NoSIGN";

  //-----------------------
  // CUTS
  //-----------------------
  //use default quality cuts std 2010 with crossed rows TPC
  Bool_t useCrossedRows = 1;
  AliRsnCutSetDaughterParticle * cutSetPi = new AliRsnCutSetDaughterParticle("cutPi", cutPid, AliPID::kPion, nsigma, aodFilterBit, useCrossedRows);
  cutSetPi->SetUse2011StdQualityCuts(kTRUE);
  Int_t icutPi = task->AddTrackCuts(cutSetPi);

  //set daughter cuts
  Int_t icut1 = icutPi;
  Int_t icut2 = icutPi;

  //monitor single-track selection based on track quality cuts only
  AliRsnCutSetDaughterParticle * cutSetQuality = new AliRsnCutSetDaughterParticle("cutQuality", AliRsnCutSetDaughterParticle::kQualityStd2011, AliPID::kPion, 10.0, aodFilterBit, useCrossedRows);
  Int_t icutQuality = task->AddTrackCuts(cutSetQuality);

  //QA plots
  if (enableMonitor){
    Printf("======== Cut monitoring enabled");
#ifdef __CINT__
   gROOT->LoadMacro("$ALICE_PHYSICS/PWGLF/RESONANCES/macros/mini/AddMonitorOutput.C");
#endif
    AddMonitorOutput(isMC, cutSetQuality->GetMonitorOutput(), monitorOpt.Data(), 0);
    AddMonitorOutput(isMC, cutSetPi->GetMonitorOutput(), monitorOpt.Data(), 0);
  }

  //-----------------------
  // OUTPUT
  //-----------------------
  /* invariant mass   */ Int_t imID   = task->CreateValue(AliRsnMiniValue::kInvMass, kFALSE);
  /* IM resolution    */ Int_t resID  = task->CreateValue(AliRsnMiniValue::kInvMassRes, kTRUE);
  /* transv. momentum */ Int_t ptID   = task->CreateValue(AliRsnMiniValue::kPt, kFALSE);
  /* centrality       */ Int_t multID = task->CreateValue(AliRsnMiniValue::kMult, kFALSE);
  /* pseudorapidity   */ Int_t etaID  = task->CreateValue(AliRsnMiniValue::kEta, kFALSE);
  /* rapidity         */ Int_t yID    = task->CreateValue(AliRsnMiniValue::kY, kFALSE);
  /* 1st daughter pt  */ Int_t fdpt   = task->CreateValue(AliRsnMiniValue::kFirstDaughterPt, kFALSE);
  /* 2nd daughter pt  */ Int_t sdpt   = task->CreateValue(AliRsnMiniValue::kSecondDaughterPt, kFALSE);
  /* 1st daughter p   */ Int_t fdp    = task->CreateValue(AliRsnMiniValue::kFirstDaughterP, kFALSE);
  /* 2nd daughter p   */ Int_t sdp    = task->CreateValue(AliRsnMiniValue::kSecondDaughterP, kFALSE);
  TString output = "HIST"; // or "SPARSE"
  TString name[6] = {"UnlikePM", "MixingPM", "LikePP", "LikeMM", "MixingPP", "MixingMM"};
  TString comp[6] = {"PAIR"    , "MIX",      "PAIR"  , "PAIR"  , "MIX"     , "MIX"     };
  Char_t charge1[6] = {'+', '+', '+', '-', '+', '-'};
  Char_t charge2[6] = {'-', '-', '+', '-', '+', '-'};

  //DATA
  for (Int_t i = 0; i < 6; i++) {
    AliRsnMiniOutput *out = task->CreateOutput(Form("f0_%s", name[i].Data()), output.Data(), comp[i].Data());
    out->SetCutID(0, icut1);
    out->SetCutID(1, icut2);
    out->SetDaughter(0, d1);
    out->SetDaughter(1, d2);
    out->SetCharge(0, charge1[i]);
    out->SetCharge(1, charge2[i]);
    out->SetMotherPDG(pdgCode);
    out->SetMotherMass(mass);
    out->SetPairCuts(cutsPair);
    // axis X: invmass
    out->AddAxis(imID, nbins, masslow, massup);
    //axis Y: mother pt
    out->AddAxis(ptID, 200, 0.0, 20.0); //default use mother pt
    //axis Z: multiplicity
    if (enaMultSel) out->AddAxis(multID, 100, 0.0, 100.0);
  }

  //Template for BG
  TString bgTemplate[7]  = {"rho", "omega", "Kstar", "antiKstar", "K0s", "phi","f2"};
  Char_t bgTemplateC1[7] = {'+', '+', '+', '+', '+', '+', '+'};
  Char_t bgTemplateC2[7] = {'-', '-', '-', '-', '-', '-', '-'};
  Int_t bgTemplatePDG[7] = {113, 223, 313, -313, 310, 333, 225};
  Double_t bgTemplateM[7]   = {775.26, 8.49, 891.66, 891.66, 497.611, 1019.461, 1275.5};
  RSNPID bgID1[7] = {AliRsnDaughter::kPion, AliRsnDaughter::kPion,AliRsnDaughter::kKaon, AliRsnDaughter::kPion, AliRsnDaughter::kPion, AliRsnDaughter::kKaon, AliRsnDaughter::kPion};
  RSNPID bgID2[7] = {AliRsnDaughter::kPion, AliRsnDaughter::kPion,AliRsnDaughter::kPion, AliRsnDaughter::kKaon, AliRsnDaughter::kPion, AliRsnDaughter::kKaon, AliRsnDaughter::kPion};

  if (isMC) {
    //TRUE RECO PAIRS - TEMPLATE FOR BG
    for (Int_t ibg = 0; ibg <7; ibg++) {
      AliRsnMiniOutput * outtempl = task->CreateOutput(Form("bg_%s", bgTemplate[ibg].Data()), output.Data(),"TRUE");
      outtempl->SetCutID(0, icut1);
      outtempl->SetCutID(1, icut2);
      outtempl->SetCharge(0, bgTemplateC1[0]);
      outtempl->SetCharge(1, bgTemplateC2[0]);
      outtempl->SetDaughter(0, bgID1[ibg]);
      outtempl->SetDaughter(1, bgID2[ibg]);
      outtempl->SetMotherPDG(bgTemplatePDG[ibg]);
      outtempl->SetMotherMass(bgTemplateM[ibg]);
      outtempl->SetPairCuts(cutsPair);
      // axis X: invmass
      outtempl->AddAxis(imID, nbins, masslow, massup);
      //axis Y: mother pt
      outtempl->AddAxis(ptID, 200, 0.0, 20.0); //default use mother pt
      // axis Z: multrality-multiplicity
      if (enaMultSel) outtempl->AddAxis(multID, 100, 0.0, 100.0);
    }
    //TRUE RECO PAIRS - MASS
    AliRsnMiniOutput * outtrue = task->CreateOutput(Form("truef0_%s", partname.Data()), output.Data(),"TRUE");
    outtrue->SetCutID(0, icut1);
    outtrue->SetCutID(1, icut2);
    outtrue->SetCharge(0, charge1[0]);
    outtrue->SetCharge(1, charge2[0]);
    outtrue->SetDaughter(0, d1);
    outtrue->SetDaughter(1, d2);
    outtrue->SetMotherPDG(pdgCode);
    outtrue->SetMotherMass(mass);
    outtrue->SetPairCuts(cutsPair);
    // axis X: invmass
    outtrue->AddAxis(imID, nbins, masslow, massup);
    //axis Y: mother pt
    outtrue->AddAxis(ptID, 200, 0.0, 20.0); //default use mother pt
    // axis Z: multiplicity
    if (enaMultSel) outtrue->AddAxis(multID, 100, 0.0, 100.0);

    //TRUE RECO PAIRS - MASS RESOLUTION
    AliRsnMiniOutput * outres = task->CreateOutput(Form("Mres_%s", partname.Data()), output.Data(),"TRUE");
    outres->SetCutID(0, icut1);
    outres->SetCutID(1, icut2);
    outres->SetCharge(0, charge1[0]);
    outres->SetCharge(1, charge2[0]);
    outres->SetDaughter(0, d1);
    outres->SetDaughter(1, d2);
    outres->SetMotherPDG(pdgCode);
    outres->SetMotherMass(mass);
    outres->SetPairCuts(cutsPair);
    // axis X: invmass resolution
    outres->AddAxis(resID, 200, -0.01, 0.01);
    //axis Y: mother pt
    outres->AddAxis(ptID, 200, 0.0, 20.0);
    // axis Z: multiplicity
    if (enaMultSel) outres->AddAxis(multID, 100, 0.0, 100.0);

    //TRUE RECO PAIRS - rapidity
    AliRsnMiniOutput * outrap = task->CreateOutput(Form("trueRap_%s", partname.Data()), output.Data(),"TRUE");
    outrap->SetCutID(0, icut1);
    outrap->SetCutID(1, icut2);
    outrap->SetCharge(0, charge1[0]);
    outrap->SetCharge(1, charge2[0]);
    outrap->SetDaughter(0, d1);
    outrap->SetDaughter(1, d2);
    outrap->SetMotherPDG(pdgCode);
    outrap->SetMotherMass(mass);
    outrap->SetPairCuts(cutsPair);
    outrap->AddAxis(ptID, 160, 0.0, 16.0);
    outrap->AddAxis(yID,  120, -0.6, 0.6);
    outrap->AddAxis(etaID, 200, -1., 1.);

    //GENERATED PAIRS
    AliRsnMiniOutput * outm = task->CreateOutput(Form("motherf0_%s", partname.Data()), output.Data(),"MOTHER");
    outm->SetDaughter(0, d1);
    outm->SetDaughter(1, d2);
    outm->SetMotherPDG(pdgCode);
    outm->SetMotherMass(mass);
    outm->SetPairCuts(cutsPair);
    outm->AddAxis(imID, nbins, masslow, massup);
    outm->AddAxis(ptID, 200, 0.0, 20.0);
    if (enaMultSel) outm->AddAxis(multID, 100, 0.0, 100.0);

    //GENERATED PAIRS
    AliRsnMiniOutput * outmy = task->CreateOutput(Form("motherRap_%s", partname.Data()), output.Data(),"MOTHER");
    outmy->SetDaughter(0, d1);
    outmy->SetDaughter(1, d2);
    outmy->SetMotherPDG(pdgCode);
    outmy->SetMotherMass(mass);
    outmy->SetPairCuts(cutsPair);
    outmy->AddAxis(ptID, 160, 0.0, 16.0);
    outmy->AddAxis(yID,  120, -0.6, 0.6);
    outmy->AddAxis(etaID, 200, -1., 1.);

    //f2 GENERATED PAIRS
    AliRsnMiniOutput * outm2 = task->CreateOutput("motherf2", output.Data(),"MOTHER");
    outm2->SetDaughter(0, d1);
    outm2->SetDaughter(1, d2);
    outm2->SetMotherPDG(bgTemplatePDG[6]);
    outm2->SetMotherMass(bgTemplateM[6]);
    outm2->SetPairCuts(cutsPair);
    outm2->AddAxis(imID, nbins, masslow, massup);
    outm2->AddAxis(ptID, 200, 0.0, 20.0);
    if (enaMultSel) outm2->AddAxis(multID, 100, 0.0, 100.0);

    //f2 GENERATED PAIRS
    AliRsnMiniOutput * outmy2 = task->CreateOutput("motherf2Rap", output.Data(),"MOTHER");
    outmy2->SetDaughter(0, d1);
    outmy2->SetDaughter(1, d2);
    outmy2->SetMotherPDG(bgTemplatePDG[6]);
    outmy2->SetMotherMass(bgTemplateM[6]);
    outmy2->SetPairCuts(cutsPair);
    outmy2->AddAxis(ptID, 160, 0.0, 16.0);
    outmy2->AddAxis(yID,  120, -0.6, 0.6);
    outmy2->AddAxis(etaID, 200, -1., 1.);
  }

  return kTRUE;
}
<|endoftext|>