graph.cpp 3.78 KB
Newer Older
Arnaud Blanchard's avatar
Arnaud Blanchard committed
1
2
3
4
5
6
#include "blc_program.h"
#include "graph.h"
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>

7
void init_term(FILE *pipef, char const *title, char const* verbatim){
Arnaud Blanchard's avatar
Arnaud Blanchard committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    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;
    }
    
    switch (input->type){
        case 'UIN8':
            gnuplot_format="%uchar";
            element_size=sizeof(uchar);
            break;
        case 'INT8':
            gnuplot_format="%char";
            element_size=sizeof(char);
            break;
        case 'FL32':
            gnuplot_format="%float";
            element_size=sizeof(float);
            break;
        default: EXIT_ON_ARRAY_ERROR(input, "The type is not managed");
    }
    
    init_term(pipef, title, verbatim);

69
70
    if (min!=max) fprintf(pipef, "set yrange [%f:%f]\n", min, max);
    if (xmin!=xmax) fprintf(pipef, "set xrange [%f:%f]\n", xmin, xmax);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
71
72

    if (input->dims_nb==2){
73
74
75
    	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);
Arnaud Blanchard's avatar
Arnaud Blanchard committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
    	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);
}