<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

#ifndef FEATURE_STYLE_PROCESSOR_HPP
#define FEATURE_STYLE_PROCESSOR_HPP

// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/memory_datasource.hpp>

#ifdef MAPNIK_DEBUG
//#include <mapnik/wall_clock_timer.hpp>
#endif
// boost
#include <boost/foreach.hpp>
//stl
#include <vector>

namespace mapnik
{

template <typename Processor>
class feature_style_processor
{
    /** Calls the renderer's process function,
      * \param output     Renderer
      * \param f          Feature to process
      * \param prj_trans  Projection
      * \param sym        Symbolizer object
      */
    struct symbol_dispatch : public boost::static_visitor<>
    {
        symbol_dispatch (Processor & output,
                         Feature const& f,
                         proj_transform const& prj_trans)
            : output_(output),
              f_(f),
              prj_trans_(prj_trans)  {}

        template <typename T>
        void operator () (T const& sym) const
        {
            output_.process(sym,f_,prj_trans_);
        }

        Processor & output_;
        Feature const& f_;
        proj_transform const& prj_trans_;
    };
public:
    explicit feature_style_processor(Map const& m, double scale_factor = 1.0)
        : m_(m),
          scale_factor_(scale_factor) {}

    void apply()
    {
#ifdef MAPNIK_DEBUG
        //mapnik::wall_clock_progress_timer t(std::clog, "map rendering took: ");
#endif
        Processor & p = static_cast<Processor&>(*this);
        p.start_map_processing(m_);

        try
        {
            projection proj(m_.srs()); // map projection

            Map::const_metawriter_iterator metaItr = m_.begin_metawriters();
            Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->set_size(m_.width(), m_.height());
                metaItr->second->set_map_srs(proj);
                metaItr->second->start(m_.metawriter_output_properties);
            }

            double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
            scale_denom *= scale_factor_;
#ifdef MAPNIK_DEBUG
            std::clog << "scale denominator = " << scale_denom << "\n";
#endif
            BOOST_FOREACH ( layer const& lyr, m_.layers() )
            {
                if (lyr.isVisible(scale_denom))
                {
                    apply_to_layer(lyr, p, proj, scale_denom);
                }
            }

            metaItr = m_.begin_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->stop();
            }
        }
        catch (proj_init_error& ex)
        {
            std::clog << "proj_init_error:" << ex.what() << "\n";
        }

        p.end_map_processing(m_);
    }
private:
    void apply_to_layer(layer const& lay, Processor & p,
                        projection const& proj0, double scale_denom)
    {
#ifdef MAPNIK_DEBUG
        //wall_clock_progress_timer timer(clog, "end layer rendering: ");
#endif
        boost::shared_ptr<datasource> ds = lay.datasource();
        if (!ds)
        {
            std::clog << "WARNING: No datasource for layer '" << lay.name() << "'\n";
            return;
        }

        p.start_layer_processing(lay);

        if (ds)
        {

            box2d<double> ext = m_.get_buffered_extent();
            projection proj1(lay.srs());
            proj_transform prj_trans(proj0,proj1);

            // todo: only display raster if src and dest proj are matched
            // todo: add raster re-projection as an optional feature
            if (ds->type() == datasource::Raster && !prj_trans.equal())
            {
                std::clog << "WARNING: Map srs does not match layer srs, skipping raster layer '" << lay.name() << "' as raster re-projection is not currently supported (http://trac.mapnik.org/ticket/663)\n";
                std::clog << "map srs: '" << m_.srs() << "'\nlayer srs: '" << lay.srs() << "' \n";
                return;
            }

            //

            box2d<double> layer_ext = lay.envelope();

            double lx0 = layer_ext.minx();
            double ly0 = layer_ext.miny();
            double lz0 = 0.0;
            double lx1 = layer_ext.maxx();
            double ly1 = layer_ext.maxy();
            double lz1 = 0.0;
            // back project layers extent into main map projection
            prj_trans.backward(lx0,ly0,lz0);
            prj_trans.backward(lx1,ly1,lz1);

            // if no intersection then nothing to do for layer
            if ( lx0 > ext.maxx() || lx1 < ext.minx() || ly0 > ext.maxy() || ly1 < ext.miny() )
            {
                return;
            }

            // clip query bbox
            lx0 = std::max(ext.minx(),lx0);
            ly0 = std::max(ext.miny(),ly0);
            lx1 = std::min(ext.maxx(),lx1);
            ly1 = std::min(ext.maxy(),ly1);

            prj_trans.forward(lx0,ly0,lz0);
            prj_trans.forward(lx1,ly1,lz1);
            box2d<double> bbox(lx0,ly0,lx1,ly1);

            query::resolution_type res(m_.width()/m_.get_current_extent().width(),m_.height()/m_.get_current_extent().height());
            query q(bbox,res,scale_denom); //BBOX query

            std::vector<feature_type_style*> active_styles;
            std::set<std::string> names;
            attribute_collector collector(names);
            double filt_factor = 1;
            directive_collector d_collector(&filt_factor);

            std::vector<std::string> const& style_names = lay.styles();
            // iterate through all named styles collecting active styles and attribute names
            BOOST_FOREACH(std::string const& style_name, style_names)
            {
                boost::optional<feature_type_style const&> style=m_.find_style(style_name);
                if (!style)
                {
                    std::clog << "WARNING: style '" << style_name << "' required for layer '" << lay.name() << "' does not exist.\n";
                    continue;
                }

                const std::vector<rule>& rules=(*style).get_rules();
                bool active_rules=false;

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        active_rules = true;
                        if (ds->type() == datasource::Vector)
                        {
                            collector(r);
                        }
                        // TODO - in the future rasters should be able to be filtered.
                    }
                }
                if (active_rules)
                {
                    active_styles.push_back(const_cast<feature_type_style*>(&(*style)));
                }
            }

            // push all property names
            BOOST_FOREACH(std::string const& name, names)
            {
                q.add_property_name(name);
            }

            memory_datasource cache;
            bool cache_features = lay.cache_features() && style_names.size()>1?true:false;
            bool first = true;

            BOOST_FOREACH (feature_type_style * style, active_styles)
            {
                std::vector<rule*> if_rules;
                std::vector<rule*> else_rules;

                std::vector<rule> const& rules=style->get_rules();

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        if (r.has_else_filter())
                        {
                            else_rules.push_back(const_cast<rule*>(&r));
                        }
                        else
                        {
                            if_rules.push_back(const_cast<rule*>(&r));
                        }

                        if ( (ds->type() == datasource::Raster) &&
                             (ds->params().get<double>("filter_factor",0.0) == 0.0) )
                        {
                            rule::symbolizers const& symbols = r.get_symbolizers();
                            rule::symbolizers::const_iterator symIter = symbols.begin();
                            rule::symbolizers::const_iterator symEnd = symbols.end();
                            while (symIter != symEnd)
                            {
                                // if multiple raster symbolizers, last will be respected
                                // should we warn or throw?
                                boost::apply_visitor(d_collector,*symIter++);
                            }
                            q.set_filter_factor(filt_factor);
                        }
                    }
                }

                // process features
                featureset_ptr fs;
                if (first)
                {
                    if (cache_features)
                        first = false;
                    fs = ds->features(q);
                }
                else
                {
                    fs = cache.features(q);
                }

                if (fs)
                {
                    feature_ptr feature;
                    while ((feature = fs->next()))
                    {
                        bool do_else=true;

                        if (cache_features)
                        {
                            cache.push(feature);
                        }

                        BOOST_FOREACH(rule * r, if_rules )
                        {
                            expression_ptr const& expr=r->get_filter();
                            value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
                            if (result.to_bool())
                            {
                                do_else=false;
                                rule::symbolizers const& symbols = r->get_symbolizers();

                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {

                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                                if (style->get_filter_mode() == FILTER_FIRST)
                                {
                                    // Stop iterating over rules and proceed with next feature.
                                    break;
                                }
                            }
                        }
                        if (do_else)
                        {
                            BOOST_FOREACH( rule * r, else_rules )
                            {
                                rule::symbolizers const& symbols = r->get_symbolizers();
                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
//#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
//#endif
                                {
                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                            }
                        }
                    }
                }
                cache_features = false;
            }
        }

        p.end_layer_processing(lay);
    }

    Map const& m_;
    double scale_factor_;
};
}

#endif //FEATURE_STYLE_PROCESSOR_HPP
<commit_msg>+ restore #ifdefs around -> if(!p.process(symbols,*feature,prj_trans))<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

#ifndef FEATURE_STYLE_PROCESSOR_HPP
#define FEATURE_STYLE_PROCESSOR_HPP

// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/memory_datasource.hpp>

#ifdef MAPNIK_DEBUG
//#include <mapnik/wall_clock_timer.hpp>
#endif
// boost
#include <boost/foreach.hpp>
//stl
#include <vector>

namespace mapnik
{

template <typename Processor>
class feature_style_processor
{
    /** Calls the renderer's process function,
      * \param output     Renderer
      * \param f          Feature to process
      * \param prj_trans  Projection
      * \param sym        Symbolizer object
      */
    struct symbol_dispatch : public boost::static_visitor<>
    {
        symbol_dispatch (Processor & output,
                         Feature const& f,
                         proj_transform const& prj_trans)
            : output_(output),
              f_(f),
              prj_trans_(prj_trans)  {}

        template <typename T>
        void operator () (T const& sym) const
        {
            output_.process(sym,f_,prj_trans_);
        }

        Processor & output_;
        Feature const& f_;
        proj_transform const& prj_trans_;
    };
public:
    explicit feature_style_processor(Map const& m, double scale_factor = 1.0)
        : m_(m),
          scale_factor_(scale_factor) {}

