/* @(#)plotcon.c 17.1.1.1 (ESO-DMD) 01/25/02 17:45:03 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1993 European Southern Observatory .IDENTifer PLOTCON .AUTHOR R.M. van Hees IPG-ESO Garching .KEYWORDS Graphics, bulk data frame, one-dimensional plotting .LANGUAGE C .PURPOSE Plot or overplot a contour map of two-dimensional FRAME in/output: IN_A/C/1/60 = input frame IN_B/C/1/60 = coord_string P3/R/1/4 = scales in X and Y and offset X and Y (default is auto scaling to device filling) INPUTC/C/1/72 = contour levels INPUTC/C/73/4 = contour type INPUTI/I/1/1 = smoothing parameter .COMMENTS none .ENVIRONment MIDAS #include Prototypes for MIDAS interfaces #include General symbols for Plot routines .VERSION 1.2 25-Nov-1993 Removed restrictions on frame size, RvH 010423 last modif ------------------------------------------------------------*/ /* * Define _POSIX_SOURCE to indicate * that this is a POSIX program */ #define _POSIX_SOURCE 1 /* * definition of the used functions */ #include #include #include #include /* * define some macros and constants */ #include #include #define MAXLEV 50 /* maximum num of contour levels */ #define MAXPIX 512 /* max frame dimension (X,Y) accessed at once */ #define MAXSIZ (MAXPIX * MAXPIX) /*++++++++++++++++++++ .IDENTifer GET_CONTOURS .PURPOSE fill two arrays with contour levels and line types output: int *nlevl number of requested contour levels float *clevl array with contour levels int *ctype line type for each contour .COMMENTS static function --------------------*/ #ifdef __STDC__ static void GET_CONTOURS( int *nlevl, float *clevl, int *ctype ) #else static void GET_CONTOURS( nlevl, clevl, ctype ) int *nlevl, *ctype; float *clevl; #endif { int actvals, ic, ltype; char *cbuff, option[5], input[72]; char *err_usrin = "*** FATAL: error detected in USRINP"; /* * get contour levels as character string */ (void) SCKGETC( "INPUTC", 1, 72, &actvals, input ); cbuff = (char *) clevl; if ( USRINP( 'r', input, MAXLEV, cbuff, nlevl ) != ERR_NORMAL ) SCETER( 1, err_usrin ); /* * sort the contour levels */ SORLEV( *nlevl-1, clevl ); /* * get C_TYPE option for the plotting of the contours */ (void) SCKGETC( "INPUTC", 73, 4, &actvals, option ); if ( *option == 'n' || *option == 'N' ) /* dashed negative contours */ { for ( ic = 0; ic < *nlevl; ic++ ) { if ( fabs( (double) clevl[ic] ) < PLT_EPS ) ctype[ic] = 2; /*dashed*/ else if ( clevl[ic] < 0.0 ) ctype[ic] = 1; /*dotted*/ else ctype[ic] = 0; /*solid*/ } } else if ( *option == 'l' || *option == 'L' ) /* use LTYPE */ { PCKRDI( "LTYPE", 1, &actvals, <ype ); ltype = MYMAX( ltype-1, 0 ); for ( ic = 0; ic < *nlevl; ic++ ) ctype[ic] = ltype; } else /* draw odd contours dashed */ { for ( ic = 0; ic < *nlevl; ic++ ) { if ( ic % 2 == 0 ) ctype[ic] = 1; /*dotted*/ else ctype[ic] = 0; /*solid*/ } } return; } /*++++++++++++++++++++++++++++++++++++++++++++++++++ * * here starts the code of the function */ int main() { register int ii; int actvals, chunks, imf, indx, knul, naxis, nr, size, stat, unit, ctype[MAXLEV], ndum[PLDIM2], npix[PLDIM2], nrpix[PLDIM2], sublo[PLDIM2], subhi[PLDIM2]; float amin, amax, *p_img, last_row, zmin, zmax, area[4], image[4], wcfram[12], clevl[MAXLEV]; double start[PLDIM2], step[PLDIM2]; char cmnd[21], ident[33], cunit[49], name[61], input[61], buff[81], *label[4]; /* * initialised variables */ char *err_1dim = "*** FATAL: Frame has only one dimension", *err_coord = "*** FATAL: invalid coordinate input ...", *err_xcuts = "*** FATAL: range in x has no overlap with current graph abscissa - NO PLOT", *err_ycuts = "*** FATAL: range in y has no overlap with current graph abscissa - NO PLOT", *info_flat = "*** WARNING: zero dynamic range in data at %13.8g", *info_levl = "*** WARNING: no contour level falls within the dynamic range of your data"; static char *axis[PLDIM2] = { "MANU", "MANU" }; int access = 0, /* parameter for PCOPEN: plot mode */ plmode = -1, /* plot mode taken from keyword PMODE */ nlevl = 0, /* Default number of contours is zero */ ismoot = 1, /* Default no smooting of the data */ nrdrawn = 0; /* no contours drawn yet */ /* * allocate memory for different character pointers and initialise a few */ for ( ii = 0; ii < 4; ii++ ) label[ii] = osmmget(81); (void) strcpy( label[0], "Position (" ); (void) strcpy( label[1], "Position (" ); (void) strcpy( label[2], "Frame: " ); (void) strcpy( label[3], "Ident: " ); /* * start of executable code */ (void) SCSPRO( "PLTCON" ); /*contact with the MIDAS monitor*/ /* * plot or overplot mode */ (void) SCKGETC( "MID$CMND", 1, 20, &actvals, cmnd ); if ( *cmnd == 'O' ) access = 1; /* * find file name and read header information */ (void) SCKGETC( "IN_A", 1, 60, &actvals, name ); (void) SCFOPN( name, D_R4_FORMAT, 0, F_IMA_TYPE, &imf ); (void) SCDRDI( imf, "NAXIS", 1, 1, &actvals, &naxis, &unit, &knul ); (void) SCDRDI( imf, "NPIX" , 1, PLDIM2, &actvals, npix , &unit, &knul ); /* * check frame parameters */ if ( naxis < 2 || (npix[0] == 1 || npix[1] == 1) ) SCETER( 1, err_1dim ); /* * read the descriptor */ (void) SCDRDD( imf, "START", 1, PLDIM2, &actvals, start, &unit, &knul ); (void) SCDRDD( imf, "STEP" , 1, PLDIM2, &actvals, step , &unit, &knul ); (void) SCDGETC( imf, "IDENT", 1, 32, &actvals, ident ); (void) SCDGETC( imf, "CUNIT", 1, 48, &actvals, cunit ); /* * Get the manual setting for the axes */ PCKRDR( "XAXIS", 4, &actvals, wcfram ); PCKRDR( "YAXIS", 4, &actvals, wcfram+FOR_Y ); /* * read window coordinates and take action */ (void) SCKGETC( "IN_B", 1, 60, &actvals, input ); if ( *input == 'm' || *input == 'M' ) /* manual scaling */ { BOXWTP( wcfram, npix[0], start[0], step[0], image ); BOXWTP( wcfram+FOR_Y, npix[1], start[1], step[1], image+2 ); } else { if ( *input == 'c' || *input == 'C' ) /* display input */ { (void) SCKRDR( "OUTPUTR", 10, 1, &actvals, image, &unit, &knul); (void) SCKRDR( "OUTPUTR", 11, 1, &actvals, image+2, &unit, &knul); (void) SCKRDR( "OUTPUTR", 15, 1, &actvals, image+1, &unit, &knul); (void) SCKRDR( "OUTPUTR", 16, 1, &actvals, image+3, &unit, &knul); } else /* automatic scaling */ { stat = Convcoo(1,imf,input,PLDIM2,ndum,sublo,subhi); if ( stat != 0 ) SCETER( 2, err_coord ); image[0] = sublo[0] + 1; image[1] = subhi[0] + 1; image[2] = sublo[1] + 1; image[3] = subhi[1] + 1; } } BOXPTW( image, npix[0], start[0], step[0], area ); BOXPTW( image+2, npix[1], start[1], step[1], area+2 ); PCKWRR( "PIXEL", 4, image ); if ( access == 0 ) { /* * get size of frame along X-axis */ if ( fabs( *wcfram ) < PLT_EPS && fabs( *(wcfram+1) ) < PLT_EPS ) { axis[0] = "AUTO"; wcfram[0] = area[0]; wcfram[1] = area[1]; wcfram[2] = wcfram[3] = 0.0; } /* * get size of frame along Y-axis */ if ( fabs( *(wcfram+FOR_Y) ) < PLT_EPS && fabs( *(wcfram+FOR_Y+1) ) < PLT_EPS ) { axis[1] = "AUTO"; wcfram[FOR_Y] = area[2]; wcfram[FOR_Y+1] = area[3]; wcfram[FOR_Y+2] = wcfram[FOR_Y+3] = 0.0; } GETFRM( axis[0], wcfram ); GETFRM( axis[1], wcfram + FOR_Y ); PCKWRR( "XWNDL", 4, wcfram ); PCKWRR( "YWNDL", 4, wcfram+FOR_Y ); } else /* overplot mode*/ { PCKRDR( "XWNDL", 4, &actvals, wcfram ); PCKRDR( "YWNDL", 4, &actvals, wcfram+FOR_Y ); /* * does overplot data fall within plotted frame? */ amin = MYMIN( *wcfram, *(wcfram + 1) ); amax = MYMAX( *wcfram, *(wcfram + 1) ); if ( ( MYMAX( area[0], area[1] ) < amin ) || ( MYMIN( area[0], area[1] ) > amax ) ) SCETER( 3, err_xcuts ); amin = MYMIN( *(wcfram + FOR_Y), *(wcfram + FOR_Y + 1) ); amax = MYMAX( *(wcfram + FOR_Y), *(wcfram + FOR_Y + 1) ); if ( ( MYMAX( area[2], area[3] ) < amin ) || ( MYMIN( area[2], area[3] ) > amax ) ) SCETER( 4, err_ycuts ); } /* * get contours levels */ GET_CONTOURS( &nlevl, clevl, ctype ); /* * setup graphic device according to MIDAS settings */ PCOPEN( " ", " ", access, &plmode ); /* * get the smooting parameter */ (void) SCKRDI( "INPUTI", 1, 1, &actvals, &ismoot, &unit, &knul); /* * determine number of pixels and number of chunks */ nrpix[0] = (int) fabs( image[1] - image[0] ) + 1; nrpix[1] = (int) fabs( image[3] - image[2] ) + 1; last_row = MYMAX( image[2], image[3]); chunks = (int) ceil( (double) nrpix[0] * nrpix[1] / MAXSIZ ); nrpix[1] = (int) ceil( (double) nrpix[1] / chunks ); /* * allocate virtual memory and scratch space */ size = nrpix[0] * nrpix[1]; p_img = (float *) osmmget( size * sizeof( float )); wcfram[FOR_Z] = 1e+12, /* minimum in frame */ wcfram[FOR_Z+1] = -1e+12; /* maximum in frame */ for ( ii = 0; ii < chunks; ii++ ) { if ( image[3] > image[2] ) /* size of chunk p.c.*/ { if ( ii > 0 ) image[2] += nrpix[1] - 1.0; image[3] = MYMIN( last_row, image[2] + nrpix[1] - 1 ); } else { if ( ii > 0 ) image[3] += nrpix[1] - 1.0; image[2] = MYMIN( last_row, image[3] + nrpix[1] - 1 ); } /* * get size of chunk in w.c. */ BOXPTW( image+2, npix[1], start[1], step[1], area+2 ); /* * extract chunck from original frame */ GETDAT( imf, MAXSIZ, npix, image, ismoot, p_img ); /* * get dynamic range of the data */ MINMAX( p_img, size, &zmin, &zmax ); wcfram[FOR_Z] = MYMIN( wcfram[FOR_Z], zmin ); wcfram[FOR_Z+1] = MYMAX( wcfram[FOR_Z+1], zmax ); /* * determine the actual number of contours to be plotted */ indx = 0; while ( clevl[indx] < zmin ) indx++; nr = nlevl; while ( clevl[nr-1] > zmax ) nr--; nr -= indx; nrdrawn = MYMAX( nr, nrdrawn ); /* * draw the contours */ PLCON( p_img, image, area, step, nr, clevl+indx, ctype+indx ); /* * updating for the next loop */ nrpix[1] = MYMIN( last_row - ii * nrpix[1], nrpix[1] ); size = nrpix[0] * nrpix[1]; } (void) SCFCLO( imf ); /* * give a warning if no contour is drawn */ if ( nrdrawn == 0 ) SCTPUT( info_levl ); /* * store min and max found in the whole frame */ if ( wcfram[FOR_Z] == wcfram[FOR_Z+1] ) { (void) sprintf( buff, info_flat, wcfram+FOR_Z ); SCTPUT( buff ); } PCKWRR( "ZWNDL", 2, wcfram+FOR_Z ); /* * draw the axes and the label */ if ( plmode >= 0 && access == 0 ) { if ( strlen( cunit ) > (size_t) 32 ) { (void) strcat( label[1], cunit+32 ); *(cunit+32) = '\0'; } if ( strlen( cunit ) > (size_t) 16 ) (void) strcat( label[0], cunit+16 ); for ( ii = 0; ii < PLDIM2; ii++ ) { (void) strcat( label[ii], ")" ); LABSTR( label[ii] ); } /* * get format for the axes */ /* * plot axes and labels */ PCFRAM( wcfram, wcfram+FOR_Y, label[0], label[1] ); if ( plmode == 1 ) { (void) strcat( label[2], name ); (void) strcat( label[3], ident ); PLIDEN( plmode, label[2], label[3] ); } else if ( plmode == 2 ) PLCONI( plmode, name, ident, clevl, ctype, nlevl ); } /* * close plot file and terminate graphic operations */ PCCLOS(); return SCSEPI(); }