/* // ----------------------------------------------------------------------- // pgplot_related.c: New functions for use with PGPLOT. // ----------------------------------------------------------------------- // Copyright (C) 2006, Matthew Whiting, ATNF // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. // // Duchamp 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 General Public License // for more details. // // You should have received a copy of the GNU General Public License // along with Duchamp; if not, write to the Free Software Foundation, // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA // // Correspondence concerning Duchamp may be directed to: // Internet email: Matthew.Whiting [at] atnf.csiro.au // Postal address: Dr. Matthew Whiting // Australia Telescope National Facility, CSIRO // PO Box 76 // Epping NSW 1710 // AUSTRALIA // ----------------------------------------------------------------------- */ #include #include #include #include #include #include #define WDGPIX 100 /* used by cpgwedglog --> number of increments in the wedge. */ /* This file contains the following programs, all in C code: int cpgtest() --> a front-end to cpgqinf, to test whether a pgplot device is currently open. void cpgwedglog(const char* side, float disp, float width, float fg, float bg, const char *label) --> a C-code version of pgwedg, plotting the wedge scale in logarithmic units. void cpgcumul(int npts, float *data, float datamin, float datamax, int pgflag) --> a new pgplot routine that draws a cumulative distribution. Uses _swap and _sort. void cpghistlog(npts, data, datamin, datamax, nbin, pgflag) --> as for cpghist, with the y-axis on a logarithmic scale. */ /********************************************************************/ /* CPGTEST */ /********************************************************************/ int cpgtest() { /** * A front-end to cpgqinf, to test whether a pgplot device is * currently open. Returns 1 if there is, else 0. */ char answer[10]; /* The PGQINF return string */ int answer_len = sizeof(answer); /* allocated size of answer[] */ cpgqinf("STATE", answer, &answer_len); return strcmp(answer, "OPEN") == 0; } /********************************************************************/ /* CPGWEDGLOG */ /********************************************************************/ void cpgwedglog(const char* side, float disp, float width, float fg, float bg, const char *label) { /** * A C-code version of PGWEDG that writes the scale of the wedge in * logarithmic coordinates. All parameters are exactly as for cpgwedg. */ float wxa,wxb,wya,wyb, xa,xb,ya,yb; /* Temporary window coord storage.*/ float vxa,vxb,vya,vyb; /* Viewport coords of wedge. */ float oldch, newch; /* Original and annotation character heights. */ float ndcsiz; /* Size of unit character height (NDC units). */ int horiz; /* Logical: True (=1) if wedge plotted horizontally. */ int image; /* Logical: Use PGIMAG (T=1) or PGGRAY (F=0). */ int nside,i; /* nside = symbolic version of side. */ const int bot=1,top=2,lft=3,rgt=4; float wedwid, wdginc, vwidth, vdisp, xch, ych, labwid, fg1, bg1; float txtfrc=0.6; /* Set the fraction of WIDTH used for anotation. */ float txtsep=2.2; /* Char separation between numbers and LABEL. */ float wdgarr[WDGPIX]; /* Array to draw wedge in. */ float tr[6] = {0.0,1.0,0.0,0.0,0.0,1.0}; /* if(pgnoto("pgwedg")) return; */ /* Get a numeric version of SIDE. */ nside=bot; /* initialise */ horiz=1; /* initialise */ if(tolower(side[0])=='b'){ nside = bot; horiz = 1; } else if(tolower(side[0]=='t')){ nside = top; horiz = 1; } else if(tolower(side[0]=='l')){ nside = lft; horiz = 0; } else if(tolower(side[0]=='r')){ nside = rgt; horiz = 0; } /* else gwarn("Invalid \"SIDE\" argument in PGWEDG."); */ else fprintf(stdout,"%%PGPLOT, Invalid \"SIDE\" argument in CPGWEDGLOG."); /* Determine which routine to use. */ image=0; /* initialise */ if(strlen(side)<2) image = 0; else if(tolower(side[1])=='i') image = 1; else if(tolower(side[1])=='g') image = 0; else fprintf(stdout,"%%PGPLOT, Invalid \"SIDE\" argument in CPGWEDGLOG."); cpgbbuf(); /* Store the current world and viewport coords and the character height. */ cpgqwin(&wxa, &wxb, &wya, &wyb); cpgqvp(0, &xa, &xb, &ya, &yb); cpgqch(&oldch); /* Determine the unit character height in NDC coords. */ cpgsch(1.0); cpgqcs(0, &xch, &ych); if(horiz == 1) ndcsiz = ych; else ndcsiz = xch; /* Convert 'WIDTH' and 'DISP' into viewport units. */ vwidth = width * ndcsiz * oldch; vdisp = disp * ndcsiz * oldch; /* Determine the number of character heights required under the wedge. */ labwid = txtsep; if(strcmp(label," ")!=0) labwid = labwid + 1.0; /* Determine and set the character height required to fit the wedge anotation text within the area allowed for it. */ newch = txtfrc*vwidth / (labwid*ndcsiz); cpgsch(newch); /* Determine the width of the wedge part of the plot minus the anotation. (NDC units). */ wedwid = vwidth * (1.0-txtfrc); /* Use these to determine viewport coordinates for the wedge + annotation.*/ vxa = xa; vxb = xb; vya = ya; vyb = yb; if(nside==bot){ vyb = ya - vdisp; vya = vyb - wedwid; } else if(nside==top) { vya = yb + vdisp; vyb = vya + wedwid; } else if(nside==lft) { vxb = xa - vdisp; vxa = vxb - wedwid; } else if(nside==rgt) { vxa = xb + vdisp; vxb = vxa + wedwid; } /* Set the viewport for the wedge. */ cpgsvp(vxa, vxb, vya, vyb); /* Swap FG/BG if necessary to get axis direction right. */ /* fg1 = max(fg,bg); */ /* bg1 = min(fg,bg); */ if(fg>bg) { fg1 = fg; bg1 = bg; } else { fg1 = bg; bg1 = fg; } /* Create a dummy wedge array to be plotted. */ wdginc = (fg1-bg1)/(WDGPIX-1); for(i=0;i pivot) { j--; k--; t = array[i]; array[i] = array[j]; array[j] = array[k]; array[k] = t; } else { j--; _swap(&array[i], &array[j]); } } i--; _swap(&array[begin], &array[i]); if (i - begin > 1) _sort(array, begin, i); if (end - k > 1) _sort(array, k, end); } void cpgcumul(int npts, float *data, float datamin, float datamax, int pgflag) { /** * A new pgplot routine that draws a cumulative distribution. * The use of pgflag is similar to cpghist & cpghist_log: *
  • 0 --> draw a new graph using cpgenv, going from 0 to 1 * on the y-axis. *
  • 2 --> draw the plot on the current graph, without * re-drawing any axes. *