    void apply()
    {
#ifdef MAPNIK_DEBUG
        //mapnik::wall_clock_progress_timer t(std::clog, "map rendering took: ");
#endif
        Processor & p = static_cast<Processor&>(*this);
        p.start_map_processing(m_);

        try
        {
            projection proj(m_.srs()); // map projection

            Map::const_metawriter_iterator metaItr = m_.begin_metawriters();
            Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->set_size(m_.width(), m_.height());
                metaItr->second->set_map_srs(proj);
                metaItr->second->start(m_.metawriter_output_properties);
            }

            double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
            scale_denom *= scale_factor_;
#ifdef MAPNIK_DEBUG
            std::clog << "scale denominator = " << scale_denom << "\n";
#endif
            BOOST_FOREACH ( layer const& lyr, m_.layers() )
            {
                if (lyr.isVisible(scale_denom))
                {
                    apply_to_layer(lyr, p, proj, scale_denom);
                }
            }

            metaItr = m_.begin_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->stop();
            }
        }
        catch (proj_init_error& ex)
        {
            std::clog << "proj_init_error:" << ex.what() << "\n";
        }

        p.end_map_processing(m_);
    }
private:
    void apply_to_layer(layer const& lay, Processor & p,
                        projection const& proj0, double scale_denom)
    {
#ifdef MAPNIK_DEBUG
        //wall_clock_progress_timer timer(clog, "end layer rendering: ");
#endif
        boost::shared_ptr<datasource> ds = lay.datasource();
        if (!ds)
        {
            std::clog << "WARNING: No datasource for layer '" << lay.name() << "'\n";
            return;
        }

        p.start_layer_processing(lay);

        if (ds)
        {

            box2d<double> ext = m_.get_buffered_extent();
            projection proj1(lay.srs());
            proj_transform prj_trans(proj0,proj1);

            // todo: only display raster if src and dest proj are matched
            // todo: add raster re-projection as an optional feature
            if (ds->type() == datasource::Raster && !prj_trans.equal())
            {
                std::clog << "WARNING: Map srs does not match layer srs, skipping raster layer '" << lay.name() << "' as raster re-projection is not currently supported (http://trac.mapnik.org/ticket/663)\n";
                std::clog << "map srs: '" << m_.srs() << "'\nlayer srs: '" << lay.srs() << "' \n";
                return;
            }

            //

            box2d<double> layer_ext = lay.envelope();

            double lx0 = layer_ext.minx();
            double ly0 = layer_ext.miny();
            double lz0 = 0.0;
            double lx1 = layer_ext.maxx();
            double ly1 = layer_ext.maxy();
            double lz1 = 0.0;
            // back project layers extent into main map projection
            prj_trans.backward(lx0,ly0,lz0);
            prj_trans.backward(lx1,ly1,lz1);

            // if no intersection then nothing to do for layer
            if ( lx0 > ext.maxx() || lx1 < ext.minx() || ly0 > ext.maxy() || ly1 < ext.miny() )
            {
                return;
            }

            // clip query bbox
            lx0 = std::max(ext.minx(),lx0);
            ly0 = std::max(ext.miny(),ly0);
            lx1 = std::min(ext.maxx(),lx1);
            ly1 = std::min(ext.maxy(),ly1);

            prj_trans.forward(lx0,ly0,lz0);
            prj_trans.forward(lx1,ly1,lz1);
            box2d<double> bbox(lx0,ly0,lx1,ly1);

            query::resolution_type res(m_.width()/m_.get_current_extent().width(),m_.height()/m_.get_current_extent().height());
            query q(bbox,res,scale_denom); //BBOX query

            std::vector<feature_type_style*> active_styles;
            std::set<std::string> names;
            attribute_collector collector(names);
            double filt_factor = 1;
            directive_collector d_collector(&filt_factor);

            std::vector<std::string> const& style_names = lay.styles();
            // iterate through all named styles collecting active styles and attribute names
            BOOST_FOREACH(std::string const& style_name, style_names)
            {
                boost::optional<feature_type_style const&> style=m_.find_style(style_name);
                if (!style)
                {
                    std::clog << "WARNING: style '" << style_name << "' required for layer '" << lay.name() << "' does not exist.\n";
                    continue;
                }

                const std::vector<rule>& rules=(*style).get_rules();
                bool active_rules=false;

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        active_rules = true;
                        if (ds->type() == datasource::Vector)
                        {
                            collector(r);
                        }
                        // TODO - in the future rasters should be able to be filtered.
                    }
                }
                if (active_rules)
                {
                    active_styles.push_back(const_cast<feature_type_style*>(&(*style)));
                }
            }

            // push all property names
            BOOST_FOREACH(std::string const& name, names)
            {
                q.add_property_name(name);
            }

            memory_datasource cache;
            bool cache_features = lay.cache_features() && style_names.size()>1?true:false;
            bool first = true;

            BOOST_FOREACH (feature_type_style * style, active_styles)
            {
                std::vector<rule*> if_rules;
                std::vector<rule*> else_rules;

                std::vector<rule> const& rules=style->get_rules();

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        if (r.has_else_filter())
                        {
                            else_rules.push_back(const_cast<rule*>(&r));
                        }
                        else
                        {
                            if_rules.push_back(const_cast<rule*>(&r));
                        }

                        if ( (ds->type() == datasource::Raster) &&
                             (ds->params().get<double>("filter_factor",0.0) == 0.0) )
                        {
                            rule::symbolizers const& symbols = r.get_symbolizers();
                            rule::symbolizers::const_iterator symIter = symbols.begin();
                            rule::symbolizers::const_iterator symEnd = symbols.end();
                            while (symIter != symEnd)
                            {
                                // if multiple raster symbolizers, last will be respected
                                // should we warn or throw?
                                boost::apply_visitor(d_collector,*symIter++);
                            }
                            q.set_filter_factor(filt_factor);
                        }
                    }
                }

                // process features
                featureset_ptr fs;
                if (first)
                {
                    if (cache_features)
                        first = false;
                    fs = ds->features(q);
                }
                else
                {
                    fs = cache.features(q);
                }

                if (fs)
                {
                    feature_ptr feature;
                    while ((feature = fs->next()))
                    {
                        bool do_else=true;

                        if (cache_features)
                        {
                            cache.push(feature);
                        }

                        BOOST_FOREACH(rule * r, if_rules )
                        {
                            expression_ptr const& expr=r->get_filter();
                            value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
                            if (result.to_bool())
                            {
                                do_else=false;
                                rule::symbolizers const& symbols = r->get_symbolizers();

                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {

                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                                if (style->get_filter_mode() == FILTER_FIRST)
                                {
                                    // Stop iterating over rules and proceed with next feature.
                                    break;
                                }
                            }
                        }
                        if (do_else)
                        {
                            BOOST_FOREACH( rule * r, else_rules )
                            {
                                rule::symbolizers const& symbols = r->get_symbolizers();
                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {
                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                            }
                        }
                    }
                }
                cache_features = false;
            }
        }

        p.end_layer_processing(lay);
    }

    Map const& m_;
    double scale_factor_;
};
}

#endif //FEATURE_STYLE_PROCESSOR_HPP
<|endoftext|>


<commit_before>#pragma once

#include <optional>
#include <string>
#include <string_view>
#include <variant>

namespace sdbusplus
{

namespace message
{

namespace details
{

/** Simple wrapper class for std::string to allow conversion to and from an
 *  alternative typename. */
struct string_wrapper
{
    std::string str;

    string_wrapper() = default;
    string_wrapper(const string_wrapper&) = default;
    string_wrapper& operator=(const string_wrapper&) = default;
    string_wrapper(string_wrapper&&) = default;
    string_wrapper& operator=(string_wrapper&&) = default;
    ~string_wrapper() = default;

    string_wrapper(const std::string& str) : str(str)
    {}
    string_wrapper(std::string&& str) : str(std::move(str))
    {}

    operator const std::string&() const volatile&
    {
        return const_cast<const string_wrapper*>(this)->str;
    }
    operator std::string&&() &&
    {
        return std::move(str);
    }

    bool operator==(const string_wrapper& r) const
    {
        return str == r.str;
    }
    bool operator!=(const string_wrapper& r) const
    {
        return str != r.str;
    }
    bool operator<(const string_wrapper& r) const
    {
        return str < r.str;
    }
    bool operator==(const std::string& r) const
    {
        return str == r;
    }
    bool operator!=(const std::string& r) const
    {
        return str != r;
    }
    bool operator<(const std::string& r) const
    {
        return str < r;
    }

    friend bool operator==(const std::string& l, const string_wrapper& r)
    {
        return l == r.str;
    }
    friend bool operator!=(const std::string& l, const string_wrapper& r)
    {
        return l != r.str;
    }
    friend bool operator<(const std::string& l, const string_wrapper& r)
    {
        return l < r.str;
    }
};

/** Simple wrapper class for std::string to allow conversion to and from an
 *  alternative typename. */
struct string_path_wrapper
{
    std::string str;

    string_path_wrapper() = default;
    string_path_wrapper(const string_path_wrapper&) = default;
    string_path_wrapper& operator=(const string_path_wrapper&) = default;
    string_path_wrapper(string_path_wrapper&&) = default;
    string_path_wrapper& operator=(string_path_wrapper&&) = default;
    ~string_path_wrapper() = default;

    string_path_wrapper(const std::string& str) : str(str)
    {}
    string_path_wrapper(std::string&& str) : str(std::move(str))
    {}

    operator const std::string&() const volatile&
    {
        return const_cast<const string_path_wrapper*>(this)->str;
    }
    operator std::string&&() &&
    {
        return std::move(str);
    }

    bool operator==(const string_path_wrapper& r) const
    {
        return str == r.str;
    }
    bool operator!=(const string_path_wrapper& r) const
    {
        return str != r.str;
    }
    bool operator<(const string_path_wrapper& r) const
    {
        return str < r.str;
    }
    bool operator==(const std::string& r) const
    {
        return str == r;
    }
    bool operator!=(const std::string& r) const
    {
        return str != r;
    }
    bool operator<(const std::string& r) const
    {
        return str < r;
    }

