1
/*===========================================================================
2
Copyright (C) 1993-2009 European Southern Observatory (ESO)
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License as
6
published by the Free Software Foundation; either version 2 of
7
the License, or (at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public
15
License along with this program; if not, write to the Free
16
Software Foundation, Inc., 675 Massachusetss Ave, Cambridge,
19
Corresponding concerning ESO-MIDAS should be addressed as follows:
20
Internet e-mail: midas@eso.org
21
Postal address: European Southern Observatory
22
Data Management Division
23
Karl-Schwarzschild-Strasse 2
24
D 85748 Garching bei Muenchen
26
===========================================================================*/
28
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
.IDENTifer module PLGRA
30
.AUTHOR R.M. van Hees IPG-ESO Garching
31
.KEYWORDS plot software, graphics, bulk data fame, gray scale plotting
33
.PURPOSE Grayscale plotting routine for two dimensional data
34
.COMMENTS holds PLGRA, WEDGE and PLGRAI
35
.ENVIRONment MIDAS and AGL
36
#include <agl.h> Prototypes for AGL application programs
37
#include <midas_def.h> Prototypes for MIDAS interfaces
38
#include <plot_def.h> Symbols used by the PLT interfaces
40
.VERSION 1.1 23-Sep-1993 FORTRAN --> ANSI-C RvH
43
------------------------------------------------------------*/
45
* Define _POSIX_SOURCE to indicate
46
* that this is a POSIX program
48
#define _POSIX_SOURCE 1
51
* definition of the used functions in this module
58
#include <midas_def.h>
61
* define some macros and constants
66
#define RAND_MAX 32768.0
70
* The array "options" holds TRUE and FALSE values for the following options
72
#define LINS ( (*options == FALSE) ? TRUE : FALSE ) /*lineair scaling*/
73
#define LOGS ( (*options == TRUE) ? TRUE : FALSE ) /*log. scaling*/
74
#define CONT ( (*(options+1) == FALSE) ? TRUE : FALSE ) /*cont. gray scale*/
75
#define STEP ( (*(options+1) == TRUE) ? TRUE : FALSE ) /*stepwise gray*/
76
#define FLIP ( (*(options+2) == TRUE) ? TRUE : FALSE ) /*change sign*/
77
#define ABSV ( (*(options+3) == TRUE) ? TRUE : FALSE ) /*take abs values*/
78
#define CUTP ( (*(options+4) == TRUE) ? TRUE : FALSE ) /*only gray between
80
/*++++++++++++++++++++++++++++++
82
.PURPOSE return the "traditional" Dwingeloo/Westerbork log scaling
85
.COMMENTS static function
86
--------------------------------*/
88
static double DWLOG( double value )
90
static double DWLOG( value )
94
value *= 0.549999 + 0.45 * value;
95
return log10( 30 * value + 1 )/ log10( 30.42 ) - 0.007;
98
/*++++++++++++++++++++++++++++++
100
.PURPOSE Produce halftone plot of a 2-D image
101
input: double vnom normalized intensity: 0 <= vnom <= 1.0
102
int ipx number of pixels in the X direction
103
int ipy number of pixels in the Y direction
104
double pixx pixel size in world coordinates in X
105
double pixy pixel size in world coordinates in Y
106
double xstr position of stip in plotter coordinates
107
double ystr position of stip in plotter coordinates
108
float greynes grayness parameter: 0 <= greyness <= 1.0
110
.COMMENTS static function
111
--------------------------------*/
113
static void HALFT( double vnom, int ipx, int ipy, double pixx,
114
double pixy, double xstr, double ystr, float greynes )
116
static void HALFT( vnom, ipx, ipy, pixx, pixy, xstr, ystr, greynes )
119
double vnom, pixx, pixy, xstr, ystr;
127
if ( (ipx+1) * pixx < 1.0 ) ipx +=1;
129
vnom *= greynes * RAND_MAX;
130
for ( ix = 0; ix < ipx; ix++ )
131
{ for ( iy = 0; iy < ipy; iy++ )
132
{ rrand = fmod( (double) rand(), RAND_MAX );
135
{ xpos = (float) (xstr + ix * pixx);
136
ypos = (float) (ystr + iy * pixy);
137
AG_GPLM( &xpos, &ypos, 1, 0 );
143
/*++++++++++++++++++++++++++++++++++++++++++++++++++
145
.PURPOSE Gray scale plotting routine for two dimensional data
146
input: float *p_img pointer to the data of the frame
147
float *image image size in pixel coordinates
148
float *area image size in world coordinates
149
double *step distance between pixels in world units
150
float *glevl level of the countours
151
int nlevl number of countours
152
int *options holds the following options:
153
LIN - LOG gray scaling
154
STEP - CONTineously increasing gray scale
155
POS - NEG increasing or decreasing gray scale
156
ABS take the absolute values
157
CUTS only gray scaling between the cuts
158
float greynes grayness parameter between 0.0 and 1.0,
159
1.0 gives the maximum blackness
162
.COMMENTS if image[0] > image[1] or image[2] > image[3] then
163
the values are put in the right order
164
--------------------------------*/
166
void PLGRA(float *p_img, float *image, float *area, double *step, float *glevl, int nlevl, int *options, float greynes)
168
void PLGRA( p_img, image, area, step, glevl, nlevl, options, greynes )
170
float *p_img, *image, *area, *glevl, greynes;
174
int ipx, ipy, ipy1, ix, iy, nl, nx, ny, pixnx, pixny;
176
float rres[2], clpl[4], wndl[4];
178
double delwx, delwy, delcx, delcy, diff, eps, pixx, pixy, val, vnom,
179
xnom, xstr, ystr, ynom;
182
* this functions only works if the number of levels is greater than zero
184
if ( nlevl == 0 ) return;
187
* get viewport characteristics
189
(void) AG_RGET( "clpl", clpl );
190
(void) AG_RGET( "wndl", wndl );
191
(void) AG_RGET( "reso", rres );
192
AG_SSET( "sydi=0.10" );
195
* get the start world coordinates and window characteristics
197
nx = (int) fabs( image[1] - image[0] ) + 1;
198
ny = (int) fabs( image[3] - image[2] ) + 1;
201
xnom = MYMAX( area[0], area[1] );
203
xnom = MYMIN( area[0], area[1] );
205
delwx = wndl[1] - wndl[0]; /* window size in X */
206
delwy = wndl[3] - wndl[2]; /* window size in Y */
207
delcx = fabs( clpl[1] - clpl[0] ); /* clipping size in X */
208
delcy = fabs( clpl[3] - clpl[2] ); /* clipping size in Y */
209
pixnx = NINT( delcx / rres[0] ); /* number of X pixels */
210
pixny = NINT( delcy / rres[1] ); /* number of Y pixels */
211
pixx = delwx / pixnx; /* size of a X pixel in w.c. */
212
pixy = delwy / pixny; /* size of a Y pixel in w.c. */
213
eps = fabs( *glevl * 0.0001 );
218
ipx = (int) ceil( *step/pixx );
219
ipy = (int) ceil( *(step+1)/pixy );
222
* reverse order of contours and reverse sign
225
{ for ( nl = 0; nl < NINT( nlevl/2.0 ); nl++ )
226
{ register int nn = nlevl - nl - 1;
227
register float dummy = *(glevl+nl);
228
*(glevl+nl) = - *(glevl+nn);
229
*(glevl+nn) = - dummy;
233
* Begin value in Y of gray - tone
234
* ynom = nominal plot position; ystr = actual starting plot position
237
ynom = MYMAX( area[2], area[3] ) - 1.5 * *(step+1);
239
ynom = MYMIN( area[2], area[3] ) - 1.5 * *(step+1);
242
for ( iy = 0; iy < ny - 1; iy++ )
243
{ ystr += ipy * pixy;
246
if ( diff < 0 ) ystr += pixy; /* Does it start too low? */
248
if ( diff > pixy ) ystr -= pixy; /* Does it start too high? */
250
* how many lines within grid-interval
252
ipy1 = (int) ceil( (ynom - ystr + *(step+1))/pixy );
254
for ( ix = 0; ix < nx; ix++ )
255
{ xstr = xnom + (ix - 0.5) * *step; /* start position in X */
258
if ( fabs( val ) < eps ) val = 0.0;
260
if ( ABSV ) val = fabs( val );
261
if ( FLIP ) val = -val;
263
if ( val > (double) *glevl )
264
{ if ( val >= (double) *(glevl+nlevl - 1) )
265
{ val = *(glevl+nlevl-1);
266
if ( CUTP ) val += eps;
273
{ for ( nl = 0; nl < nlevl-1; nl++ )
274
{ if ( val >= (double) *(glevl+nl)
275
&& val < (double) *(glevl+nl+1))
276
{ vnom = (double) (nl+1) / nlevl;
277
if ( LOGS ) /* "log" scale Dwi/Wbrk.*/
278
vnom = DWLOG( vnom );
282
if ( val == (double) *(glevl+nlevl-1) )
284
if ( LOGS ) /* "log" scale Dwi/Wbrk.*/
285
vnom = DWLOG( vnom );
289
{ if ( val >= (double) *glevl && val <= (double) *(glevl+1) )
290
{ vnom = (val - *glevl)/fabs( *(glevl+1) - *glevl );
291
if ( LOGS ) /* "log" scale Dwi/Wbrk.*/
292
vnom = DWLOG( vnom );
295
if ( val >= (double) *glevl && val <= (double) *(glevl+nlevl-1) )
296
HALFT( vnom, ipx, ipy1, pixx, pixy, xstr, ystr, greynes);
299
* set the pointer to the begin of the new line to be drawn
305
* reverse order of contours and reverse sign to get the original values
308
{ for ( nl = 0; nl < NINT( nlevl/2.0 ); nl++ )
309
{ register int nn = nlevl - nl - 1;
310
register float dummy = *(glevl+nl);
311
*(glevl+nl) = - *(glevl+nn);
312
*(glevl+nn) = - dummy;
319
/*++++++++++++++++++++++++++++++++++++++++++++++++++
321
.PURPOSE plots a gray scale wedge
323
float *glevl level of the countours
324
int nlevl number of countours
325
int *option holds the following options:
326
LIN - LOG gray scaling
327
STEP - CONTineously increasing gray scale
328
POS - NEG increasing or decreasing gray scale
329
ABS take the absolute values
330
CUTS only gray scaling between the cuts
331
float greynes grayness parameter between 0.0 and 1.0,
332
1.0 gives the maximum blackness
335
----------------------------------------------------*/
337
void WEDGE(double *step, float *glevl, int nlevl, int *options, float greynes)
339
void WEDGE( step, glevl, nlevl, options, greynes )
341
float *glevl, greynes;
345
int il, ix, iy, ngray, nx, ny;
346
float eps, clpl[4], frame[4], image[4], xl[2], yl[2], *wdata;
348
(void) AG_RGET( "clpl", clpl );
351
* define the area for the wedge
353
clpl[2] = clpl[3] - (clpl[3] - clpl[2]) / 20;
354
AG_VN2U( clpl[0], clpl[2], frame , frame+2 );
355
AG_VN2U( clpl[1], clpl[3], frame+1, frame+3 );
359
* draw a line between the wedge and the gray scale plot
365
AG_GPLL( xl, yl, 2 );
367
nx = (int) fabs( (frame[1] - frame[0]) / *step ) + 2;
368
ny = (int) fabs( (frame[3] - frame[2]) / *(step+1) ) + 2;
369
wdata = (float *) osmmget( nx * ny * sizeof( float ));
372
{ ngray = NINT( (float) nx / nlevl ); /* # gr. pnts. with same gray tone */
373
for ( iy = 0; iy < ny; iy++ )
374
{ for ( il = 0; il < nlevl-1; il++ )
375
{ eps = 0.00001 * (double) glevl[il];
376
for ( ix = 0; ix < ngray; ix++ )
377
*(wdata + (il-1) * ngray + ix) = *(glevl+il) + eps;
379
for ( ix = (nlevl-1) * ngray; ix < nx; ix++ )
380
*(wdata + ix) = *(glevl+il) + eps;
385
else /* continuous gray scale */
386
{ for ( iy = 0; iy < ny; iy++ )
387
{ for ( ix = 0; ix < nx; ix++ )
388
{ *(wdata + ix) = *glevl + ix * ( *(glevl+1) - *glevl) / nx;
395
* size of the wedge in pixel coordinates
397
image[0] = image[2] = 0;
402
* size of the wedge in world coordinates
404
frame[0] += 1.5 * *step;
405
frame[1] += 1.5 * *step;
406
frame[2] += 0.5 * *(step+1);
407
frame[3] += 0.5 * *(step+1);
408
PLGRA( wdata, image, frame, step, glevl, nlevl, options, greynes );
413
/*++++++++++++++++++++++++++++++++++++++++++++++++++
415
.PURPOSE produce plot information for a two-dimensional grayscaler plot
416
input: int plmode plot mode, see PMODE in PLISTAT
417
char *name data frame name
418
char *ident ascii identifier of image
419
int nlevl number of contour levels
420
float *glevl values of the contours
422
----------------------------------------------------*/
423
void PLGRAI( plmode, name, ident, nlevl, glevl, options )
424
int plmode, nlevl, *options;
430
float one, ssize, tsize, x1, x2, y1, y2, xt, yt, yh, xstr;
431
float mnmx[2], scale[2], xl[3], yl[3], clpl[4], image[4], wndl[4];
435
* only plot mode is 2
437
if ( plmode != 2 ) return;
440
* get the symbol and character dimensions, from the MIDAS keywords
442
PCKRDR( "SSIZE", 1, &actvals, &ssize );
443
PCKRDR( "TSIZE", 1, &actvals, &tsize );
446
* if the symbol size or the text size is not equal to 1, set it to 1
447
* and call PCTSET to get the proper sizes for the MIDAS layout
449
if ( ssize != 1.0 || tsize != 1.0 )
451
PCKWRR( "SSIZE", 1, &one );
452
PCKWRR( "TSIZE", 1, &one );
459
(void) AG_RGET( "clpl", clpl );
460
(void) AG_RGET( "wndl", wndl );
465
AG_CDEF( x1, x2, y1, y2);
466
AG_WDEF( 0.0, 1.0, 0.0, 1.0 );
474
* set character height
476
AG_SSET( "sydi=0.75;chdi=0.75,0.75" );
477
AG_TGET( "M", xl, yl );
484
AG_GTXT( xt, yt, buff, 1 );
490
if ( strlen( name ) > (size_t) 12 )
491
{ AG_GTXT( xt, yt, "Frame:", 1 );
493
AG_GTXT( xt, yt, name, 1 );
496
{ (void) sprintf( buff, "Frame: %s", name );
497
AG_GTXT( xt, yt, buff, 1 );
502
if ( strlen( ident ) > (size_t) 0 )
504
AG_GTXT( xt, yt, "Identification:", 1 );
506
AG_GTXT( xt, yt, ident, 1 );
511
PCKRDR( "PIXEL", 4, &actvals, image );
513
AG_GTXT( xt, yt, "Area:", 1 );
515
(void) sprintf( buff, "X: %.0f to %.0f", image[0], image[1] );
516
AG_GTXT( xt, yt, buff, 1 );
518
(void) sprintf( buff, "Y: %.0f to %.0f", image[2], image[3] );
519
AG_GTXT( xt, yt, buff, 1 );
523
PCKRDR( "SCALES", 2, &actvals, scale );
525
AG_GTXT( xt, yt, "Scales:", 1 );
527
(void) sprintf( buff, "X: %-.6g", scale[0] );
528
AG_GTXT( xt, yt, buff, 1 );
530
(void) sprintf( buff, "Y: %-.6g", scale[1] );
531
AG_GTXT( xt, yt, buff, 1 );
533
* minimum and maximum
535
PCKRDR( "ZWNDL", 2, &actvals, mnmx );
537
(void) sprintf( buff, "Min: %-.3g ", mnmx[0] );
538
AG_GTXT( xt, yt, buff, 1 );
540
(void) sprintf( buff, "Max: %-.3g ", mnmx[1] );
541
AG_GTXT( xt, yt, buff, 1 );
548
AG_GTXT( xt, yt, "Gray scale levels:", 1 );
551
AG_GTXT( xt, yt, "Gray scale range:", 1 );
554
for ( ii = 0; ii < nlevl; ii++ )
555
{ xstr = xt + 11 * xl[1];
560
(void) sprintf( buff, "%8.5g", glevl[ii] );
561
AG_GTXT( xstr, yt, buff, 1 );
568
* back to standard sizes
570
AG_CDEF( clpl[0], clpl[1], clpl[2], clpl[3] );
571
AG_WDEF( wndl[0], wndl[1], wndl[2], wndl[3] );
574
* reset if necessary the symbol and text size
576
if ( ssize != 1.0 || tsize != 1.0 )
577
{ PCKWRR( "SSIZE", 1, &ssize );
578
PCKWRR( "TSIZE", 1, &tsize );