*/ int i; float *sorted; float MINCOUNT=0.; sorted = (float *)calloc(npts,sizeof(float)); for(i=0;i=0)&&(bin0) num[i] = log10(num[i]); else num[i] = MINCOUNT; } maxNum = num[0]; for(i=1; imaxNum) maxNum = num[i]; binSize = (datamax - datamin) / (float)nbin; /* BOUNDARIES OF PLOT */ x1 = datamin; x2 = datamax; y1 = MINCOUNT; y2 = ceil(maxNum); /* DEFINE ENVIRONMENT IF NECESSARY */ if(pgflag%2 == 0) cpgenv(x1,x2,y1,y2,0,20); /* DRAW HISTOGRAM */ if(pgflag/2 == 0){ older = 0.; x2 = datamin; cpgmove(datamin,MINCOUNT); for(i=0;i=0)&&(bin0) num[i] = log10(num[i]); */ /* else num[i] = MINCOUNT; */ /* } */ /* maxNum = num[0]; */ /* for(i=1; imaxNum) maxNum = num[i]; */ /* binSize = (datamax - datamin) / (float)nbin; */ /* /\* BOUNDARIES OF PLOT *\/ */ /* x1 = datamin; */ /* x2 = datamax; */ /* y1 = MINCOUNT; */ /* y2 = ceil(maxNum); */ /* /\* DEFINE ENVIRONMENT IF NECESSARY *\/ */ /* if(pgflag%2 == 0) cpgenv(x1,x2,y1,y2,0,20); */ /* /\* DRAW HISTOGRAM *\/ */ /* if(pgflag/2 == 0){ */ /* older = 0.; */ /* x2 = datamin; */ /* cpgmove(datamin,MINCOUNT); */ /* for(i=0;i