/* @(#)coord.c 17.1.1.1 (ESO-DMD) 01/25/02 17:39:58 */ /*=========================================================================== 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: Copyright (c) 1994 European Southern Observatory, all rights reserved .IDENTIFIER COORD .LANGUAGE C .AUTHOR K. Banse IPG-ESO Garching .KEYWORDS ImageDisplay, cursor .PURPOSE Read the position of the two cursors on the ImageDisplay and get density of relevant pixel. Store xworld, yworld + intensity of cursor in descriptor or table or not at all .ALGORITHM Use enabled cursor(s) and read screen pixels, get real pixels and world coord when the ENTER button is pressed on the cursor board. Exit by pressing ENTER with enabled cursor(s) off. Max. no. of coords is read from CURSOR(1), if this maximum is reached, we exit automatically! The real pixels, world coordinates + intensity are written to key OUTPUTR(10,...) Total no. of coords. read is stored in OUTPUTI(1). Screen pixels are written to CURSOR(1,...4) within CURPOS. .INPUT/OUTPUT the following keywords are used: DAZHOLD/I/1/14 cursor(s) enabled, cursor form(s), split screen mode + other info P1/C/1/15 OR optional descriptor name where world coordinates + pixel values should be stored OR table name, if data should go to a table OR ?, if data only to be displayed on terminal P2/C/1/2 = A or ?, for appending values to descriptor or table or creating new descriptor/table = ID for using identifiers in tables = NO[,start_no] for automatic numbering in tables start_no an optional starting number P3/C/1/3 mark flag, (1:1) = Y for putting cross on screen, else no in case of P2 = ID or NO (2:2) = Y for writing also the identifier into the overlay channel (3:3) = Y or Z for on-demand or continuous polling INPUTI/I/15/1 holds zoom factor, if we work with zoom window OUTPUTR/R/10/10 gets real pix, wld coords + intens for each cursor OUTPUTI/I/1/1 receives total no. of coordinates obtained CURSOR/I/1/4 (1) holds max. no. of coords reading on input (1,,,4) will be filled with last cursor pos. .ENVIRONment MIDAS and IDI #include Prototypes for MIDAS interfaces #include Global variables for DISPLAY interfaces .VERSIONS 1.00 940615 F77 -> C of COORD.FOR, RvH 010423 last modif ------------------------------------------------------------*/ /* Define _POSIX_SOURCE to indicate that this is a POSIX program */ #define _POSIX_SOURCE 1 #include #include #include #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #define JUST_OUTPUT 0 #define TBL_OUTPUT 1 #define DES_OUTPUT 2 #define INIT 1 #define WORK 0 #define CLOSE -1 static int imno; static int ra_flag, tra_flag, cooco[2]; static char inframe[64]; /* */ /*++++++++++++++++++++++++++++++ .PURPOSE write cursor output in to descriptor ------------------------------*/ #ifdef __STDC__ static void WR_DESCR(int *flag, char *frame, char *descr, int ncurs, int circfl, float *xyinfoA, float *xyinfoB ) #else static void WR_DESCR(flag,frame,descr,ncurs,circfl,xyinfoA,xyinfoB) char *frame, *descr; int *flag, ncurs, circfl; float *xyinfoA, *xyinfoB; #endif { register int ii; int actvals; int unit = 0; char output[2]; /* saved variables */ static int mxrec = 10, felem, fid, indx, ncols, norec; static float rbuff[60]; /* max. 2 * 3 * mxrec data points */ if (*flag == INIT) { indx = norec = 0; *flag = WORK; if ( ncurs == 2 ) { if ( circfl ) /* circle */ { ncols = 4; if ( xyinfoB[3] > 0.0 ) ncols ++; /* also Radius2 */ if ( xyinfoB[4] > 0.0 ) ncols ++; /* also Radius3 */ } else ncols = 6; } else ncols = 3; (void) SCKGETC( "P2", 1, 1, &actvals, output ); /* get output_option */ if ((*output == 'a') || (*output == 'A')) felem = -1; /* append the data */ else felem = 1; /* open frame to write in descriptor */ (void) SCFOPN( frame, D_R4_FORMAT, 0, F_IMA_TYPE, &fid ); } /* Do the actual writing into the descriptor */ if ( *flag == WORK ) { for (ii=0; ii<3; ii++) rbuff[indx++] = xyinfoA[ii+4]; if ( ncurs == 2 ) { if (circfl) { rbuff[indx++] = xyinfoB[2]; if (ncols >= 5) rbuff[indx++] = xyinfoB[3]; if (ncols >= 6) rbuff[indx++] = xyinfoB[4]; } else { for (ii=0; ii<3; ii++) rbuff[indx++] = xyinfoB[ii+4]; } } if ( ++norec == mxrec ) /* we buffer the output */ { (void) SCDWRR(fid,descr,rbuff,felem,(ncols*norec),&unit); felem = -1; indx = norec = 0; } } if ( *flag == CLOSE ) { if (norec > 0) (void) SCDWRR(fid,descr,rbuff,felem,(ncols*norec),&unit); (void) SCFCLO( fid ); } } /* */ /*++++++++++++++++++++++++++++++ .PURPOSE write cursor output in to table ------------------------------*/ #ifdef __STDC__ static void WR_TABLE( int *flag, char *table, int ncurs, int circfl, float *xyinfoA, float *xyinfoB, char *labl ) #else static void WR_TABLE( flag, table, ncurs, circfl, xyinfoA, xyinfoB, labl ) char *table, *labl; int *flag, ncurs, circfl; float *xyinfoA, *xyinfoB; #endif { register int ii; int actvals, idum, tindx, m, begin, unit; static int dim3_plane; float rdum, rbuff[10]; static float zplane; double ddum; char *pntr, idstr[10], buff[24], cbuf[3][24], tbunit[20], output[84]; /* initialized variables */ static char *info_iden = "enter identifier (with cursor in display window!): "; static char *tblabl[3][10] = { {"X_coord","Y_coord","Value","X_coordpix","Y_coordpix"," "," "," "," "}, {"Xstart","Ystart","Value1","Xend","Yend","Value2", "Xstartpix","Ystartpix","Xendpix","Yendpix"}, {"X_coord","Y_coord","Value","Radius1","Radius2","Radius3", "X_coordpix","Y_coordpix"," "," "} }; static char *zlabl[2] = {"Z_coord","Z_coordpix"}; char tlabel[10][20]; static int col_id, col_nr, ap_flag = -1, no_flag = -1, id_flag = -1, tid, ncols, nooff, napp, nrow, colref[10]; static char oldstr[10]; if ( *flag == INIT ) { int naxis; *flag = WORK; tra_flag = 0; if ( ncurs == 2 ) /* 3,6 columns for 1,2 cursors */ { if ( circfl ) /* circle */ { ncols = 6; tindx = 2; for (ii=0; ii<4; ii++) (void) strcpy(&tlabel[ii][0],tblabl[tindx][ii]); idum = 4; if ( xyinfoB[3] > 0.0 ) { ncols ++; /* also Radius2 */ (void) strcpy(&tlabel[idum++][0],tblabl[tindx][4]); } if ( xyinfoB[4] > 0.0 ) { ncols ++; /* also Radius3 */ (void) strcpy(&tlabel[idum++][0],tblabl[tindx][5]); } (void) strcpy(&tlabel[idum++][0],tblabl[tindx][6]); (void) strcpy(&tlabel[idum][0],tblabl[tindx][7]); } else /* rectangle */ { ncols = 10; tindx = 1; for (ii=0; ii 2) /* test, if a cube is loaded */ { dim3_plane = ZPLANE; /* frame z-pixel */ (void) SCDRDD(imno,"START",3,1,&actvals,&ddum,&unit,&m); zplane = (float)ddum; (void) SCDRDD(imno,"STEP",3,1,&actvals,&ddum,&unit,&m); rdum = (float)ddum; zplane += (dim3_plane-1) * rdum; /* world coords */ } else dim3_plane = 0; if (ap_flag == -1) /* create new table */ { /* create a (ncols+10)*100 table to have enough space for later use */ (void) TCTINI(table,F_TRANS,F_O_MODE,ncols+10,100,&tid); for (ii=0; ii 0) (void) strcpy(tbunit,"Pixels"); else if (*buff == 'V') (void) strcpy(tbunit," "); else { if (CGN_INDEXS(buff,"pix") > 0) (void) strcpy(tbunit,"Frame Pixels"); else (void) strcpy(tbunit,"World Coords"); } if (tra_flag == 1) /* single cursor */ { if (ii == 0) (void) TCCINI(tid,D_R4_FORMAT,1,"S11.6",tbunit,buff,colref+ii); else if (ii == 1) (void) TCCINI(tid,D_R4_FORMAT,1,"S13.6",tbunit,buff,colref+ii); else (void) TCCINI(tid,D_R4_FORMAT,1,"G12.6",tbunit,buff,colref+ii); } else (void) TCCINI(tid,D_R4_FORMAT,1,"G12.6",tbunit,buff,colref+ii); } if (dim3_plane != 0) { (void) TCCINI(tid,D_R4_FORMAT,1,"G12.6","World Coords","Z_coord", colref+ncols); (void) TCCINI(tid,D_R4_FORMAT,1,"G12.6","Frame Pixels","Z_coordpix", colref+ncols+1); } if (no_flag != -1) /* handle optional number column */ { nooff = 0; (void) TCCINI(tid,D_I4_FORMAT,1,"I8"," ","No",&col_nr); idum = CGN_INDEXC(&cbuf[no_flag][0],','); if ( idum > 0) { actvals = CGN_CNVT(&cbuf[no_flag][idum+1],1,1,&nooff,&rdum,&ddum); if ( actvals <= 0 ) nooff = 0; } if (id_flag != -1) /* ID + NO is not possible */ SCTPUT("ID and NO flag not o.k. - only NO: column supported."); } else (void) TCCINI(tid,D_C_FORMAT,8,"a8"," ","Ident",&col_id); nrow = 0; } else /* open existing table and search for the required columns */ { (void) TCTOPN( table, F_IO_MODE, &tid ); for (ii=0; ii 0) (void) strcpy(tbunit,"Frame Pixels"); else (void) strcpy(tbunit,"World Coords"); } (void) TCCINI(tid,D_R4_FORMAT,1,"G12.6",tbunit,buff,colref+ii); } } if (dim3_plane != 0) { ii = ncols; (void) TCLSER(tid,zlabl[0],colref+ii); if (colref[ii] <= 0) (void) TCCINI(tid,D_R4_FORMAT,1,"G12.6","World Coords","Z_coord", colref+ii); ii ++; (void) TCLSER(tid,zlabl[1],colref+ii); if (colref[ii] <= 0) (void) TCCINI(tid,D_R4_FORMAT,1,"G12.6","Frame Pixels", "Z_coordpix",colref+ii); } if (no_flag != -1) /* handle optional number column */ { (void) TCLSER(tid,"No",&col_nr); if (col_nr <= 0) (void) TCCINI(tid,D_I4_FORMAT,1,"I8"," ","No",&col_nr); nooff = 0; idum = CGN_INDEXC(&cbuf[no_flag][0],','); if ( idum > 0) { actvals = CGN_CNVT(&cbuf[no_flag][idum+1],1,1,&nooff,&rdum,&ddum); if ( actvals <= 0 ) nooff = 0; } if (id_flag != -1) /* ID + NO is not possible */ SCTPUT("ID and NO flag not o.k. - only NO: column supported."); } else { (void) TCLSER(tid,"Ident",&col_id); if (col_id <= 0) (void) TCCINI(tid,D_C_FORMAT,8,"a8"," ","Ident",&col_id); } /* We append after the last row in the table */ (void) TCIGET( tid, &idum, &nrow, &idum, &idum, &idum ); } napp = nrow; } /* Do the actual writing in the table */ if ( *flag == WORK ) { nrow++; /* write in a new row */ for (ii=0; ii<3; ii++) rbuff[ii] = *(xyinfoA+4+ii); if (tra_flag == 1) rbuff[0] /= 15.0; if (ncurs == 0) { rbuff[3] = *(xyinfoA+2); rbuff[4] = *(xyinfoA+3); (void) TCRWRR(tid,nrow,5,colref,rbuff); } else { if ( circfl ) /* circle */ { rbuff[3] = *(xyinfoB+2); if (ncols >= 7) rbuff[4] = *(xyinfoB+3); if (ncols >= 8) rbuff[5] = *(xyinfoB+4); rbuff[ncols-2] = *(xyinfoA+2); rbuff[ncols-1] = *(xyinfoA+3); (void) TCRWRR(tid,nrow,ncols,colref,rbuff); } else { for (ii=0; ii<3; ii++) rbuff[3+ii] = *(xyinfoB+4+ii); rbuff[6] = *(xyinfoA+2); rbuff[7] = *(xyinfoA+3); rbuff[8] = *(xyinfoB+2); rbuff[9] = *(xyinfoB+3); (void) TCRWRR(tid,nrow,10,colref,rbuff); } } if (dim3_plane != 0) { rbuff[0] = zplane; rbuff[1] = (float) dim3_plane; (void) TCRWRR(tid,nrow,2,colref+ncols,rbuff); } /* handle optional number and ident column */ if (no_flag != -1) { idum = ++nooff; (void) TCRWRI(tid,nrow,1,&col_nr,&idum); (void) sprintf(labl,"%-d",idum); } else { if (id_flag != -1) { SCTDIS(info_iden,-1); actvals = 8; /* max. number of characters */ Cgetstr(idstr,&actvals); if ( actvals < 1 ) (void) strcpy(idstr,oldstr); else (void) strcpy(oldstr,idstr); SCTDIS(buff,-9); } else { idum = napp + cooco[1]; sprintf(idstr,"ID%4.4d",idum); } (void) TCEWRC(tid,nrow,col_id,idstr); (void) strcpy( labl, idstr ); } } if (*flag == CLOSE) { (void) sprintf(output,"Created via GET/CURSOR with image: %s",inframe); (void) SCDWRC(tid,"HISTORY",1,output,-1,80,&unit); (void) TCTCLO(tid); } } /* */ int main() { int actvals, circfl, color, coomax, forma, give_info, go_on, knul, noc, statA, statB, trncur, usr_lev, xpos, ypos, zoomwn; int store, dazhld[2], ibuff[5]; static int coords[4] = { -1, -1, -1, -1 }; /* initial position of cursor */ float xyinfoA[7], xyinfoB[7]; char *pntr, draw[4], cursfl[8], labl[9], cbuff[61], outname[61], output[81]; char *info_usr = "switch cursor(s) on - next time we exit..."; int outflg = FALSE, /* output to standard output */ conly = FALSE, scrfl = INIT, tblfl = INIT, desfl = INIT, unit = 0; ra_flag = 0; labl[0] = '\0'; /* initialize MIDAS and global display variables */ (void) SCSPRO("Coord"); DCOPEN(1); CONCHA_C(QDSPNO,QOVCH,1,0); /* Clear overlay-channel if necessary */ /* get main control block for ImageDisplay + keyword DAZHOLD */ (void) SCKRDI( "DAZHOLD", 1, 2, &actvals, dazhld, &unit, &knul ); forma = dazhld[1]; circfl = FALSE; /* get cursor(s) involved */ (void) SCKRDI( "CURSOR", 1, 2, &actvals, ibuff, &unit, &knul ); noc = ibuff[1]; if (noc == 2) { if (dazhld[0] != 2) /* if last curs shape was for single cursor */ forma = 1; /* we default to rectangle */ else if (forma == 2) circfl = TRUE; /* circular ROI */ } else { noc = 0; /* no support for single cursor #1 ... */ if (dazhld[0] > 1) /* if last curs shape was for two cursors */ forma = 3; /* we default to open cross */ } coomax = *ibuff; if ( coomax < 0 ) { conly = TRUE; scrfl = CLOSE; /* No info given on standard output */ coomax = 1; } /* get marker flag for drawing cross (and identifier) */ (void) strcpy(cursfl,"Y Y ?C0"); /* default to NoZoomWindow */ (void) SCKGETC("P3",1,3,&actvals,draw); CGN_UPSTR(draw); cursfl[3] = draw[2]; if (cursfl[3] == 'Z') /* on-demand or continuous cursor read */ { cursfl[1] = 'N'; /* no marks in continuous mode */ noc = 0; /* force to only one cursor ... */ circfl = FALSE; /* rectangular cursor */ coomax = 100000000; /* put it to 100 000 000 */ } else cursfl[1] = *draw; /* this is the mark flag for the cross */ /* Read keyword DAZIN, it contains resp.: zoom factor and auxilary window dimensions */ (void) SCKRDI("DAZIN",1,5,&actvals,ibuff,&unit,&knul); if ((zoomwn = *ibuff) <= 0) /* no zoom window */ trncur = noc; /* true cursor no. */ else /* zoom window */ { if ((ibuff[1] == 0) || (ibuff[2] == 0)) SCETER( 31, "FATAL: invalid window_specs..." ); /* Ok, x,y dimension auxilary window not zero */ cursfl[4] = 'Z'; /* that indicates zooming */ if (noc == 0) trncur = 0; else { if (! circfl) /* pass also cursor no. of zoom window */ cursfl[6] = '2'; else /* indicate, that it's a circle... */ cursfl[6] = '7'; trncur = 2; } noc = 0; /* force to single cursor in main window */ forma = 3; /* for novice users display help */ (void) SCKRDI( "ERROR", 2, 1,&actvals, &usr_lev, &unit, &knul ); if ( usr_lev == 1 ) auxhelp( 0 ); } /* init cursor(s) in main window */ if ( noc == 2 ) { color = 0; /* define cursor colour */ if ( forma == -1 ) forma = 1; } else { color = 2; if ( forma == -1 ) forma = 3; } (void) SETCUR_C(QDSPNO,noc,forma,color,coords); /* Set output flag and name of output table or descriptor */ (void) SCKGETC("P1",1,60,&actvals,outname); if (*outname == '?') outflg = JUST_OUTPUT; else { int idum; idum = CGN_INDEXS(outname,",d"); if (idum < 0) idum = CGN_INDEXS(outname,",D"); if (idum > 0) { outflg = DES_OUTPUT; outname[idum] = '\0'; } else { outflg = TBL_OUTPUT; (void) strcpy(cbuff,outname); CGN_FRAME(cbuff,3,outname,0); } } cooco[0] = 0; /* counter for cursor reading */ cooco[1] = 0; /* counter for data storing */ (void) strcpy(inframe," "); /* necessary for calls of GetCursor */ /* read cursor position(s) */ give_info = go_on = TRUE; while ((go_on) && (*cooco < coomax)) { Cursor_loop: GetCursor(cursfl,inframe,xyinfoA,&statA,xyinfoB,&statB); if ((statA == -9) && (*cooco == 0)) goto Cursor_loop; /* first entry & no keybd-input */ if ( (trncur == 0 && statA == 0) || (trncur == 2 && statA == 0 && statB == 0) ) { if ( give_info && *cooco == 0 ) { SCTDIS(output,-9); SCTDIS(info_usr,80); (void) strcpy(inframe," "); give_info = FALSE; } else { if (cursfl[3] != 'Z') SCTDIS(" ",0); else SCTDIS(output,-9); /* erase last line */ go_on = FALSE; } } /* we got cursor input - increment counter */ else { (*cooco)++; /* increment cursor read counter */ if (*cooco == 1) { int kk; double dd1[3], dd2[3]; (void) SCFOPN(inframe,D_OLD_FORMAT,0,F_IMA_TYPE,&imno); kk = fp2wc(0,imno,dd1,dd2); if (kk == 0) ra_flag = 1; } store = 0; if ((cursfl[3] != 'Z') || (statA < 0)) { cooco[1]++; if (outflg != JUST_OUTPUT) store = 1; /* store info in keyword OUTPUTR[10,...,20] */ (void) SCKWRR("OUTPUTR",xyinfoA+2,10,5,&unit); if (trncur == 2) (void) SCKWRR("OUTPUTR",xyinfoB+2,15,5,&unit); if (outflg == TBL_OUTPUT) /* fill table */ WR_TABLE(&tblfl,outname,trncur,circfl,xyinfoA,xyinfoB,labl); else if (outflg == DES_OUTPUT) /* fill descriptor */ WR_DESCR(&desfl,inframe,outname,trncur,circfl,xyinfoA,xyinfoB); /* if desired, draw label or number in overlay plane */ if ( draw[1] == 'Y') { /* move one char. to the right */ xpos = CGN_NINT( xyinfoA[0] ) + 9; ypos = CGN_NINT( xyinfoA[1] ); if ( trncur == 2 ) ypos += 9; (void) IIGTXT_C(QDSPNO,QOVCH,labl,xpos,ypos,0,0,255,0); } } /* in all cases, display line with complete info */ WR_SCREEN(&scrfl,cursfl,trncur,circfl,ra_flag,xyinfoA,xyinfoB,labl); if (store == 1) { labl[0] = '\0'; /* clear label + advance one line */ } } } /* end of the while-loop */ /* That's it folks... */ if (cooco[1] > 0) /* something was entered */ { if ( outflg == TBL_OUTPUT ) { tblfl = CLOSE; WR_TABLE(&tblfl,outname,trncur,circfl,xyinfoA,xyinfoB,labl); } else if (outflg == DES_OUTPUT) { desfl = CLOSE; WR_DESCR(&desfl,inframe,outname,trncur,circfl,xyinfoA,xyinfoB); } ibuff[0] = xyinfoA[0]; ibuff[1] = xyinfoA[1]; ibuff[2] = xyinfoB[0]; ibuff[3] = xyinfoB[1]; } else if (conly) /* if Cursor only, get coords any way */ (void) IICRCP_C(QDSPNO,-1,noc,ibuff,ibuff+1,ibuff+2); (void) SCKWRI("CURSOR",ibuff,1,4,&unit); /* Save no. of coordinates obtained for subsequent applications */ (void) SCKWRI("OUTPUTI",cooco+1,1,1,&unit); if ( zoomwn > 0 ) /* reset cursor setup */ SETCUR_C(QDSPNO,trncur,dazhld[1],2,coords); DCCLOS(QDSPNO); if ( cursfl[1] == 'Y') (void) Crefrovr(); /* refresh overlay */ return SCSEPI(); }