Skip to content
Snippets Groups Projects
Commit 1711507b authored by Vesa Oikonen's avatar Vesa Oikonen
Browse files

new func

parent 8e0f93cc
No related branches found
No related tags found
No related merge requests found
/// @file histplot.c
/// @brief Plot histogram in SVG format from dataset stored in TAC structure.
/// @author Vesa Oikonen
///
/*****************************************************************************/
#include "tpcclibConfig.h"
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
/*****************************************************************************/
#include "tpcextensions.h"
#include "tpctac.h"
#include "libtpcsvg.h"
/*****************************************************************************/
#include "tpctacmod.h"
/*****************************************************************************/
/*****************************************************************************/
extern int SVG_INLINE;
/*****************************************************************************/
/** SVG plot of histogram from data given in TAC data structure.
@return enum tpcerror (TPCERROR_OK when successful).
@sa tacPlotLineSVG, tacPlotFitSVG, mtgaPlotSVG
@author Vesa Oikonen
*/
int tacPlotHistogramSVG(
/** Pointer to TAC structure. Only the first dataset is used. */
TAC *d,
/** String for plot main title, or "". */
const char *main_title,
/** Start x value; NaN if determined from data. */
const double x1,
/** End x value; NaN if determined from data. */
const double x2,
/** Minimum y value; NaN if determined from data. */
const double y1,
/** Maximum y value; NaN if determined from data. */
const double y2,
/** SVG file name. */
const char *fname,
/** Pointer to status data; obligatory. */
TPCSTATUS *status
) {
if(status==NULL) return TPCERROR_FAIL;
if(status->verbose>1)
printf("%s(tac, '%s', %g, %g, %g, %g, '%s')\n", __func__, main_title, x1, x2, y1, y2, fname);
if(d==NULL || d->sampleNr<1 || d->tacNr<1) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA); return(status->error);}
if(fname==NULL || strnlen(fname, 1)<1) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FILENAME); return(status->error);}
/* Determine the plot min and max x and y values */
double minx, maxx, miny, maxy, tx1, tx2, ty1, ty2;
if(tacSampleXRange(d, &tx1, &tx2)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE); return(status->error);}
minx=tx1; maxx=tx2;
if(minx>0.0) {double f=maxx-minx; minx-=0.05*f; if(minx<0.0) minx=0.0;}
if(isfinite(x1)) minx=x1;
if(isfinite(x2)) maxx=x2;
if(status->verbose>1) {printf(" minx := %g\n maxx := %g\n", minx, maxx); fflush(stdout);}
/* Determine the plot min and max y values inside the x range */
if(tacYRangeInXRange(d, 0, minx, maxx, &ty1, &ty2, NULL, NULL, NULL, NULL)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE); return(status->error);}
// if(ty1>0.0) ty1=0.0;
// if(ty2<0.0) ty2=0.0;
miny=ty1; maxy=ty2;
if(miny>0.0) {double f=maxy-miny; miny-=0.05*f; if(miny<0.0) miny=0.0;}
else if(maxy<0.0) maxy=0.0;
if(isfinite(y1)) miny=y1;
if(isfinite(y2)) maxy=y2;
if(status->verbose>1) {printf(" miny := %g\n maxy := %g\n", miny, maxy); fflush(stdout);}
/* Calculate the axis ticks */
struct svg_viewports viewports; svg_init_viewports(&viewports);
viewports.x.min=minx; viewports.x.max=maxx;
viewports.y.min=miny; viewports.y.max=maxy;
viewports.label_area_viewport.is=0; // no plot legends
if(svg_calculate_axes(&viewports, status->verbose-1)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE); return(status->error);}
/* Set the plot window and window area sizes */
if(svg_define_viewports(0, 0, strlen(main_title), 0, 0, 0, &viewports, status->verbose-1)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE); return(status->error);}
/* Initiate graphics file */
FILE *fp=svg_initiate(fname, 0, 0, &viewports, NULL, status->verbose-1);
if(fp==NULL) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_OPEN); return(status->error);}
/* Put the graph titles into their own viewports */
if(svg_create_main_title(fp, main_title, "", &viewports, NULL, status->verbose-2)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
/* Put the plot into its own viewport */
if(svg_start_plot_viewport(fp, &viewports, NULL, status->verbose-2)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
/* Start coordinate area viewport */
if(svg_start_coordinate_viewport(fp, &viewports, NULL, status->verbose-3)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
/* Write plot axes */
if(svg_write_axes(fp, &viewports, NULL, status->verbose-3)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
/*
* Draw the data
*/
char ilc[9], tmp[1024];
if(SVG_INLINE) strcpy(ilc, "svg:"); else strcpy(ilc, "");
/* Initiate the data object group */
sprintf(tmp, "\n<%sg stroke=\"black\" stroke-width=\"25\" fill=\"black\">\n", ilc);
if(svg_write(fp, tmp, NULL, status->verbose-5)!=0) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
if(d->isframe==0) { // vertical lines
/* Open the path */
sprintf(tmp, "<%spath fill=\"none\" d=\"", ilc);
svg_write(fp, tmp, NULL, status->verbose-5);
for(int i=0; i<d->sampleNr; i++) {
if(!isfinite(d->x[i]) || !isfinite(d->c[0].y[i])) continue;
double nx1, ny1, nx2, ny2;
nx1=nx2=viewports.x.origo+d->x[i]*viewports.x.scale;
ny1=viewports.coordinate_area_viewport.h-(viewports.y.origo+viewports.y.scale*0.0);
ny2=viewports.coordinate_area_viewport.h-(viewports.y.origo+viewports.y.scale*d->c[0].y[i]);
/* Do not plot if x is outside viewport */
if(nx1<0 && nx2<=0) continue;
if(nx1>viewports.coordinate_area_viewport.w+1 || nx1>viewports.coordinate_area_viewport.w+1)
continue;
/* Do not plot if both y's are outside viewport */
if((ny1<0 || ny2>viewports.coordinate_area_viewport.h+1) &&
(ny2<0 || ny1>viewports.coordinate_area_viewport.h+1)) continue;
/* Set y limit to the viewport border */
if(ny1<0) ny1=0.0; else if(ny2<0) ny2=0.0;
if(ny1>viewports.coordinate_area_viewport.h+1) ny1=viewports.coordinate_area_viewport.h+1;
else if(ny2>viewports.coordinate_area_viewport.h+1) ny2=viewports.coordinate_area_viewport.h+1;
/* Draw */
sprintf(tmp, " M%.0f %.0f L%.0f %.0f", nx1, ny1, nx2, ny2);
svg_write(fp, tmp, NULL, status->verbose-5);
}
/* Close the path */
strcpy(tmp, "\" />\n");
svg_write(fp, tmp, NULL, status->verbose-5);
} else { // rectangles
for(int i=0; i<d->sampleNr; i++) {
if(!isfinite(d->x[i]) || !isfinite(d->c[0].y[i])) continue;
double nx1, ny1, nx2, ny2;
nx1=viewports.x.origo+d->x1[i]*viewports.x.scale;
nx2=viewports.x.origo+d->x2[i]*viewports.x.scale;
ny1=viewports.coordinate_area_viewport.h-(viewports.y.origo+viewports.y.scale*0.0);
ny2=viewports.coordinate_area_viewport.h-(viewports.y.origo+viewports.y.scale*d->c[0].y[i]);
/* Do not plot if x is outside viewport */
if(nx1<0 && nx2<=0) continue;
if(nx1>viewports.coordinate_area_viewport.w+1 || nx1>viewports.coordinate_area_viewport.w+1)
continue;
/* Do not plot if both y's are outside viewport */
if((ny1<0 || ny2>viewports.coordinate_area_viewport.h+1) &&
(ny2<0 || ny1>viewports.coordinate_area_viewport.h+1)) continue;
/* Set y limit to the viewport border */
if(ny1<0) ny1=0.0; else if(ny2<0) ny2=0.0;
if(ny1>viewports.coordinate_area_viewport.h+1) ny1=viewports.coordinate_area_viewport.h+1;
else if(ny2>viewports.coordinate_area_viewport.h+1) ny2=viewports.coordinate_area_viewport.h+1;
if(ny1>ny2) {double f=ny1; ny1=ny2; ny2=f;}
/* Draw */
sprintf(tmp, " <rect x=\"%.0f\" y=\"%.0f\" width=\"%.0f\" height=\"%.0f\" />\n",
nx1, ny1, nx2-nx1, fabs(ny2-ny1));
svg_write(fp, tmp, NULL, status->verbose-5);
}
}
/* Close the data object group */
sprintf(tmp, "</%sg>\n", ilc);
if(svg_write(fp, tmp, NULL, status->verbose-5)!=0) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
/* Close the coordinate viewport */
if(svg_end_coordinate_viewport(fp, NULL, status->verbose-1)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
/* Write the axis ticks */
if(svg_write_xticks(fp, &viewports, NULL, status->verbose-3)!=0 ||
svg_write_yticks(fp, &viewports, NULL, status->verbose-3)!=0) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
/* Close the plot viewport */
if(svg_end_plot_viewport(fp, NULL, status->verbose-2)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
/* Close the SVG file */
if(svg_close(fp, NULL, status->verbose-1)) {
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
fclose(fp); return(status->error);
}
if(status->verbose>0) fprintf(stdout, " written file %s\n", fname);
statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
return(TPCERROR_OK);
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
#include "tpcclibConfig.h"
/*****************************************************************************/
#include "unistd.h"
/*****************************************************************************/
#include "tpcextensions.h"
#include "test_tpctacmod.h"
/*****************************************************************************/
/*****************************************************************************/
int test_tacPlotHistogramSVG(
TPCSTATUS *status
) {
int verbose=0; if(status!=NULL) verbose=status->verbose;
statusSet(status, __func__, __FILE__, __LINE__, 0);
if(verbose>0) {
printf("\n=====================================\n");
printf("\n%s\n", __func__);
printf("\n=====================================\n");
fflush(stdout);
}
int ret;
TAC tac; tacInit(&tac);
char fname[128]; strcpy(fname, "");
if(verbose>1) {printf("\n testing with NULL data.\n"); fflush(stdout);}
strcpy(fname, "tacplothistogram0.svg");
ret=tacPlotHistogramSVG(NULL, NULL, 0.0, 0.0, 0.0, 0.0, fname, status);
if(ret==TPCERROR_OK) return(1);
if(access(fname, 0)!=-1) return(2);
if(verbose>1) printf("\n testing with empty data.\n");
ret=tacPlotHistogramSVG(&tac, "Main title", 0.0, 1.0, 0.0, 1.0, fname, status);
if(ret==TPCERROR_OK) return(3);
if(access(fname, 0)!=-1) return(4);
if(verbose>1) {printf("\n creating test data\n"); fflush(stdout);}
/* Allocate memory */
ret=tacAllocate(&tac, 5, 1); if(ret!=TPCERROR_OK) return(10);
tac.tacNr=1; tac.sampleNr=5;
/* Set TAC information */
tac.isframe=0;
/* Set region names */
for(int i=0; i<tac.tacNr; i++) sprintf(tac.c[i].name, "tac%d", 1+i);
/* Set data contents */
int ri=0, fi;
fi=0; tac.x1[fi]=0.0; tac.x2[fi]=2.0; tac.x[fi]=1.0; tac.c[ri].y[fi]=20.0;
fi=1; tac.x1[fi]=2.0; tac.x2[fi]=4.0; tac.x[fi]=3.0; tac.c[ri].y[fi]=10.0;
fi=2; tac.x1[fi]=4.0; tac.x2[fi]=6.0; tac.x[fi]=5.0; tac.c[ri].y[fi]=60.0;
fi=3; tac.x1[fi]=6.0; tac.x2[fi]=10.0; tac.x[fi]=8.0; tac.c[ri].y[fi]=40.0;
fi=4; tac.x1[fi]=10.; tac.x2[fi]=13.0; tac.x[fi]=11.5; tac.c[ri].y[fi]=50.0;
if(verbose>1) {printf("\n plotting test data with x\n"); fflush(stdout);}
strcpy(fname, "tacplothistogram1.svg"); (void)remove(fname);
tac.isframe=0;
ret=tacPlotHistogramSVG(&tac, "Main title", nan(""), nan(""), nan(""), nan(""), fname, status);
if(ret!=TPCERROR_OK) {tacFree(&tac); return(11);}
if(access(fname, 0)==-1) {tacFree(&tac); return(12);}
if(verbose>1) {printf("\n plotting test data with x1 and x2\n"); fflush(stdout);}
strcpy(fname, "tacplothistogram2.svg"); (void)remove(fname);
tac.isframe=1;
ret=tacPlotHistogramSVG(&tac, "Main title", nan(""), nan(""), nan(""), nan(""), fname, status);
if(ret!=TPCERROR_OK) {tacFree(&tac); return(21);}
if(access(fname, 0)==-1) {tacFree(&tac); return(22);}
for(fi=0; fi<tac.sampleNr; fi++) for(ri=0; ri<tac.tacNr; ri++) tac.c[ri].y[fi]*=-1.0;
if(verbose>1) {printf("\n plotting negative test data with x1 and x2\n"); fflush(stdout);}
strcpy(fname, "tacplothistogram2n.svg"); (void)remove(fname);
tac.isframe=1;
ret=tacPlotHistogramSVG(&tac, "Main title", nan(""), nan(""), nan(""), nan(""), fname, status);
if(ret!=TPCERROR_OK) {tacFree(&tac); return(23);}
if(access(fname, 0)==-1) {tacFree(&tac); return(24);}
if(verbose>1) {printf("\n plotting negative test data with x\n"); fflush(stdout);}
strcpy(fname, "tacplothistogram1n.svg"); (void)remove(fname);
tac.isframe=0;
ret=tacPlotHistogramSVG(&tac, "Main title", nan(""), nan(""), nan(""), nan(""), fname, status);
if(ret!=TPCERROR_OK) {tacFree(&tac); return(13);}
if(access(fname, 0)==-1) {tacFree(&tac); return(14);}
for(fi=0; fi<tac.sampleNr; fi++) for(ri=0; ri<tac.tacNr; ri++) tac.c[ri].y[fi]+=35.0;
if(verbose>1) {printf("\n plotting +/- test data with x\n"); fflush(stdout);}
strcpy(fname, "tacplothistogram1np.svg"); (void)remove(fname);
tac.isframe=0;
ret=tacPlotHistogramSVG(&tac, "Main title", nan(""), nan(""), nan(""), nan(""), fname, status);
if(ret!=TPCERROR_OK) {tacFree(&tac); return(15);}
if(access(fname, 0)==-1) {tacFree(&tac); return(16);}
if(verbose>1) {printf("\n plotting +/- test data with x1 and x2\n"); fflush(stdout);}
strcpy(fname, "tacplothistogram2np.svg"); (void)remove(fname);
tac.isframe=1;
ret=tacPlotHistogramSVG(&tac, "Main title", nan(""), nan(""), nan(""), nan(""), fname, status);
if(ret!=TPCERROR_OK) {tacFree(&tac); return(25);}
if(access(fname, 0)==-1) {tacFree(&tac); return(26);}
fflush(stdout); fflush(stderr);
tacFree(&tac);
statusSet(status, __func__, __FILE__, __LINE__, 0);
return(0);
}
/*****************************************************************************/
/*****************************************************************************/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment