graph.cpp 3.84 KB
#include "blc_program.h"
#include "graph.h"
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>

void init_term(FILE *pipef, char const *title, char const* verbatim){
    fprintf(pipef, "set term qt 1 noraise\n"); //Keep focus on the calling terminal
    fprintf(pipef, "set datafile nofpe_trap\n"); //Speend up acquisition but crash if there is a problem with the DATA
    fprintf(pipef, "set title '%s'\n", title); //axis x en y  only
    fprintf(pipef, "set border 3\n"); //axis x en y  only
    fprintf(pipef, "set title font ',20'\n");
    fprintf(pipef, "set label font ',10'\n");
    fprintf(pipef, "set key font ',10'\n");
    fprintf(pipef, "set terminal qt noenhanced\n");//avoid interpretation of '_'
    fprintf(pipef, "set style %s\n", style_option);
    fprintf(pipef, "set boxwidth 0.9 relative\n");
    fprintf(pipef, "set grid\n");
    if (verbatim) fprintf(pipef, "%s\n", verbatim);
}

void create_graph(blc_channel *input, char const *title, int refresh_period, float min, float max, float xmin, float xmax, float label_max, char const *verbatim){
    char const *gnuplot_format=NULL;
    char command[LINE_MAX];
    char code;
    int i, offset, columns_nb=0, rows_nb=0;
    FILE *pipef;
    size_t element_size;
    char *buffer;
    
    SYSTEM_ERROR_CHECK(pipef=popen("gnuplot", "w"), NULL, "Calling gnuplot");
    
    switch (input->dims_nb){
    case 0:
        columns_nb=1;
        rows_nb=1;
        break;
    case 1:
        columns_nb=input->dims[0].length;
        rows_nb=1;
        break;
    case 2:
        columns_nb=input->dims[0].length;
        rows_nb=input->dims[1].length;
        break;
    default:
        EXIT_ON_ARRAY_ERROR(input, "Too many dims");
        break;
    }
    element_size=input->get_type_size();
    switch (input->type){
    case 'UIN8':gnuplot_format="%uchar";break;
    case 'INT8':gnuplot_format="%char";break;
    case 'IN16':gnuplot_format="%int16";break;
    case 'UI16':gnuplot_format="%uint16";break;
    case 'IN32':gnuplot_format="%int32";break;
    case 'UI32':gnuplot_format="%uint32";break;
    case 'FL32':gnuplot_format="%float32";break;
    case 'FL64':gnuplot_format="%float64";break;
    default: EXIT_ON_ARRAY_ERROR(input, "The type is not managed");
    }
    
    init_term(pipef, title, verbatim);

    if (min!=max) fprintf(pipef, "set yrange [%f:%f]\n", min, max);
    if (columns_nb==1) xmin=-1;
    if (xmin!=xmax) fprintf(pipef, "set xrange [%f:%f]\n", xmin, xmax);

    if (input->dims_nb==2){
        fprintf(pipef, "set xrange [%f:%f]\n", 0.f, 10.f);
        fprintf(pipef, "set yrange [%f:%f]\n", 0.f, 10.f);
        fprintf(pipef, "set zrange [%f:%f]\n", min, max);
        fprintf(pipef, "set view 30,190\n");
        offset=snprintf(command, LINE_MAX, "splot '-' binary format='%s' array=%dx%d  title 'values' with pm3d ", gnuplot_format, columns_nb, rows_nb);
    }
    else{
        offset=snprintf(command, LINE_MAX, "plot '-' binary format='%s' record=%d using ($0*%f):1 title '%d' with %s", gnuplot_format, columns_nb, label_max/(float)columns_nb, 0, with_option);

        for(i=1; i!=rows_nb; i++){
            if (i<10) code=48+i;
            else code=97+i-10;
            offset+=snprintf(command+offset, LINE_MAX-offset, ", '-'  binary format='%s' record=%d  title '%c' with %s", gnuplot_format, columns_nb,  code, with_option);
        }
    }
    
    buffer=MANY_ALLOCATIONS(input->size, char);
    
    blc_loop_try_add_waiting_semaphore(input->sem_new_data);
    BLC_COMMAND_LOOP(refresh_period){
        memcpy(buffer, input->data, input->size);
        if (input->sem_ack_data) SYSTEM_ERROR_CHECK(sem_post(input->sem_ack_data), -1, NULL);
        fprintf(pipef, "\n%s\n", command);
        SYSTEM_ERROR_CHECK(fwrite(buffer, element_size, columns_nb*rows_nb, pipef), -1, NULL);
        SYSTEM_ERROR_CHECK(fflush(pipef), -1, NULL);
    }
    SYSTEM_ERROR_CHECK(fclose(pipef), -1, NULL);
    FREE(buffer);
}