<commit_before>/// HEADER
#include "vector_plot.h"

/// PROJECT
#include <csapex/msg/io.h>
#include <csapex_opencv/cv_mat_message.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/msg/generic_value_message.hpp>
#include <csapex/view/utility/QtCvImageConverter.h>
#include <csapex/msg/generic_vector_message.hpp>

/// SYSTEM
#include <qwt_scale_engine.h>


using namespace csapex;
using namespace csapex::connection_types;

CSAPEX_REGISTER_CLASS(csapex::VectorPlot, csapex::Node)

VectorPlot::VectorPlot():
    initialize_(true),
    has_time_in_(false)
{

}

void VectorPlot::setup(NodeModifier &node_modifier)
{
    setupVariadic(node_modifier);
    in_time_  = node_modifier.addOptionalInput<GenericVectorMessage, double>("time");

    out_ = node_modifier.addOutput<CvMatMessage>("Plot");

    color_line_.resize(num_plots_);
}

void VectorPlot::setupParameters(Parameterizable &parameters)
{

    setupVariadicParameters(parameters);

    Plot::setupParameters(parameters);

    parameters.addParameter(param::ParameterFactory::declareRange
                            ("~plot/width",
                             128, 4096, 640, 1),
                            [this](param::Parameter* p) {
        width_ = p->as<int>();
        update();
    });
    parameters.addParameter(param::ParameterFactory::declareRange
                            ("~plot/height",
                             128, 4096, 320, 1),
                            [this](param::Parameter* p) {
        height_ = p->as<int>();
        update();
    });

    parameters.addParameter(param::ParameterFactory::declareRange(
                                "~plot/line/width", 0.0, 10.0, 0.0, 0.01),
                            line_width_);

    parameters.addParameter(param::ParameterFactory::declareBool
                            ("~output/time/relative",
                             param::ParameterDescription("Use time relative to the first entry"),
                             true),
                            time_relative_);
    parameters.addParameter(param::ParameterFactory::declareBool
                            ("~output/time/seconds",
                             param::ParameterDescription("Convert the time to seconds"),
                             true),
                            time_seconds_);

    parameters.addParameter(param::ParameterFactory::declareTrigger("reset"),
                            [this](param::Parameter*) {
        reset();
    });


    color_fill_.setAlpha(100);
}