    friend bool operator==(const std::string& l, const string_path_wrapper& r)
    {
        return l == r.str;
    }
    friend bool operator!=(const std::string& l, const string_path_wrapper& r)
    {
        return l != r.str;
    }
    friend bool operator<(const std::string& l, const string_path_wrapper& r)
    {
        return l < r.str;
    }

    std::string filename() const;
    string_path_wrapper parent_path() const;
    string_path_wrapper operator/(std::string_view) const;
    string_path_wrapper& operator/=(std::string_view);
};

/** Typename for sdbus SIGNATURE types. */
struct signature_type
{};
/** Typename for sdbus UNIX_FD types. */
struct unix_fd_type
{
    int fd;

    unix_fd_type() = default;
    unix_fd_type(int f) : fd(f)
    {}

    operator int() const
    {
        return fd;
    }
};

} // namespace details

/** std::string wrapper for OBJECT_PATH. */
using object_path = details::string_path_wrapper;
/** std::string wrapper for SIGNATURE. */
using signature = details::string_wrapper;
using unix_fd = details::unix_fd_type;

namespace details
{

template <typename T>
struct convert_from_string
{
    static auto op(const std::string&) noexcept = delete;
};

template <typename T>
struct convert_to_string
{
    static std::string op(T) = delete;
};

} // namespace details

/** @brief Convert from a string to a native type.
 *
 *  Some C++ types cannot be represented directly on dbus, so we encode
 *  them as strings.  Enums are the primary example of this.  This is a
 *  template function prototype for the conversion from string functions.
 *
 *  @return A std::optional<T> containing the value if conversion is possible.
 */
template <typename T>
auto convert_from_string(const std::string& str) noexcept
{
    return details::convert_from_string<T>::op(str);
};

/** @brief Convert from a native type to a string.
 *
 *  Some C++ types cannot be represented directly on dbus, so we encode
 *  them as strings.  Enums are the primary example of this.  This is a
 *  template function prototype for the conversion to string functions.
 *
 *  @return A std::string containing an encoding of the value, if conversion is
 *          possible.
 */
template <typename T>
std::string convert_to_string(T t)
{
    return details::convert_to_string<T>::op(t);
}

namespace details
{
// SFINAE templates to determine if convert_from_string exists for a type.
template <typename T>
auto has_convert_from_string_helper(T)
    -> decltype(convert_from_string<T>::op(std::declval<std::string>()),
                std::true_type());
auto has_convert_from_string_helper(...) -> std::false_type;

template <typename T>
struct has_convert_from_string :
    decltype(has_convert_from_string_helper(std::declval<T>()))
{};

template <typename T>
inline constexpr bool has_convert_from_string_v =
    has_convert_from_string<T>::value;

// Specialization of 'convert_from_string' for variant.
template <typename... Types>
struct convert_from_string<std::variant<Types...>>
{
    static auto op(const std::string& str)
        -> std::optional<std::variant<Types...>>
    {
        if constexpr (0 < sizeof...(Types))
        {
            return process<Types...>(str);
        }
        return {};
    }

    // We need to iterate through all the variant types and find
    // the one which matches the contents of the string.  Often,
    // a variant can contain both a convertible-type (ie. enum) and
    // a string, so we need to iterate through all the convertible-types
    // first and convert to string as a last resort.
    template <typename T, typename... Args>
    static auto process(const std::string& str)
        -> std::optional<std::variant<Types...>>
    {
        // If convert_from_string exists for the type, attempt it.
        if constexpr (has_convert_from_string_v<T>)
        {
            auto r = convert_from_string<T>::op(str);
            if (r)
            {
                return r;
            }
        }

        // If there are any more types in the variant, try them.
        if constexpr (0 < sizeof...(Args))
        {
            auto r = process<Args...>(str);
            if (r)
            {
                return r;
            }
        }

        // Otherwise, if this is a string, do last-resort conversion.
        if constexpr (std::is_same_v<std::string, std::remove_cv_t<T>>)
        {
            return str;
        }

        return {};
    }
};

} // namespace details

} // namespace message
} // namespace sdbusplus

namespace std
{

/** Overload of std::hash for details::string_wrappers */
template <>
struct hash<sdbusplus::message::details::string_wrapper>
{
    using argument_type = sdbusplus::message::details::string_wrapper;
    using result_type = std::size_t;

    result_type operator()(argument_type const& s) const
    {
        return hash<std::string>()(s.str);
    }
};

/** Overload of std::hash for details::string_wrappers */
template <>
struct hash<sdbusplus::message::details::string_path_wrapper>
{
    using argument_type = sdbusplus::message::details::string_path_wrapper;
    using result_type = std::size_t;

    result_type operator()(argument_type const& s) const
    {
        return hash<std::string>()(s.str);
    }
};

} // namespace std
<commit_msg>message: export has_convert_from_string<commit_after>#pragma once

#include <optional>
#include <string>
#include <string_view>
#include <variant>

namespace sdbusplus
{

namespace message
{

namespace details
{

/** Simple wrapper class for std::string to allow conversion to and from an
 *  alternative typename. */
struct string_wrapper
{
    std::string str;

    string_wrapper() = default;
    string_wrapper(const string_wrapper&) = default;
    string_wrapper& operator=(const string_wrapper&) = default;
    string_wrapper(string_wrapper&&) = default;
    string_wrapper& operator=(string_wrapper&&) = default;
    ~string_wrapper() = default;

    string_wrapper(const std::string& str) : str(str)
    {}
    string_wrapper(std::string&& str) : str(std::move(str))
    {}

    operator const std::string&() const volatile&
    {
        return const_cast<const string_wrapper*>(this)->str;
    }
    operator std::string&&() &&
    {
        return std::move(str);
    }

    bool operator==(const string_wrapper& r) const
    {
        return str == r.str;
    }
    bool operator!=(const string_wrapper& r) const
    {
        return str != r.str;
    }
    bool operator<(const string_wrapper& r) const
    {
        return str < r.str;
    }
    bool operator==(const std::string& r) const
    {
        return str == r;
    }
    bool operator!=(const std::string& r) const
    {
        return str != r;
    }
    bool operator<(const std::string& r) const
    {
        return str < r;
    }

    friend bool operator==(const std::string& l, const string_wrapper& r)
    {
        return l == r.str;
    }
    friend bool operator!=(const std::string& l, const string_wrapper& r)
    {
        return l != r.str;
    }
    friend bool operator<(const std::string& l, const string_wrapper& r)
    {
        return l < r.str;
    }
};

/** Simple wrapper class for std::string to allow conversion to and from an
 *  alternative typename. */
struct string_path_wrapper
{
    std::string str;

    string_path_wrapper() = default;
    string_path_wrapper(const string_path_wrapper&) = default;
    string_path_wrapper& operator=(const string_path_wrapper&) = default;
    string_path_wrapper(string_path_wrapper&&) = default;
    string_path_wrapper& operator=(string_path_wrapper&&) = default;
    ~string_path_wrapper() = default;

    string_path_wrapper(const std::string& str) : str(str)
    {}
    string_path_wrapper(std::string&& str) : str(std::move(str))
    {}

    operator const std::string&() const volatile&
    {
        return const_cast<const string_path_wrapper*>(this)->str;
    }
    operator std::string&&() &&
    {
        return std::move(str);
    }

    bool operator==(const string_path_wrapper& r) const
    {
        return str == r.str;
    }
    bool operator!=(const string_path_wrapper& r) const
    {
        return str != r.str;
    }
    bool operator<(const string_path_wrapper& r) const
    {
        return str < r.str;
    }
    bool operator==(const std::string& r) const
    {
        return str == r;
    }
    bool operator!=(const std::string& r) const
    {
        return str != r;
    }
    bool operator<(const std::string& r) const
    {
        return str < r;
    }

    friend bool operator==(const std::string& l, const string_path_wrapper& r)
    {
        return l == r.str;
    }
    friend bool operator!=(const std::string& l, const string_path_wrapper& r)
    {
        return l != r.str;
    }
    friend bool operator<(const std::string& l, const string_path_wrapper& r)
    {
        return l < r.str;
    }

    std::string filename() const;
    string_path_wrapper parent_path() const;
    string_path_wrapper operator/(std::string_view) const;
    string_path_wrapper& operator/=(std::string_view);
};

/** Typename for sdbus SIGNATURE types. */
struct signature_type
{};
/** Typename for sdbus UNIX_FD types. */
struct unix_fd_type
{
    int fd;

    unix_fd_type() = default;
    unix_fd_type(int f) : fd(f)
    {}

