/* @(#)plottbl.c 17.1.1.1 (ESO-DMD) 01/25/02 17:45:04 */ /*=========================================================================== 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 .IDENTIFIER PLOTTBL .AUTHOR R.M. van Hees IPG-ESO Garching .KEYWORDS Graphics, 3-D & 2-D tables .LANGUAGE C .PURPOSE Plot or overplot one or two columns or planes from a TABLE input: IN_A/C/1/60 = input table P2/C/1/60 = input string for plane 1 P3/C/1/60 = input string for plane 2 P4/R/2 = scales in x and y; default is auto scaling p5/C/1/40 = symbol types; default is set by SET/GRAPHIC p6/C/1/40 = line types; default is set by SET/GRAPHIC INPUTC/C/1/20 = flag which specifies the way the planes are read; default Default, alternative is Other or Opposite: flag = "D" yz-plane, column by column (y) xz-plane, array by array (z) xy-plane, column by column (y) flag = "O" yz-plane, array by array (z) xz-plane, row by row (x) xy-plane, row by row (x) .COMMENTS none .ENVIRONment MIDAS #include Prototypes for MIDAS interfaces #include General symbols for Plot routines .VERSION 1.1 20-Sep-1993 created by R.M. van Hees 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 TBLDIM 3 /* a input table may have upto 3 dimensions */ #define COLMAX 256 /* maximum number of columns in a TABLE */ /*++++++++++++++++++++++++++++++ .IDENTIFIER LOG_FLAG .PURPOSE Find out if the user requested a logaritmic scaling in/output char *string if this string starts with "LOG", "log", "LN" or "ln", than this is taken away (together with the brackets) and "ilog" is set output int *ilog log flag: 0) no log scaling requested 1) decimal log requested 2) natural log requested .COMMENT static function --------------------------------*/ #ifdef __STDC__ static void LOG_FLAG( char *string, int *ilog ) #else static void LOG_FLAG( string, ilog ) char *string; int *ilog; #endif { char *pntr; *ilog = 0; if ( strncmp( string, "LOG", 3 ) == 0 || strncmp( string, "log", 3 ) == 0 ) { *ilog = 1; pntr = strchr( string, '(' ) + 1; (void) strcpy( string, strtok( pntr, ")" ) ); } else if ( strncmp( string, "LN", 2 ) == 0 || strncmp( string, "ln", 2 ) == 0 ) { *ilog = 2; pntr = strchr( string, '(' ) + 1; (void) strcpy( string, strtok( pntr, ")" ) ); } return; } /*++++++++++++++++++++++++++++++ .IDENTIFIER GET_LABELS .PURPOSE write the X and Y label input int tid table id char *colref column reference int ilog log scaling or not output char *label character string with the label .COMMENT static function --------------------------------*/ #ifdef __STDC__ static void GET_LABELS( int tid, char *colref, int depth, int items, int ilog, char *label ) #else static void GET_LABELS( tid, colref, depth, items, ilog, label ) int tid, depth, items, ilog; char *colref, *label; #endif { int bytes, dtype, nc, ncol, ndepth, icol[COLMAX], sflag[COLMAX]; char cunit1[17], cunit2[17], buff[41]; char *err_fcol = "*** FATAL: column has character format"; (void) TCCSEL( tid, colref, COLMAX, icol, sflag, &ncol ); nc = 0; (void) TCBGET( tid, icol[nc], &dtype, &ndepth, &bytes ); if ( dtype == D_C_FORMAT ) (void) SCETER( 1, err_fcol ); (void) TCLGET( tid, icol[nc], label ); (void) TCUGET( tid, icol[nc], cunit1 ); if ( ncol > 1 ) { nc++; do { (void) strcpy( cunit2, cunit1 ); (void) TCBGET( tid, icol[nc], &dtype, &ndepth, &bytes ); if ( dtype == D_C_FORMAT ) (void) SCETER( 1, err_fcol ); (void) TCUGET( tid, icol[nc], cunit1 ); } while( strcmp( cunit1, cunit2 ) == 0 && ++nc < ncol ); if ( nc != ncol ) (void) strcpy( cunit1, "MIXED UNITS" ); } /* * write the column names */ if ( ncol == 1 ) { if ( strlen( label ) == 0 ) (void) sprintf( buff, "Column: #%-d", icol[0] ); else (void) strcpy( buff, label ); } else (void) sprintf( buff, "Column: #%-d..%-d", icol[0], icol[ncol-1] ); /* * add if requered depth & range */ if ( ndepth > 1 ) { if ( items == 1 ) (void) sprintf( buff, "%s[%-d]", buff, depth ); else if ( items > 1 ) (void) sprintf( buff, "%s[%-d..%-d]", buff, depth, depth + items-1 ); else (void) sprintf( buff, "%s[%-d..LAST]", buff, depth ); (void) strcat( label, buff ); } /* * add if requered column unit and log flag */ if ( ilog == 0 ) (void) sprintf( label, "%s (%s)", buff, cunit1 ); else if ( ilog == 1 ) (void) sprintf( label, "LOG10 %s (%s)", buff, cunit1 ); else (void) sprintf( label, "LN %s (%s)", buff, cunit1 ); } /*++++++++++++++++++++++++++++++ .IDENTIFIER GET_SLTYPE .PURPOSE fill two array with the requested Symbol and Line types input char *cstype symbol types given by the user char *cltype line types given by the user int nrdraw numbers of drawn lines in/output int *stype symbol types, upon input: default symbol type int *ltype line type, upon input: default line type .COMMENT static function --------------------------------*/ #ifdef __STDC__ static void GET_SLTYPE( char *cstype, char *cltype, int nrdraw, int *stype, int *ltype ) #else static void GET_SLTYPE( cstype, cltype, nrdraw, stype, ltype ) char *cstype, *cltype; int nrdraw, *stype, *ltype; #endif { int ii, nsym, nlin; char *cbuff; char *err_usrin = "*** FATAL: too many symbol or line types given"; (void) strtok( cstype, " " ); (void) strtok( cltype, " " ); /* * get symbol types */ if ( strcmp( cstype, "?" ) == 0 ) for ( ii = 1; ii < nrdraw; ii++ ) *(stype+ii) = *stype; else { cbuff = (char *) stype; if ( USRINP( 'i', cstype, nrdraw, cbuff, &nsym ) != ERR_NORMAL ) (void) SCETER( 2, err_usrin ); for ( ii = 0; ii < nrdraw - nsym; ii++ ) *(stype+nsym+ii) = *(stype+ii); } /* * get line types */ if ( strcmp( cltype, "?" ) == 0 ) { for ( ii = 0; ii < nrdraw; ii++ ) { if ( *(stype+ii) != 0 ) *(ltype+ii) = 0; else *(ltype+ii) = *ltype; } } else { cbuff = (char *) ltype; if ( USRINP( 'i', cltype, nrdraw, cbuff, &nlin ) != ERR_NORMAL ) (void) SCETER( 2, err_usrin ); for ( ii = 0; ii < nrdraw - nlin; ii++ ) *(ltype+nlin+ii) = *(ltype+ii); } return; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * * here starts the code of the function */ int main() { register int ii; int actcol, actrow, actvals, allcol, allrow, bin, bytes, dtype, icol, mxdepth, nrdraw, ndepth, nrcol, nrrow, nsort, nconn, nnull, tid, count, stat, x_or_y, xy, *inul[PLDIM2], *ltype, *stype, dir[PLDIM2], ilog[PLDIM2], index[PLDIM2], items[PLDIM2], nline[PLDIM2], row[PLDIM2], type[PLDIM2]; float *rval[PLDIM2], wcfram[8]; char *pntr, binmod[4], cflag[21], cmnd[21], colref[41], cltype[41], cstype[41], table[61], buff[128], sel[81], *column[PLDIM2], *string[PLDIM2], *label[4]; /* * initialised variables */ int plmode = -1, /* plot mode taken from keyword PMODE */ access = 0, /* parameter for PCOPEN: NEW plot mode */ tbldim = TBLDIM; /* default for the table dimension */ char *err_row = "*** FATAL: no (selected) points in this table ....", *err_clmn = "*** FATAL: you should give at least one column", *err_plane = "*** FATAL: problems with plane: col=%s row=%-d [%d..%d]", *war_null = "*** WARNING: Table contains %d illegal or NULL values", *war_sltyp = "*** WARNING: STYPE and LTYPE equal 0: no data plotted", *err_dim = "*** FATAL: The data to be plotted does not have the same dimension in X or Y"; static char *axis[PLDIM2] = { "MANU", "MANU" }, *err_flat[PLDIM2] = { "*** WARNING: zero dynamics range in x: %13.8g", "*** WARNING: zero dynamics range in y: %13.8g" }; /* * allocate memory for different character pointers and initialise a few */ for ( xy = 0; xy < PLDIM2; xy++ ) { column[xy] = osmmget(41); string[xy] = osmmget(61); *column[xy] = '\0'; } for ( ii = 0; ii < 4; ii++ ) { label[ii] = osmmget(81); *label[ii] = '\0'; } (void) strcpy( label[2], "Table: " ); /* * start of executable code */ (void) SCSPRO( "PLTTBL" ); /*contact with the MIDAS monitor*/ /* * find file name and read header information */ (void) SCKGETC( "IN_A", 1, 60, &actvals, table ); /* * Try to open table, this routine EXITS the program if the table can not * be found !! */ (void) TCTOPN( table, F_I_MODE, &tid ); /* * read table size information: number of columns, rows and depth */ (void) TCIGET( tid, &nrcol, &nrrow, &nsort, &allcol, &allrow ); (void) TCSCNT( tid, &count); if ( nrrow == 0 || count <= 0 ) { SCTPUT(err_row ); return SCSEPI(); } mxdepth = 1; for ( ii = 1; ii <= nrcol; ii++ ) { (void) TCBGET( tid, ii, &dtype, &ndepth, &bytes ); mxdepth = MYMAX( mxdepth, ndepth ); } if ( mxdepth == 1 ) tbldim = 2; /* a 2-D table */ /* * get description of the planes in the table and their orientation */ (void) SCKGETC( "P2", 1, 60, &actvals, string[0] ); (void) SCKGETC( "P3", 1, 60, &actvals, string[1] ); LOG_FLAG( string[0], ilog ); LOG_FLAG( string[1], ilog+1 ); TBL_USRINP( string[0], type, column[0], row, index, items ); TBL_USRINP( string[1], type+1, column[1], row+1, index+1, items+1 ); if ( type[0] == 0 && type[1] == 0 ) SCETER( 2, err_clmn ); /* * The user may have used a short hand for the description of the planes if * the orientation of the planes are the same. We have to check and repair! */ if ( tbldim != 2 && type[0] == type[1] ) { if ( type[0] == 1 || type[0] == 2 ) { if ( items[0] != items[1] && items[0] == 0 ) { (void) TCCSER( tid, column[0], &icol ); (void) TCBGET( tid, icol, &dtype, &ndepth, &bytes ); if ( ndepth != 1 ) { index[0] = index[1]; items[0] = items[1]; } } } if ( type[0] == 2 || type[0] == 3 ) { if ( strcmp( column[0], column[1] ) != 0 ) if ( *column[0] == '\0' ) (void) strcpy( column[0], column[1] ); } } /* * Get flag for storage direction of data of the requested planes */ (void) SCKGETC( "INPUTC", 1, 20, &actvals, cflag ); CGN_LOWSTR( cflag ); dir[0] = ( *cflag == 'd' ) ? 0 : 1; if ( (pntr = strchr( cflag, ',' )) == NULL ) dir[1] = dir[0]; else dir[1] = ( *(pntr+1) == 'd' ) ? 0 : 1; /* * read table data */ for ( xy = 0; xy < PLDIM2; xy++ ) { (void) strcpy( colref, column[xy] ); if ( type[xy] == 1 ) /* data from column or YZ-plane */ { inul[xy] = (int *) osmmget(mxdepth * nrrow * sizeof(int)); rval[xy] = (float *) osmmget(mxdepth * nrrow * sizeof(float)); stat = tbl_readplaneyz( tid, colref, index[xy], items[xy], 1, dir[xy], nrrow, items+xy, &actrow, rval[xy], inul[xy] ); if ( stat != ERR_NORMAL ) { (void) sprintf( buff, err_plane, column[xy], row[xy], index[xy], index[xy]+items[xy]-1 ); (void) SCETER( 0, buff ); } if ( xy == 0 || type[0] == 0 ) /* numb. of points */ { nconn = actrow; if ( dir[xy] == 1 ) nconn = items[xy]; } else if ( (dir[xy] == 0 && actrow != nconn) || (dir[xy] == 1 && items[xy] != nconn) ) (void) SCETER( 4, err_dim ); nline[xy] = items[xy]; /* numb. of lines */ if ( dir[xy] == 1 ) nline[xy] = actrow; } else if ( type[xy] == 2 ) /* data from row or XZ-plane */ { inul[xy] = (int *) osmmget(mxdepth * nrcol * sizeof(int)); rval[xy] = (float *) osmmget(mxdepth * nrcol * sizeof(float)); stat = tbl_readplanexz( tid, colref, row[xy], index[xy], items[xy], 1, dir[xy], &actcol, items+xy, rval[xy], inul[xy] ); if ( stat != ERR_NORMAL ) { (void) sprintf( buff, err_plane, column[xy], row[xy], index[xy], index[xy]+items[xy]-1 ); (void) SCETER( 0, buff ); } if ( xy == 0 || type[0] == 0 ) /* numb. of points */ { nconn = items[xy]; if ( dir[xy] == 1 ) nconn = actcol; } else if ( (dir[xy] == 0 && items[xy] != nconn) || (dir[xy] == 1 && actcol != nconn) ) SCETER( 4, err_dim ); nline[xy] = actcol; /* numb. of lines */ if ( dir[xy] == 1 ) nline[xy] = items[xy]; } else if ( type[xy] == 3 ) /* data from array (depth) or XY-plane */ { inul[xy] = (int *) osmmget( nrrow * nrcol * sizeof(int)); rval[xy] = (float *) osmmget( nrrow * nrcol * sizeof(float)); stat = tbl_readplanexy( tid, colref, index[xy], nrrow, 1, dir[xy], &actrow, &actcol, rval[xy], inul[xy] ); if ( stat != ERR_NORMAL ) { (void) sprintf( buff, err_plane, column[xy], row[xy], index[xy], index[xy]+items[xy]-1 ); (void) SCETER( 0, buff ); } if ( xy == 0 || type[0] == 0 ) /* numb. of points */ { nconn = actrow; if ( dir[xy] == 1 ) nconn = actcol; } else if ( (dir[xy] == 0 && actrow != nconn ) || (dir[xy] == 1 && actcol != nconn) ) (void) SCETER( 4, err_dim ); nline[xy] = actcol; /* numb. of lines */ if ( dir[xy] == 1 ) nline[xy] = actrow; } else /* axis is the row sequence */ nline[xy] = 1; /* * log scaling or not... */ if ( type[xy] != 0 && ilog[xy] == 1 ) { for ( ii = 0; ii < nconn * nline[xy]; ii++ ) if (*(rval[xy] + ii) > 0.0) *(rval[xy] + ii) = (float) log10( *(rval[xy] + ii)); else *(inul[xy] + ii) = 1; } else if ( type[xy] != 0 && ilog[xy] == 2 ) { for ( ii = 0; ii < nconn * nline[xy]; ii++ ) if (*(rval[xy] + ii) > 0.0) *(rval[xy] + ii) = (float) log( *(rval[xy] + ii)); else *(inul[xy] + ii) = 1; } } /* * fill array with values if the row sequence is used */ if ( ( type[0] == 0 ) || ( type[1] == 0 ) ) { if ( type[0] == 0 ) xy = 0; else xy = 1; inul[xy] = (int *) osmmget( nconn * sizeof(int)); rval[xy] = (float *) osmmget( nconn * sizeof(float)); for ( ii = 0; ii < nconn; ii++ ) { *(inul[xy]+ii) = 0; *(rval[xy]+ii) = ii+1; } } /* * reject NULL values and issue warning */ SKIPNULL( nline, inul, rval, &nconn, &nnull, rval ); if ( nnull > 0 ) { (void) sprintf( buff, war_null, nnull ); SCTPUT( buff ); SCTPUT( " Data points not plotted" ); } /* * set the number of lines to be plotted */ if ( nline[0] == 1 || nline[1] == 1 ) nrdraw = MYMAX( nline[0], nline[1] ); else nrdraw = MYMIN( nline[0], nline[1] ); /* * Plot mode or Overplot mode?? */ (void) SCKGETC( "MID$CMND", 1, 20, &actvals, cmnd ); if ( *cmnd != 'P' ) access = 1; /* * Get the manual setting for the axes */ PCKRDR( "XAXIS", 4, &actvals, wcfram ); PCKRDR( "YAXIS", 4, &actvals, wcfram+FOR_Y ); /* * If plot mode: write labels, and determine frame size */ if ( access == 0 ) { for ( xy = 0; xy < PLDIM2; xy++ ) { if ( type[xy] != 0 ) { GET_LABELS( tid, column[xy], index[xy], items[xy], ilog[xy], label[xy] ); LABSTR( label[xy] ); } else (void) strcpy( label[xy], "Sequence" ); x_or_y = ( xy == 0 ) ? FOR_X : FOR_Y; if ( fabs( *(wcfram+x_or_y)) < PLT_EPS && fabs( *(wcfram+x_or_y+1)) < PLT_EPS ) { axis[xy] = "AUTO"; if ( type[xy] == 0 ) { wcfram[x_or_y] = *rval[0]; wcfram[x_or_y+1] = *(rval[0])+nconn-1; } else { MINMAX( rval[xy], nconn * nline[xy], wcfram + x_or_y, wcfram + x_or_y+1 ); if ( wcfram[x_or_y] == wcfram[x_or_y+1] ) { (void) sprintf( buff, err_flat[xy], wcfram[x_or_y] ); SCTPUT( buff ); } } wcfram[x_or_y+2] = wcfram[x_or_y+3] = 0.0; } /* * calculate large and small tick marks */ GETFRM( axis[xy], wcfram+x_or_y ); } PCKWRR( "XWNDL", 4, wcfram ); PCKWRR( "YWNDL", 4, wcfram+FOR_Y ); } /* * setup graphic device according to MIDAS settings */ PCOPEN( " ", " ", access, &plmode ); /* * get symbol and line types */ (void) SCKGETC( "P5", 1, 40, &actvals, cstype ); /* stype by user */ (void) SCKGETC( "P6", 1, 40, &actvals, cltype ); /* ltype by user */ stype = (int *) osmmget( nrdraw * sizeof( int )); ltype = (int *) osmmget( nrdraw * sizeof( int )); PCKRDI( "STYPE", 1, &actvals, stype ); /* default stype */ PCKRDI( "LTYPE", 1, &actvals, ltype ); /* default ltype */ PCKRDC( "BINMOD", 4, &actvals, binmod ); /* default binmode */ bin = (strncmp( binmod, "ON", 2 ) == 0) ? 1 : 0; GET_SLTYPE( cstype, cltype, nrdraw, stype, ltype ); /* * do the work */ for ( ii = 0; ii < nrdraw; ii++ ) { register int k = ii * nconn; if ( ltype[ii] == 0 && stype[ii] == 0 ) SCTPUT( war_sltyp ); else { if ( stype[ii] != 0 ) { if ( ii >= nline[0] ) PCDATA( stype[ii], 0, bin, rval[0], rval[1]+k, 0.0, nconn ); else if ( ii >= nline[1] ) PCDATA( stype[ii], 0, bin, rval[0]+k, rval[1], 0.0, nconn ); else PCDATA( stype[ii],0, bin, rval[0]+k, rval[1]+k,0.0, nconn ); } if ( ltype[ii] != 0 ) { if ( ii >= nline[0] ) PCDATA( 0, ltype[ii], bin, rval[0], rval[1]+k, 0.0, nconn ); else if ( ii >= nline[1] ) PCDATA( 0, ltype[ii], bin, rval[0]+k, rval[1], 0.0, nconn ); else PCDATA(0, ltype[ii], bin, rval[0]+k, rval[1]+k,0.0, nconn ); } } } /* * draw the axes and the label */ if ( plmode >= 0 && access == 0 ) { /* * plot axes and labels */ PCFRAM( wcfram, wcfram+FOR_Y, label[0], label[1] ); (void) TCSINF( tid, sel ); if ( plmode == 1 ) { (void) strcat ( label[2], table ); (void) sprintf( label[3], "Sel: %s", sel ); PLIDEN( plmode, label[2], label[3] ); } else if ( plmode == 2 ) PLTBLI( plmode, tid, table, string, sel, tbldim ); } PCCLOS(); return SCSEPI(); }