void VectorPlot::process()
{
    {
        std::unique_lock<std::recursive_mutex> lock(mutex_);
        std::size_t num_inputs = VariadicInputs::getVariadicInputCount();
        num_plots_ = num_inputs;

        for(std::size_t i_inputs = 0; i_inputs < num_plots_; ++i_inputs){
            InputPtr in = VariadicInputs::getVariadicInput(i_inputs);
            if(!msg::isConnected(in.get())){
                --num_plots_;
            }

        }

        data_v_.resize(num_plots_);
        updateLineColors();

        std::size_t data_counter = 0;

        for(std::size_t i_inputs = 0; i_inputs < num_inputs; ++i_inputs){

            InputPtr in = VariadicInputs::getVariadicInput(i_inputs);
            if(msg::isConnected(in.get())){
                GenericVectorMessage::ConstPtr message = msg::getMessage<GenericVectorMessage>(in.get());

                apex_assert(std::dynamic_pointer_cast<GenericValueMessage<double>>(message->nestedType()));

                data_v_[data_counter].resize(message->nestedValueCount());

                for(std::size_t n_point = 0; n_point <message->nestedValueCount(); ++n_point){
                    auto pval = std::dynamic_pointer_cast<GenericValueMessage<double> const>(message->nestedValue(n_point));
                    data_v_[data_counter][n_point] = pval->value;
                }
                //            if(data_counter > 0){
                //                apex_assert(data_v_[data_counter].size() == data_v_[data_counter -1].size());
                //            }
                ++data_counter;
            }
        }

        data_t_raw_.clear();
        if(msg::hasMessage(in_time_)){
            has_time_in_ = true;
            std::shared_ptr<std::vector<double> const> time = msg::getMessage<GenericVectorMessage, double>(in_time_);
            data_t_raw_.resize(time->size());
            for(std::size_t n = 0; n < time->size(); ++n){
                data_t_raw_[n] = time->at(n);
            }

            apex_assert(!data_v_.empty());
            apex_assert(data_t_raw_.size() == data_v_.front().size());
        }
        else{
            has_time_in_ = false;
            data_t_.resize(data_v_.front().size());
            for(std::size_t i = 0; i < data_t_.size();++i){
                data_t_[i] = i;
            }
        }<commit_msg>Fix a segfault in vector_plot if no time messages are connected<commit_after>/// HEADER
#include "vector_plot.h"

/// PROJECT
#include <csapex/msg/io.h>
#include <csapex_opencv/cv_mat_message.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/msg/generic_value_message.hpp>
#include <csapex/view/utility/QtCvImageConverter.h>
#include <csapex/msg/generic_vector_message.hpp>

/// SYSTEM
#include <qwt_scale_engine.h>


using namespace csapex;
using namespace csapex::connection_types;

CSAPEX_REGISTER_CLASS(csapex::VectorPlot, csapex::Node)

VectorPlot::VectorPlot():
    initialize_(true),
    has_time_in_(false)
{

}

void VectorPlot::setup(NodeModifier &node_modifier)
{
    setupVariadic(node_modifier);
    in_time_  = node_modifier.addOptionalInput<GenericVectorMessage, double>("time");

    out_ = node_modifier.addOutput<CvMatMessage>("Plot");

    color_line_.resize(num_plots_);
}

void VectorPlot::setupParameters(Parameterizable &parameters)
{

    setupVariadicParameters(parameters);

    Plot::setupParameters(parameters);

    parameters.addParameter(param::ParameterFactory::declareRange
                            ("~plot/width",
                             128, 4096, 640, 1),
                            [this](param::Parameter* p) {
        width_ = p->as<int>();
        update();
    });
    parameters.addParameter(param::ParameterFactory::declareRange
                            ("~plot/height",
                             128, 4096, 320, 1),
                            [this](param::Parameter* p) {
        height_ = p->as<int>();
        update();
    });

    parameters.addParameter(param::ParameterFactory::declareRange(
                                "~plot/line/width", 0.0, 10.0, 0.0, 0.01),
                            line_width_);

    parameters.addParameter(param::ParameterFactory::declareBool
                            ("~output/time/relative",
                             param::ParameterDescription("Use time relative to the first entry"),
                             true),
                            time_relative_);
    parameters.addParameter(param::ParameterFactory::declareBool
                            ("~output/time/seconds",
                             param::ParameterDescription("Convert the time to seconds"),
                             true),
                            time_seconds_);

    parameters.addParameter(param::ParameterFactory::declareTrigger("reset"),
                            [this](param::Parameter*) {
        reset();
    });


    color_fill_.setAlpha(100);
}

void VectorPlot::process()
{
    {
        std::unique_lock<std::recursive_mutex> lock(mutex_);
        std::size_t num_inputs = VariadicInputs::getVariadicInputCount();
        num_plots_ = num_inputs;

        for(std::size_t i_inputs = 0; i_inputs < num_plots_; ++i_inputs){
            InputPtr in = VariadicInputs::getVariadicInput(i_inputs);
            if(!msg::isConnected(in.get())){
                --num_plots_;
            }

        }

        data_v_.resize(num_plots_);
        updateLineColors();

        std::size_t data_counter = 0;

        for(std::size_t i_inputs = 0; i_inputs < num_inputs; ++i_inputs){

            InputPtr in = VariadicInputs::getVariadicInput(i_inputs);
            if(msg::isConnected(in.get())){
                GenericVectorMessage::ConstPtr message = msg::getMessage<GenericVectorMessage>(in.get());

                apex_assert(std::dynamic_pointer_cast<GenericValueMessage<double>>(message->nestedType()));

                data_v_[data_counter].resize(message->nestedValueCount());

                for(std::size_t n_point = 0; n_point <message->nestedValueCount(); ++n_point){
                    auto pval = std::dynamic_pointer_cast<GenericValueMessage<double> const>(message->nestedValue(n_point));
                    data_v_[data_counter][n_point] = pval->value;
                }
                //            if(data_counter > 0){
                //                apex_assert(data_v_[data_counter].size() == data_v_[data_counter -1].size());
                //            }
                ++data_counter;
            }
        }

        data_t_raw_.clear();
        if(msg::hasMessage(in_time_)){
            has_time_in_ = true;
            std::shared_ptr<std::vector<double> const> time = msg::getMessage<GenericVectorMessage, double>(in_time_);
            data_t_raw_.resize(time->size());
            for(std::size_t n = 0; n < time->size(); ++n){
                data_t_raw_[n] = time->at(n);
            }

            apex_assert(!data_v_.empty());
            apex_assert(data_t_raw_.size() == data_v_.front().size());
        }
        else{
            if(data_v_.empty()){
                return;
            }
            has_time_in_ = false;
            std::size_t n_elments = data_v_.front().size();
            data_t_.resize(n_elments);
            std::size_t i = 0;
            for(auto& v : data_t_){
                v = i;
                ++i;
            }
        }
{'fraction_non_alphanumeric': 0.1280748929389503, 'fraction_numerical': 0.008564883975699631, 'mean_word_length': 2.0993827160493828, 'pattern_counts': {'":': 0, '<': 56, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4128175', 'n_tokens_mistral': 3048, 'n_tokens_neox': 2853, 'n_words': 403}