    operator int() const
    {
        return fd;
    }
};

} // namespace details

/** std::string wrapper for OBJECT_PATH. */
using object_path = details::string_path_wrapper;
/** std::string wrapper for SIGNATURE. */
using signature = details::string_wrapper;
using unix_fd = details::unix_fd_type;

namespace details
{

template <typename T>
struct convert_from_string
{
    static auto op(const std::string&) noexcept = delete;
};

template <typename T>
struct convert_to_string
{
    static std::string op(T) = delete;
};

} // namespace details

/** @brief Convert from a string to a native type.
 *
 *  Some C++ types cannot be represented directly on dbus, so we encode
 *  them as strings.  Enums are the primary example of this.  This is a
 *  template function prototype for the conversion from string functions.
 *
 *  @return A std::optional<T> containing the value if conversion is possible.
 */
template <typename T>
auto convert_from_string(const std::string& str) noexcept
{
    return details::convert_from_string<T>::op(str);
};

/** @brief Convert from a native type to a string.
 *
 *  Some C++ types cannot be represented directly on dbus, so we encode
 *  them as strings.  Enums are the primary example of this.  This is a
 *  template function prototype for the conversion to string functions.
 *
 *  @return A std::string containing an encoding of the value, if conversion is
 *          possible.
 */
template <typename T>
std::string convert_to_string(T t)
{
    return details::convert_to_string<T>::op(t);
}

namespace details
{
// SFINAE templates to determine if convert_from_string exists for a type.
template <typename T>
auto has_convert_from_string_helper(T)
    -> decltype(convert_from_string<T>::op(std::declval<std::string>()),
                std::true_type());
auto has_convert_from_string_helper(...) -> std::false_type;

template <typename T>
struct has_convert_from_string :
    decltype(has_convert_from_string_helper(std::declval<T>()))
{};

template <typename T>
inline constexpr bool has_convert_from_string_v =
    has_convert_from_string<T>::value;

// Specialization of 'convert_from_string' for variant.
template <typename... Types>
struct convert_from_string<std::variant<Types...>>
{
    static auto op(const std::string& str)
        -> std::optional<std::variant<Types...>>
    {
        if constexpr (0 < sizeof...(Types))
        {
            return process<Types...>(str);
        }
        return {};
    }

    // We need to iterate through all the variant types and find
    // the one which matches the contents of the string.  Often,
    // a variant can contain both a convertible-type (ie. enum) and
    // a string, so we need to iterate through all the convertible-types
    // first and convert to string as a last resort.
    template <typename T, typename... Args>
    static auto process(const std::string& str)
        -> std::optional<std::variant<Types...>>
    {
        // If convert_from_string exists for the type, attempt it.
        if constexpr (has_convert_from_string_v<T>)
        {
            auto r = convert_from_string<T>::op(str);
            if (r)
            {
                return r;
            }
        }

        // If there are any more types in the variant, try them.
        if constexpr (0 < sizeof...(Args))
        {
            auto r = process<Args...>(str);
            if (r)
            {
                return r;
            }
        }

        // Otherwise, if this is a string, do last-resort conversion.
        if constexpr (std::is_same_v<std::string, std::remove_cv_t<T>>)
        {
            return str;
        }

        return {};
    }
};

} // namespace details

/** Export template helper to determine if a type has convert_from_string. */
template <typename T>
inline constexpr bool has_convert_from_string_v =
    details::has_convert_from_string_v<T>;

} // namespace message
} // namespace sdbusplus

namespace std
{

/** Overload of std::hash for details::string_wrappers */
template <>
struct hash<sdbusplus::message::details::string_wrapper>
{
    using argument_type = sdbusplus::message::details::string_wrapper;
    using result_type = std::size_t;

    result_type operator()(argument_type const& s) const
    {
        return hash<std::string>()(s.str);
    }
};

/** Overload of std::hash for details::string_wrappers */
template <>
struct hash<sdbusplus::message::details::string_path_wrapper>
{
    using argument_type = sdbusplus::message::details::string_path_wrapper;
    using result_type = std::size_t;

    result_type operator()(argument_type const& s) const
    {
        return hash<std::string>()(s.str);
    }
};

} // namespace std
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*! @file
    @brief  SEEDA03 client クラス
	@copyright Copyright 2017 Kunihito Hiramatsu All Right Reserved.
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "main.hpp"

#include "GR/core/ethernet_client.hpp"
#include "sample.hpp"

// #define CLIENT_DEBUG

namespace seeda {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  client クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class client {

#ifdef CLIENT_DEBUG
		typedef utils::format debug_format;
#else
		typedef utils::null_format debug_format;
#endif

		static const uint16_t PORT = 3000;	///< クライアント・ポート

		net::ethernet_client	client_;

		typedef utils::basic_format<net::ether_string<net::ethernet::format_id::client0, 2048> > format;

		enum class task {
			startup,
			req_connect,
			wait_connect,
			time_sync,
			make_form,
			url_decode,
			send_data,
			disconnect,
			sync_close,
		};

		task		task_;

		net::ip_address		ip_;

		uint16_t	port_;
		uint32_t	delay_;
		uint32_t	timeout_;

		time_t		time_;

		struct tm	tm_;

		char		form_[1024];
		char		data_[2048];

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクタ
		*/
		//-----------------------------------------------------------------//
		client(net::ethernet& eth) : client_(eth, PORT), task_(task::startup),
#ifdef SEEDA
			ip_(192, 168, 1, 3),
#else
			ip_(192, 168, 3, 7),
#endif
			port_(PORT),
			delay_(0), timeout_(0), time_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  IP アドレスの取得
			@return IP アドレス
		*/
		//-----------------------------------------------------------------//
		const net::ip_address& get_ip() const { return ip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  IP アドレスの参照
			@return IP アドレス
		*/
		//-----------------------------------------------------------------//
		net::ip_address& at_ip() { return ip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  ポートの取得
			@return ポート
		*/
		//-----------------------------------------------------------------//
		uint16_t get_port() const { return port_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  ポートの設定
			@param[in]	port	ポート
		*/
		//-----------------------------------------------------------------//
		void set_port(uint16_t port) { port_ = port; }

		//-----------------------------------------------------------------//
		/*!
			@brief  接続開始
		*/
		//-----------------------------------------------------------------//
		void start_connect()
		{
			task_ = task::req_connect;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  再接続
		*/
		//-----------------------------------------------------------------//
		void restart()
		{
			task_ = task::disconnect;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  サービス
		*/
		//-----------------------------------------------------------------//
		void service()
		{
			time_t t;
			switch(task_) {

			case task::startup:
				break;

			case task::req_connect:
				if(client_.connect(ip_, port_, TMO_NBLK)) {
				}
				timeout_ = 5 * 100;  // 再接続待ち時間
				task_ = task::wait_connect;
				break;

			case task::wait_connect:
				if(!client_.connected()) {
					if(timeout_ > 0) {
						--timeout_;
					} else {
						auto st = client_.get_ethernet().get_stat(client_.get_cepid());
						debug_format("TCP Client stat: %d\n") % static_cast<int>(st);
						// 接続しないので、「re_connect」要求を出してみる
						if(st == TCP_API_STAT_CLOSED) {
							task_ = task::disconnect;
						} else {
							client_.re_connect();
							task_ = task::req_connect;
							timeout_ = 5 * 100;  // 再接続待ち時間
						}
					}
					break;
				} else {
					debug_format("Start SEEDA03 Client: %s port(%d), fd(%d)\n")
						% ip_.c_str() % port_ % client_.get_cepid();
					format::chaout().set_fd(client_.get_cepid());
					time_ = get_sample_data().time_;
					task_ = task::time_sync;
				}
				break;

			case task::time_sync:
				{
					auto t = get_sample_data().time_;
					if(time_ == t) break;
					time_ = t;
					struct tm* m = localtime(&t);
					tm_ = *m;
					task_ = task::make_form;
				}
				break;

			case task::make_form:
				utils::sformat("%04d/%02d/%02d,%02d:%02d:%02d", form_, sizeof(form_))
					% static_cast<uint32_t>(tm_.tm_year + 1900)
					% static_cast<uint32_t>(tm_.tm_mon + 1)
					% static_cast<uint32_t>(tm_.tm_mday)
					% static_cast<uint32_t>(tm_.tm_hour)
					% static_cast<uint32_t>(tm_.tm_min)
					% static_cast<uint32_t>(tm_.tm_sec);
				{
					const sample_data& smd = get_sample_data();
					for(int ch = 0; ch < 8; ++ch) {
						utils::sformat(",", form_, sizeof(form_), true);
						smd.smp_[ch].make_csv2(form_, sizeof(form_), true);
					}
				}
				utils::sformat("\n", form_, sizeof(form_), true);
				task_ = task::url_decode;
				break;

			case task::url_decode:
				utils::str::url_decode_to_str(form_, data_, sizeof(data_));
				task_ = task::send_data;
				break;

			case task::send_data:
				format::chaout().clear();
				format("POST /api/?val=%s HTTP/1.1\n") % data_;
				format("Host: %d.%d.%d.%d\n")
					% static_cast<int>(ip_[0])
					% static_cast<int>(ip_[1])
					% static_cast<int>(ip_[2])
					% static_cast<int>(ip_[3]);
				format("Content-Type: application/x-www-form-urlencoded\n");
				format("User-Agent: SEEDA03 Post Client\n");
				format("Connection: close\n\n");
				format::chaout().flush();
				task_ = task::disconnect;
				break;

			case task::disconnect:
				client_.stop();
				timeout_ = 5;
				task_ = task::sync_close;
				break;

			case task::sync_close:
				if(timeout_ > 0) {
					--timeout_;
				} else {
					debug_format("Client disconnected: %s\n") % ip_.c_str();
					task_ = task::req_connect;
				}
				break;
			}
		}
	};
}
<commit_msg>update client connection management<commit_after>#pragma once
//=====================================================================//
/*! @file
    @brief  SEEDA03 client クラス
	@copyright Copyright 2017 Kunihito Hiramatsu All Right Reserved.
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "main.hpp"

#include "GR/core/ethernet_client.hpp"
#include "sample.hpp"

// #define CLIENT_DEBUG

namespace seeda {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  client クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class client {

#ifdef CLIENT_DEBUG
		typedef utils::format debug_format;
#else
		typedef utils::null_format debug_format;
#endif

		static const uint16_t PORT = 3000;	///< クライアント・ポート

		net::ethernet_client	client_;

		typedef utils::basic_format<net::ether_string<net::ethernet::format_id::client0, 2048> > format;

		enum class task {
			startup,
			req_connect,
			wait_connect,
			time_sync,
			make_form,
			url_decode,
			send_data,
			disconnect,
			sync_close,
		};

		task		task_;

		net::ip_address		ip_;

		uint16_t	port_;
		uint32_t	delay_;
		uint32_t	timeout_;

		time_t		time_;

		struct tm	tm_;

		char		form_[1024];
		char		data_[2048];

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクタ
		*/
		//-----------------------------------------------------------------//
		client(net::ethernet& eth) : client_(eth, PORT), task_(task::startup),
#ifdef SEEDA
			ip_(192, 168, 1, 3),
#else
			ip_(192, 168, 3, 7),
#endif
			port_(PORT),
			delay_(0), timeout_(0), time_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  IP アドレスの取得
			@return IP アドレス
		*/
		//-----------------------------------------------------------------//
		const net::ip_address& get_ip() const { return ip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  IP アドレスの参照
			@return IP アドレス
		*/
		//-----------------------------------------------------------------//
		net::ip_address& at_ip() { return ip_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  ポートの取得
			@return ポート
		*/
		//-----------------------------------------------------------------//
		uint16_t get_port() const { return port_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  ポートの設定
			@param[in]	port	ポート
		*/
		//-----------------------------------------------------------------//
		void set_port(uint16_t port) { port_ = port; }

		//-----------------------------------------------------------------//
		/*!
			@brief  接続開始
		*/
		//-----------------------------------------------------------------//
		void start_connect()
		{
			task_ = task::req_connect;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  サービス
		*/
		//-----------------------------------------------------------------//
		void service()
		{
			time_t t;
			switch(task_) {

			case task::startup:
				break;

			case task::req_connect:
				if(client_.connect(ip_, port_, TMO_NBLK)) {
				}
				timeout_ = 5 * 100;  // 再接続待ち時間
				task_ = task::wait_connect;
				break;

			case task::wait_connect:
				if(!client_.connected()) {
					if(timeout_ > 0) {
						--timeout_;
					} else {
						auto st = client_.get_ethernet().get_stat(client_.get_cepid());
						debug_format("TCP Client re_connect: %d\n") % static_cast<int>(st);
						// 接続しないので、「re_connect」要求を出してみる
						// ※ re_connect では、タイムアウト（１０分）を無効にする。
						client_.re_connect();
						timeout_ = 5 * 100;  // 再接続待ち時間
					}
				} else {
					debug_format("Start SEEDA03 Client: %s port(%d), fd(%d)\n")
						% ip_.c_str() % port_ % client_.get_cepid();
					format::chaout().set_fd(client_.get_cepid());
					time_ = get_sample_data().time_;
					task_ = task::time_sync;
				}
				break;

			case task::time_sync:
				{
					auto t = get_sample_data().time_;
					if(time_ == t) break;
					time_ = t;
					struct tm* m = localtime(&t);
					tm_ = *m;
					task_ = task::make_form;
				}
				break;

			case task::make_form:
				utils::sformat("%04d/%02d/%02d,%02d:%02d:%02d", form_, sizeof(form_))
					% static_cast<uint32_t>(tm_.tm_year + 1900)
					% static_cast<uint32_t>(tm_.tm_mon + 1)
					% static_cast<uint32_t>(tm_.tm_mday)
					% static_cast<uint32_t>(tm_.tm_hour)
					% static_cast<uint32_t>(tm_.tm_min)
					% static_cast<uint32_t>(tm_.tm_sec);
				{
					const sample_data& smd = get_sample_data();
					for(int ch = 0; ch < 8; ++ch) {
						utils::sformat(",", form_, sizeof(form_), true);
						smd.smp_[ch].make_csv2(form_, sizeof(form_), true);
					}
				}
				utils::sformat("\n", form_, sizeof(form_), true);
				task_ = task::url_decode;
				break;

			case task::url_decode:
				utils::str::url_decode_to_str(form_, data_, sizeof(data_));
				task_ = task::send_data;
				break;

			case task::send_data:
				format::chaout().clear();
				format("POST /api/?val=%s HTTP/1.1\n") % data_;
				format("Host: %d.%d.%d.%d\n")
					% static_cast<int>(ip_[0])
					% static_cast<int>(ip_[1])
					% static_cast<int>(ip_[2])
					% static_cast<int>(ip_[3]);
				format("Content-Type: application/x-www-form-urlencoded\n");
				format("User-Agent: SEEDA03 Post Client\n");
				format("Connection: close\n\n");
				format::chaout().flush();
				task_ = task::disconnect;
				break;

			case task::disconnect:
				client_.stop();
				timeout_ = 5;
				task_ = task::sync_close;
				break;

			case task::sync_close:
				if(timeout_ > 0) {
					--timeout_;
				} else {
					debug_format("Client disconnected: %s\n") % ip_.c_str();
					task_ = task::req_connect;
				}
				break;
			}
		}
	};
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008-2018 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix3 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.
 *
 * For more details, see http://www.mrtrix.org/
 */

#include "command.h"
#include "image.h"
#include "algo/loop.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "David Raffelt (david.raffelt@florey.edu.au)";

  SYNOPSIS = "Pad an image to increase the FOV";

  ARGUMENTS
  + Argument ("image_in",
              "the image to be padded").type_image_in()
  + Argument ("image_out",
              "the output path for the resulting padded image").type_image_out();

  OPTIONS
  + Option   ("uniform",
              "pad the input image by a uniform number of voxels on all sides (in 3D)")
  + Argument ("number").type_integer (0)

  + Option   ("axis",
              "pad the input image along the provided axis (defined by index). Lower and upper define "
              "the number of voxels to add to the lower and upper bounds of the axis").allow_multiple()
  + Argument ("index").type_integer (0, 2)
  + Argument ("lower").type_integer (0)
  + Argument ("upper").type_integer (0);
}

void run ()
{
  Header input_header = Header::open (argument[0]);
  auto input = input_header.get_image<float>();

  ssize_t bounds[3][2] = { {0, input_header.size (0) - 1},
                       {0, input_header.size (1) - 1},
                       {0, input_header.size (2) - 1} };

  ssize_t padding[3][2] = { {0, 0}, {0, 0}, {0, 0} };

  auto opt = get_options ("uniform");
  if (opt.size()) {
    ssize_t pad = opt[0][0];
    for (size_t axis = 0; axis < 3; axis++) {
      padding[axis][0] = pad;
      padding[axis][1] = pad;
    }
  }

  opt = get_options ("axis");
  for (size_t i = 0; i != opt.size(); ++i) {
    // Manual padding of axis overrides uniform padding
    const size_t axis  = opt[i][0];
    padding[axis][0] = opt[i][1];
    padding[axis][1] = opt[i][2];
  }

  Header output_header (input_header);
  auto output_transform = input_header.transform();
  for (size_t axis = 0; axis < 3; ++axis) {
    output_header.size (axis) = output_header.size(axis) + padding[axis][0] + padding[axis][1];
    output_transform (axis, 3) +=	(output_transform (axis, 0) * (bounds[0][0] - padding[0][0]) * input_header.spacing (0))
                                + (output_transform (axis, 1) * (bounds[1][0] - padding[0][0]) * input_header.spacing (1))
                                + (output_transform (axis, 2) * (bounds[2][0] - padding[0][0]) * input_header.spacing (2));
  }
  output_header.transform() = output_transform;
  auto output = Image<float>::create (argument[1], output_header);

  for (auto l = Loop ("padding image... ", output) (output); l; ++l) {
    bool in_bounds = true;
    for (size_t axis = 0; axis < 3; ++axis) {
      input.index(axis) = output.index(axis) - padding[axis][0];
      if (input.index(axis) < 0 || input.index(axis) >= input_header.size (axis))
        in_bounds = false;
    }
    if (input.ndim() > 3)
      input.index (3) = output.index (3);
    if (in_bounds)
      output.value() = input.value();
    else
      output.value() = 0;
  }

}

<commit_msg>mrpad: fix header translation of y and z axes<commit_after>/*
 * Copyright (c) 2008-2018 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix3 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.
 *
 * For more details, see http://www.mrtrix.org/
 */

#include "command.h"
#include "image.h"
#include "algo/loop.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "David Raffelt (david.raffelt@florey.edu.au)";

  SYNOPSIS = "Pad an image to increase the FOV";

  ARGUMENTS
  + Argument ("image_in",
              "the image to be padded").type_image_in()
  + Argument ("image_out",
              "the output path for the resulting padded image").type_image_out();

  OPTIONS
  + Option   ("uniform",
              "pad the input image by a uniform number of voxels on all sides (in 3D)")
  + Argument ("number").type_integer (0)

  + Option   ("axis",
              "pad the input image along the provided axis (defined by index). Lower and upper define "
              "the number of voxels to add to the lower and upper bounds of the axis").allow_multiple()
  + Argument ("index").type_integer (0, 2)
  + Argument ("lower").type_integer (0)
  + Argument ("upper").type_integer (0);
}

void run ()
{
  Header input_header = Header::open (argument[0]);
  auto input = input_header.get_image<float>();

  ssize_t bounds[3][2] = { {0, input_header.size (0) - 1},
                       {0, input_header.size (1) - 1},
                       {0, input_header.size (2) - 1} };

  ssize_t padding[3][2] = { {0, 0}, {0, 0}, {0, 0} };

  auto opt = get_options ("uniform");
  if (opt.size()) {
    ssize_t pad = opt[0][0];
    for (size_t axis = 0; axis < 3; axis++) {
      padding[axis][0] = pad;
      padding[axis][1] = pad;
    }
  }

  opt = get_options ("axis");
  for (size_t i = 0; i != opt.size(); ++i) {
    // Manual padding of axis overrides uniform padding
    const size_t axis  = opt[i][0];
    padding[axis][0] = opt[i][1];
    padding[axis][1] = opt[i][2];
  }

  Header output_header (input_header);
  auto output_transform = input_header.transform();
  for (size_t axis = 0; axis < 3; ++axis) {
    output_header.size (axis) = output_header.size(axis) + padding[axis][0] + padding[axis][1];
    output_transform (axis, 3) +=	(output_transform (axis, 0) * (bounds[0][0] - padding[0][0]) * input_header.spacing (0))
                                + (output_transform (axis, 1) * (bounds[1][0] - padding[1][0]) * input_header.spacing (1))
                                + (output_transform (axis, 2) * (bounds[2][0] - padding[2][0]) * input_header.spacing (2));
  }
  output_header.transform() = output_transform;
  auto output = Image<float>::create (argument[1], output_header);

  for (auto l = Loop ("padding image... ", output) (output); l; ++l) {
    bool in_bounds = true;
    for (size_t axis = 0; axis < 3; ++axis) {
      input.index(axis) = output.index(axis) - padding[axis][0];
      if (input.index(axis) < 0 || input.index(axis) >= input_header.size (axis))
        in_bounds = false;
    }
    if (input.ndim() > 3)
      input.index (3) = output.index (3);
    if (in_bounds)
      output.value() = input.value();
    else
      output.value() = 0;
  }

}

<|endoftext|>


<commit_before>//
// Macro designed for use with the AliAnalysisTaskDptDptCorrelations task.
//
// Author: Claude Pruneau, Wayne State
/////////////////////////////////////////////////////////////////////////////////
AliAnalysisTaskDptDptCorrelations *AddTaskDptDptCorrelations(int    singlesOnly            = 1,
                                                             int    useWeights             = 0,
                                                             int    centralityMethod       = 4)

{
  // Set Default Configuration of this analysis
  // ==========================================
  int    debugLevel             = 0;
  int    singlesOnly            = 1;
  int    useWeights             = 0;
  int    rejectPileup           = 1;
  int    rejectPairConversion   = 1;
  int    sameFilter             = 1;

  int    centralityMethod       =  4;
  int    nCentrality            =  10;
  double minCentrality[] = { 0.5,   5., 10., 20., 30., 40., 50., 60., 70., 80. };
  double maxCentrality[] = { 5.0,  10., 20., 30., 40., 50., 60., 70., 80., 90. };

  int    nChargeSets             = 1;
  int    chargeSets[] = { 1, 0, 3 };

  double zMin                   = -10.;
  double zMax                   =  10.;
  double ptMin                  =  0.2;
  double ptMax                  =  2.0;
  double etaMin                 = -1.0;
  double etaMax                 =  1.0;
  double dcaZMin                = -3.0;
  double dcaZMax                =  3.0;
  double dcaXYMin               = -3.0;
  double dcaXYMax               =  3.0;
  double dedxMin                =  0.0;
  double dedxMax                =  20000.0;
  int    nClusterMin            =   70;
  int    trackFilterBit         =  128;

  int    requestedCharge1       =  1; //default
  int    requestedCharge2       = -1; //default

  // Get the pointer to the existing analysis manager via the static access method.
  // ==============================================================================
  AliAnalysisManager *analysisManager = AliAnalysisManager::GetAnalysisManager();

  if (!analysisManager)
    {
    ::Error("AddTaskDptDptCorrelations", "No analysis manager to connect to.");
    return NULL;
    }

  TString part1Name;
  TString part2Name;
  TString eventName;
  TString prefixName        = "Corr_";
  TString pileupRejecSuffix = "_PileupRejec";
  TString pairRejecSuffix   = "_PairRejec";
  TString calibSuffix       = "_calib";
  TString singlesOnlySuffix = "_SO";
  TString suffix;

  TString inputPath         = ".";
  TString outputPath        = ".";
  TString baseName;
  TString listName;
  TString taskName;
  TString inputHistogramFileName;
  TString outputHistogramFileName;

  // Create the task and add subtask.
  // ===========================================================================
  int iTask = 0; // task counter
  AliAnalysisDataContainer *taskInputContainer;
  AliAnalysisDataContainer *taskOutputContainer;

  for (int iCentrality=0; iCentrality < nCentrality; ++iCentrality)
    {
    for (int iChargeSet=0; iChargeSet < nChargeSets; iChargeSet++)
      {
      switch (chargeSets[iChargeSet])
        {
          case 0: part1Name = "P_"; part2Name = "P_"; requestedCharge1 =  1; requestedCharge2 =  1; sameFilter = 1; break;
          case 1: part1Name = "P_"; part2Name = "M_"; requestedCharge1 =  1; requestedCharge2 = -1; sameFilter = 0;   break;
          case 2: part1Name = "M_"; part2Name = "P_"; requestedCharge1 = -1; requestedCharge2 =  1; sameFilter = 0;   break;
          case 3: part1Name = "M_"; part2Name = "M_"; requestedCharge1 = -1; requestedCharge2 = -1; sameFilter = 1;   break;
        }
      //part1Name += int(1000*etaMin);
      part1Name += "eta";
      part1Name += int(1000*etaMax);
      part1Name += "_";
      part1Name += int(1000*ptMin);
      part1Name += "pt";
      part1Name += int(1000*ptMax);
      part1Name += "_";
      //part2Name += int(1000*etaMin);
      part2Name += "eta";
      part2Name += int(1000*etaMax);
      part2Name += "_";
      part2Name += int(1000*ptMin);
      part2Name += "pt";
      part2Name += int(1000*ptMax);
      part2Name += "_";
      eventName =  "";
      eventName += int(10.*minCentrality[iCentrality] );
      eventName += "Vo";
      eventName += int(10.*maxCentrality[iCentrality] );
      //eventName += "_";
      //eventName += int(10*zMin );
      //eventName += "Z";
      //eventName += int(10*zMax );
      if (rejectPileup)         eventName += pileupRejecSuffix;
      if (rejectPairConversion) eventName += pairRejecSuffix;
      baseName     =   prefixName;
      baseName     +=  part1Name;
      baseName     +=  part2Name;
      baseName     +=  eventName;
      listName     =   baseName;
      taskName     =   baseName;
      //inputHistogramFileName = inputPath;
      //inputHistogramFileName += "/";
      inputHistogramFileName =  baseName;
      inputHistogramFileName += calibSuffix;
      inputHistogramFileName += ".root";
      //outputHistogramFileName = outputPath;
      //outputHistogramFileName += "/";
      outputHistogramFileName = baseName;
      if (singlesOnly) outputHistogramFileName += singlesOnlySuffix;
      outputHistogramFileName += ".root";

      cout << "                   iTask: " << iTask << endl;
      cout << "               Task Name: " << taskName << endl;
      cout << "               List Name: " << listName << endl;
      cout << "  inputHistogramFileName: " << inputHistogramFileName  << endl;
      cout << " outputHistogramFileName: " << outputHistogramFileName << endl;
      cout << "           using weights: " << useWeights              << endl;
      TFile  * inputFile  = 0;
      TList  * histoList  = 0;
      TH3F   * weight_1   = 0;
      TH3F   * weight_2   = 0;
      if (useWeights)
        {
        inputFile = new TFile(inputHistogramFileName);
        if (!inputFile)
          {
          cout << "Requested file:" << inputHistogramFileName << " was not opened. ABORT." << endl;
          return;
          }
        histoList = (TList *) inputFile->Get(listName);
        if (!histoList)
          {
          cout << "Requested list:" << listName << " was not found. ABORT." << endl;
          return;
          }
        if (requestedCharge1 == 1)
          weight_1 = (TH3 *) histoList->FindObject("correction_p");
        else
          weight_1 = (TH3 *) histoList->FindObject("correction_m");
        if (!weight_1)
          {
          cout << "Requested histogram 'correction_p/m' was not found. ABORT." << endl;
          return;
          }
        if (!sameFilter)
          {
          weight_2 = 0;
          if (requestedCharge2 == 1)
            weight_2 = (TH3 *) histoList->FindObject("correction_p");
          else
            weight_2 = (TH3 *) histoList->FindObject("correction_m");
          if (!weight_2)
            {
            cout << "Requested histogram 'correction_p/m' was not found. ABORT." << endl;
            return;
            }
          }
        }
      AliAnalysisTaskDptDptCorrelations* task = new  AliAnalysisTaskDptDptCorrelations(taskName);
      //configure my task
      task->SetDebugLevel(          debugLevel      );
      task->SetSameFilter(          sameFilter      );
      task->SetSinglesOnly(         singlesOnly     );
      task->SetUseWeights(          useWeights      );
      task->SetRejectPileup(        rejectPileup    );
      task->SetRejectPairConversion(rejectPairConversion);
      task->SetVertexZMin(          zMin            );
      task->SetVertexZMax(          zMax            );
      task->SetVertexXYMin(         -1.            );
      task->SetVertexXYMax(          1.            );
      task->SetCentralityMethod(    centralityMethod);
      task->SetCentrality(          minCentrality[iCentrality], maxCentrality[iCentrality]);
      task->SetPtMin1(              ptMin           );
      task->SetPtMax1(              ptMax           );
      task->SetEtaMin1(             etaMin          );
      task->SetEtaMax1(             etaMax          );
      task->SetPtMin2(              ptMin           );
      task->SetPtMax2(              ptMax           );
      task->SetEtaMin2(             etaMin          );
      task->SetEtaMax2(             etaMax          );
      task->SetDcaZMin(             dcaZMin         );
      task->SetDcaZMax(             dcaZMax         );
      task->SetDcaXYMin(            dcaXYMin        );
      task->SetDcaXYMax(            dcaXYMax        );
      task->SetDedxMin(             dedxMin         );
      task->SetDedxMax(             dedxMax         );
      task->SetNClusterMin(         nClusterMin     );
      task->SetTrackFilterBit(      trackFilterBit  );
      task->SetRequestedCharge_1(   requestedCharge1);
      task->SetRequestedCharge_2(   requestedCharge2);
      task->SetWeigth_1(            weight_1        );
      task->SetWeigth_2(            weight_2        );

      cout << "Creating task output container" << endl;
      taskOutputContainer = analysisManager->CreateContainer(listName,
                                                             TList::Class(),
                                                             AliAnalysisManager::kOutputContainer,
                                                             Form("%s:%s", AliAnalysisManager::GetCommonFileName(), listName)); //outputHistogramFileName);
      cout << "Add task to analysis manager and connect it to input and output containers" << endl;
      analysisManager->AddTask(task);
      analysisManager->ConnectInput( task,  0, analysisManager->GetCommonInputContainer());
      analysisManager->ConnectOutput(task,  0, taskOutputContainer );
      cout << "Task added ...." << endl;

      iTask++;
      }
    }

  return task;
}
<commit_msg>changed output file name<commit_after>//
// Macro designed for use with the AliAnalysisTaskDptDptCorrelations task.
//
// Author: Claude Pruneau, Wayne State
/////////////////////////////////////////////////////////////////////////////////
AliAnalysisTaskDptDptCorrelations *AddTaskDptDptCorrelations(int    singlesOnly            = 1,
                                                             int    useWeights             = 0,
                                                             int    centralityMethod       = 4)

{
  // Set Default Configuration of this analysis
  // ==========================================
  int    debugLevel             = 0;
  int    singlesOnly            = 1;
  int    useWeights             = 0;
  int    rejectPileup           = 1;
  int    rejectPairConversion   = 1;
  int    sameFilter             = 1;

  int    centralityMethod       =  4;
  int    nCentrality            =  10;
  double minCentrality[] = { 0.5,   5., 10., 20., 30., 40., 50., 60., 70., 80. };
  double maxCentrality[] = { 5.0,  10., 20., 30., 40., 50., 60., 70., 80., 90. };

  int    nChargeSets             = 1;
  int    chargeSets[] = { 1, 0, 3 };

  double zMin                   = -10.;
  double zMax                   =  10.;
  double ptMin                  =  0.2;
  double ptMax                  =  2.0;
  double etaMin                 = -1.0;
  double etaMax                 =  1.0;
  double dcaZMin                = -3.0;
  double dcaZMax                =  3.0;
  double dcaXYMin               = -3.0;
  double dcaXYMax               =  3.0;
  double dedxMin                =  0.0;
  double dedxMax                =  20000.0;
  int    nClusterMin            =   70;
  int    trackFilterBit         =  128;

  int    requestedCharge1       =  1; //default
  int    requestedCharge2       = -1; //default

  // Get the pointer to the existing analysis manager via the static access method.
  // ==============================================================================
  AliAnalysisManager *analysisManager = AliAnalysisManager::GetAnalysisManager();

  if (!analysisManager)
    {
    ::Error("AddTaskDptDptCorrelations", "No analysis manager to connect to.");
    return NULL;
    }

  TString part1Name;
  TString part2Name;
  TString eventName;
  TString prefixName        = "Corr_";
  TString pileupRejecSuffix = "_PileupRejec";
  TString pairRejecSuffix   = "_PairRejec";
  TString calibSuffix       = "_calib";
  TString singlesOnlySuffix = "_SO";
  TString suffix;

  TString inputPath         = ".";
  TString outputPath        = ".";
  TString baseName;
  TString listName;
  TString taskName;
  TString inputHistogramFileName;
  TString outputHistogramFileName;

  // Create the task and add subtask.
  // ===========================================================================
  int iTask = 0; // task counter
  AliAnalysisDataContainer *taskInputContainer;
  AliAnalysisDataContainer *taskOutputContainer;

  for (int iCentrality=0; iCentrality < nCentrality; ++iCentrality)
    {
    for (int iChargeSet=0; iChargeSet < nChargeSets; iChargeSet++)
      {
      switch (chargeSets[iChargeSet])
        {
          case 0: part1Name = "P_"; part2Name = "P_"; requestedCharge1 =  1; requestedCharge2 =  1; sameFilter = 1; break;
          case 1: part1Name = "P_"; part2Name = "M_"; requestedCharge1 =  1; requestedCharge2 = -1; sameFilter = 0;   break;
          case 2: part1Name = "M_"; part2Name = "P_"; requestedCharge1 = -1; requestedCharge2 =  1; sameFilter = 0;   break;
          case 3: part1Name = "M_"; part2Name = "M_"; requestedCharge1 = -1; requestedCharge2 = -1; sameFilter = 1;   break;
        }
      //part1Name += int(1000*etaMin);
      part1Name += "eta";
      part1Name += int(1000*etaMax);
      part1Name += "_";
      part1Name += int(1000*ptMin);
      part1Name += "pt";
      part1Name += int(1000*ptMax);
      part1Name += "_";
      //part2Name += int(1000*etaMin);
      part2Name += "eta";
      part2Name += int(1000*etaMax);
      part2Name += "_";
      part2Name += int(1000*ptMin);
      part2Name += "pt";
      part2Name += int(1000*ptMax);
      part2Name += "_";
      eventName =  "";
      eventName += int(10.*minCentrality[iCentrality] );
      eventName += "Vo";
      eventName += int(10.*maxCentrality[iCentrality] );
      //eventName += "_";
      //eventName += int(10*zMin );
      //eventName += "Z";
      //eventName += int(10*zMax );
      if (rejectPileup)         eventName += pileupRejecSuffix;
      if (rejectPairConversion) eventName += pairRejecSuffix;
      baseName     =   prefixName;
      baseName     +=  part1Name;
      baseName     +=  part2Name;
      baseName     +=  eventName;
      listName     =   baseName;
      taskName     =   baseName;
      //inputHistogramFileName = inputPath;
      //inputHistogramFileName += "/";
      inputHistogramFileName =  baseName;
      inputHistogramFileName += calibSuffix;
      inputHistogramFileName += ".root";
      //outputHistogramFileName = outputPath;
      //outputHistogramFileName += "/";
      outputHistogramFileName = baseName;
      if (singlesOnly) outputHistogramFileName += singlesOnlySuffix;
      outputHistogramFileName += ".root";

      cout << "                   iTask: " << iTask << endl;
      cout << "               Task Name: " << taskName << endl;
      cout << "               List Name: " << listName << endl;
      cout << "  inputHistogramFileName: " << inputHistogramFileName  << endl;
      cout << " outputHistogramFileName: " << outputHistogramFileName << endl;
      cout << "           using weights: " << useWeights              << endl;
      TFile  * inputFile  = 0;
      TList  * histoList  = 0;
      TH3F   * weight_1   = 0;
      TH3F   * weight_2   = 0;
      if (useWeights)
        {
        inputFile = new TFile(inputHistogramFileName);
        if (!inputFile)
          {
          cout << "Requested file:" << inputHistogramFileName << " was not opened. ABORT." << endl;
          return;
          }
        histoList = (TList *) inputFile->Get(listName);
        if (!histoList)
          {
          cout << "Requested list:" << listName << " was not found. ABORT." << endl;
          return;
          }
        if (requestedCharge1 == 1)
          weight_1 = (TH3 *) histoList->FindObject("correction_p");
        else
          weight_1 = (TH3 *) histoList->FindObject("correction_m");
        if (!weight_1)
          {
          cout << "Requested histogram 'correction_p/m' was not found. ABORT." << endl;
          return;
          }
        if (!sameFilter)
          {
          weight_2 = 0;
          if (requestedCharge2 == 1)
            weight_2 = (TH3 *) histoList->FindObject("correction_p");
          else
            weight_2 = (TH3 *) histoList->FindObject("correction_m");
          if (!weight_2)
            {
            cout << "Requested histogram 'correction_p/m' was not found. ABORT." << endl;
            return;
            }
          }
        }
      AliAnalysisTaskDptDptCorrelations* task = new  AliAnalysisTaskDptDptCorrelations(taskName);
      //configure my task
      task->SetDebugLevel(          debugLevel      );
      task->SetSameFilter(          sameFilter      );
      task->SetSinglesOnly(         singlesOnly     );
      task->SetUseWeights(          useWeights      );
      task->SetRejectPileup(        rejectPileup    );
      task->SetRejectPairConversion(rejectPairConversion);
      task->SetVertexZMin(          zMin            );
      task->SetVertexZMax(          zMax            );
      task->SetVertexXYMin(         -1.            );
      task->SetVertexXYMax(          1.            );
      task->SetCentralityMethod(    centralityMethod);
      task->SetCentrality(          minCentrality[iCentrality], maxCentrality[iCentrality]);
      task->SetPtMin1(              ptMin           );
      task->SetPtMax1(              ptMax           );
      task->SetEtaMin1(             etaMin          );
      task->SetEtaMax1(             etaMax          );
      task->SetPtMin2(              ptMin           );
      task->SetPtMax2(              ptMax           );
      task->SetEtaMin2(             etaMin          );
      task->SetEtaMax2(             etaMax          );
      task->SetDcaZMin(             dcaZMin         );
      task->SetDcaZMax(             dcaZMax         );
      task->SetDcaXYMin(            dcaXYMin        );
      task->SetDcaXYMax(            dcaXYMax        );
      task->SetDedxMin(             dedxMin         );
      task->SetDedxMax(             dedxMax         );
      task->SetNClusterMin(         nClusterMin     );
      task->SetTrackFilterBit(      trackFilterBit  );
      task->SetRequestedCharge_1(   requestedCharge1);
      task->SetRequestedCharge_2(   requestedCharge2);
      task->SetWeigth_1(            weight_1        );
      task->SetWeigth_2(            weight_2        );

      cout << "Creating task output container" << endl;
      taskOutputContainer = analysisManager->CreateContainer(listName,
                                                             TList::Class(),
                                                             AliAnalysisManager::kOutputContainer,
                                                             Form("%s:Histos", AliAnalysisManager::GetCommonFileName()));
      cout << "Add task to analysis manager and connect it to input and output containers" << endl;
      analysisManager->AddTask(task);
      analysisManager->ConnectInput( task,  0, analysisManager->GetCommonInputContainer());
      analysisManager->ConnectOutput(task,  0, taskOutputContainer );
      cout << "Task added ...." << endl;

      iTask++;
      }
    }

  return task;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <string.h>
#include <cmath>
#include <uqEnvironment.h>
#include <uqGslVector.h>
#include <uqGslMatrix.h>
#include <uqVectorSpace.h>
#include <uqVectorSubset.h>
#include <uqVectorRV.h>

using namespace std;

int main(int argc, char **argv) {
  int i, j, num_samples = 1e5, seed;
  double sigmasq = 1.0;
  double *mean;
  double *var;
  double *sumsq;
  double *delta;
  FILE *fpRand = fopen("/dev/random", "r");

  fread(&seed, sizeof(int), 1, fpRand);
  fclose(fpRand);

  MPI_Init(&argc, &argv);

  uqEnvOptionsValuesClass *opts = new uqEnvOptionsValuesClass();
  opts->m_seed = seed;

  uqFullEnvironmentClass *env = new uqFullEnvironmentClass(MPI_COMM_WORLD,
      NULL, "", opts);

  uqVectorSpaceClass<uqGslVectorClass, uqGslMatrixClass> *param_space;
  param_space = new uqVectorSpaceClass<uqGslVectorClass, uqGslMatrixClass>(
      *env, "param_", 4, NULL);

  mean = new double[4];
  var = new double[4];
  sumsq = new double[4];
  delta = new double[4];

  uqGslVectorClass mins(param_space->zeroVector());
  uqGslVectorClass maxs(param_space->zeroVector());
  mins.cwSet(-INFINITY);
  maxs.cwSet(INFINITY);
  uqBoxSubsetClass<uqGslVectorClass, uqGslMatrixClass> *param_domain;
  param_domain = new uqBoxSubsetClass<uqGslVectorClass, uqGslMatrixClass>(
      "param_", *param_space, mins, maxs);

  // Mean zero
  uqGslVectorClass prior_mean_vals(param_space->zeroVector());
  // Variance
  uqGslVectorClass prior_var_vals(param_space->zeroVector());
  prior_var_vals.cwSet(sigmasq);

  uqGaussianVectorRVClass<uqGslVectorClass, uqGslMatrixClass> *prior;
  prior = new uqGaussianVectorRVClass<uqGslVectorClass, uqGslMatrixClass>(
      "prior_", *(param_domain), prior_mean_vals, prior_var_vals);

  uqGslVectorClass draw(param_space->zeroVector());

  for (j = 0; j < 4; j++) {
    mean[j] = 0.0;
    sumsq[j] = 0.0;
  }

  for (i = 1; i < num_samples + 1; i++) {
    prior->realizer().realization(draw);
    for (j = 0; j < 4; j++) {
      delta[j] = draw[j] - mean[j];
      mean[j] += (double) delta[j] / i;
      sumsq[j] += delta[j] * (draw[j] - mean[j]);
    }
  }

  for (j = 0; j < 4; j++) {
    // This is the sample variance
    var[j] = sumsq[j] / (num_samples - 1);
  }

  cout << var[0] << " "
       << var[1] << " "
       << var[2] << " "
       << var[3] << endl;

  double mean_min = -3.0 * sqrt(sigmasq) / sqrt(num_samples);
  double mean_max =  3.0 * sqrt(sigmasq) / sqrt(num_samples);

  int return_val = 0;
  for (j = 0; j < 4; j++) {
    if (mean[j] < mean_min || mean[j] > mean_max) {
      return_val = 1;
      break;
    }
  }

  double var_min = sigmasq - 3.0 * sqrt(2.0 * sigmasq * sigmasq / (num_samples - 1));
  double var_max = sigmasq + 3.0 * sqrt(2.0 * sigmasq * sigmasq / (num_samples - 1));

  // var[j] should be approximately ~ N(sigma^2, 2 sigma^4 / (num_samples - 1))
  for (j = 0; j < 4; j++) {
    if (var[j] < var_min || var[j] > var_max) {
      return_val = 1;
      break;
    }
  }

  delete env;
  MPI_Finalize();

  return return_val;
}
<commit_msg>[queso]: Add conditional MPI checkage. Provide 'free'dom for teh mallocs.<commit_after>#include <stdio.h>
#include <string.h>
#include <cmath>
#include <uqEnvironment.h>
#include <uqGslVector.h>
#include <uqGslMatrix.h>
#include <uqVectorSpace.h>
#include <uqVectorSubset.h>
#include <uqVectorRV.h>

using namespace std;

int main(int argc, char **argv) {
  int i, j, num_samples = 1e5, seed;
  double sigmasq = 1.0;
  double *mean;
  double *var;
  double *sumsq;
  double *delta;
  FILE *fpRand = fopen("/dev/random", "r");

  fread(&seed, sizeof(int), 1, fpRand);
  fclose(fpRand);

  uqEnvOptionsValuesClass *opts = new uqEnvOptionsValuesClass();
  opts->m_seed = seed;

#ifdef QUESO_HAS_MPI
  MPI_Init(&argc, &argv);
#endif
  uqFullEnvironmentClass *env =
#ifdef QUESO_HAS_MPI
    new uqFullEnvironmentClass(MPI_COMM_WORLD, NULL, "", opts);
#else
    new uqFullEnvironmentClass(0, NULL, "", opts);
#endif

  uqVectorSpaceClass<uqGslVectorClass, uqGslMatrixClass> *param_space;
  param_space = new uqVectorSpaceClass<uqGslVectorClass, uqGslMatrixClass>(
      *env, "param_", 4, NULL);

  mean = new double[4];
  var = new double[4];
  sumsq = new double[4];
  delta = new double[4];

  uqGslVectorClass mins(param_space->zeroVector());
  uqGslVectorClass maxs(param_space->zeroVector());
  mins.cwSet(-INFINITY);
  maxs.cwSet(INFINITY);
  uqBoxSubsetClass<uqGslVectorClass, uqGslMatrixClass> *param_domain;
  param_domain = new uqBoxSubsetClass<uqGslVectorClass, uqGslMatrixClass>(
      "param_", *param_space, mins, maxs);

  // Mean zero
  uqGslVectorClass prior_mean_vals(param_space->zeroVector());
  // Variance
  uqGslVectorClass prior_var_vals(param_space->zeroVector());
  prior_var_vals.cwSet(sigmasq);

  uqGaussianVectorRVClass<uqGslVectorClass, uqGslMatrixClass> *prior;
  prior = new uqGaussianVectorRVClass<uqGslVectorClass, uqGslMatrixClass>(
      "prior_", *(param_domain), prior_mean_vals, prior_var_vals);

  uqGslVectorClass draw(param_space->zeroVector());

  for (j = 0; j < 4; j++) {
    mean[j] = 0.0;
    sumsq[j] = 0.0;
  }

  for (i = 1; i < num_samples + 1; i++) {
    prior->realizer().realization(draw);
    for (j = 0; j < 4; j++) {
      delta[j] = draw[j] - mean[j];
      mean[j] += (double) delta[j] / i;
      sumsq[j] += delta[j] * (draw[j] - mean[j]);
    }
  }

  for (j = 0; j < 4; j++) {
    // This is the sample variance
    var[j] = sumsq[j] / (num_samples - 1);
  }

  cout << var[0] << " "
       << var[1] << " "
       << var[2] << " "
       << var[3] << endl;

  double mean_min = -3.0 * sqrt(sigmasq) / sqrt(num_samples);
  double mean_max =  3.0 * sqrt(sigmasq) / sqrt(num_samples);

  int return_val = 0;
  for (j = 0; j < 4; j++) {
    if (mean[j] < mean_min || mean[j] > mean_max) {
      return_val = 1;
      break;
    }
  }

  double var_min = sigmasq - 3.0 * sqrt(2.0 * sigmasq * sigmasq / (num_samples - 1));
  double var_max = sigmasq + 3.0 * sqrt(2.0 * sigmasq * sigmasq / (num_samples - 1));

  // var[j] should be approximately ~ N(sigma^2, 2 sigma^4 / (num_samples - 1))
  for (j = 0; j < 4; j++) {
    if (var[j] < var_min || var[j] > var_max) {
      return_val = 1;
      break;
    }
  }

  delete env;
  delete opts;
  delete mean;
  delete var;
  delete delta;
  delete sumsq;
  delete param_space;
  delete param_domain;
  delete prior;
#ifdef QUESO_HAS_MPI
  MPI_Finalize();
#endif

  return return_val;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "RootShadowNode.h"

#include <react/components/view/conversions.h>

namespace facebook {
namespace react {

const char RootComponentName[] = "RootView";

void RootShadowNode::layout() {
  ensureUnsealed();
  layout(getProps()->layoutContext);

  // This is the rare place where shadow node must layout (set `layoutMetrics`)
  // itself because there is no a parent node which usually should do it.
  setLayoutMetrics(layoutMetricsFromYogaNode(yogaNode_));
}

} // namespace react
} // namespace facebook
<commit_msg>Add systrace to calculation of Yoga layout() in Fabric<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "RootShadowNode.h"

#include <react/components/view/conversions.h>
#include <react/debug/SystraceSection.h>

namespace facebook {
namespace react {

const char RootComponentName[] = "RootView";

void RootShadowNode::layout() {
  SystraceSection s("RootShadowNode::layout");
  ensureUnsealed();
  layout(getProps()->layoutContext);

  // This is the rare place where shadow node must layout (set `layoutMetrics`)
  // itself because there is no a parent node which usually should do it.
  setLayoutMetrics(layoutMetricsFromYogaNode(yogaNode_));
}

} // namespace react
} // namespace facebook
<|endoftext|>